Skip to content

Commit 81823b1

Browse files
committed
Generalise the seed in Gen.
This is needed since it appears that, in hspec, we can only get access to a specific QCGen. However, this also implements `StdGen`, so can be used here.
1 parent ea4eb90 commit 81823b1

File tree

2 files changed

+16
-18
lines changed

2 files changed

+16
-18
lines changed

cuddle.cabal

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
cabal-version: 3.4
22
name: cuddle
3-
version: 0.1.10.0
3+
version: 0.1.11.0
44
synopsis: CDDL Generator and test utilities
55

66
-- description:

src/Codec/CBOR/Cuddle/CBOR/Gen.hs

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ import Control.Monad (replicateM, (<=<))
3434
import Control.Monad.Reader (Reader, runReader)
3535
import Control.Monad.State.Strict (StateT, runStateT)
3636
import Data.ByteString (ByteString)
37+
import Data.ByteString.Base16 qualified as Base16
3738
import Data.Functor ((<&>))
3839
import Data.Functor.Identity (Identity (runIdentity))
3940
import Data.List.NonEmpty qualified as NE
@@ -48,13 +49,11 @@ import System.Random.Stateful
4849
RandomGen (genShortByteString, genWord32, genWord64),
4950
RandomGenM,
5051
StatefulGen (..),
51-
StdGen,
5252
UniformRange (uniformRM),
5353
applyRandomGenM,
5454
randomM,
5555
uniformByteStringM,
5656
)
57-
import qualified Data.ByteString.Base16 as Base16
5857

5958
--------------------------------------------------------------------------------
6059
-- Generator infrastructure
@@ -110,8 +109,6 @@ instance (RandomGen g) => StatefulGen (CapGenM g) (M g) where
110109
instance (RandomGen r) => RandomGenM (CapGenM r) r (M r) where
111110
applyRandomGenM f _ = state @"randomSeed" f
112111

113-
type Gen = M StdGen
114-
115112
runGen :: M g a -> GenEnv g -> GenState g -> (a, GenState g)
116113
runGen (M m) env st = runReader (runStateT m st) env
117114

@@ -141,21 +138,21 @@ genText n = pure $ T.pack $ take n ['a' ..]
141138
-- Combinators
142139
--------------------------------------------------------------------------------
143140

144-
choose :: [a] -> Gen a
141+
choose :: (RandomGen g) => [a] -> M g a
145142
choose xs = genUniformRM (0, length xs) >>= \i -> pure $ xs !! i
146143

147-
oneOf :: [Gen a] -> Gen a
144+
oneOf :: (RandomGen g) => [M g a] -> M g a
148145
oneOf xs = genUniformRM (0, length xs) >>= \i -> xs !! i
149146

150-
oneOfGenerated :: Gen [a] -> Gen a
147+
oneOfGenerated :: (RandomGen g) => M g [a] -> M g a
151148
oneOfGenerated genXs = genXs >>= choose
152149

153150
--------------------------------------------------------------------------------
154151
-- Postlude
155152
--------------------------------------------------------------------------------
156153

157154
-- | Primitive types defined by the CDDL specification, with their generators
158-
genPostlude :: PTerm -> Gen Term
155+
genPostlude :: (RandomGen g) => PTerm -> M g Term
159156
genPostlude pt = case pt of
160157
PTBool ->
161158
genRandomM
@@ -233,7 +230,7 @@ pattern G xs = GroupTerm xs
233230
-- Generator functions
234231
--------------------------------------------------------------------------------
235232

236-
genForCTree :: CTree MonoRef -> Gen WrappedTerm
233+
genForCTree :: (RandomGen g) => CTree MonoRef -> M g WrappedTerm
237234
genForCTree (CTree.Literal v) = S <$> genValue v
238235
genForCTree (CTree.Postlude pt) = S <$> genPostlude pt
239236
genForCTree (CTree.Map nodes) = do
@@ -322,12 +319,12 @@ genForCTree (CTree.Enum node) = do
322319
_ -> error "Attempt to form an enum from something other than a group"
323320
genForCTree (CTree.Unwrap node) = genForCTree =<< resolveIfRef node
324321

325-
genForNode :: CTree.Node MonoRef -> Gen WrappedTerm
322+
genForNode :: (RandomGen g) => CTree.Node MonoRef -> M g WrappedTerm
326323
genForNode = genForCTree <=< resolveIfRef
327324

328325
-- | Take something which might be a reference and resolve it to the relevant
329326
-- Tree, following multiple links if necessary.
330-
resolveIfRef :: CTree.Node MonoRef -> Gen (CTree MonoRef)
327+
resolveIfRef :: (RandomGen g) => CTree.Node MonoRef -> M g (CTree MonoRef)
331328
resolveIfRef (MIt a) = pure a
332329
resolveIfRef (MRuleRef n) = do
333330
(CTreeRoot cddl) <- ask @"cddl"
@@ -343,7 +340,7 @@ resolveIfRef (MRuleRef n) = do
343340
-- This will throw an error if the generated item does not correspond to a
344341
-- single CBOR term (e.g. if the name resolves to a group, which cannot be
345342
-- generated outside a context).
346-
genForName :: Name -> Gen Term
343+
genForName :: (RandomGen g) => Name -> M g Term
347344
genForName n = do
348345
(CTreeRoot cddl) <- ask @"cddl"
349346
case Map.lookup n cddl of
@@ -359,9 +356,10 @@ genForName n = do
359356

360357
-- | Apply an occurence indicator to a group entry
361358
applyOccurenceIndicator ::
359+
(RandomGen g) =>
362360
OccurrenceIndicator ->
363-
Gen WrappedTerm ->
364-
Gen WrappedTerm
361+
M g WrappedTerm ->
362+
M g WrappedTerm
365363
applyOccurenceIndicator OIOptional oldGen =
366364
genRandomM >>= \case
367365
False -> pure $ G mempty
@@ -376,23 +374,23 @@ applyOccurenceIndicator (OIBounded mlb mub) oldGen =
376374
genUniformRM (fromMaybe 0 mlb :: Word64, fromMaybe 10 mub)
377375
>>= \i -> G <$> replicateM (fromIntegral i) oldGen
378376

379-
genValue :: Value -> Gen Term
377+
genValue :: (RandomGen g) => Value -> M g Term
380378
genValue (VUInt i) = pure . TInt $ fromIntegral i
381379
genValue (VNInt i) = pure . TInt $ fromIntegral (-i)
382380
genValue (VBignum i) = pure $ TInteger i
383381
genValue (VFloat16 i) = pure . THalf $ i
384382
genValue (VFloat32 i) = pure . TFloat $ i
385383
genValue (VFloat64 i) = pure . TDouble $ i
386384
genValue (VText t) = pure $ TString t
387-
genValue (VBytes b) = case Base16.decode b of
385+
genValue (VBytes b) = case Base16.decode b of
388386
Right bHex -> pure $ TBytes bHex
389387
Left err -> error $ "Unable to parse hex encoded bytestring: " <> err
390388

391389
--------------------------------------------------------------------------------
392390
-- Generator functions
393391
--------------------------------------------------------------------------------
394392

395-
generateCBORTerm :: CTreeRoot' Identity MonoRef -> Name -> StdGen -> Term
393+
generateCBORTerm :: (RandomGen g) => CTreeRoot' Identity MonoRef -> Name -> g -> Term
396394
generateCBORTerm cddl n stdGen =
397395
let genEnv = GenEnv {cddl, fakeSeed = CapGenM}
398396
genState = GenState {randomSeed = stdGen}

0 commit comments

Comments
 (0)