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_Normal -- ^ Perform normal build
| BuildMode_Repair -- ^ Try to repair corrupted or missing paths by re-building or re-downloading them | 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) | 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 -- | Build result status
data BuildStatus = data BuildStatus =
@ -43,7 +43,7 @@ data BuildStatus =
| BuildStatus_NotDeterministic | BuildStatus_NotDeterministic
| BuildStatus_ResolvesToAlreadyValid | BuildStatus_ResolvesToAlreadyValid
| BuildStatus_NoSubstituters | BuildStatus_NoSubstituters
deriving (Eq, Generic, Ord, Enum, Show) deriving (Bounded, Eq, Generic, Ord, Enum, Show)
-- | Result of the build -- | Result of the build
data BuildResult = BuildResult data BuildResult = BuildResult

View File

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

View File

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

View File

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