1
1
{-# LANGUAGE DeriveAnyClass #-}
2
2
{-# LANGUAGE DerivingStrategies #-}
3
+ {-# LANGUAGE PatternSynonyms #-}
3
4
4
5
-- | This module defined the data structure of CDDL as specified in
5
6
-- https://datatracker.ietf.org/doc/rfc8610/
6
7
module Codec.CBOR.Cuddle.CDDL (
7
8
CDDL (.. ),
9
+ CBORGenerator (.. ),
8
10
sortCDDL ,
9
11
cddlTopLevel ,
10
12
cddlRules ,
@@ -33,10 +35,18 @@ module Codec.CBOR.Cuddle.CDDL (
33
35
GrpChoice (.. ),
34
36
unwrap ,
35
37
compareRuleName ,
38
+ WrappedTerm (.. ),
39
+ flattenWrappedList ,
40
+ singleTermList ,
41
+ pairTermList ,
42
+ pattern S ,
43
+ pattern G ,
44
+ pattern P ,
36
45
) where
37
46
38
47
import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp )
39
48
import Codec.CBOR.Cuddle.Comments (CollectComments (.. ), Comment , HasComment (.. ))
49
+ import Codec.CBOR.Term (Term )
40
50
import Data.ByteString qualified as B
41
51
import Data.Default.Class (Default (.. ))
42
52
import Data.Function (on , (&) )
@@ -51,14 +61,60 @@ import GHC.Generics (Generic)
51
61
import Optics.Core ((%) , (.~) )
52
62
import Optics.Getter (view )
53
63
import Optics.Lens (lens )
64
+ import System.Random.Stateful (StatefulGen )
65
+
66
+ --------------------------------------------------------------------------------
67
+ -- Kinds of terms
68
+ --------------------------------------------------------------------------------
69
+
70
+ data WrappedTerm
71
+ = SingleTerm Term
72
+ | PairTerm Term Term
73
+ | GroupTerm [WrappedTerm ]
74
+ deriving (Eq , Show , Generic )
75
+
76
+ -- | Recursively flatten wrapped list. That is, expand any groups out to their
77
+ -- individual entries.
78
+ flattenWrappedList :: [WrappedTerm ] -> [WrappedTerm ]
79
+ flattenWrappedList [] = []
80
+ flattenWrappedList (GroupTerm xxs : xs) =
81
+ flattenWrappedList xxs <> flattenWrappedList xs
82
+ flattenWrappedList (y : xs) = y : flattenWrappedList xs
83
+
84
+ pattern S :: Term -> WrappedTerm
85
+ pattern S t = SingleTerm t
86
+
87
+ -- | Convert a list of wrapped terms to a list of terms. If any 'PairTerm's are
88
+ -- present, we just take their "value" part.
89
+ singleTermList :: [WrappedTerm ] -> Maybe [Term ]
90
+ singleTermList [] = Just []
91
+ singleTermList (S x : xs) = (x : ) <$> singleTermList xs
92
+ singleTermList (P _ y : xs) = (y : ) <$> singleTermList xs
93
+ singleTermList _ = Nothing
94
+
95
+ pattern P :: Term -> Term -> WrappedTerm
96
+ pattern P t1 t2 = PairTerm t1 t2
97
+
98
+ -- | Convert a list of wrapped terms to a list of pairs of terms, or fail if any
99
+ -- 'SingleTerm's are present.
100
+ pairTermList :: [WrappedTerm ] -> Maybe [(Term , Term )]
101
+ pairTermList [] = Just []
102
+ pairTermList (P x y : xs) = ((x, y) : ) <$> pairTermList xs
103
+ pairTermList _ = Nothing
104
+
105
+ pattern G :: [WrappedTerm ] -> WrappedTerm
106
+ pattern G xs = GroupTerm xs
107
+
108
+ newtype CBORGenerator
109
+ = CBORGenerator (forall g m . StatefulGen g m => g -> m WrappedTerm )
54
110
55
111
-- | The CDDL constructor takes three arguments:
56
112
-- 1. Top level comments that precede the first definition
57
113
-- 2. The root definition
58
114
-- 3. All the other top level comments and definitions
59
115
-- This ensures that `CDDL` is correct by construction.
60
116
data CDDL = CDDL [Comment ] Rule [TopLevel ]
61
- deriving (Eq , Generic , Show , ToExpr )
117
+ deriving (Generic )
62
118
63
119
-- | Sort the CDDL Rules on the basis of their names
64
120
-- Top level comments will be removed!
@@ -92,7 +148,7 @@ instance Semigroup CDDL where
92
148
data TopLevel
93
149
= TopLevelRule Rule
94
150
| TopLevelComment Comment
95
- deriving (Eq , Generic , Show , ToExpr )
151
+ deriving (Generic )
96
152
97
153
-- |
98
154
-- A name can consist of any of the characters from the set {"A" to
@@ -209,9 +265,9 @@ data Rule = Rule
209
265
, ruleAssign :: Assign
210
266
, ruleTerm :: TypeOrGroup
211
267
, ruleComment :: Comment
268
+ , ruleGenerator :: Maybe CBORGenerator
212
269
}
213
- deriving (Eq , Generic , Show )
214
- deriving anyclass (ToExpr )
270
+ deriving (Generic )
215
271
216
272
instance HasComment Rule where
217
273
commentL = lens ruleComment (\ x y -> x {ruleComment = y})
0 commit comments