11{-# LANGUAGE DeriveAnyClass #-}
22{-# LANGUAGE DerivingStrategies #-}
3+ {-# LANGUAGE PatternSynonyms #-}
34
45-- | This module defined the data structure of CDDL as specified in
56-- https://datatracker.ietf.org/doc/rfc8610/
67module Codec.CBOR.Cuddle.CDDL (
78 CDDL (.. ),
9+ CBORGenerator (.. ),
810 sortCDDL ,
911 cddlTopLevel ,
1012 cddlRules ,
@@ -33,10 +35,18 @@ module Codec.CBOR.Cuddle.CDDL (
3335 GrpChoice (.. ),
3436 unwrap ,
3537 compareRuleName ,
38+ WrappedTerm (.. ),
39+ flattenWrappedList ,
40+ singleTermList ,
41+ pairTermList ,
42+ pattern S ,
43+ pattern G ,
44+ pattern P ,
3645) where
3746
3847import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp )
3948import Codec.CBOR.Cuddle.Comments (CollectComments (.. ), Comment , HasComment (.. ))
49+ import Codec.CBOR.Term (Term )
4050import Data.ByteString qualified as B
4151import Data.Default.Class (Default (.. ))
4252import Data.Function (on , (&) )
@@ -51,14 +61,60 @@ import GHC.Generics (Generic)
5161import Optics.Core ((%) , (.~) )
5262import Optics.Getter (view )
5363import 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 )
54110
55111-- | The CDDL constructor takes three arguments:
56112-- 1. Top level comments that precede the first definition
57113-- 2. The root definition
58114-- 3. All the other top level comments and definitions
59115-- This ensures that `CDDL` is correct by construction.
60116data CDDL = CDDL [Comment ] Rule [TopLevel ]
61- deriving (Eq , Generic , Show , ToExpr )
117+ deriving (Generic )
62118
63119-- | Sort the CDDL Rules on the basis of their names
64120-- Top level comments will be removed!
@@ -92,7 +148,7 @@ instance Semigroup CDDL where
92148data TopLevel
93149 = TopLevelRule Rule
94150 | TopLevelComment Comment
95- deriving (Eq , Generic , Show , ToExpr )
151+ deriving (Generic )
96152
97153-- |
98154-- A name can consist of any of the characters from the set {"A" to
@@ -209,9 +265,9 @@ data Rule = Rule
209265 , ruleAssign :: Assign
210266 , ruleTerm :: TypeOrGroup
211267 , ruleComment :: Comment
268+ , ruleGenerator :: Maybe CBORGenerator
212269 }
213- deriving (Eq , Generic , Show )
214- deriving anyclass (ToExpr )
270+ deriving (Generic )
215271
216272instance HasComment Rule where
217273 commentL = lens ruleComment (\ x y -> x {ruleComment = y})
0 commit comments