Skip to content

Commit

Permalink
Merge pull request #284 from haskell-nix/srk/enumBounds
Browse files Browse the repository at this point in the history
fix min/maxBound serializer checks
  • Loading branch information
sorki authored Jul 31, 2024
2 parents c105037 + 67687b7 commit de88b65
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 11 deletions.
4 changes: 2 additions & 2 deletions hnix-store-core/src/System/Nix/Build.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand All @@ -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
Expand Down
18 changes: 14 additions & 4 deletions hnix-store-remote/src/Data/Serializer/Example.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
14 changes: 10 additions & 4 deletions hnix-store-remote/src/System/Nix/Store/Remote/Serializer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion hnix-store-remote/tests/EnumSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ spec :: Spec
spec = do
let
itE
:: ( Enum a
:: ( Bounded a
, Enum a
, Show a
)
=> String
Expand Down

0 comments on commit de88b65

Please sign in to comment.