hegel-0.1.0: src/Hegel/Generator/Range.hs
-- | Shared range option types and validation helpers.
module Hegel.Generator.Range
( RangeOpts (..)
, defaultRangeOpts
, validateSizeBounds
) where
import Data.Default (Default (def))
import Data.Maybe (fromMaybe)
-- | Configuration for lower and upper bounds used by range-limited generators.
--
-- Use 'def' for the default unbounded case, or update specific fields:
--
-- @
-- integers def { rangeMin = Just 0, rangeMax = Just 100 }
-- text def { rangeMin = Just 1, rangeMax = Just 10 }
-- @
--
-- Collection-like generators interpret these fields as @min_size@ and
-- @max_size@ bounds.
data RangeOpts a = RangeOpts
{ rangeMin :: !(Maybe a)
-- ^ Inclusive lower bound when present.
, rangeMax :: !(Maybe a)
-- ^ Inclusive upper bound when present.
} deriving (Eq, Show)
instance Default (RangeOpts a) where
def = RangeOpts
{ rangeMin = Nothing
, rangeMax = Nothing
}
-- | Convenience alias for 'def'.
defaultRangeOpts :: RangeOpts a
defaultRangeOpts = def
-- | Validate non-negative size bounds and return the normalized min/max pair.
validateSizeBounds :: String -> RangeOpts Int -> (Int, Maybe Int)
validateSizeBounds label RangeOpts {rangeMin = minSize, rangeMax = maxSize} =
(if minSize' < 0
then error $ label ++ ": min_size=" ++ show minSize' ++ " must be non-negative"
else ())
`seq`
(case maxSize of
Just mx | mx < 0 ->
error $ label ++ ": max_size=" ++ show mx ++ " must be non-negative"
Just mx | minSize' > mx ->
error $ label ++ ": max_size=" ++ show mx ++ " < min_size=" ++ show minSize'
_ -> ())
`seq`
(minSize', maxSize)
where
minSize' = fromMaybe 0 minSize