Merge pull request #284 from haskell-nix/srk/enumBounds

fix min/maxBound serializer checks
This commit is contained in:
Sorki 2024-07-31 14:50:53 +00:00 committed by GitHub
commit de88b657b5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 28 additions and 11 deletions

View File

@ -24,7 +24,7 @@ data BuildMode
= BuildMode_Normal -- ^ Perform normal build
| BuildMode_Repair -- ^ Try to repair corrupted or missing paths by re-building or re-downloading them
| BuildMode_Check -- ^ Check if the build is reproducible (rebuild and compare to previous build)
deriving (Eq, Generic, Ord, Enum, Show)
deriving (Bounded, Eq, Generic, Ord, Enum, Show)
-- | Build result status
data BuildStatus =
@ -43,7 +43,7 @@ data BuildStatus =
| BuildStatus_NotDeterministic
| BuildStatus_ResolvesToAlreadyValid
| BuildStatus_NoSubstituters
deriving (Eq, Generic, Ord, Enum, Show)
deriving (Bounded, Eq, Generic, Ord, Enum, Show)
-- | Result of the build
data BuildResult = BuildResult

View File

@ -302,14 +302,24 @@ putBool True = putInt (1 :: Int8)
putBool False = putInt (0 :: Int8)
-- | Utility toEnum version checking bounds using Bounded class
toEnumCheckBounds :: Enum a => Int -> Either String a
toEnumCheckBounds
:: forall a
. ( Bounded a
, Enum a
)
=> Int
-> Either String a
toEnumCheckBounds = \case
x | x < minBound -> Left $ "enum out of min bound " ++ show x
x | x > maxBound -> Left $ "enum out of max bound " ++ show x
x | x < fromEnum (minBound @a) -> Left $ "enum out of min bound " ++ show x
x | x > fromEnum (maxBound @a) -> Left $ "enum out of max bound " ++ show x
x | otherwise -> Right $ toEnum x
-- | Deserialize @Enum@ to integer
getEnum :: Enum a => Get a
getEnum
:: ( Bounded a
, Enum a
)
=> Get a
getEnum =
toEnumCheckBounds <$> getInt
>>= either fail pure

View File

@ -345,17 +345,23 @@ byteString = Serializer
-- | Utility toEnum version checking bounds using Bounded class
toEnumCheckBoundsM
:: ( Enum a
:: forall a m
. ( Bounded a
, Enum a
, MonadError SError m
)
=> Int
-> m a
toEnumCheckBoundsM = \case
x | x < minBound -> throwError $ SError_EnumOutOfMinBound x
x | x > maxBound -> throwError $ SError_EnumOutOfMaxBound x
x | x < fromEnum (minBound @a) -> throwError $ SError_EnumOutOfMinBound x
x | x > fromEnum (maxBound @a) -> throwError $ SError_EnumOutOfMaxBound x
x | otherwise -> pure $ toEnum x
enum :: Enum a => NixSerializer r SError a
enum
:: ( Bounded a
, Enum a
)
=> NixSerializer r SError a
enum = Serializer
{ getS = getS int >>= toEnumCheckBoundsM
, putS = putS int . fromEnum

View File

@ -24,7 +24,8 @@ spec :: Spec
spec = do
let
itE
:: ( Enum a
:: ( Bounded a
, Enum a
, Show a
)
=> String