1+ {-# LANGUAGE DeriveAnyClass #-}
2+ {-# LANGUAGE DerivingStrategies #-}
3+
14-- | This module defined the data structure of CDDL as specified in
25-- 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
435
536import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp )
637import Data.ByteString qualified as B
738import Data.Hashable (Hashable )
39+ import Data.List.NonEmpty (NonEmpty )
840import Data.List.NonEmpty qualified as NE
941import Data.Text qualified as T
42+ import Data.TreeDiff (ToExpr )
1043import Data.Word (Word64 , Word8 )
1144import GHC.Generics (Generic )
1245
13- newtype CDDL = CDDL (NE. NonEmpty ( WithComments Rule ) )
46+ newtype CDDL = CDDL (NE. NonEmpty TopLevel )
1447 deriving (Eq , Generic , Show )
1548
49+ data TopLevel
50+ = TopLevelRule (Maybe Comment ) Rule (Maybe Comment )
51+ | TopLevelComment Comment
52+ deriving (Eq , Ord , Generic , Show )
53+
1654-- | Sort the CDDL Rules on the basis of their names
1755sortCDDL :: CDDL -> CDDL
1856sortCDDL (CDDL xs) = CDDL $ NE. sort xs
1957
2058data WithComments a = WithComments a (Maybe Comment )
2159 deriving (Eq , Show , Generic )
60+ deriving anyclass (ToExpr )
2261
2362instance Ord a => Ord (WithComments a ) where
2463 compare (WithComments a1 _) (WithComments a2 _) = compare a1 a2
@@ -54,6 +93,7 @@ noComment a = WithComments a Nothing
5493-- encoding, but names used as "barewords" in member keys do.
5594newtype Name = Name T. Text
5695 deriving (Eq , Generic , Ord , Show )
96+ deriving anyclass (ToExpr )
5797
5898instance Hashable Name
5999
@@ -72,6 +112,7 @@ instance Hashable Name
72112-- side the first entry in the choice being created.)
73113data Assign = AssignEq | AssignExt
74114 deriving (Eq , Generic , Show )
115+ deriving anyclass (ToExpr )
75116
76117-- |
77118-- Generics
@@ -90,10 +131,14 @@ data Assign = AssignEq | AssignExt
90131-- Generic rules can be used for establishing names for both types and
91132-- groups.
92133newtype GenericParam = GenericParam (NE. NonEmpty Name )
93- deriving (Eq , Generic , Show , Semigroup )
134+ deriving (Eq , Generic , Show )
135+ deriving newtype (Semigroup )
136+ deriving anyclass (ToExpr )
94137
95138newtype GenericArg = GenericArg (NE. NonEmpty Type1 )
96- deriving (Eq , Generic , Show , Semigroup )
139+ deriving (Eq , Generic , Show )
140+ deriving newtype (Semigroup )
141+ deriving anyclass (ToExpr )
97142
98143-- |
99144-- rule = typename [genericparm] S assignt S type
@@ -120,6 +165,7 @@ newtype GenericArg = GenericArg (NE.NonEmpty Type1)
120165-- definitions before a determination can be made.)
121166data Rule = Rule Name (Maybe GenericParam ) Assign TypeOrGroup
122167 deriving (Eq , Generic , Show )
168+ deriving anyclass (ToExpr )
123169
124170instance Ord Rule where
125171 compare (Rule n1 _ _ _) (Rule n2 _ _ _) = compare n1 n2
@@ -132,14 +178,17 @@ instance Ord Rule where
132178-- included for ".." and excluded for "...".
133179data RangeBound = ClOpen | Closed
134180 deriving (Eq , Generic , Show )
181+ deriving anyclass (ToExpr )
135182
136183instance Hashable RangeBound
137184
138185data TyOp = RangeOp RangeBound | CtrlOp CtlOp
139186 deriving (Eq , Generic , Show )
187+ deriving anyclass (ToExpr )
140188
141189data TypeOrGroup = TOGType Type0 | TOGGroup GroupEntry
142190 deriving (Eq , Generic , Show )
191+ deriving anyclass (ToExpr )
143192
144193{- - |
145194 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
191240 which suggested the thread-like "~" character.)
192241-}
193242unwrap :: 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
195244 T2Map g -> Just g
196245 T2Array g -> Just g
197246 _ -> Nothing
@@ -202,12 +251,15 @@ unwrap _ = Nothing
202251-- choice matches a data item if the data item matches any one of the
203252-- types given in the choice.
204253newtype Type0 = Type0 (NE. NonEmpty Type1 )
205- deriving (Eq , Generic , Show , Semigroup )
254+ deriving (Eq , Generic , Show )
255+ deriving newtype (Semigroup )
256+ deriving anyclass (ToExpr )
206257
207258-- |
208259-- Two types can be combined with a range operator (see below)
209260data Type1 = Type1 Type2 (Maybe (TyOp , Type2 ))
210261 deriving (Eq , Generic , Show )
262+ deriving anyclass (ToExpr )
211263
212264data Type2
213265 = -- | A type can be just a single value (such as 1 or "icecream" or
@@ -244,6 +296,7 @@ data Type2
244296 | -- | Any data item
245297 T2Any
246298 deriving (Eq , Generic , Show )
299+ deriving anyclass (ToExpr )
247300
248301-- |
249302-- An optional _occurrence_ indicator can be given in front of a group
@@ -265,14 +318,17 @@ data OccurrenceIndicator
265318 | OIOneOrMore
266319 | OIBounded (Maybe Word64 ) (Maybe Word64 )
267320 deriving (Eq , Generic , Show )
321+ deriving anyclass (ToExpr )
268322
269323instance Hashable OccurrenceIndicator
270324
271325-- |
272326-- A group matches any sequence of key/value pairs that matches any of
273327-- the choices given (again using PEG semantics).
274328newtype Group = Group (NE. NonEmpty GrpChoice )
275- deriving (Eq , Generic , Show , Semigroup )
329+ deriving (Eq , Generic , Show )
330+ deriving newtype (Semigroup )
331+ deriving anyclass (ToExpr )
276332
277333type GrpChoice = [WithComments GroupEntry ]
278334
@@ -288,6 +344,12 @@ data GroupEntry
288344 | GERef (Maybe OccurrenceIndicator ) Name (Maybe GenericArg )
289345 | GEGroup (Maybe OccurrenceIndicator ) Group
290346 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
291353
292354-- |
293355-- Key types can be given by a type expression, a bareword (which stands
@@ -302,6 +364,7 @@ data MemberKey
302364 | MKBareword Name
303365 | MKValue Value
304366 deriving (Eq , Generic , Show )
367+ deriving anyclass (ToExpr )
305368
306369data Value
307370 = VUInt Word64
@@ -313,8 +376,14 @@ data Value
313376 | VText T. Text
314377 | VBytes B. ByteString
315378 deriving (Eq , Generic , Show )
379+ deriving anyclass (ToExpr )
316380
317381instance Hashable Value
318382
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