From 67687b76975cde5fa5eafd6c4d429706d96fba96 Mon Sep 17 00:00:00 2001 From: sorki Date: Wed, 31 Jul 2024 16:13:15 +0200 Subject: [PATCH] fix min/maxBound serializer checks before it wrongly compared to min/maxBound of Int(eger). --- hnix-store-core/src/System/Nix/Build.hs | 4 ++-- .../src/Data/Serializer/Example.hs | 18 ++++++++++++++---- .../src/System/Nix/Store/Remote/Serializer.hs | 14 ++++++++++---- hnix-store-remote/tests/EnumSpec.hs | 3 ++- 4 files changed, 28 insertions(+), 11 deletions(-) diff --git a/hnix-store-core/src/System/Nix/Build.hs b/hnix-store-core/src/System/Nix/Build.hs index 248732d..17e484c 100644 --- a/hnix-store-core/src/System/Nix/Build.hs +++ b/hnix-store-core/src/System/Nix/Build.hs @@ -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 diff --git a/hnix-store-remote/src/Data/Serializer/Example.hs b/hnix-store-remote/src/Data/Serializer/Example.hs index d7709d3..a53d6dc 100644 --- a/hnix-store-remote/src/Data/Serializer/Example.hs +++ b/hnix-store-remote/src/Data/Serializer/Example.hs @@ -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 diff --git a/hnix-store-remote/src/System/Nix/Store/Remote/Serializer.hs b/hnix-store-remote/src/System/Nix/Store/Remote/Serializer.hs index b661bf3..14c9708 100644 --- a/hnix-store-remote/src/System/Nix/Store/Remote/Serializer.hs +++ b/hnix-store-remote/src/System/Nix/Store/Remote/Serializer.hs @@ -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 diff --git a/hnix-store-remote/tests/EnumSpec.hs b/hnix-store-remote/tests/EnumSpec.hs index 1c28c1c..d77eaf5 100644 --- a/hnix-store-remote/tests/EnumSpec.hs +++ b/hnix-store-remote/tests/EnumSpec.hs @@ -24,7 +24,8 @@ spec :: Spec spec = do let itE - :: ( Enum a + :: ( Bounded a + , Enum a , Show a ) => String