1
+ {-# LANGUAGE DeriveAnyClass #-}
2
+ {-# LANGUAGE DerivingStrategies #-}
3
+
1
4
-- | This module defined the data structure of CDDL as specified in
2
5
-- https://datatracker.ietf.org/doc/rfc8610/
3
- module Codec.CBOR.Cuddle.CDDL where
6
+ module Codec.CBOR.Cuddle.CDDL (
7
+ CDDL (.. ),
8
+ TopLevel (.. ),
9
+ Name (.. ),
10
+ WithComments (.. ),
11
+ Comment (.. ),
12
+ Rule (.. ),
13
+ TypeOrGroup (.. ),
14
+ Assign (.. ),
15
+ GenericArg (.. ),
16
+ GenericParam (.. ),
17
+ Type0 (.. ),
18
+ Type1 (.. ),
19
+ Type2 (.. ),
20
+ TyOp (.. ),
21
+ RangeBound (.. ),
22
+ OccurrenceIndicator (.. ),
23
+ Group (.. ),
24
+ GroupEntry (.. ),
25
+ MemberKey (.. ),
26
+ Value (.. ),
27
+ GrpChoice ,
28
+ sortCDDL ,
29
+ comment ,
30
+ stripComment ,
31
+ noComment ,
32
+ unwrap ,
33
+ groupEntryOccurrenceIndicator ,
34
+ ) where
4
35
5
36
import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp )
6
37
import Data.ByteString qualified as B
7
38
import Data.Hashable (Hashable )
39
+ import Data.List.NonEmpty (NonEmpty )
8
40
import Data.List.NonEmpty qualified as NE
9
41
import Data.Text qualified as T
42
+ import Data.TreeDiff (ToExpr )
10
43
import Data.Word (Word64 , Word8 )
11
44
import GHC.Generics (Generic )
12
45
13
- newtype CDDL = CDDL (NE. NonEmpty ( WithComments Rule ) )
46
+ newtype CDDL = CDDL (NE. NonEmpty TopLevel )
14
47
deriving (Eq , Generic , Show )
15
48
49
+ data TopLevel
50
+ = TopLevelRule (Maybe Comment ) Rule (Maybe Comment )
51
+ | TopLevelComment Comment
52
+ deriving (Eq , Ord , Generic , Show )
53
+
16
54
-- | Sort the CDDL Rules on the basis of their names
17
55
sortCDDL :: CDDL -> CDDL
18
56
sortCDDL (CDDL xs) = CDDL $ NE. sort xs
19
57
20
58
data WithComments a = WithComments a (Maybe Comment )
21
59
deriving (Eq , Show , Generic )
60
+ deriving anyclass (ToExpr )
22
61
23
62
instance Ord a => Ord (WithComments a ) where
24
63
compare (WithComments a1 _) (WithComments a2 _) = compare a1 a2
@@ -54,6 +93,7 @@ noComment a = WithComments a Nothing
54
93
-- encoding, but names used as "barewords" in member keys do.
55
94
newtype Name = Name T. Text
56
95
deriving (Eq , Generic , Ord , Show )
96
+ deriving anyclass (ToExpr )
57
97
58
98
instance Hashable Name
59
99
@@ -72,6 +112,7 @@ instance Hashable Name
72
112
-- side the first entry in the choice being created.)
73
113
data Assign = AssignEq | AssignExt
74
114
deriving (Eq , Generic , Show )
115
+ deriving anyclass (ToExpr )
75
116
76
117
-- |
77
118
-- Generics
@@ -90,10 +131,14 @@ data Assign = AssignEq | AssignExt
90
131
-- Generic rules can be used for establishing names for both types and
91
132
-- groups.
92
133
newtype GenericParam = GenericParam (NE. NonEmpty Name )
93
- deriving (Eq , Generic , Show , Semigroup )
134
+ deriving (Eq , Generic , Show )
135
+ deriving newtype (Semigroup )
136
+ deriving anyclass (ToExpr )
94
137
95
138
newtype GenericArg = GenericArg (NE. NonEmpty Type1 )
96
- deriving (Eq , Generic , Show , Semigroup )
139
+ deriving (Eq , Generic , Show )
140
+ deriving newtype (Semigroup )
141
+ deriving anyclass (ToExpr )
97
142
98
143
-- |
99
144
-- rule = typename [genericparm] S assignt S type
@@ -120,6 +165,7 @@ newtype GenericArg = GenericArg (NE.NonEmpty Type1)
120
165
-- definitions before a determination can be made.)
121
166
data Rule = Rule Name (Maybe GenericParam ) Assign TypeOrGroup
122
167
deriving (Eq , Generic , Show )
168
+ deriving anyclass (ToExpr )
123
169
124
170
instance Ord Rule where
125
171
compare (Rule n1 _ _ _) (Rule n2 _ _ _) = compare n1 n2
@@ -132,14 +178,17 @@ instance Ord Rule where
132
178
-- included for ".." and excluded for "...".
133
179
data RangeBound = ClOpen | Closed
134
180
deriving (Eq , Generic , Show )
181
+ deriving anyclass (ToExpr )
135
182
136
183
instance Hashable RangeBound
137
184
138
185
data TyOp = RangeOp RangeBound | CtrlOp CtlOp
139
186
deriving (Eq , Generic , Show )
187
+ deriving anyclass (ToExpr )
140
188
141
189
data TypeOrGroup = TOGType Type0 | TOGGroup GroupEntry
142
190
deriving (Eq , Generic , Show )
191
+ deriving anyclass (ToExpr )
143
192
144
193
{- - |
145
194
The group that is used to define a map or an array can often be reused in the
@@ -191,7 +240,7 @@ data TypeOrGroup = TOGType Type0 | TOGGroup GroupEntry
191
240
which suggested the thread-like "~" character.)
192
241
-}
193
242
unwrap :: TypeOrGroup -> Maybe Group
194
- unwrap (TOGType (Type0 (( Type1 t2 Nothing ) NE. :| [] ))) = case t2 of
243
+ unwrap (TOGType (Type0 (Type1 t2 Nothing NE. :| [] ))) = case t2 of
195
244
T2Map g -> Just g
196
245
T2Array g -> Just g
197
246
_ -> Nothing
@@ -202,12 +251,15 @@ unwrap _ = Nothing
202
251
-- choice matches a data item if the data item matches any one of the
203
252
-- types given in the choice.
204
253
newtype Type0 = Type0 (NE. NonEmpty Type1 )
205
- deriving (Eq , Generic , Show , Semigroup )
254
+ deriving (Eq , Generic , Show )
255
+ deriving newtype (Semigroup )
256
+ deriving anyclass (ToExpr )
206
257
207
258
-- |
208
259
-- Two types can be combined with a range operator (see below)
209
260
data Type1 = Type1 Type2 (Maybe (TyOp , Type2 ))
210
261
deriving (Eq , Generic , Show )
262
+ deriving anyclass (ToExpr )
211
263
212
264
data Type2
213
265
= -- | A type can be just a single value (such as 1 or "icecream" or
@@ -244,6 +296,7 @@ data Type2
244
296
| -- | Any data item
245
297
T2Any
246
298
deriving (Eq , Generic , Show )
299
+ deriving anyclass (ToExpr )
247
300
248
301
-- |
249
302
-- An optional _occurrence_ indicator can be given in front of a group
@@ -265,14 +318,17 @@ data OccurrenceIndicator
265
318
| OIOneOrMore
266
319
| OIBounded (Maybe Word64 ) (Maybe Word64 )
267
320
deriving (Eq , Generic , Show )
321
+ deriving anyclass (ToExpr )
268
322
269
323
instance Hashable OccurrenceIndicator
270
324
271
325
-- |
272
326
-- A group matches any sequence of key/value pairs that matches any of
273
327
-- the choices given (again using PEG semantics).
274
328
newtype Group = Group (NE. NonEmpty GrpChoice )
275
- deriving (Eq , Generic , Show , Semigroup )
329
+ deriving (Eq , Generic , Show )
330
+ deriving newtype (Semigroup )
331
+ deriving anyclass (ToExpr )
276
332
277
333
type GrpChoice = [WithComments GroupEntry ]
278
334
@@ -288,6 +344,12 @@ data GroupEntry
288
344
| GERef (Maybe OccurrenceIndicator ) Name (Maybe GenericArg )
289
345
| GEGroup (Maybe OccurrenceIndicator ) Group
290
346
deriving (Eq , Generic , Show )
347
+ deriving anyclass (ToExpr )
348
+
349
+ groupEntryOccurrenceIndicator :: GroupEntry -> Maybe OccurrenceIndicator
350
+ groupEntryOccurrenceIndicator (GEType oi _ _) = oi
351
+ groupEntryOccurrenceIndicator (GERef oi _ _) = oi
352
+ groupEntryOccurrenceIndicator (GEGroup oi _) = oi
291
353
292
354
-- |
293
355
-- Key types can be given by a type expression, a bareword (which stands
@@ -302,6 +364,7 @@ data MemberKey
302
364
| MKBareword Name
303
365
| MKValue Value
304
366
deriving (Eq , Generic , Show )
367
+ deriving anyclass (ToExpr )
305
368
306
369
data Value
307
370
= VUInt Word64
@@ -313,8 +376,14 @@ data Value
313
376
| VText T. Text
314
377
| VBytes B. ByteString
315
378
deriving (Eq , Generic , Show )
379
+ deriving anyclass (ToExpr )
316
380
317
381
instance Hashable Value
318
382
319
- newtype Comment = Comment T. Text
320
- deriving (Eq , Generic , Show )
383
+ newtype Comment = Comment { unComment :: NonEmpty T. Text}
384
+ deriving (Eq , Ord , Generic , Show )
385
+ deriving newtype (Semigroup )
386
+ deriving anyclass (ToExpr )
387
+
388
+ comment :: T. Text -> Comment
389
+ comment t = Comment $ t NE. :| []
0 commit comments