Skip to content

Commit 2618ae7

Browse files
committed
WIP
1 parent adcc5e8 commit 2618ae7

File tree

6 files changed

+255
-145
lines changed

6 files changed

+255
-145
lines changed

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

Lines changed: 16 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,17 @@ import Codec.CBOR.Cuddle.CDDL (
2525
Value (..),
2626
ValueVariant (..),
2727
)
28-
import Codec.CBOR.Cuddle.CDDL.CTree (CTree, CTreeRoot' (..))
28+
import Codec.CBOR.Cuddle.CDDL.CTree (
29+
CTree,
30+
CTreeRoot' (..),
31+
WrappedTerm,
32+
flattenWrappedList,
33+
pairTermList,
34+
singleTermList,
35+
pattern G,
36+
pattern P,
37+
pattern S,
38+
)
2939
import Codec.CBOR.Cuddle.CDDL.CTree qualified as CTree
3040
import Codec.CBOR.Cuddle.CDDL.CtlOp qualified as CtlOp
3141
import Codec.CBOR.Cuddle.CDDL.Postlude (PTerm (..))
@@ -53,6 +63,7 @@ import System.Random.Stateful (
5363
Random,
5464
RandomGen (..),
5565
StateGenM (..),
66+
StatefulGen (..),
5667
UniformRange (uniformRM),
5768
randomM,
5869
uniformByteStringM,
@@ -207,53 +218,11 @@ genPostlude pt = case pt of
207218
PTNil -> pure TNull
208219
PTUndefined -> pure $ TSimple 23
209220

210-
--------------------------------------------------------------------------------
211-
-- Kinds of terms
212-
--------------------------------------------------------------------------------
213-
214-
data WrappedTerm
215-
= SingleTerm Term
216-
| PairTerm Term Term
217-
| GroupTerm [WrappedTerm]
218-
deriving (Eq, Show)
219-
220-
-- | Recursively flatten wrapped list. That is, expand any groups out to their
221-
-- individual entries.
222-
flattenWrappedList :: [WrappedTerm] -> [WrappedTerm]
223-
flattenWrappedList [] = []
224-
flattenWrappedList (GroupTerm xxs : xs) =
225-
flattenWrappedList xxs <> flattenWrappedList xs
226-
flattenWrappedList (y : xs) = y : flattenWrappedList xs
227-
228-
pattern S :: Term -> WrappedTerm
229-
pattern S t = SingleTerm t
230-
231-
-- | Convert a list of wrapped terms to a list of terms. If any 'PairTerm's are
232-
-- present, we just take their "value" part.
233-
singleTermList :: [WrappedTerm] -> Maybe [Term]
234-
singleTermList [] = Just []
235-
singleTermList (S x : xs) = (x :) <$> singleTermList xs
236-
singleTermList (P _ y : xs) = (y :) <$> singleTermList xs
237-
singleTermList _ = Nothing
238-
239-
pattern P :: Term -> Term -> WrappedTerm
240-
pattern P t1 t2 = PairTerm t1 t2
241-
242-
-- | Convert a list of wrapped terms to a list of pairs of terms, or fail if any
243-
-- 'SingleTerm's are present.
244-
pairTermList :: [WrappedTerm] -> Maybe [(Term, Term)]
245-
pairTermList [] = Just []
246-
pairTermList (P x y : xs) = ((x, y) :) <$> pairTermList xs
247-
pairTermList _ = Nothing
248-
249-
pattern G :: [WrappedTerm] -> WrappedTerm
250-
pattern G xs = GroupTerm xs
251-
252221
--------------------------------------------------------------------------------
253222
-- Generator functions
254223
--------------------------------------------------------------------------------
255224

256-
genForCTree :: RandomGen g => CTree MonoRef -> M g WrappedTerm
225+
genForCTree :: forall g. RandomGen g => CTree MonoRef -> M g WrappedTerm
257226
genForCTree (CTree.Literal v) = S <$> genValue v
258227
genForCTree (CTree.Postlude pt) = S <$> genPostlude pt
259228
genForCTree (CTree.Map nodes) = do
@@ -362,6 +331,7 @@ genForCTree (CTree.Tag tag node) = do
362331
case enc of
363332
S x -> pure $ S $ TTagged tag x
364333
_ -> error "Tag controller does not correspond to a single term"
334+
genForCTree (CTree.WithGen gen _) = gen StateGenM
365335

366336
genForNode :: RandomGen g => CTree.Node MonoRef -> M g WrappedTerm
367337
genForNode = genForCTree <=< resolveIfRef
@@ -446,7 +416,8 @@ generateCBORTerm cddl n stdGen =
446416
genState = GenState {randomSeed = stdGen, depth = 1}
447417
in evalGen (genForName n) genEnv genState
448418

449-
generateCBORTerm' :: RandomGen g => CTreeRoot' Identity MonoRef -> Name -> g -> (Term, g)
419+
generateCBORTerm' ::
420+
(RandomGen g, StatefulGen g (M g)) => CTreeRoot' Identity MonoRef -> Name -> g -> (Term, g)
450421
generateCBORTerm' cddl n stdGen =
451422
let genEnv = GenEnv {cddl}
452423
genState = GenState {randomSeed = stdGen, depth = 1}

src/Codec/CBOR/Cuddle/CBOR/Validator.hs

Lines changed: 67 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,9 @@ validateCBOR' bs rule cddl@(CTreeRoot tree) =
145145
-- spec
146146
validateTerm ::
147147
MonadReader CDDL m =>
148-
Term -> Rule -> m CBORTermResult
148+
Term ->
149+
Rule ->
150+
m CBORTermResult
149151
validateTerm term rule =
150152
let f = case term of
151153
TInt i -> validateInteger (fromIntegral i)
@@ -183,7 +185,9 @@ validateTerm term rule =
183185
-- Ints, so we convert everything to Integer.
184186
validateInteger ::
185187
MonadReader CDDL m =>
186-
Integer -> Rule -> m CDDLResult
188+
Integer ->
189+
Rule ->
190+
m CDDLResult
187191
validateInteger i rule =
188192
($ rule) <$> do
189193
getRule rule >>= \case
@@ -308,7 +312,9 @@ controlInteger i Ne ctrl =
308312
-- | Validating a `Float16`
309313
validateHalf ::
310314
MonadReader CDDL m =>
311-
Float -> Rule -> m CDDLResult
315+
Float ->
316+
Rule ->
317+
m CDDLResult
312318
validateHalf f rule =
313319
($ rule) <$> do
314320
getRule rule >>= \case
@@ -343,7 +349,9 @@ controlHalf f Ne ctrl =
343349
-- | Validating a `Float32`
344350
validateFloat ::
345351
MonadReader CDDL m =>
346-
Float -> Rule -> m CDDLResult
352+
Float ->
353+
Rule ->
354+
m CDDLResult
347355
validateFloat f rule =
348356
($ rule) <$> do
349357
getRule rule >>= \case
@@ -383,7 +391,9 @@ controlFloat f Ne ctrl =
383391
-- | Validating a `Float64`
384392
validateDouble ::
385393
MonadReader CDDL m =>
386-
Double -> Rule -> m CDDLResult
394+
Double ->
395+
Rule ->
396+
m CDDLResult
387397
validateDouble f rule =
388398
($ rule) <$> do
389399
getRule rule >>= \case
@@ -430,7 +440,9 @@ controlDouble f Ne ctrl =
430440
-- | Validating a boolean
431441
validateBool ::
432442
MonadReader CDDL m =>
433-
Bool -> Rule -> m CDDLResult
443+
Bool ->
444+
Rule ->
445+
m CDDLResult
434446
validateBool b rule =
435447
($ rule) <$> do
436448
getRule rule >>= \case
@@ -463,7 +475,9 @@ controlBool b Ne ctrl =
463475
-- | Validating a `TSimple`. It is unclear if this is used for anything else than undefined.
464476
validateSimple ::
465477
MonadReader CDDL m =>
466-
Word8 -> Rule -> m CDDLResult
478+
Word8 ->
479+
Rule ->
480+
m CDDLResult
467481
validateSimple 23 rule =
468482
($ rule) <$> do
469483
getRule rule >>= \case
@@ -498,7 +512,9 @@ validateNull rule =
498512
-- | Validating a byte sequence
499513
validateBytes ::
500514
MonadReader CDDL m =>
501-
BS.ByteString -> Rule -> m CDDLResult
515+
BS.ByteString ->
516+
Rule ->
517+
m CDDLResult
502518
validateBytes bs rule =
503519
($ rule) <$> do
504520
getRule rule >>= \case
@@ -517,7 +533,11 @@ validateBytes bs rule =
517533
-- | Controls for byte strings
518534
controlBytes ::
519535
forall m.
520-
MonadReader CDDL m => BS.ByteString -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
536+
MonadReader CDDL m =>
537+
BS.ByteString ->
538+
CtlOp ->
539+
Rule ->
540+
m (Either (Maybe CBORTermResult) ())
521541
controlBytes bs Size ctrl =
522542
getRule ctrl >>= \case
523543
Literal (Value (VUInt (fromIntegral -> sz)) _) -> pure $ boolCtrl $ BS.length bs == sz
@@ -568,7 +588,9 @@ controlBytes bs Cborseq ctrl =
568588
-- | Validating text strings
569589
validateText ::
570590
MonadReader CDDL m =>
571-
T.Text -> Rule -> m CDDLResult
591+
T.Text ->
592+
Rule ->
593+
m CDDLResult
572594
validateText txt rule =
573595
($ rule) <$> do
574596
getRule rule >>= \case
@@ -607,7 +629,10 @@ controlText s Regexp ctrl =
607629
-- | Validating a `TTagged`
608630
validateTagged ::
609631
MonadReader CDDL m =>
610-
Word64 -> Term -> Rule -> m CDDLResult
632+
Word64 ->
633+
Term ->
634+
Rule ->
635+
m CDDLResult
611636
validateTagged tag term rule =
612637
($ rule) <$> do
613638
getRule rule >>= \case
@@ -633,25 +658,25 @@ flattenGroup :: CDDL -> [Rule] -> [Rule]
633658
flattenGroup cddl nodes =
634659
mconcat
635660
[ case resolveIfRef cddl rule of
636-
Literal {} -> [rule]
637-
Postlude {} -> [rule]
638-
Map {} -> [rule]
639-
Array {} -> [rule]
640-
Choice {} -> [rule]
641-
KV {} -> [rule]
642-
Occur {} -> [rule]
643-
Range {} -> [rule]
644-
Control {} -> [rule]
645-
Enum e -> case resolveIfRef cddl e of
646-
Group g -> flattenGroup cddl g
647-
_ -> error "Malformed cddl"
648-
Unwrap g -> case resolveIfRef cddl g of
649-
Map n -> flattenGroup cddl n
650-
Array n -> flattenGroup cddl n
651-
Tag _ n -> [n]
652-
_ -> error "Malformed cddl"
653-
Tag {} -> [rule]
661+
Literal {} -> [rule]
662+
Postlude {} -> [rule]
663+
Map {} -> [rule]
664+
Array {} -> [rule]
665+
Choice {} -> [rule]
666+
KV {} -> [rule]
667+
Occur {} -> [rule]
668+
Range {} -> [rule]
669+
Control {} -> [rule]
670+
Enum e -> case resolveIfRef cddl e of
654671
Group g -> flattenGroup cddl g
672+
_ -> error "Malformed cddl"
673+
Unwrap g -> case resolveIfRef cddl g of
674+
Map n -> flattenGroup cddl n
675+
Array n -> flattenGroup cddl n
676+
Tag _ n -> [n]
677+
_ -> error "Malformed cddl"
678+
Tag {} -> [rule]
679+
Group g -> flattenGroup cddl g
655680
| rule <- nodes
656681
]
657682

@@ -725,7 +750,9 @@ isOptional rule =
725750
validateListWithExpandedRules ::
726751
forall m.
727752
MonadReader CDDL m =>
728-
[Term] -> [Rule] -> m [(Rule, CBORTermResult)]
753+
[Term] ->
754+
[Rule] ->
755+
m [(Rule, CBORTermResult)]
729756
validateListWithExpandedRules terms rules =
730757
go (zip terms rules)
731758
where
@@ -795,7 +822,9 @@ validateList terms rule =
795822
validateMapWithExpandedRules ::
796823
forall m.
797824
MonadReader CDDL m =>
798-
[(Term, Term)] -> [Rule] -> m ([AMatchedItem], Maybe ANonMatchedItem)
825+
[(Term, Term)] ->
826+
[Rule] ->
827+
m ([AMatchedItem], Maybe ANonMatchedItem)
799828
validateMapWithExpandedRules =
800829
go
801830
where
@@ -853,7 +882,9 @@ validateExpandedMap terms rules = go rules
853882

854883
validateMap ::
855884
MonadReader CDDL m =>
856-
[(Term, Term)] -> Rule -> m CDDLResult
885+
[(Term, Term)] ->
886+
Rule ->
887+
m CDDLResult
857888
validateMap terms rule =
858889
($ rule) <$> do
859890
getRule rule >>= \case
@@ -899,7 +930,10 @@ dummyRule = MRuleRef (Name "dummy" mempty)
899930
-- | Validate both rules
900931
ctrlAnd ::
901932
Monad m =>
902-
(Rule -> m CDDLResult) -> Rule -> Rule -> m (Rule -> CDDLResult)
933+
(Rule -> m CDDLResult) ->
934+
Rule ->
935+
Rule ->
936+
m (Rule -> CDDLResult)
903937
ctrlAnd v tgt ctrl =
904938
v tgt >>= \case
905939
Valid _ ->

src/Codec/CBOR/Cuddle/CDDL/CTree.hs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{-# LANGUAGE DataKinds #-}
2+
{-# LANGUAGE PatternSynonyms #-}
23

34
module Codec.CBOR.Cuddle.CDDL.CTree where
45

@@ -10,11 +11,55 @@ import Codec.CBOR.Cuddle.CDDL (
1011
)
1112
import Codec.CBOR.Cuddle.CDDL.CtlOp
1213
import Codec.CBOR.Cuddle.CDDL.Postlude (PTerm)
14+
import Codec.CBOR.Term (Term)
1315
import Data.Hashable (Hashable)
1416
import Data.List.NonEmpty qualified as NE
1517
import Data.Map.Strict qualified as Map
1618
import Data.Word (Word64)
1719
import GHC.Generics (Generic)
20+
import System.Random.Stateful (StatefulGen)
21+
22+
--------------------------------------------------------------------------------
23+
-- Kinds of terms
24+
--------------------------------------------------------------------------------
25+
26+
data WrappedTerm
27+
= SingleTerm Term
28+
| PairTerm Term Term
29+
| GroupTerm [WrappedTerm]
30+
deriving (Eq, Show, Generic)
31+
32+
-- | Recursively flatten wrapped list. That is, expand any groups out to their
33+
-- individual entries.
34+
flattenWrappedList :: [WrappedTerm] -> [WrappedTerm]
35+
flattenWrappedList [] = []
36+
flattenWrappedList (GroupTerm xxs : xs) =
37+
flattenWrappedList xxs <> flattenWrappedList xs
38+
flattenWrappedList (y : xs) = y : flattenWrappedList xs
39+
40+
pattern S :: Term -> WrappedTerm
41+
pattern S t = SingleTerm t
42+
43+
-- | Convert a list of wrapped terms to a list of terms. If any 'PairTerm's are
44+
-- present, we just take their "value" part.
45+
singleTermList :: [WrappedTerm] -> Maybe [Term]
46+
singleTermList [] = Just []
47+
singleTermList (S x : xs) = (x :) <$> singleTermList xs
48+
singleTermList (P _ y : xs) = (y :) <$> singleTermList xs
49+
singleTermList _ = Nothing
50+
51+
pattern P :: Term -> Term -> WrappedTerm
52+
pattern P t1 t2 = PairTerm t1 t2
53+
54+
-- | Convert a list of wrapped terms to a list of pairs of terms, or fail if any
55+
-- 'SingleTerm's are present.
56+
pairTermList :: [WrappedTerm] -> Maybe [(Term, Term)]
57+
pairTermList [] = Just []
58+
pairTermList (P x y : xs) = ((x, y) :) <$> pairTermList xs
59+
pairTermList _ = Nothing
60+
61+
pattern G :: [WrappedTerm] -> WrappedTerm
62+
pattern G xs = GroupTerm xs
1863

1964
--------------------------------------------------------------------------------
2065

@@ -44,7 +89,7 @@ data CTree f
4489
| Enum (Node f)
4590
| Unwrap (Node f)
4691
| Tag Word64 (Node f)
47-
deriving (Generic)
92+
| WithGen (forall g m. StatefulGen g m => g -> m WrappedTerm) (Node f)
4893

4994
-- | Traverse the CTree, carrying out the given operation at each node
5095
traverseCTree :: Monad m => (Node f -> m (Node g)) -> CTree f -> m (CTree g)
@@ -70,6 +115,7 @@ traverseCTree atNode (Control o t c) = do
70115
traverseCTree atNode (Enum ref) = Enum <$> atNode ref
71116
traverseCTree atNode (Unwrap ref) = Unwrap <$> atNode ref
72117
traverseCTree atNode (Tag i ref) = Tag i <$> atNode ref
118+
traverseCTree atNode (WithGen g ref) = WithGen g <$> atNode ref
73119

74120
type Node f = f (CTree f)
75121

0 commit comments

Comments
 (0)