packages feed

cuddle 1.0.0.0 → 1.1.0.0

raw patch · 38 files changed

+4416/−2148 lines, 38 filesdep +generic-randomdep +pretty-simpledep ~cborgdep ~containersdep ~randomPVP ok

version bump matches the API change (PVP)

Dependencies added: generic-random, pretty-simple

Dependency ranges changed: cborg, containers, random

API changes (from Hackage documentation)

- Codec.CBOR.Cuddle.CBOR.Gen: instance Capability.Reader.Internal.Class.HasReader "cddl" (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot' Data.Functor.Identity.Identity Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef) (Codec.CBOR.Cuddle.CBOR.Gen.M g)
- Codec.CBOR.Cuddle.CBOR.Gen: instance Capability.Source.Internal.Class.HasSource "cddl" (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot' Data.Functor.Identity.Identity Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef) (Codec.CBOR.Cuddle.CBOR.Gen.M g)
- Codec.CBOR.Cuddle.CBOR.Gen: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CBOR.Gen.WrappedTerm
- Codec.CBOR.Cuddle.CBOR.Gen: instance GHC.Show.Show Codec.CBOR.Cuddle.CBOR.Gen.WrappedTerm
- Codec.CBOR.Cuddle.CBOR.Validator: AMatchedItem :: Term -> Term -> Rule -> AMatchedItem
- Codec.CBOR.Cuddle.CBOR.Validator: ANonMatchedItem :: Term -> Term -> [Either (Rule, CDDLResult) (Rule, CDDLResult, CDDLResult)] -> ANonMatchedItem
- Codec.CBOR.Cuddle.CBOR.Validator: [amiKey] :: AMatchedItem -> Term
- Codec.CBOR.Cuddle.CBOR.Validator: [amiRule] :: AMatchedItem -> Rule
- Codec.CBOR.Cuddle.CBOR.Validator: [amiValue] :: AMatchedItem -> Term
- Codec.CBOR.Cuddle.CBOR.Validator: [anmiKey] :: ANonMatchedItem -> Term
- Codec.CBOR.Cuddle.CBOR.Validator: [anmiResults] :: ANonMatchedItem -> [Either (Rule, CDDLResult) (Rule, CDDLResult, CDDLResult)]
- Codec.CBOR.Cuddle.CBOR.Validator: [anmiValue] :: ANonMatchedItem -> Term
- Codec.CBOR.Cuddle.CBOR.Validator: boolCtrl :: Bool -> Either (Maybe CBORTermResult) ()
- Codec.CBOR.Cuddle.CBOR.Validator: check :: Bool -> Rule -> CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: controlBool :: MonadReader CDDL m => Bool -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: controlBytes :: MonadReader CDDL m => ByteString -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: controlDouble :: MonadReader CDDL m => Double -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: controlFloat :: MonadReader CDDL m => Float -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: controlHalf :: MonadReader CDDL m => Float -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: controlInteger :: MonadReader CDDL m => Integer -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: controlText :: MonadReader CDDL m => Text -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())
- Codec.CBOR.Cuddle.CBOR.Validator: ctrlAnd :: Monad m => (Rule -> m CDDLResult) -> Rule -> Rule -> m (Rule -> CDDLResult)
- Codec.CBOR.Cuddle.CBOR.Validator: ctrlDispatch :: Monad m => (Rule -> m CDDLResult) -> CtlOp -> Rule -> Rule -> (CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())) -> m (Rule -> CDDLResult)
- Codec.CBOR.Cuddle.CBOR.Validator: data AMatchedItem
- Codec.CBOR.Cuddle.CBOR.Validator: data ANonMatchedItem
- Codec.CBOR.Cuddle.CBOR.Validator: dummyRule :: Rule
- Codec.CBOR.Cuddle.CBOR.Validator: expandRule :: Int -> Rule -> Reader CDDL [[Rule]]
- Codec.CBOR.Cuddle.CBOR.Validator: expandRules :: Int -> [Rule] -> Reader CDDL [[Rule]]
- Codec.CBOR.Cuddle.CBOR.Validator: flattenGroup :: CDDL -> [Rule] -> [Rule]
- Codec.CBOR.Cuddle.CBOR.Validator: getIndicesOfChoice :: MonadReader CDDL m => NonEmpty Rule -> m [Word64]
- Codec.CBOR.Cuddle.CBOR.Validator: getIndicesOfEnum :: MonadReader CDDL m => Rule -> m [Word64]
- Codec.CBOR.Cuddle.CBOR.Validator: getIndicesOfRange :: MonadReader CDDL m => Rule -> Rule -> RangeBound -> m [Word64]
- Codec.CBOR.Cuddle.CBOR.Validator: getRule :: MonadReader CDDL m => Rule -> m ResolvedRule
- Codec.CBOR.Cuddle.CBOR.Validator: ifM :: Monad m => m Bool -> m a -> m a -> m a
- Codec.CBOR.Cuddle.CBOR.Validator: isOptional :: MonadReader CDDL m => Rule -> m Bool
- Codec.CBOR.Cuddle.CBOR.Validator: range :: Ord a => RangeBound -> a -> a -> Bool
- Codec.CBOR.Cuddle.CBOR.Validator: replaceRule :: CDDLResult -> Rule -> CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: resolveIfRef :: CDDL -> Rule -> ResolvedRule
- Codec.CBOR.Cuddle.CBOR.Validator: type CDDL = CTreeRoot' Identity MonoRef
- Codec.CBOR.Cuddle.CBOR.Validator: type ResolvedRule = CTree MonoRef
- Codec.CBOR.Cuddle.CBOR.Validator: type Rule = Node MonoRef
- Codec.CBOR.Cuddle.CBOR.Validator: validateBool :: MonadReader CDDL m => Bool -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateBytes :: MonadReader CDDL m => ByteString -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateCBOR' :: ByteString -> Name -> CDDL -> CBORTermResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateChoice :: Monad m => (Rule -> m CDDLResult) -> NonEmpty Rule -> m (Rule -> CDDLResult)
- Codec.CBOR.Cuddle.CBOR.Validator: validateDouble :: MonadReader CDDL m => Double -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateExpandedList :: MonadReader CDDL m => [Term] -> [[Rule]] -> m (Rule -> CDDLResult)
- Codec.CBOR.Cuddle.CBOR.Validator: validateExpandedMap :: MonadReader CDDL m => [(Term, Term)] -> [[Rule]] -> m (Rule -> CDDLResult)
- Codec.CBOR.Cuddle.CBOR.Validator: validateFloat :: MonadReader CDDL m => Float -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateHalf :: MonadReader CDDL m => Float -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateInteger :: MonadReader CDDL m => Integer -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateList :: MonadReader CDDL m => [Term] -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateListWithExpandedRules :: MonadReader CDDL m => [Term] -> [Rule] -> m [(Rule, CBORTermResult)]
- Codec.CBOR.Cuddle.CBOR.Validator: validateMap :: MonadReader CDDL m => [(Term, Term)] -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateMapWithExpandedRules :: MonadReader CDDL m => [(Term, Term)] -> [Rule] -> m ([AMatchedItem], Maybe ANonMatchedItem)
- Codec.CBOR.Cuddle.CBOR.Validator: validateNull :: MonadReader CDDL m => Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateSimple :: MonadReader CDDL m => Word8 -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateTagged :: MonadReader CDDL m => Word64 -> Term -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateTerm :: MonadReader CDDL m => Term -> Rule -> m CBORTermResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateText :: MonadReader CDDL m => Text -> Rule -> m CDDLResult
- Codec.CBOR.Cuddle.CDDL: GenericParam :: NonEmpty Name -> GenericParam
- Codec.CBOR.Cuddle.CDDL: TopLevelComment :: Comment -> TopLevel
- Codec.CBOR.Cuddle.CDDL: [geComment] :: GroupEntry -> Comment
- Codec.CBOR.Cuddle.CDDL: [nameComment] :: Name -> Comment
- Codec.CBOR.Cuddle.CDDL: [name] :: Name -> Text
- Codec.CBOR.Cuddle.CDDL: [ruleComment] :: Rule -> Comment
- Codec.CBOR.Cuddle.CDDL: cddlRules :: CDDL -> NonEmpty Rule
- Codec.CBOR.Cuddle.CDDL: data Name
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.GroupEntryVariant
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.GrpChoice
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments Codec.CBOR.Cuddle.CDDL.TypeOrGroup
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.GrpChoice
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.Name
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.Rule
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance Data.Default.Internal.Default Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance Data.Default.Internal.Default Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.CDDL
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.GenericParam
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.GroupEntryVariant
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.GrpChoice
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.MemberKey
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.Rule
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.TopLevel
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr Codec.CBOR.Cuddle.CDDL.TypeOrGroup
- Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup Codec.CBOR.Cuddle.CDDL.CDDL
- Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup Codec.CBOR.Cuddle.CDDL.GenericParam
- Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.CDDL
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.GenericParam
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.GroupEntryVariant
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.GrpChoice
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.MemberKey
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Rule
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.TopLevel
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.TypeOrGroup
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.CDDL
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.GenericParam
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.GroupEntryVariant
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.GrpChoice
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.MemberKey
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.Rule
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.TopLevel
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.TypeOrGroup
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.CDDL
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.GenericParam
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.Group
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.GroupEntryVariant
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.GrpChoice
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.MemberKey
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.Rule
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.TopLevel
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.TypeOrGroup
- Codec.CBOR.Cuddle.CDDL: newtype GenericParam
- Codec.CBOR.Cuddle.CDDL.CTree: Parametrised :: a -> w -> ParametrisedWith w a
- Codec.CBOR.Cuddle.CDDL.CTree: Unparametrised :: a -> ParametrisedWith w a
- Codec.CBOR.Cuddle.CDDL.CTree: [params] :: ParametrisedWith w a -> w
- Codec.CBOR.Cuddle.CDDL.CTree: [underlying] :: ParametrisedWith w a -> a
- Codec.CBOR.Cuddle.CDDL.CTree: data ParametrisedWith w a
- Codec.CBOR.Cuddle.CDDL.CTree: instance (Data.Hashable.Class.Hashable w, Data.Hashable.Class.Hashable a) => Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w a)
- Codec.CBOR.Cuddle.CDDL.CTree: instance (GHC.Classes.Eq a, GHC.Classes.Eq w) => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w a)
- Codec.CBOR.Cuddle.CDDL.CTree: instance (GHC.Show.Show a, GHC.Show.Show w) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w a)
- Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Foldable.Foldable (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w)
- Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Traversable.Traversable (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w)
- Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Base.Functor (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w)
- Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.CTree.CTree f)
- Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot' poly f)
- Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith w a)
- Codec.CBOR.Cuddle.CDDL.CTree: newtype CTreeRoot' (poly :: Type -> Type) (f :: Type -> Type)
- Codec.CBOR.Cuddle.CDDL.CTree: type CTreeRoot (f :: Type -> Type) = CTreeRoot' ParametrisedWith [Name] f
- Codec.CBOR.Cuddle.CDDL.Postlude: PTAny :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTBool :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTBytes :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTDouble :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTFloat :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTHalf :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTInt :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTNInt :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTNil :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTText :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTUInt :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: PTUndefined :: PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: data PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: instance Data.Hashable.Class.Hashable Codec.CBOR.Cuddle.CDDL.Postlude.PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Postlude.PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: instance GHC.Classes.Ord Codec.CBOR.Cuddle.CDDL.Postlude.PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.Postlude.PTerm
- Codec.CBOR.Cuddle.CDDL.Postlude: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.Postlude.PTerm
- Codec.CBOR.Cuddle.CDDL.Prelude: prependPrelude :: CDDL -> CDDL
- Codec.CBOR.Cuddle.CDDL.Resolve: MIt :: a -> MonoRef a
- Codec.CBOR.Cuddle.CDDL.Resolve: MRuleRef :: Name -> MonoRef a
- Codec.CBOR.Cuddle.CDDL.Resolve: data MonoRef a
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Reader.Internal.Class.HasReader "global" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith [Codec.CBOR.Cuddle.CDDL.Name] (Codec.CBOR.Cuddle.CDDL.CTree.Node Codec.CBOR.Cuddle.CDDL.Resolve.DistRef))) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Reader.Internal.Class.HasReader "local" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.CTree.Node Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef)) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Source.Internal.Class.HasSource "global" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.CTree.ParametrisedWith [Codec.CBOR.Cuddle.CDDL.Name] (Codec.CBOR.Cuddle.CDDL.CTree.Node Codec.CBOR.Cuddle.CDDL.Resolve.DistRef))) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Source.Internal.Class.HasSource "local" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.CTree.Node Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef)) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.DistRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.DistRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef a)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Base.Functor Codec.CBOR.Cuddle.CDDL.Resolve.DistRef
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Base.Functor Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Base.Functor Codec.CBOR.Cuddle.CDDL.Resolve.OrRef
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.DistRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.DistRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq a => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef a)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Resolve.BindingEnv poly f g)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef a)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.DistRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.OrRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.DistRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.OrRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (poly (Codec.CBOR.Cuddle.CDDL.CTree.Node Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef)) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot' poly Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show a => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef a)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show a => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Resolve.MonoRef a)
- Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show a => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Resolve.OrRef a)
- Codec.CBOR.Cuddle.Huddle: data Named a
- Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Huddle.IsChoosable (Codec.CBOR.Cuddle.Huddle.Named Codec.CBOR.Cuddle.Huddle.Group) Codec.CBOR.Cuddle.Huddle.Type2
- Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Huddle.IsType0 (Codec.CBOR.Cuddle.Huddle.Named Codec.CBOR.Cuddle.Huddle.Group)
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show (Codec.CBOR.Cuddle.Huddle.Constrainable a)
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show (Codec.CBOR.Cuddle.Huddle.Named a)
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.ArrayChoice
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.ArrayEntry
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.Constrained
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.Group
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.Huddle
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.HuddleItem
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.Key
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.MapChoice
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.MapEntry
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.RangeBound
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.Ranged
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show Codec.CBOR.Cuddle.Huddle.Type2
- Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show a => GHC.Show.Show (Codec.CBOR.Cuddle.Huddle.GRule a)
- Codec.CBOR.Cuddle.Huddle: instance forall k (a :: k). GHC.Show.Show (Codec.CBOR.Cuddle.Huddle.ValueConstraint a)
- Codec.CBOR.Cuddle.Huddle: type GRuleCall = Named GRule Type2
- Codec.CBOR.Cuddle.Huddle: type GRuleDef = Named GRule GRef
- Codec.CBOR.Cuddle.Huddle: type Rule = Named Type0
- Codec.CBOR.Cuddle.Huddle.HuddleM: data Named a
- Codec.CBOR.Cuddle.Huddle.HuddleM: instance Codec.CBOR.Cuddle.Huddle.HuddleM.Includable (Codec.CBOR.Cuddle.Huddle.Named Codec.CBOR.Cuddle.Huddle.Group)
- Codec.CBOR.Cuddle.Huddle.HuddleM: type GRuleCall = Named GRule Type2
- Codec.CBOR.Cuddle.Huddle.HuddleM: type GRuleDef = Named GRule GRef
- Codec.CBOR.Cuddle.Huddle.HuddleM: type Rule = Named Type0
- Codec.CBOR.Cuddle.Huddle.Optics: commentL :: HasField' "description" a (Maybe Text) => AffineTraversal a a Text Text
- Codec.CBOR.Cuddle.Huddle.Optics: nameL :: Lens (Named a) (Named a) Text Text
- Codec.CBOR.Cuddle.Parser: pGenericParam :: Parser GenericParam
- Codec.CBOR.Cuddle.Pretty: AsArray :: GroupRender
- Codec.CBOR.Cuddle.Pretty: AsGroup :: GroupRender
- Codec.CBOR.Cuddle.Pretty: AsMap :: GroupRender
- Codec.CBOR.Cuddle.Pretty: cEncloseSep :: Doc ann -> Doc ann -> Doc ann -> [Doc ann] -> Doc ann
- Codec.CBOR.Cuddle.Pretty: columnarGroupChoice :: GrpChoice -> Columnar ann
- Codec.CBOR.Cuddle.Pretty: data GroupRender
- Codec.CBOR.Cuddle.Pretty: groupIfNoComments :: CollectComments a => a -> Doc ann -> Doc ann
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.CDDL
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.GenericArg
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.GenericParam
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.GroupEntry
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.MemberKey
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.Rule
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.TopLevel
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.Type0
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.Type1
- Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty Codec.CBOR.Cuddle.CDDL.Type2
- Codec.CBOR.Cuddle.Pretty: memberKeySep :: MemberKey -> Doc ann
- Codec.CBOR.Cuddle.Pretty: prettyCommentNoBreak :: Comment -> Doc ann
- Codec.CBOR.Cuddle.Pretty: prettyCommentNoBreakWS :: Comment -> Doc ann
- Codec.CBOR.Cuddle.Pretty: prettyGroup :: GroupRender -> Group -> Doc ann
- Codec.CBOR.Cuddle.Pretty: type0Def :: Type0 -> Doc ann
+ Codec.CBOR.Cuddle.CBOR.Gen: instance Capability.Reader.Internal.Class.HasReader "cddl" (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced) (Codec.CBOR.Cuddle.CBOR.Gen.M g)
+ Codec.CBOR.Cuddle.CBOR.Gen: instance Capability.Source.Internal.Class.HasSource "cddl" (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced) (Codec.CBOR.Cuddle.CBOR.Gen.M g)
+ Codec.CBOR.Cuddle.CBOR.Gen: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced Codec.CBOR.Cuddle.CBOR.Gen.MonoDropGen
+ Codec.CBOR.Cuddle.CBOR.Gen: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.XXCTree Codec.CBOR.Cuddle.CBOR.Gen.MonoDropGen)
+ Codec.CBOR.Cuddle.CBOR.Validator: [ctrResult] :: CBORTermResult -> CDDLResult
+ Codec.CBOR.Cuddle.CBOR.Validator: [ctrTerm] :: CBORTermResult -> Term
+ Codec.CBOR.Cuddle.CBOR.Validator: data ValidatorStage
+ Codec.CBOR.Cuddle.CBOR.Validator: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced Codec.CBOR.Cuddle.CBOR.Validator.ValidatorStage
+ Codec.CBOR.Cuddle.CBOR.Validator: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced Codec.CBOR.Cuddle.CBOR.Validator.ValidatorStage
+ Codec.CBOR.Cuddle.CBOR.Validator: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.XXCTree Codec.CBOR.Cuddle.CBOR.Validator.ValidatorStage)
+ Codec.CBOR.Cuddle.CBOR.Validator: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CBOR.Validator.ValidatorStage)
+ Codec.CBOR.Cuddle.CDDL: GenericParameter :: Name -> XTerm i -> GenericParameter i
+ Codec.CBOR.Cuddle.CDDL: GenericParameters :: NonEmpty (GenericParameter i) -> GenericParameters i
+ Codec.CBOR.Cuddle.CDDL: XXTopLevel :: XXTopLevel i -> TopLevel i
+ Codec.CBOR.Cuddle.CDDL: XXType2 :: XXType2 i -> Type2 i
+ Codec.CBOR.Cuddle.CDDL: [cddlExt] :: CDDL i -> [XXTopLevel i]
+ Codec.CBOR.Cuddle.CDDL: [geExt] :: GroupEntry i -> XTerm i
+ Codec.CBOR.Cuddle.CDDL: [gpExt] :: GenericParameter i -> XTerm i
+ Codec.CBOR.Cuddle.CDDL: [gpName] :: GenericParameter i -> Name
+ Codec.CBOR.Cuddle.CDDL: [rootDefinition] :: CDDL i -> Rule i
+ Codec.CBOR.Cuddle.CDDL: [ruleExt] :: Rule i -> XRule i
+ Codec.CBOR.Cuddle.CDDL: [topLevelDefinitions] :: CDDL i -> [TopLevel i]
+ Codec.CBOR.Cuddle.CDDL: [unName] :: Name -> Text
+ Codec.CBOR.Cuddle.CDDL: appendRules :: CDDL i -> [Rule i] -> CDDL i
+ Codec.CBOR.Cuddle.CDDL: class HasName a
+ Codec.CBOR.Cuddle.CDDL: data GenericParameter i
+ Codec.CBOR.Cuddle.CDDL: data family XXType2 i
+ Codec.CBOR.Cuddle.CDDL: getName :: HasName a => a -> Name
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.GenericArg i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.GroupEntry i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.GroupEntryVariant i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.GrpChoice i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.Type0 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.Type1 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.Type2 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Codec.CBOR.Cuddle.Comments.CollectComments => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.TypeOrGroup i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.CDDL i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.GenericArg i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.GroupEntry i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.GroupEntryVariant i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.GrpChoice i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.MemberKey i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.Rule i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.TopLevel i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.Type0 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.Type1 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.Type2 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i Data.TreeDiff.Class.ToExpr => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.TypeOrGroup i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CDDL i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.GenericArg i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.GroupEntry i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.GroupEntryVariant i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.GrpChoice i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.MemberKey i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Rule i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.TopLevel i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Type0 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Type1 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Type2 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Classes.Eq => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.TypeOrGroup i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CDDL i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.GenericArg i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.GroupEntry i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.GroupEntryVariant i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.GrpChoice i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.MemberKey i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Rule i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.TopLevel i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Type0 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Type1 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Type2 i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.ForAllExtensions i GHC.Show.Show => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.TypeOrGroup i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.CDDL.HasName Codec.CBOR.Cuddle.CDDL.Name
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.XTerm i) => Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.GenericParameter i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XRule i) => Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.Rule i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm i) => Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.GenericParameter i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm i) => Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm i) => Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.GroupEntry i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm i) => Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.GrpChoice i)
+ Codec.CBOR.Cuddle.CDDL: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm i) => Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.Type1 i)
+ Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XTerm i) => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.GenericParameter i)
+ Codec.CBOR.Cuddle.CDDL: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XTerm i) => Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.GenericParameters i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Monoid Codec.CBOR.Cuddle.CDDL.Name
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.GenericArg i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.GenericParameters i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.Type0 i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Base.Semigroup Codec.CBOR.Cuddle.CDDL.Name
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XTerm i) => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.GenericParameter i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XTerm i) => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.GenericParameters i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.CDDL i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.GenericArg i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.GenericParameter i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.GenericParameters i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Group i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.GroupEntry i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.GroupEntryVariant i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.GrpChoice i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.MemberKey i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Rule i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.TopLevel i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Type0 i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Type1 i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Type2 i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.TypeOrGroup i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm i) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.GenericParameter i)
+ Codec.CBOR.Cuddle.CDDL: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm i) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.GenericParameters i)
+ Codec.CBOR.Cuddle.CDDL: newtype GenericParameters i
+ Codec.CBOR.Cuddle.CDDL: newtype Name
+ Codec.CBOR.Cuddle.CDDL: type ForAllExtensions i (c :: Type -> Constraint) = (c XCddl i, c XTerm i, c XRule i, c XXTopLevel i, c XXType2 i)
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: CBORGenerator :: (forall g (m :: Type -> Type). StatefulGen g m => g -> m WrappedTerm) -> CBORGenerator
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: G :: [WrappedTerm] -> WrappedTerm
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: P :: Term -> Term -> WrappedTerm
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: S :: Term -> WrappedTerm
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: class HasGenerator a
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: data WrappedTerm
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: generatorL :: HasGenerator a => Lens' a (Maybe CBORGenerator)
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.CBORGenerator.WrappedTerm
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.CBORGenerator.WrappedTerm
+ Codec.CBOR.Cuddle.CDDL.CBORGenerator: newtype CBORGenerator
+ Codec.CBOR.Cuddle.CDDL.CTree: CTreeE :: XXCTree i -> CTree i
+ Codec.CBOR.Cuddle.CDDL.CTree: PTAny :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTBool :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTBytes :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTDouble :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTFloat :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTHalf :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTInt :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTNInt :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTNil :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTText :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTUInt :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: PTUndefined :: PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: data CTreePhase
+ Codec.CBOR.Cuddle.CDDL.CTree: data PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: data family XXCTree i
+ Codec.CBOR.Cuddle.CDDL.CTree: foldCTree :: (XXCTree i -> CTree j) -> (CTree i -> CTree j) -> CTree i -> CTree j
+ Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Default.Internal.Default (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.Node f) => Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.CTree f)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance Data.Hashable.Class.Hashable Codec.CBOR.Cuddle.CDDL.CTree.PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.Node f) => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.CTree f)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.CTree.PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Ord (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Ord (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Ord (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Ord (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Classes.Ord Codec.CBOR.Cuddle.CDDL.CTree.PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.CTree.CTree i)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot i)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Generics.Generic Codec.CBOR.Cuddle.CDDL.CTree.PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTree i) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTreeRoot i)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.Node f) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.CTree f)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase)
+ Codec.CBOR.Cuddle.CDDL.CTree: instance GHC.Show.Show Codec.CBOR.Cuddle.CDDL.CTree.PTerm
+ Codec.CBOR.Cuddle.CDDL.CTree: newtype CTreeRoot i
+ Codec.CBOR.Cuddle.CDDL.Postlude: appendPostlude :: (IndexMappable XXType2 ParserStage i, IndexMappable XTerm ParserStage i, IndexMappable XRule ParserStage i) => CDDL i -> CDDL i
+ Codec.CBOR.Cuddle.CDDL.Postlude: cddlPostlude :: CDDL ParserStage
+ Codec.CBOR.Cuddle.CDDL.Resolve: data MonoReferenced
+ Codec.CBOR.Cuddle.CDDL.Resolve: data family XXCTree i
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Reader.Internal.Class.HasReader "global" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.DistReferenced))) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Reader.Internal.Class.HasReader "local" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced)) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Source.Internal.Class.HasSource "global" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.DistReferenced))) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Capability.Source.Internal.Class.HasSource "local" (Data.Map.Internal.Map Codec.CBOR.Cuddle.CDDL.Name (Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.MonoReferenced)) Codec.CBOR.Cuddle.CDDL.Resolve.MonoM
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.DistReferenced Codec.CBOR.Cuddle.CDDL.Resolve.DistReferencedNoGen
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.CTree.CTree Codec.CBOR.Cuddle.CDDL.Resolve.OrReferenced Codec.CBOR.Cuddle.CDDL.Resolve.OrReferencedDropGen
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.Resolve.DistRef Codec.CBOR.Cuddle.CDDL.Resolve.DistReferenced Codec.CBOR.Cuddle.CDDL.Resolve.DistReferencedNoGen
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Foldable.Foldable Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.Node i) => Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef i)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.CTree.XXCTree Codec.CBOR.Cuddle.CDDL.Resolve.DistReferencedNoGen)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters a)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance Data.Traversable.Traversable Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Base.Functor Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.Node i) => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef i)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.XXCTree Codec.CBOR.Cuddle.CDDL.Resolve.DistReferencedNoGen)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.CTree.XXCTree Codec.CBOR.Cuddle.CDDL.Resolve.OrReferencedDropGen)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq Codec.CBOR.Cuddle.CDDL.Resolve.NameResolutionFailure
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Classes.Eq a => GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters a)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Resolve.BindingEnv i j)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef i)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Resolve.PartialCTreeRoot i)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters a)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.Node i) => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Resolve.DistRef i)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.CTree.XXCTree Codec.CBOR.Cuddle.CDDL.Resolve.OrReferencedDropGen)
+ Codec.CBOR.Cuddle.CDDL.Resolve: instance GHC.Show.Show a => GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.Resolve.ProvidedParameters a)
+ Codec.CBOR.Cuddle.Comments: instance Codec.CBOR.Cuddle.Comments.CollectComments ()
+ Codec.CBOR.Cuddle.Comments: instance Codec.CBOR.Cuddle.Comments.CollectComments GHC.Base.Void
+ Codec.CBOR.Cuddle.Huddle: GRuleCall :: Named (GRule Type2) -> XRule HuddleStage -> GRuleCall
+ Codec.CBOR.Cuddle.Huddle: GRuleDef :: Named (GRule GRef) -> XRule HuddleStage -> GRuleDef
+ Codec.CBOR.Cuddle.Huddle: GroupDef :: Named Group -> XRule HuddleStage -> GroupDef
+ Codec.CBOR.Cuddle.Huddle: Rule :: Named Type0 -> XRule HuddleStage -> Rule
+ Codec.CBOR.Cuddle.Huddle: [gdExt] :: GroupDef -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle: [gdNamed] :: GroupDef -> Named Group
+ Codec.CBOR.Cuddle.Huddle: [grcBody] :: GRuleCall -> Named (GRule Type2)
+ Codec.CBOR.Cuddle.Huddle: [grcExtra] :: GRuleCall -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle: [grdBody] :: GRuleDef -> Named (GRule GRef)
+ Codec.CBOR.Cuddle.Huddle: [grdExtra] :: GRuleDef -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle: [ruleDefinition] :: Rule -> Named Type0
+ Codec.CBOR.Cuddle.Huddle: [ruleExtra] :: Rule -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle: bool :: Bool -> Literal
+ Codec.CBOR.Cuddle.Huddle: class HasName a
+ Codec.CBOR.Cuddle.Huddle: data GRuleCall
+ Codec.CBOR.Cuddle.Huddle: data GRuleDef
+ Codec.CBOR.Cuddle.Huddle: data GroupDef
+ Codec.CBOR.Cuddle.Huddle: data HuddleStage
+ Codec.CBOR.Cuddle.Huddle: data Rule
+ Codec.CBOR.Cuddle.Huddle: data family XXType2 i
+ Codec.CBOR.Cuddle.Huddle: getName :: HasName a => a -> Name
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.CDDL.CBORGenerator.HasGenerator Codec.CBOR.Cuddle.Huddle.Rule
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.CDDL.HasName (Codec.CBOR.Cuddle.Huddle.Named a)
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.CDDL.HasName Codec.CBOR.Cuddle.Huddle.GRuleDef
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.CDDL.HasName Codec.CBOR.Cuddle.Huddle.GroupDef
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.CDDL.HasName Codec.CBOR.Cuddle.Huddle.HuddleItem
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.CDDL.HasName Codec.CBOR.Cuddle.Huddle.Rule
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.Huddle.GroupDef
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Comments.HasComment Codec.CBOR.Cuddle.Huddle.Rule
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Huddle.IsChoosable Codec.CBOR.Cuddle.Huddle.GroupDef Codec.CBOR.Cuddle.Huddle.Type2
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Huddle.IsRangeBound Codec.CBOR.Cuddle.Huddle.Rule
+ Codec.CBOR.Cuddle.Huddle: instance Codec.CBOR.Cuddle.Huddle.IsType0 Codec.CBOR.Cuddle.Huddle.GroupDef
+ Codec.CBOR.Cuddle.Huddle: instance Data.Default.Internal.Default (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic Codec.CBOR.Cuddle.Huddle.GroupDef
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Generics.Generic Codec.CBOR.Cuddle.Huddle.Rule
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Huddle.HuddleStage)
+ Codec.CBOR.Cuddle.Huddle: instance GHC.Show.Show a => GHC.Show.Show (Codec.CBOR.Cuddle.Huddle.Named a)
+ Codec.CBOR.Cuddle.Huddle: withGenerator :: HasGenerator a => (forall g (m :: Type -> Type). StatefulGen g m => g -> m WrappedTerm) -> a -> a
+ Codec.CBOR.Cuddle.Huddle.HuddleM: GRuleCall :: Named (GRule Type2) -> XRule HuddleStage -> GRuleCall
+ Codec.CBOR.Cuddle.Huddle.HuddleM: GRuleDef :: Named (GRule GRef) -> XRule HuddleStage -> GRuleDef
+ Codec.CBOR.Cuddle.Huddle.HuddleM: GroupDef :: Named Group -> XRule HuddleStage -> GroupDef
+ Codec.CBOR.Cuddle.Huddle.HuddleM: Rule :: Named Type0 -> XRule HuddleStage -> Rule
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [gdExt] :: GroupDef -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [gdNamed] :: GroupDef -> Named Group
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [grcBody] :: GRuleCall -> Named (GRule Type2)
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [grcExtra] :: GRuleCall -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [grdBody] :: GRuleDef -> Named (GRule GRef)
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [grdExtra] :: GRuleDef -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [ruleDefinition] :: Rule -> Named Type0
+ Codec.CBOR.Cuddle.Huddle.HuddleM: [ruleExtra] :: Rule -> XRule HuddleStage
+ Codec.CBOR.Cuddle.Huddle.HuddleM: bool :: Bool -> Literal
+ Codec.CBOR.Cuddle.Huddle.HuddleM: class HasName a
+ Codec.CBOR.Cuddle.Huddle.HuddleM: data GRuleCall
+ Codec.CBOR.Cuddle.Huddle.HuddleM: data GRuleDef
+ Codec.CBOR.Cuddle.Huddle.HuddleM: data GroupDef
+ Codec.CBOR.Cuddle.Huddle.HuddleM: data HuddleStage
+ Codec.CBOR.Cuddle.Huddle.HuddleM: data Rule
+ Codec.CBOR.Cuddle.Huddle.HuddleM: data family XXType2 i
+ Codec.CBOR.Cuddle.Huddle.HuddleM: getName :: HasName a => a -> Name
+ Codec.CBOR.Cuddle.Huddle.HuddleM: instance Codec.CBOR.Cuddle.Huddle.HuddleM.Includable Codec.CBOR.Cuddle.Huddle.GroupDef
+ Codec.CBOR.Cuddle.Huddle.HuddleM: withGenerator :: HasGenerator a => (forall g (m :: Type -> Type). StatefulGen g m => g -> m WrappedTerm) -> a -> a
+ Codec.CBOR.Cuddle.IndexMappable: ($dmmapIndex) :: (IndexMappable f i j, Coercible (f i) (f j)) => f i -> f j
+ Codec.CBOR.Cuddle.IndexMappable: class IndexMappable (f :: k -> Type) (i :: k) (j :: k)
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXTopLevel i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.CDDL i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.Group i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.GroupEntry i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.GrpChoice i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXTopLevel i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.TopLevel i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.GenericArg i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.GroupEntryVariant i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.MemberKey i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.Type0 i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.Type1 i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.Type2 i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.TypeOrGroup i j
+ Codec.CBOR.Cuddle.IndexMappable: instance (Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j, Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule i j) => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.Rule i j
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Huddle.HuddleStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Parser.ParserStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Parser.ParserStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Huddle.HuddleStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Parser.ParserStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.GenericParameter i j
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XTerm i j => Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.GenericParameters i j
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Huddle.HuddleStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Parser.ParserStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Huddle.HuddleStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.CDDL.CTree.CTreePhase
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Huddle.HuddleStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Parser.ParserStage
+ Codec.CBOR.Cuddle.IndexMappable: instance Codec.CBOR.Cuddle.IndexMappable.IndexMappable Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage Codec.CBOR.Cuddle.Pretty.PrettyStage
+ Codec.CBOR.Cuddle.IndexMappable: mapCDDLDropExt :: (IndexMappable XXType2 i j, IndexMappable XTerm i j, IndexMappable XRule i j) => CDDL i -> CDDL j
+ Codec.CBOR.Cuddle.IndexMappable: mapIndex :: IndexMappable f i j => f i -> f j
+ Codec.CBOR.Cuddle.Parser: data ParserStage
+ Codec.CBOR.Cuddle.Parser: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Parser.ParserStage)
+ Codec.CBOR.Cuddle.Parser: pGenericParameter :: Parser (GenericParameter ParserStage)
+ Codec.CBOR.Cuddle.Parser: pGenericParameters :: Parser (GenericParameters ParserStage)
+ Codec.CBOR.Cuddle.Pretty: data PrettyStage
+ Codec.CBOR.Cuddle.Pretty: data family XRule i
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.CollectComments (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Codec.CBOR.Cuddle.Comments.HasComment (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.Default.Internal.Default (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.String.IsString (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Data.TreeDiff.Class.ToExpr (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Base.Monoid (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Base.Semigroup (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Classes.Eq (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Generics.Generic (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XCddl Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XRule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XTerm Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXTopLevel Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance GHC.Show.Show (Codec.CBOR.Cuddle.CDDL.XXType2 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.CDDL Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.GenericArg Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.GenericParameter Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.GenericParameters Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.GroupEntry Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.MemberKey Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.Rule Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.TopLevel Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.Type0 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.Type1 Codec.CBOR.Cuddle.Pretty.PrettyStage)
+ Codec.CBOR.Cuddle.Pretty: instance Prettyprinter.Internal.Pretty (Codec.CBOR.Cuddle.CDDL.Type2 Codec.CBOR.Cuddle.Pretty.PrettyStage)
- Codec.CBOR.Cuddle.CBOR.Gen: generateCBORTerm :: RandomGen g => CTreeRoot' Identity MonoRef -> Name -> g -> Term
+ Codec.CBOR.Cuddle.CBOR.Gen: generateCBORTerm :: (HasCallStack, RandomGen g) => CTreeRoot MonoReferenced -> Name -> g -> Term
- Codec.CBOR.Cuddle.CBOR.Gen: generateCBORTerm' :: RandomGen g => CTreeRoot' Identity MonoRef -> Name -> g -> (Term, g)
+ Codec.CBOR.Cuddle.CBOR.Gen: generateCBORTerm' :: (HasCallStack, RandomGen g) => CTreeRoot MonoReferenced -> Name -> g -> (Term, g)
- Codec.CBOR.Cuddle.CBOR.Validator: UnapplicableRule :: Rule -> CDDLResult
+ Codec.CBOR.Cuddle.CBOR.Validator: UnapplicableRule :: String -> Rule -> CDDLResult
- Codec.CBOR.Cuddle.CBOR.Validator: validateCBOR :: ByteString -> Name -> CDDL -> IO ()
+ Codec.CBOR.Cuddle.CBOR.Validator: validateCBOR :: ByteString -> Name -> CDDL -> CBORTermResult
- Codec.CBOR.Cuddle.CDDL: CDDL :: [Comment] -> Rule -> [TopLevel] -> CDDL
+ Codec.CBOR.Cuddle.CDDL: CDDL :: Rule i -> [TopLevel i] -> [XXTopLevel i] -> CDDL i
- Codec.CBOR.Cuddle.CDDL: GEGroup :: Group -> GroupEntryVariant
+ Codec.CBOR.Cuddle.CDDL: GEGroup :: Group i -> GroupEntryVariant i
- Codec.CBOR.Cuddle.CDDL: GERef :: Name -> Maybe GenericArg -> GroupEntryVariant
+ Codec.CBOR.Cuddle.CDDL: GERef :: Name -> Maybe (GenericArg i) -> GroupEntryVariant i
- Codec.CBOR.Cuddle.CDDL: GEType :: Maybe MemberKey -> Type0 -> GroupEntryVariant
+ Codec.CBOR.Cuddle.CDDL: GEType :: Maybe (MemberKey i) -> Type0 i -> GroupEntryVariant i
- Codec.CBOR.Cuddle.CDDL: GenericArg :: NonEmpty Type1 -> GenericArg
+ Codec.CBOR.Cuddle.CDDL: GenericArg :: NonEmpty (Type1 i) -> GenericArg i
- Codec.CBOR.Cuddle.CDDL: Group :: NonEmpty GrpChoice -> Group
+ Codec.CBOR.Cuddle.CDDL: Group :: NonEmpty (GrpChoice i) -> Group i
- Codec.CBOR.Cuddle.CDDL: GroupEntry :: Maybe OccurrenceIndicator -> Comment -> GroupEntryVariant -> GroupEntry
+ Codec.CBOR.Cuddle.CDDL: GroupEntry :: Maybe OccurrenceIndicator -> GroupEntryVariant i -> XTerm i -> GroupEntry i
- Codec.CBOR.Cuddle.CDDL: GrpChoice :: [GroupEntry] -> Comment -> GrpChoice
+ Codec.CBOR.Cuddle.CDDL: GrpChoice :: [GroupEntry i] -> XTerm i -> GrpChoice i
- Codec.CBOR.Cuddle.CDDL: MKBareword :: Name -> MemberKey
+ Codec.CBOR.Cuddle.CDDL: MKBareword :: Name -> MemberKey i
- Codec.CBOR.Cuddle.CDDL: MKType :: Type1 -> MemberKey
+ Codec.CBOR.Cuddle.CDDL: MKType :: Type1 i -> MemberKey i
- Codec.CBOR.Cuddle.CDDL: MKValue :: Value -> MemberKey
+ Codec.CBOR.Cuddle.CDDL: MKValue :: Value -> MemberKey i
- Codec.CBOR.Cuddle.CDDL: Name :: Text -> Comment -> Name
+ Codec.CBOR.Cuddle.CDDL: Name :: Text -> Name
- Codec.CBOR.Cuddle.CDDL: Rule :: Name -> Maybe GenericParam -> Assign -> TypeOrGroup -> Comment -> Rule
+ Codec.CBOR.Cuddle.CDDL: Rule :: Name -> Maybe (GenericParameters i) -> Assign -> TypeOrGroup i -> XRule i -> Rule i
- Codec.CBOR.Cuddle.CDDL: T2Any :: Type2
+ Codec.CBOR.Cuddle.CDDL: T2Any :: Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Array :: Group -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Array :: Group i -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2DataItem :: Word8 -> Maybe Word64 -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2DataItem :: Word8 -> Maybe Word64 -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Enum :: Group -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Enum :: Group i -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2EnumRef :: Name -> Maybe GenericArg -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2EnumRef :: Name -> Maybe (GenericArg i) -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Group :: Type0 -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Group :: Type0 i -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Map :: Group -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Map :: Group i -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Name :: Name -> Maybe GenericArg -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Name :: Name -> Maybe (GenericArg i) -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Tag :: Maybe Word64 -> Type0 -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Tag :: Maybe Word64 -> Type0 i -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Unwrapped :: Name -> Maybe GenericArg -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Unwrapped :: Name -> Maybe (GenericArg i) -> Type2 i
- Codec.CBOR.Cuddle.CDDL: T2Value :: Value -> Type2
+ Codec.CBOR.Cuddle.CDDL: T2Value :: Value -> Type2 i
- Codec.CBOR.Cuddle.CDDL: TOGGroup :: GroupEntry -> TypeOrGroup
+ Codec.CBOR.Cuddle.CDDL: TOGGroup :: GroupEntry i -> TypeOrGroup i
- Codec.CBOR.Cuddle.CDDL: TOGType :: Type0 -> TypeOrGroup
+ Codec.CBOR.Cuddle.CDDL: TOGType :: Type0 i -> TypeOrGroup i
- Codec.CBOR.Cuddle.CDDL: TopLevelRule :: Rule -> TopLevel
+ Codec.CBOR.Cuddle.CDDL: TopLevelRule :: Rule i -> TopLevel i
- Codec.CBOR.Cuddle.CDDL: Type0 :: NonEmpty Type1 -> Type0
+ Codec.CBOR.Cuddle.CDDL: Type0 :: NonEmpty (Type1 i) -> Type0 i
- Codec.CBOR.Cuddle.CDDL: Type1 :: Type2 -> Maybe (TyOp, Type2) -> Comment -> Type1
+ Codec.CBOR.Cuddle.CDDL: Type1 :: Type2 i -> Maybe (TyOp, Type2 i) -> XTerm i -> Type1 i
- Codec.CBOR.Cuddle.CDDL: [gcComment] :: GrpChoice -> Comment
+ Codec.CBOR.Cuddle.CDDL: [gcComment] :: GrpChoice i -> XTerm i
- Codec.CBOR.Cuddle.CDDL: [gcGroupEntries] :: GrpChoice -> [GroupEntry]
+ Codec.CBOR.Cuddle.CDDL: [gcGroupEntries] :: GrpChoice i -> [GroupEntry i]
- Codec.CBOR.Cuddle.CDDL: [geOccurrenceIndicator] :: GroupEntry -> Maybe OccurrenceIndicator
+ Codec.CBOR.Cuddle.CDDL: [geOccurrenceIndicator] :: GroupEntry i -> Maybe OccurrenceIndicator
- Codec.CBOR.Cuddle.CDDL: [geVariant] :: GroupEntry -> GroupEntryVariant
+ Codec.CBOR.Cuddle.CDDL: [geVariant] :: GroupEntry i -> GroupEntryVariant i
- Codec.CBOR.Cuddle.CDDL: [ruleAssign] :: Rule -> Assign
+ Codec.CBOR.Cuddle.CDDL: [ruleAssign] :: Rule i -> Assign
- Codec.CBOR.Cuddle.CDDL: [ruleGenParam] :: Rule -> Maybe GenericParam
+ Codec.CBOR.Cuddle.CDDL: [ruleGenParam] :: Rule i -> Maybe (GenericParameters i)
- Codec.CBOR.Cuddle.CDDL: [ruleName] :: Rule -> Name
+ Codec.CBOR.Cuddle.CDDL: [ruleName] :: Rule i -> Name
- Codec.CBOR.Cuddle.CDDL: [ruleTerm] :: Rule -> TypeOrGroup
+ Codec.CBOR.Cuddle.CDDL: [ruleTerm] :: Rule i -> TypeOrGroup i
- Codec.CBOR.Cuddle.CDDL: [t0Type1] :: Type0 -> NonEmpty Type1
+ Codec.CBOR.Cuddle.CDDL: [t0Type1] :: Type0 i -> NonEmpty (Type1 i)
- Codec.CBOR.Cuddle.CDDL: [t1Comment] :: Type1 -> Comment
+ Codec.CBOR.Cuddle.CDDL: [t1Comment] :: Type1 i -> XTerm i
- Codec.CBOR.Cuddle.CDDL: [t1Main] :: Type1 -> Type2
+ Codec.CBOR.Cuddle.CDDL: [t1Main] :: Type1 i -> Type2 i
- Codec.CBOR.Cuddle.CDDL: [t1TyOp] :: Type1 -> Maybe (TyOp, Type2)
+ Codec.CBOR.Cuddle.CDDL: [t1TyOp] :: Type1 i -> Maybe (TyOp, Type2 i)
- Codec.CBOR.Cuddle.CDDL: [unGroup] :: Group -> NonEmpty GrpChoice
+ Codec.CBOR.Cuddle.CDDL: [unGroup] :: Group i -> NonEmpty (GrpChoice i)
- Codec.CBOR.Cuddle.CDDL: cddlTopLevel :: CDDL -> NonEmpty TopLevel
+ Codec.CBOR.Cuddle.CDDL: cddlTopLevel :: CDDL i -> NonEmpty (TopLevel i)
- Codec.CBOR.Cuddle.CDDL: compareRuleName :: Rule -> Rule -> Ordering
+ Codec.CBOR.Cuddle.CDDL: compareRuleName :: Ord (XTerm i) => Rule i -> Rule i -> Ordering
- Codec.CBOR.Cuddle.CDDL: data CDDL
+ Codec.CBOR.Cuddle.CDDL: data CDDL i
- Codec.CBOR.Cuddle.CDDL: data GroupEntry
+ Codec.CBOR.Cuddle.CDDL: data GroupEntry i
- Codec.CBOR.Cuddle.CDDL: data GroupEntryVariant
+ Codec.CBOR.Cuddle.CDDL: data GroupEntryVariant i
- Codec.CBOR.Cuddle.CDDL: data GrpChoice
+ Codec.CBOR.Cuddle.CDDL: data GrpChoice i
- Codec.CBOR.Cuddle.CDDL: data MemberKey
+ Codec.CBOR.Cuddle.CDDL: data MemberKey i
- Codec.CBOR.Cuddle.CDDL: data Rule
+ Codec.CBOR.Cuddle.CDDL: data Rule i
- Codec.CBOR.Cuddle.CDDL: data TopLevel
+ Codec.CBOR.Cuddle.CDDL: data TopLevel i
- Codec.CBOR.Cuddle.CDDL: data Type1
+ Codec.CBOR.Cuddle.CDDL: data Type1 i
- Codec.CBOR.Cuddle.CDDL: data Type2
+ Codec.CBOR.Cuddle.CDDL: data Type2 i
- Codec.CBOR.Cuddle.CDDL: data TypeOrGroup
+ Codec.CBOR.Cuddle.CDDL: data TypeOrGroup i
- Codec.CBOR.Cuddle.CDDL: fromRule :: Rule -> CDDL
+ Codec.CBOR.Cuddle.CDDL: fromRule :: Monoid (XCddl i) => Rule i -> CDDL i
- Codec.CBOR.Cuddle.CDDL: fromRules :: NonEmpty Rule -> CDDL
+ Codec.CBOR.Cuddle.CDDL: fromRules :: Monoid (XCddl i) => NonEmpty (Rule i) -> CDDL i
- Codec.CBOR.Cuddle.CDDL: newtype GenericArg
+ Codec.CBOR.Cuddle.CDDL: newtype GenericArg i
- Codec.CBOR.Cuddle.CDDL: newtype Group
+ Codec.CBOR.Cuddle.CDDL: newtype Group i
- Codec.CBOR.Cuddle.CDDL: newtype Type0
+ Codec.CBOR.Cuddle.CDDL: newtype Type0 i
- Codec.CBOR.Cuddle.CDDL: sortCDDL :: CDDL -> CDDL
+ Codec.CBOR.Cuddle.CDDL: sortCDDL :: CDDL i -> NonEmpty (Rule i)
- Codec.CBOR.Cuddle.CDDL: unwrap :: TypeOrGroup -> Maybe Group
+ Codec.CBOR.Cuddle.CDDL: unwrap :: TypeOrGroup i -> Maybe (Group i)
- Codec.CBOR.Cuddle.CDDL.CTree: Array :: [Node f] -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Array :: [CTree i] -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: CTreeRoot :: Map Name (poly (Node f)) -> CTreeRoot' (poly :: Type -> Type) (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: CTreeRoot :: Map Name (CTree i) -> CTreeRoot i
- Codec.CBOR.Cuddle.CDDL.CTree: Choice :: NonEmpty (Node f) -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Choice :: NonEmpty (CTree i) -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Control :: CtlOp -> Node f -> Node f -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Control :: CtlOp -> CTree i -> CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Enum :: Node f -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Enum :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Group :: [Node f] -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Group :: [CTree i] -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: KV :: Node f -> Node f -> Bool -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: KV :: CTree i -> CTree i -> Bool -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Literal :: Value -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Literal :: Value -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Map :: [Node f] -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Map :: [CTree i] -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Occur :: Node f -> OccurrenceIndicator -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Occur :: CTree i -> OccurrenceIndicator -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Postlude :: PTerm -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Postlude :: PTerm -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Range :: Node f -> Node f -> RangeBound -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Range :: CTree i -> CTree i -> RangeBound -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Tag :: Word64 -> Node f -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Tag :: Word64 -> CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: Unwrap :: Node f -> CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: Unwrap :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [controller] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [controller] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [cut] :: CTree (f :: Type -> Type) -> Bool
+ Codec.CBOR.Cuddle.CDDL.CTree: [cut] :: CTree i -> Bool
- Codec.CBOR.Cuddle.CDDL.CTree: [from] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [from] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [inclusive] :: CTree (f :: Type -> Type) -> RangeBound
+ Codec.CBOR.Cuddle.CDDL.CTree: [inclusive] :: CTree i -> RangeBound
- Codec.CBOR.Cuddle.CDDL.CTree: [item] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [item] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [key] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [key] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [occurs] :: CTree (f :: Type -> Type) -> OccurrenceIndicator
+ Codec.CBOR.Cuddle.CDDL.CTree: [occurs] :: CTree i -> OccurrenceIndicator
- Codec.CBOR.Cuddle.CDDL.CTree: [op] :: CTree (f :: Type -> Type) -> CtlOp
+ Codec.CBOR.Cuddle.CDDL.CTree: [op] :: CTree i -> CtlOp
- Codec.CBOR.Cuddle.CDDL.CTree: [target] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [target] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [to] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [to] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: [value] :: CTree (f :: Type -> Type) -> Node f
+ Codec.CBOR.Cuddle.CDDL.CTree: [value] :: CTree i -> CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: data CTree (f :: Type -> Type)
+ Codec.CBOR.Cuddle.CDDL.CTree: data CTree i
- Codec.CBOR.Cuddle.CDDL.CTree: traverseCTree :: Monad m => (Node f -> m (Node g)) -> CTree f -> m (CTree g)
+ Codec.CBOR.Cuddle.CDDL.CTree: traverseCTree :: Monad m => (XXCTree i -> m (CTree j)) -> (CTree i -> m (CTree j)) -> CTree i -> m (CTree j)
- Codec.CBOR.Cuddle.CDDL.CTree: type Node (f :: Type -> Type) = f CTree f
+ Codec.CBOR.Cuddle.CDDL.CTree: type Node i = XXCTree i
- Codec.CBOR.Cuddle.CDDL.Resolve: ArgsToPostlude :: PTerm -> [Node OrRef] -> NameResolutionFailure
+ Codec.CBOR.Cuddle.CDDL.Resolve: ArgsToPostlude :: PTerm -> [CTree OrReferencedDropGen] -> NameResolutionFailure
- Codec.CBOR.Cuddle.CDDL.Resolve: asMap :: CDDL -> CDDLMap
+ Codec.CBOR.Cuddle.CDDL.Resolve: asMap :: CDDL CTreePhase -> CDDLMap
- Codec.CBOR.Cuddle.CDDL.Resolve: buildMonoCTree :: CTreeRoot DistRef -> Either NameResolutionFailure (CTreeRoot' Identity MonoRef)
+ Codec.CBOR.Cuddle.CDDL.Resolve: buildMonoCTree :: PartialCTreeRoot DistReferenced -> Either NameResolutionFailure (CTreeRoot MonoReferenced)
- Codec.CBOR.Cuddle.CDDL.Resolve: buildRefCTree :: CDDLMap -> RefCTree
+ Codec.CBOR.Cuddle.CDDL.Resolve: buildRefCTree :: CDDLMap -> PartialCTreeRoot OrReferenced
- Codec.CBOR.Cuddle.CDDL.Resolve: buildResolvedCTree :: CTreeRoot OrRef -> Either NameResolutionFailure (CTreeRoot DistRef)
+ Codec.CBOR.Cuddle.CDDL.Resolve: buildResolvedCTree :: PartialCTreeRoot OrReferenced -> Either NameResolutionFailure (PartialCTreeRoot DistReferenced)
- Codec.CBOR.Cuddle.CDDL.Resolve: fullResolveCDDL :: CDDL -> Either NameResolutionFailure (CTreeRoot' Identity MonoRef)
+ Codec.CBOR.Cuddle.CDDL.Resolve: fullResolveCDDL :: CDDL CTreePhase -> Either NameResolutionFailure (CTreeRoot MonoReferenced)
- Codec.CBOR.Cuddle.Huddle: (=:=) :: IsType0 a => Text -> a -> Rule
+ Codec.CBOR.Cuddle.Huddle: (=:=) :: IsType0 a => Name -> a -> Rule
- Codec.CBOR.Cuddle.Huddle: (=:~) :: Text -> Group -> Named Group
+ Codec.CBOR.Cuddle.Huddle: (=:~) :: Name -> Group -> GroupDef
- Codec.CBOR.Cuddle.Huddle: HIGroup :: Named Group -> HuddleItem
+ Codec.CBOR.Cuddle.Huddle: HIGroup :: GroupDef -> HuddleItem
- Codec.CBOR.Cuddle.Huddle: comment :: HasField' "description" a (Maybe Text) => Text -> a -> a
+ Codec.CBOR.Cuddle.Huddle: comment :: HasComment a => Comment -> a -> a
- Codec.CBOR.Cuddle.Huddle: toCDDL :: Huddle -> CDDL
+ Codec.CBOR.Cuddle.Huddle: toCDDL :: Huddle -> CDDL HuddleStage
- Codec.CBOR.Cuddle.Huddle: toCDDLNoRoot :: Huddle -> CDDL
+ Codec.CBOR.Cuddle.Huddle: toCDDLNoRoot :: Huddle -> CDDL HuddleStage
- Codec.CBOR.Cuddle.Huddle.HuddleM: (=::=) :: IsType0 a => Text -> a -> Rule
+ Codec.CBOR.Cuddle.Huddle.HuddleM: (=::=) :: IsType0 a => Name -> a -> Rule
- Codec.CBOR.Cuddle.Huddle.HuddleM: (=:=) :: IsType0 a => Text -> a -> HuddleM Rule
+ Codec.CBOR.Cuddle.Huddle.HuddleM: (=:=) :: IsType0 a => Name -> a -> HuddleM Rule
- Codec.CBOR.Cuddle.Huddle.HuddleM: (=:~) :: Text -> Group -> HuddleM (Named Group)
+ Codec.CBOR.Cuddle.Huddle.HuddleM: (=:~) :: Name -> Group -> HuddleM GroupDef
- Codec.CBOR.Cuddle.Huddle.HuddleM: HIGroup :: Named Group -> HuddleItem
+ Codec.CBOR.Cuddle.Huddle.HuddleM: HIGroup :: GroupDef -> HuddleItem
- Codec.CBOR.Cuddle.Huddle.HuddleM: comment :: HasField' "description" a (Maybe Text) => Text -> a -> a
+ Codec.CBOR.Cuddle.Huddle.HuddleM: comment :: HasComment a => Comment -> a -> a
- Codec.CBOR.Cuddle.Huddle.HuddleM: toCDDL :: Huddle -> CDDL
+ Codec.CBOR.Cuddle.Huddle.HuddleM: toCDDL :: Huddle -> CDDL HuddleStage
- Codec.CBOR.Cuddle.Huddle.HuddleM: toCDDLNoRoot :: Huddle -> CDDL
+ Codec.CBOR.Cuddle.Huddle.HuddleM: toCDDLNoRoot :: Huddle -> CDDL HuddleStage
- Codec.CBOR.Cuddle.Huddle.HuddleM: unsafeIncludeFromHuddle :: Huddle -> Text -> HuddleM HuddleItem
+ Codec.CBOR.Cuddle.Huddle.HuddleM: unsafeIncludeFromHuddle :: Huddle -> Name -> HuddleM HuddleItem
- Codec.CBOR.Cuddle.Parser: pCDDL :: Parser CDDL
+ Codec.CBOR.Cuddle.Parser: pCDDL :: Parser (CDDL ParserStage)
- Codec.CBOR.Cuddle.Parser: pGenericArg :: Parser GenericArg
+ Codec.CBOR.Cuddle.Parser: pGenericArg :: Parser (GenericArg ParserStage)
- Codec.CBOR.Cuddle.Parser: pGroup :: Parser Group
+ Codec.CBOR.Cuddle.Parser: pGroup :: Parser (Group ParserStage)
- Codec.CBOR.Cuddle.Parser: pGrpChoice :: Parser GrpChoice
+ Codec.CBOR.Cuddle.Parser: pGrpChoice :: Parser (GrpChoice ParserStage)
- Codec.CBOR.Cuddle.Parser: pGrpEntry :: Parser GroupEntry
+ Codec.CBOR.Cuddle.Parser: pGrpEntry :: Parser (GroupEntry ParserStage)
- Codec.CBOR.Cuddle.Parser: pMemberKey :: Parser (WithComment MemberKey)
+ Codec.CBOR.Cuddle.Parser: pMemberKey :: Parser (WithComment (MemberKey ParserStage))
- Codec.CBOR.Cuddle.Parser: pRule :: Parser Rule
+ Codec.CBOR.Cuddle.Parser: pRule :: Parser (Rule ParserStage)
- Codec.CBOR.Cuddle.Parser: pTopLevel :: Parser TopLevel
+ Codec.CBOR.Cuddle.Parser: pTopLevel :: Parser (TopLevel ParserStage)
- Codec.CBOR.Cuddle.Parser: pType0 :: Parser Type0
+ Codec.CBOR.Cuddle.Parser: pType0 :: Parser (Type0 ParserStage)
- Codec.CBOR.Cuddle.Parser: pType1 :: Parser Type1
+ Codec.CBOR.Cuddle.Parser: pType1 :: Parser (Type1 ParserStage)
- Codec.CBOR.Cuddle.Parser: pType2 :: Parser Type2
+ Codec.CBOR.Cuddle.Parser: pType2 :: Parser (Type2 ParserStage)

Files

CHANGELOG.md view
@@ -1,5 +1,47 @@ # Changelog for `cuddle` +## 1.1.0.0++* Change the type of field of `T2Group` to `GroupDef`+* Remove `Named` from exports+* Changed `T2Ref` to take a `Rule` instead of `Named Type0`+* Add `GroupDef`, `HIGroup` constructor now expects a `GroupDef` instead of `Named Group`+* Changed the following type synonyms to proper datatypes:+  - `GRuleDef` +  - `GRuleCall`+* Removed `Codec.CBOR.Cuddle.Huddle.Optics`+* Changed the `comment` to take a `Comment` argument instead of `Text`+* Changed the following functions to take a `Name` instead of `Text`:+  - `(=:=)`+  - `(=:~)`+  - `(=::=)`+  - `unsafeIncludeFromHuddle`+* Changed the type of `name` field in `Named` to `Name`+* Remove the description field from `Named`+* Renamed the `name` field to `unName` in `Name`+* Add `HasName`+* Add `bool` to `Huddle` module+* Removed most `Show` instances from `Huddle` as they were unlawful+* Added `ctrTerm` and `ctrResult` field accessors to `CBORTermResult`+* Add `ValidatorStage`+* Remove `validateCBOR'`, copied its implementation to `validateCBOR`+* Add extra information field to `UnapplicableRule`+* Implement `IndexMappable` instance for+  - `HuddleStage` to `CTreePhase`+  - `HuddleStage` to `PrettyStage`+* Change the order of fields in `GroupEntry`; the extension field is now the last field+* Add `IndexMappable` to help with traversing `CDDL` trees+* Add an index type parameter to all `CDDL` terms+* Remove `Codec.CBOR.Cuddle.CDDL.Prelude`+* Replace `cddlPrelude` with `cddlPostlude`, `prependPrelude` with `appendPostlude`+* Move `PTerm` to `Codec.CBOR.Cuddle.CDDL.CTree`+* Remove `CTreeRoot'`+* Changed the type in `CTreeRoot` to a map of resolved `CTree`s+* Changed the type of the first argument for `generateCBORTerm` and +  `generateCBORTerm'` to `CTreeRoot`+* Removed all exports in `Codec.CBOR.Cuddle.CBOR.Validator` except for +  `validateCBOR`, `validateCBOR'`, `CBORTermResult` and `CDDLResult`+ ## 1.0.0.0  * First official release to Hackage
bin/Main.hs view
@@ -4,24 +4,33 @@  import Codec.CBOR.Cuddle.CBOR.Gen (generateCBORTerm) import Codec.CBOR.Cuddle.CBOR.Validator-import Codec.CBOR.Cuddle.CDDL (Name (..), sortCDDL)-import Codec.CBOR.Cuddle.CDDL.Prelude (prependPrelude)+import Codec.CBOR.Cuddle.CDDL (Name (..), fromRules, sortCDDL)+import Codec.CBOR.Cuddle.CDDL.CTree (CTreeRoot)+import Codec.CBOR.Cuddle.CDDL.Postlude (appendPostlude) import Codec.CBOR.Cuddle.CDDL.Resolve (   fullResolveCDDL,  )+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..), mapCDDLDropExt) import Codec.CBOR.Cuddle.Parser (pCDDL)-import Codec.CBOR.Cuddle.Pretty ()+import Codec.CBOR.Cuddle.Pretty (PrettyStage) import Codec.CBOR.FlatTerm (toFlatTerm) import Codec.CBOR.Pretty (prettyHexEnc) import Codec.CBOR.Term (encodeTerm) import Codec.CBOR.Write (toStrictByteString)+import Data.ByteString qualified as BS import Data.ByteString.Base16 qualified as Base16 import Data.ByteString.Char8 qualified as BSC import Data.Text qualified as T import Data.Text.IO qualified as T import Options.Applicative-import Prettyprinter (Pretty (pretty))-import Prettyprinter.Util (putDocW)+import Prettyprinter (+  LayoutOptions (..),+  PageWidth (..),+  Pretty (pretty),+  defaultLayoutOptions,+  layoutPretty,+ )+import Prettyprinter.Render.Text qualified as PT import System.Exit (exitFailure, exitSuccess) import System.IO (hPutStrLn, stderr) import System.Random (getStdGen)@@ -185,30 +194,35 @@         Format fOpts ->           let             defs-              | sort fOpts = sortCDDL res+              | sort fOpts = fromRules $ sortCDDL res               | otherwise = res+            layoutOptions = defaultLayoutOptions {layoutPageWidth = AvailablePerLine 80 1}+            formattedText =+              PT.renderStrict . layoutPretty layoutOptions . pretty $+                mapIndex @_ @_ @PrettyStage defs+            strippedText = T.unlines . fmap (T.dropWhileEnd (== ' ')) $ T.lines formattedText            in-            putDocW 80 $ pretty defs+            T.putStr strippedText         Validate vOpts ->           let-            res'+            cddl               | vNoPrelude vOpts = res-              | otherwise = prependPrelude res+              | otherwise = appendPostlude res            in-            case fullResolveCDDL res' of+            case fullResolveCDDL $ mapCDDLDropExt cddl of               Left err -> putStrLnErr (show err) >> exitFailure               Right _ -> exitSuccess-        (GenerateCBOR gOpts) ->+        GenerateCBOR gOpts ->           let-            res'+            cddl               | gNoPrelude gOpts = res-              | otherwise = prependPrelude res+              | otherwise = appendPostlude res            in-            case fullResolveCDDL res' of+            case fullResolveCDDL $ mapCDDLDropExt cddl of               Left err -> putStrLnErr (show err) >> exitFailure               Right mt -> do                 stdGen <- getStdGen-                let term = generateCBORTerm mt (Name (itemName gOpts) mempty) stdGen+                let term = generateCBORTerm mt (Name $ itemName gOpts) stdGen                  in case outputFormat gOpts of                       AsTerm -> print term                       AsFlatTerm -> print $ toFlatTerm (encodeTerm term)@@ -218,15 +232,15 @@                       AsPrettyCBOR -> putStrLn . prettyHexEnc $ encodeTerm term         ValidateCBOR vcOpts ->           let-            res'+            cddl               | vcNoPrelude vcOpts = res-              | otherwise = prependPrelude res+              | otherwise = res            in-            case fullResolveCDDL res' of+            case fullResolveCDDL $ mapCDDLDropExt cddl of               Left err -> putStrLnErr (show err) >> exitFailure               Right mt -> do                 cbor <- BSC.readFile (vcInput vcOpts)-                validateCBOR cbor (Name (vcItemName vcOpts) mempty) mt+                runValidateCBOR cbor (Name $ vcItemName vcOpts) (mapIndex mt)  putStrLnErr :: String -> IO () putStrLnErr = hPutStrLn stderr@@ -236,3 +250,13 @@   String ->   IO (Either (ParseErrorBundle T.Text e) a) parseFromFile p file = runParser p file <$> T.readFile file++runValidateCBOR :: BS.ByteString -> Name -> CTreeRoot ValidatorStage -> IO ()+runValidateCBOR bs rule cddl =+  case validateCBOR bs rule cddl of+    ok@(CBORTermResult _ (Valid _)) -> do+      putStrLn $ "Valid " ++ show ok+      exitSuccess+    err -> do+      hPutStrLn stderr $ "Invalid " ++ show err+      exitFailure
cuddle.cabal view
@@ -1,6 +1,6 @@ cabal-version: 3.4 name: cuddle-version: 1.0.0.0+version: 1.1.0.0 synopsis: CDDL Generator and test utilities description:   Cuddle is a library for generating and manipulating [CDDL](https://datatracker.ietf.org/doc/html/rfc8610).@@ -21,25 +21,22 @@ category: Codec build-type: Simple extra-doc-files: CHANGELOG.md-tested-with: ghc =={9.6, 9.8, 9.10, 9.12}+tested-with: ghc ==9.6 || ==9.8 || ==9.10 || ==9.12+data-files:+  example/cddl-files/*.cddl+  example/cddl-files/validator/negative/*.cddl  source-repository head   type: git   location: https://github.com/input-output-hk/cuddle -source-repository this-  type: git-  location: https://github.com/input-output-hk/cuddle-  tag: cuddle-0.5.0.0- flag example   description: Enable the example executable   manual: True   default: False  common warnings-  ghc-options:-    -Wall+  ghc-options: -Wall  library   import: warnings@@ -47,15 +44,15 @@     Codec.CBOR.Cuddle.CBOR.Gen     Codec.CBOR.Cuddle.CBOR.Validator     Codec.CBOR.Cuddle.CDDL+    Codec.CBOR.Cuddle.CDDL.CBORGenerator     Codec.CBOR.Cuddle.CDDL.CTree     Codec.CBOR.Cuddle.CDDL.CtlOp     Codec.CBOR.Cuddle.CDDL.Postlude-    Codec.CBOR.Cuddle.CDDL.Prelude     Codec.CBOR.Cuddle.CDDL.Resolve     Codec.CBOR.Cuddle.Comments     Codec.CBOR.Cuddle.Huddle     Codec.CBOR.Cuddle.Huddle.HuddleM-    Codec.CBOR.Cuddle.Huddle.Optics+    Codec.CBOR.Cuddle.IndexMappable     Codec.CBOR.Cuddle.Parser     Codec.CBOR.Cuddle.Parser.Lexer     Codec.CBOR.Cuddle.Pretty@@ -134,11 +131,16 @@ test-suite cuddle-test   import: warnings   default-language: GHC2021+  autogen-modules:+    Paths_cuddle   other-modules:+    Paths_cuddle     Test.Codec.CBOR.Cuddle.CDDL.Examples     Test.Codec.CBOR.Cuddle.CDDL.Gen+    Test.Codec.CBOR.Cuddle.CDDL.GeneratorSpec     Test.Codec.CBOR.Cuddle.CDDL.Parser     Test.Codec.CBOR.Cuddle.CDDL.Pretty+    Test.Codec.CBOR.Cuddle.CDDL.Validator     Test.Codec.CBOR.Cuddle.Huddle    type: exitcode-stdio-1.0@@ -149,12 +151,17 @@     QuickCheck >=2.14,     base,     bytestring,+    cborg,+    containers,     cuddle,     data-default-class,+    generic-random,     hspec >=2.11,     hspec-megaparsec >=2.2,     megaparsec,+    pretty-simple,     prettyprinter,+    random,     string-qq >=0.0.6,     text,     tree-diff,
+ example/cddl-files/basic_assign.cddl view
@@ -0,0 +1,47 @@+coin = uint+epoch = uint++header =+  [ header_body+  , body_signature : $kes_signature+  , test : coin / null+  , withComment : null ; This is a comment+  , true+  ]++header_body = [+  issuer : text+]++$kes_signature = bytes .size 32+unit_interval<denominator> = [0 .. denominator, denominator]++unit_int = unit_interval<4294967295>++mysize = 16++sz1 = bytes .size 1+sz2 = bytes .size 2+sz32 = bytes .size 32+sz16 = bytes .size mysize++usz4 = uint .size 4+usz8 = uint .size 8++group = (usz4, usz8 / mysize, header_body, { * uint => coin })++set<a> = [ * a]+set2<a> = set<a>++coin_bag = set2<coin>++big_group = (+  "hello",+  32,+  8* 4,+  & group,+  uint,+  unit_interval<3>,+  5 ...10,+  h'11aaff3351bc'+)
+ example/cddl-files/byron.cddl view
@@ -0,0 +1,209 @@+; Cardano Byron blockchain CBOR schema++block = [0, ebblock]+      / [1, mainblock]++mainblock = [ "header" : blockhead+            , "body" : blockbody+            , "extra" : [attributes]+            ]++ebblock = [ "header" : ebbhead+          , "body" : [+ stakeholderid]+          , extra : [attributes]+          ]++u8 = uint .lt 256+u16 = uint .lt 65536+u32 = uint+u64 = uint++; Basic Cardano Types++blake2b-256 = bytes .size 32++txid = blake2b-256+blockid = blake2b-256+updid = blake2b-256+hash = blake2b-256++blake2b-224 = bytes .size 28++addressid = blake2b-224+stakeholderid = blake2b-224++epochid = u64+slotid = [ epoch: epochid, slot : u64 ]++pubkey = bytes+signature = bytes++; Attributes - at the moment we do not bother deserialising these, since they+; don't contain anything++attributes = {* any => any}++; Addresses++addrdistr = [1] / [0, stakeholderid]++addrtype = &("PubKey" : 0, "Script" : 1, "Redeem" : 2) / (u64 .gt 2)+addrattr = { ? 0 : addrdistr+           , ? 1 : bytes}+address = [ #6.24(bytes .cbor ([addressid, addrattr, addrtype])), u64 ]++; Transactions++txin = [0, #6.24(bytes .cbor ([txid, u32]))] / [u8 .ne 0, encoded-cbor]+txout = [address, u64]++tx = [[+ txin], [+ txout], attributes]++txproof = [u32, hash, hash]++twit = [0, #6.24(bytes .cbor ([pubkey, signature]))]+     / [1, #6.24(bytes .cbor ([[u16, bytes], [u16, bytes]]))]+     / [2, #6.24(bytes .cbor ([pubkey, signature]))]+     / [u8 .gt 2, encoded-cbor]++; Shared Seed Computation++vsspubkey = bytes ; This is encoded using the 'Binary' instance+                  ; for Scrape.PublicKey+vsssec = bytes ; This is encoded using the 'Binary' instance+               ; for Scrape.Secret.+vssenc = [bytes] ; This is encoded using the 'Binary' instance+                 ; for Scrape.EncryptedSi.+                 ; TODO work out why this seems to be in a length 1 array+vssdec = bytes ; This is encoded using the 'Binary' instance+               ; for Scrape.DecryptedShare+vssproof = [bytes, bytes, bytes, [* bytes]] ; This is encoded using the+                                            ; 'Binary' instance for Scrape.Proof++ssccomm = [pubkey, [{vsspubkey => vssenc},vssproof], signature]+ssccomms = #6.258([* ssccomm])++sscopens = {stakeholderid => vsssec}++sscshares = {addressid => [addressid, [* vssdec]]}++ssccert = [vsspubkey, pubkey, epochid, signature]+ssccerts = #6.258([* ssccert])++ssc = [0, ssccomms, ssccerts]+    / [1, sscopens, ssccerts]+    / [2, sscshares, ssccerts]+    / [3, ssccerts]++sscproof = [0, hash, hash]+         / [1, hash, hash]+         / [2, hash, hash]+         / [3, hash]++; Delegation++dlg = [ epoch : epochid+      , issuer : pubkey+      , delegate : pubkey+      , certificate : signature+      ]++dlgsig = [dlg, signature]++lwdlg = [ epochRange : [epochid, epochid]+        , issuer : pubkey+        , delegate : pubkey+        , certificate : signature+        ]++lwdlgsig = [lwdlg, signature]++; Updates++bver = [u16, u16, u8]++txfeepol = [0, #6.24(bytes .cbor ([bigint, bigint]))]+         / [u8 .gt 0, encoded-cbor]++bvermod = [ scriptVersion : [? u16]+          , slotDuration : [? bigint]+          , maxBlockSize : [? bigint]+          , maxHeaderSize  : [? bigint]+          , maxTxSize : [? bigint]+          , maxProposalSize : [? bigint]+          , mpcThd : [? u64]+          , heavyDelThd : [? u64]+          , updateVoteThd : [? u64]+          , updateProposalThd : [? u64]+          , updateImplicit : [? u64]+          , softForkRule : [? [u64, u64, u64]]+          , txFeePolicy : [? txfeepol]+          , unlockStakeEpoch : [? epochid]+          ]++updata = [ hash, hash, hash, hash ]++upprop = [ "blockVersion" : bver+         , "blockVersionMod" : bvermod+         , "softwareVersion" : [ text, u32 ]+         , "data" : #6.258([text, updata])+         , "attributes" : attributes+         , "from" : pubkey+         , "signature" : signature+         ]++upvote = [ "voter" : pubkey+         , "proposalId" : updid+         , "vote" : bool+         , "signature" : signature+         ]++up = [ "proposal" :  [? upprop]+     , votes : [* upvote]+     ]++; Blocks++difficulty = [u64]++blocksig = [0, signature]+         / [1, lwdlgsig]+         / [2, dlgsig]++blockcons = [slotid, pubkey, difficulty, blocksig]++blockheadex = [ "blockVersion" : bver+              , "softwareVersion" : [ text, u32 ]+              , "attributes" : attributes+              , "extraProof" : hash+              ]++blockproof = [ "txProof" : txproof+             , "sscProof" : sscproof+             , "dlgProof" : hash+             , "updProof" : hash+             ]++blockhead = [ "protocolMagic" : u32+            , "prevBlock" : blockid+            , "bodyProof" : blockproof+            , "consensusData" : blockcons+            , "extraData" : blockheadex+            ]++blockbody = [ "txPayload" : [* [tx, [* twit]]]+            , "sscPayload" : ssc+            , "dlgPayload" : [* dlg]+            , "updPayload" : up+            ]++; Epoch Boundary Blocks++ebbcons = [ epochid, difficulty ]++ebbhead = [ "protocolMagic" : u32+          , "prevBlock" : blockid+          , "bodyProof" : hash+          , "consensusData" : ebbcons+          , "extraData" : [attributes]+          ]
+ example/cddl-files/conway.cddl view
@@ -0,0 +1,683 @@+; crypto.cddl+$hash28 /= bytes .size 28+$hash32 /= bytes .size 32++$vkey /= bytes .size 32++$vrf_vkey /= bytes .size 32+$vrf_cert /= [bytes, bytes .size 80]++$kes_vkey /= bytes .size 32+$kes_signature /= bytes .size 448+signkeyKES = bytes .size 64++$signature /= bytes .size 64++; extra.cddl+; Conway era introduces an optional 258 tag for sets, which will become mandatory in the+; second era after Conway. We recommend all the tooling to account for this future breaking+; change sooner rather than later, in order to provide a smooth transition for their users.++; This is an unordered set. Duplicate elements are not allowed and the order of elements is implementation specific.+set<a> = #6.258([* a]) / [* a]++; Just like `set`, but must contain at least one element.+nonempty_set<a> = #6.258([+ a]) / [+ a]++; This is a non-empty ordered set. Duplicate elements are not allowed and the order of elements will be preserved.+nonempty_oset<a> = #6.258([+ a]) / [+ a]++positive_int = 1 .. 18446744073709551615++unit_interval = #6.30([1, 2])+  ; unit_interval = #6.30([uint, uint])+  ;+  ; Comment above depicts the actual definition for `unit_interval`.+  ;+  ; Unit interval is a number in the range between 0 and 1, which+  ; means there are two extra constraints:+  ; * numerator <= denominator+  ; * denominator > 0+  ;+  ; Relation between numerator and denominator cannot be expressed in CDDL, which+  ; poses a problem for testing. We need to be able to generate random valid data+  ; for testing implementation of our encoders/decoders. Which means we cannot use+  ; the actual definition here and we hard code the value to 1/2+++nonnegative_interval = #6.30([uint, positive_int])+++address =+  h'001000000000000000000000000000000000000000000000000000000011000000000000000000000000000000000000000000000000000000' /+  h'102000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000' /+  h'203000000000000000000000000000000000000000000000000000000033000000000000000000000000000000000000000000000000000000' /+  h'304000000000000000000000000000000000000000000000000000000044000000000000000000000000000000000000000000000000000000' /+  h'405000000000000000000000000000000000000000000000000000000087680203' /+  h'506000000000000000000000000000000000000000000000000000000087680203' /+  h'6070000000000000000000000000000000000000000000000000000000' /+  h'7080000000000000000000000000000000000000000000000000000000'++reward_account =+  h'E090000000000000000000000000000000000000000000000000000000' /+  h'F0A0000000000000000000000000000000000000000000000000000000'++bounded_bytes = bytes .size (0..64)+  ; the real bounded_bytes does not have this limit. it instead has a different+  ; limit which cannot be expressed in CDDL.+  ; The limit is as follows:+  ;  - bytes with a definite-length encoding are limited to size 0..64+  ;  - for bytes with an indefinite-length CBOR encoding, each chunk is+  ;    limited to size 0..64+  ;  ( reminder: in CBOR, the indefinite-length encoding of bytestrings+  ;    consists of a token #2.31 followed by a sequence of definite-length+  ;    encoded bytestrings and a stop code )++; a type for distinct values.+; The type parameter must support .size, for example: bytes or uint+distinct<a> = a .size 8 / a .size 16 / a .size 20 / a .size 24 / a .size 30 / a .size 32++; conway.cddl+block =+  [ header+  , transaction_bodies         : [* transaction_body]+  , transaction_witness_sets   : [* transaction_witness_set]+  , auxiliary_data_set         : {* transaction_index => auxiliary_data }+  , invalid_transactions       : [* transaction_index ]+  ]; Valid blocks must also satisfy the following two constraints:+   ; 1) the length of transaction_bodies and transaction_witness_sets+   ;    must be the same+   ; 2) every transaction_index must be strictly smaller than the+   ;    length of transaction_bodies++transaction =+  [ transaction_body+  , transaction_witness_set+  , bool+  , auxiliary_data / null+  ]++transaction_index = uint .size 2++header =+  [ header_body+  , body_signature : $kes_signature+  ]++header_body =+  [ block_number     : uint+  , slot             : uint+  , prev_hash        : $hash32 / null+  , issuer_vkey      : $vkey+  , vrf_vkey         : $vrf_vkey+  , vrf_result       : $vrf_cert ; replaces nonce_vrf and leader_vrf+  , block_body_size  : uint+  , block_body_hash  : $hash32 ; merkle triple root+  , operational_cert+  , [ protocol_version ]+  ]++operational_cert =+  [ hot_vkey        : $kes_vkey+  , sequence_number : uint+  , kes_period      : uint+  , sigma           : $signature+  ]++next_major_protocol_version = 10++major_protocol_version = 1..next_major_protocol_version++protocol_version = (major_protocol_version, uint)++transaction_body =+  { 0 : set<transaction_input>             ; inputs+  , 1 : [* transaction_output]+  , 2 : coin                               ; fee+  , ? 3 : uint                             ; time to live+  , ? 4 : certificates+  , ? 5 : withdrawals+  , ? 7 : auxiliary_data_hash+  , ? 8 : uint                             ; validity interval start+  , ? 9 : mint+  , ? 11 : script_data_hash+  , ? 13 : nonempty_set<transaction_input> ; collateral inputs+  , ? 14 : required_signers+  , ? 15 : network_id+  , ? 16 : transaction_output              ; collateral return+  , ? 17 : coin                            ; total collateral+  , ? 18 : nonempty_set<transaction_input> ; reference inputs+  , ? 19 : voting_procedures               ; New; Voting procedures+  , ? 20 : proposal_procedures             ; New; Proposal procedures+  , ? 21 : coin                            ; New; current treasury value+  , ? 22 : positive_coin                   ; New; donation+  }++voting_procedures = { + voter => { + gov_action_id => voting_procedure } }++voting_procedure =+  [ vote+  , anchor / null+  ]++proposal_procedure =+  [ deposit : coin+  , reward_account+  , gov_action+  , anchor+  ]++proposal_procedures = nonempty_set<proposal_procedure>++certificates = nonempty_set<certificate>++gov_action =+  [ parameter_change_action+  // hard_fork_initiation_action+  // treasury_withdrawals_action+  // no_confidence+  // update_committee+  // new_constitution+  // info_action+  ]++policy_hash = scripthash++parameter_change_action = (0, gov_action_id / null, protocol_param_update, policy_hash / null)++hard_fork_initiation_action = (1, gov_action_id / null, [protocol_version])++treasury_withdrawals_action = (2, { reward_account => coin }, policy_hash / null)++no_confidence = (3, gov_action_id / null)++update_committee = (4, gov_action_id / null, set<committee_cold_credential>, { committee_cold_credential => epoch }, unit_interval)++new_constitution = (5, gov_action_id / null, constitution)++constitution =+  [ anchor+  , scripthash / null+  ]++info_action = 6++; Constitutional Committee Hot KeyHash: 0+; Constitutional Committee Hot ScriptHash: 1+; DRep KeyHash: 2+; DRep ScriptHash: 3+; StakingPool KeyHash: 4+voter =+  [ 0, addr_keyhash+  // 1, scripthash+  // 2, addr_keyhash+  // 3, scripthash+  // 4, addr_keyhash+  ]++anchor =+  [ anchor_url       : url+  , anchor_data_hash : $hash32+  ]++; no - 0+; yes - 1+; abstain - 2+vote = 0 .. 2++gov_action_id =+  [ transaction_id   : $hash32+  , gov_action_index : uint+  ]++required_signers = nonempty_set<addr_keyhash>++transaction_input = [ transaction_id : $hash32+                    , index : uint+                    ]++transaction_output = legacy_transaction_output / post_alonzo_transaction_output++legacy_transaction_output =+  [ address+  , amount : value+  , ? datum_hash : $hash32+  ]++post_alonzo_transaction_output =+  { 0 : address+  , 1 : value+  , ? 2 : datum_option ; datum option+  , ? 3 : script_ref   ; script reference+  }++script_data_hash = $hash32+; This is a hash of data which may affect evaluation of a script.+; This data consists of:+;   - The redeemers from the transaction_witness_set (the value of field 5).+;   - The datums from the transaction_witness_set (the value of field 4).+;   - The value in the costmdls map corresponding to the script's language+;     (in field 18 of protocol_param_update.)+; (In the future it may contain additional protocol parameters.)+;+; Since this data does not exist in contiguous form inside a transaction, it needs+; to be independently constructed by each recipient.+;+; The bytestring which is hashed is the concatenation of three things:+;   redeemers || datums || language views+; The redeemers are exactly the data present in the transaction witness set.+; Similarly for the datums, if present. If no datums are provided, the middle+; field is omitted (i.e. it is the empty/null bytestring).+;+; language views CDDL:+; { * language => script_integrity_data }+;+; This must be encoded canonically, using the same scheme as in+; RFC7049 section 3.9:+;  - Maps, strings, and bytestrings must use a definite-length encoding+;  - Integers must be as small as possible.+;  - The expressions for map length, string length, and bytestring length+;    must be as short as possible.+;  - The keys in the map must be sorted as follows:+;     -  If two keys have different lengths, the shorter one sorts earlier.+;     -  If two keys have the same length, the one with the lower value+;        in (byte-wise) lexical order sorts earlier.+;+; For PlutusV1 (language id 0), the language view is the following:+;   - the value of costmdls map at key 0 (in other words, the script_integrity_data)+;     is encoded as an indefinite length list and the result is encoded as a bytestring.+;     (our apologies)+;     For example, the script_integrity_data corresponding to the all zero costmodel for V1+;     would be encoded as (in hex):+;     58a89f00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000ff+;   - the language ID tag is also encoded twice. first as a uint then as+;     a bytestring. (our apologies)+;     Concretely, this means that the language version for V1 is encoded as+;     4100 in hex.+; For PlutusV2 (language id 1), the language view is the following:+;   - the value of costmdls map at key 1 is encoded as an definite length list.+;     For example, the script_integrity_data corresponding to the all zero costmodel for V2+;     would be encoded as (in hex):+;     98af0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000+;   - the language ID tag is encoded as expected.+;     Concretely, this means that the language version for V2 is encoded as+;     01 in hex.+; For PlutusV3 (language id 2), the language view is the following:+;   - the value of costmdls map at key 2 is encoded as a definite length list.+;+; Note that each Plutus language represented inside a transaction must have+; a cost model in the costmdls protocol parameter in order to execute,+; regardless of what the script integrity data is.+;+; Finally, note that in the case that a transaction includes datums but does not+; include the redeemers field, the script data format becomes (in hex):+; [ 80 | datums | A0 ]+; corresponding to a CBOR empty list and an empty map.+; Note that a transaction might include the redeemers field and  it to the+; empty map, in which case the user supplied encoding of the empty map is used.++; address = bytes+; reward_account = bytes++; address format:+; [ 8 bit header | payload ];+;+; shelley payment addresses:+; bit 7: 0+; bit 6: base/other+; bit 5: pointer/enterprise [for base: stake cred is keyhash/scripthash]+; bit 4: payment cred is keyhash/scripthash+; bits 3-0: network id+;+; reward addresses:+; bits 7-5: 111+; bit 4: credential is keyhash/scripthash+; bits 3-0: network id+;+; byron addresses:+; bits 7-4: 1000++; 0000: base address: keyhash28,keyhash28+; 0001: base address: scripthash28,keyhash28+; 0010: base address: keyhash28,scripthash28+; 0011: base address: scripthash28,scripthash28+; 0100: pointer address: keyhash28, 3 variable length uint+; 0101: pointer address: scripthash28, 3 variable length uint+; 0110: enterprise address: keyhash28+; 0111: enterprise address: scripthash28+; 1000: byron address+; 1110: reward account: keyhash28+; 1111: reward account: scripthash28+; 1001 - 1101: future formats++certificate =+  [ stake_registration+  // stake_deregistration+  // stake_delegation+  // pool_registration+  // pool_retirement+  // reg_cert+  // unreg_cert+  // vote_deleg_cert+  // stake_vote_deleg_cert+  // stake_reg_deleg_cert+  // vote_reg_deleg_cert+  // stake_vote_reg_deleg_cert+  // auth_committee_hot_cert+  // resign_committee_cold_cert+  // reg_drep_cert+  // unreg_drep_cert+  // update_drep_cert+  ]++stake_registration = (0, stake_credential) ; to be deprecated in era after Conway+stake_deregistration = (1, stake_credential) ; to be deprecated in era after Conway+stake_delegation = (2, stake_credential, pool_keyhash)++; POOL+pool_registration = (3, pool_params)+pool_retirement = (4, pool_keyhash, epoch)++; numbers 5 and 6 used to be the Genesis and MIR certificates respectively,+; which were deprecated in Conway++; DELEG+reg_cert = (7, stake_credential, coin)+unreg_cert = (8, stake_credential, coin)+vote_deleg_cert = (9, stake_credential, drep)+stake_vote_deleg_cert = (10, stake_credential, pool_keyhash, drep)+stake_reg_deleg_cert = (11, stake_credential, pool_keyhash, coin)+vote_reg_deleg_cert = (12, stake_credential, drep, coin)+stake_vote_reg_deleg_cert = (13, stake_credential, pool_keyhash, drep, coin)++; GOVCERT+auth_committee_hot_cert = (14, committee_cold_credential, committee_hot_credential)+resign_committee_cold_cert = (15, committee_cold_credential, anchor / null)+reg_drep_cert = (16, drep_credential, coin, anchor / null)+unreg_drep_cert = (17, drep_credential, coin)+update_drep_cert = (18, drep_credential, anchor / null)+++delta_coin = int++credential =+  [  0, addr_keyhash+  // 1, scripthash+  ]++drep =+  [ 0, addr_keyhash+  // 1, scripthash+  // 2  ; always abstain+  // 3  ; always no confidence+  ]++stake_credential = credential+drep_credential = credential+committee_cold_credential = credential+committee_hot_credential = credential++pool_params = ( operator:       pool_keyhash+              , vrf_keyhash:    vrf_keyhash+              , pledge:         coin+              , cost:           coin+              , margin:         unit_interval+              , reward_account: reward_account+              , pool_owners:    set<addr_keyhash>+              , relays:         [* relay]+              , pool_metadata:  pool_metadata / null+              )++port = uint .le 65535+ipv4 = bytes .size 4+ipv6 = bytes .size 16+dns_name = tstr .size (0..128)++single_host_addr = ( 0+                   , port / null+                   , ipv4 / null+                   , ipv6 / null+                   )+single_host_name = ( 1+                   , port / null+                   , dns_name ; An A or AAAA DNS record+                   )+multi_host_name = ( 2+                   , dns_name ; A SRV DNS record+                   )+relay =+  [  single_host_addr+  // single_host_name+  // multi_host_name+  ]++pool_metadata = [url, pool_metadata_hash]+url = tstr .size (0..128)++withdrawals = { + reward_account => coin }++protocol_param_update =+  { ? 0:  coin                   ; minfee A+  , ? 1:  coin                   ; minfee B+  , ? 2:  uint                   ; max block body size+  , ? 3:  uint                   ; max transaction size+  , ? 4:  uint                   ; max block header size+  , ? 5:  coin                   ; key deposit+  , ? 6:  coin                   ; pool deposit+  , ? 7:  epoch                  ; maximum epoch+  , ? 8:  uint                   ; n_opt: desired number of stake pools+  , ? 9:  nonnegative_interval   ; pool pledge influence+  , ? 10: unit_interval          ; expansion rate+  , ? 11: unit_interval          ; treasury growth rate+  , ? 16: coin                   ; min pool cost+  , ? 17: coin                   ; ada per utxo byte+  , ? 18: costmdls               ; cost models for script languages+  , ? 19: ex_unit_prices         ; execution costs+  , ? 20: ex_units               ; max tx ex units+  , ? 21: ex_units               ; max block ex units+  , ? 22: uint                   ; max value size+  , ? 23: uint                   ; collateral percentage+  , ? 24: uint                   ; max collateral inputs+  , ? 25: pool_voting_thresholds ; pool voting thresholds+  , ? 26: drep_voting_thresholds ; DRep voting thresholds+  , ? 27: uint                   ; min committee size+  , ? 28: epoch                  ; committee term limit+  , ? 29: epoch                  ; governance action validity period+  , ? 30: coin                   ; governance action deposit+  , ? 31: coin                   ; DRep deposit+  , ? 32: epoch                  ; DRep inactivity period+  }++pool_voting_thresholds =+  [ unit_interval ; motion no confidence+  , unit_interval ; committee normal+  , unit_interval ; committee no confidence+  , unit_interval ; hard fork initiation+  , unit_interval ; security relevant parameter voting threshold+  ]++drep_voting_thresholds =+  [ unit_interval ; motion no confidence+  , unit_interval ; committee normal+  , unit_interval ; committee no confidence+  , unit_interval ; update constitution+  , unit_interval ; hard fork initiation+  , unit_interval ; PP network group+  , unit_interval ; PP economic group+  , unit_interval ; PP technical group+  , unit_interval ; PP governance group+  , unit_interval ; treasury withdrawal+  ]++transaction_witness_set =+  { ? 0: nonempty_set<vkeywitness>+  , ? 1: nonempty_set<native_script>+  , ? 2: nonempty_set<bootstrap_witness>+  , ? 3: nonempty_set<plutus_v1_script>+  , ? 4: nonempty_set<plutus_data>+  , ? 5: redeemers+  , ? 6: nonempty_set<plutus_v2_script>+  , ? 7: nonempty_set<plutus_v3_script>+  }++; The real type of  plutus_v1_script, plutus_v2_script and plutus_v3_script is bytes.+; However, because we enforce uniqueness when many scripts are supplied,+; we need to hack around for tests in order to avoid generating duplicates,+; since the cddl tool we use for roundtrip testing doesn't generate distinct collections.+plutus_v1_script = distinct<bytes>+plutus_v2_script = distinct<bytes>+plutus_v3_script = distinct<bytes>++plutus_data =+    constr<plutus_data>+  / { * plutus_data => plutus_data }+  / [ * plutus_data ]+  / big_int+  / bounded_bytes++big_int = int / big_uint / big_nint+big_uint = #6.2(bounded_bytes)+big_nint = #6.3(bounded_bytes)++constr<a> =+    #6.121([* a])+  / #6.122([* a])+  / #6.123([* a])+  / #6.124([* a])+  / #6.125([* a])+  / #6.126([* a])+  / #6.127([* a]) ; similarly for tag range: 6.1280 .. 6.1400 inclusive+  / #6.102([uint, [* a]])++redeemers =+  [ + [ tag: redeemer_tag, index: uint, data: plutus_data, ex_units: ex_units ] ]+; TODO: Add alternative implementation that reflects the reality more accuratly:+;  / { + [ tag: redeemer_tag, index: uint ] => [ data: plutus_data, ex_units: ex_units ] }++redeemer_tag =+    0 ; Spending+  / 1 ; Minting+  / 2 ; Certifying+  / 3 ; Rewarding+  / 4 ; Voting+  / 5 ; Proposing++ex_units = [mem: uint, steps: uint]++ex_unit_prices =+  [ mem_price: nonnegative_interval, step_price: nonnegative_interval ]++language = 0 ; Plutus v1+         / 1 ; Plutus v2+         / 2 ; Plutus v3++potential_languages = 0 .. 255++; The format for costmdls is flexible enough to allow adding Plutus built-ins and language+; versions in the future.+;+costmdls =+  { ? 0 : [ 166* int ] ; Plutus v1, only 166 integers are used, but more are accepted (and ignored)+  , ? 1 : [ 175* int ] ; Plutus v2, only 175 integers are used, but more are accepted (and ignored)+  , ? 2 : [ 223* int ] ; Plutus v3, only 223 integers are used, but more are accepted (and ignored)+  , ? 3 : [ int ] ; Any 8-bit unsigned number can be used as a key.+  }++transaction_metadatum =+    { * transaction_metadatum => transaction_metadatum }+  / [ * transaction_metadatum ]+  / int+  / bytes .size (0..64)+  / text .size (0..64)++transaction_metadatum_label = uint+metadata = { * transaction_metadatum_label => transaction_metadatum }++auxiliary_data =+  metadata ; Shelley+  / [ transaction_metadata: metadata ; Shelley-ma+    , auxiliary_scripts: [ * native_script ]+    ]+  / #6.259({ ? 0 => metadata         ; Alonzo and beyond+      , ? 1 => [ * native_script ]+      , ? 2 => [ * plutus_v1_script ]+      , ? 3 => [ * plutus_v2_script ]+      , ? 4 => [ * plutus_v3_script ]+      })++vkeywitness = [ $vkey, $signature ]++bootstrap_witness =+  [ public_key : $vkey+  , signature  : $signature+  , chain_code : bytes .size 32+  , attributes : bytes+  ]++native_script =+  [ script_pubkey+  // script_all+  // script_any+  // script_n_of_k+  // invalid_before+     ; Timelock validity intervals are half-open intervals [a, b).+     ; This field specifies the left (included) endpoint a.+  // invalid_hereafter+     ; Timelock validity intervals are half-open intervals [a, b).+     ; This field specifies the right (excluded) endpoint b.+  ]++script_pubkey = (0, addr_keyhash)+script_all = (1, [ * native_script ])+script_any = (2, [ * native_script ])+script_n_of_k = (3, n: uint, [ * native_script ])+invalid_before = (4, uint)+invalid_hereafter = (5, uint)++coin = uint++multiasset<a> = { + policy_id => { + asset_name => a } }+policy_id = scripthash+asset_name = bytes .size (0..32)++negInt64 = -9223372036854775808 .. -1+posInt64 = 1 .. 9223372036854775807+nonZeroInt64 = negInt64 / posInt64 ; this is the same as the current int64 definition but without zero++positive_coin = 1 .. 18446744073709551615++value = coin / [coin, multiasset<positive_coin>]++mint = multiasset<nonZeroInt64>++int64 = -9223372036854775808 .. 9223372036854775807++network_id = 0 / 1++epoch = uint++addr_keyhash           = $hash28+pool_keyhash           = $hash28++vrf_keyhash           = $hash32+auxiliary_data_hash   = $hash32+pool_metadata_hash    = $hash32++; To compute a script hash, note that you must prepend+; a tag to the bytes of the script before hashing.+; The tag is determined by the language.+; The tags in the Conway era are:+;   "\x00" for multisig scripts+;   "\x01" for Plutus V1 scripts+;   "\x02" for Plutus V2 scripts+;   "\x03" for Plutus V3 scripts+scripthash            = $hash28++datum_hash = $hash32+data = #6.24(bytes .cbor plutus_data)++datum_option = [ 0, $hash32 // 1, data ]++script_ref = #6.24(bytes .cbor script)++script = [ 0, native_script // 1, plutus_v1_script // 2, plutus_v2_script // 3, plutus_v3_script ]
+ example/cddl-files/costmdls_min.cddl view
@@ -0,0 +1,3 @@+costmdls =+  { 0 : [ 11* int ] ; Plutus v1, only 166 integers are used, but more are accepted (and ignored)+  }
+ example/cddl-files/issue80-min.cddl view
@@ -0,0 +1,8 @@+main = test<int, int>+set<x> = [x]+test<x, x1> = [+	1,+	x,+	set<x>+]+
+ example/cddl-files/pretty.cddl view
@@ -0,0 +1,13 @@+set<a > = [* a]++a = [ 2*30 2 : uint+  , ? 33 : bytes+  , 4444 : set<uint>+  , * 55 => uint+  ]++b = [1,uint,(3,4)]++c = { 1: a +, 2: b ; hello+}
+ example/cddl-files/shelley.cddl view
@@ -0,0 +1,288 @@+; Shelley Types++block =+  [ header+  , transaction_bodies         : [* transaction_body]+  , transaction_witness_sets   : [* transaction_witness_set]+  , transaction_metadata_set   :+      { * transaction_index => transaction_metadata }+  ]; Valid blocks must also satisfy the following two constraints:+   ; 1) the length of transaction_bodies and transaction_witness_sets+   ;    must be the same+   ; 2) every transaction_index must be strictly smaller than the+   ;    length of transaction_bodies++transaction =+  [ transaction_body+  , transaction_witness_set+  , transaction_metadata / null+  ]++transaction_index = uint .size 2++header =+  [ header_body+  , body_signature : $kes_signature+  ]++header_body =+  [ block_number     : uint+  , slot             : uint+  , prev_hash        : $hash32 / null+  , issuer_vkey      : $vkey+  , vrf_vkey         : $vrf_vkey+  , nonce_vrf        : $vrf_cert+  , leader_vrf       : $vrf_cert+  , block_body_size  : uint+  , block_body_hash  : $hash32 ; merkle triple root+  , operational_cert+  , protocol_version+  ]++operational_cert =+  ( hot_vkey        : $kes_vkey+  , sequence_number : uint+  , kes_period      : uint+  , sigma           : $signature+  )++next_major_protocol_version = 3++major_protocol_version = 1..next_major_protocol_version++protocol_version = (major_protocol_version, uint)++transaction_body =+  { 0 : set<transaction_input>+  , 1 : [* transaction_output]+  , 2 : coin ; fee+  , 3 : uint ; ttl+  , ? 4 : [* certificate]+  , ? 5 : withdrawals+  , ? 6 : update+  , ? 7 : metadata_hash+  }++transaction_input = [ transaction_id : $hash32+                    , index : uint+                    ]++transaction_output = [address, amount : coin]++; address = bytes+; reward_account = bytes++; address format:+; [ 8 bit header | payload ];+;+; shelley payment addresses:+; bit 7: 0+; bit 6: base/other+; bit 5: pointer/enterprise [for base: stake cred is keyhash/scripthash]+; bit 4: payment cred is keyhash/scripthash+; bits 3-0: network id+;+; reward addresses:+; bits 7-5: 111+; bit 4: credential is keyhash/scripthash+; bits 3-0: network id+;+; byron addresses:+; bits 7-4: 1000++; 0000: base address: keyhash28,keyhash28+; 0001: base address: scripthash28,keyhash28+; 0010: base address: keyhash28,scripthash28+; 0011: base address: scripthash28,scripthash28+; 0100: pointer address: keyhash28, 3 variable length uint+; 0101: pointer address: scripthash28, 3 variable length uint+; 0110: enterprise address: keyhash28+; 0111: enterprise address: scripthash28+; 1000: byron address+; 1110: reward account: keyhash28+; 1111: reward account: scripthash28+; 1001 - 1101: future formats++certificate =+  [ stake_registration+  // stake_deregistration+  // stake_delegation+  // pool_registration+  // pool_retirement+  // genesis_key_delegation+  // move_instantaneous_rewards_cert+  ]++stake_registration = (0, stake_credential)+stake_deregistration = (1, stake_credential)+stake_delegation = (2, stake_credential, pool_keyhash)+pool_registration = (3, pool_params)+pool_retirement = (4, pool_keyhash, epoch)+genesis_key_delegation = (5, genesishash, genesis_delegate_hash, vrf_keyhash)+move_instantaneous_rewards_cert = (6, move_instantaneous_reward)++move_instantaneous_reward = [ 0 / 1, { * stake_credential => coin } ]+; The first field determines where the funds are drawn from.+; 0 denotes the reserves, 1 denotes the treasury.++stake_credential =+  [  0, addr_keyhash+  // 1, scripthash+  ]++pool_params = ( operator:       pool_keyhash+              , vrf_keyhash:    vrf_keyhash+              , pledge:         coin+              , cost:           coin+              , margin:         unit_interval+              , reward_account: reward_account+              , pool_owners:    set<addr_keyhash>+              , relays:         [* relay]+              , pool_metadata:  pool_metadata / null+              )++port = uint .le 65535+ipv4 = bytes .size 4+ipv6 = bytes .size 16+dns_name = tstr .size (0..64)++single_host_addr = ( 0+                   , port / null+                   , ipv4 / null+                   , ipv6 / null+                   )+single_host_name = ( 1+                   , port / null+                   , dns_name ; An A or AAAA DNS record+                   )+multi_host_name = ( 2+                   , dns_name ; A SRV DNS record+                   )+relay =+  [  single_host_addr+  // single_host_name+  // multi_host_name+  ]++pool_metadata = [url, metadata_hash]+url = tstr .size (0..64)++withdrawals = { * reward_account => coin }++update = [ proposed_protocol_parameter_updates+         , epoch+         ]++proposed_protocol_parameter_updates =+  { * genesishash => protocol_param_update }++protocol_param_update =+  { ? 0:  uint               ; minfee A+  , ? 1:  uint               ; minfee B+  , ? 2:  uint               ; max block body size+  , ? 3:  uint               ; max transaction size+  , ? 4:  uint               ; max block header size+  , ? 5:  coin               ; key deposit+  , ? 6:  coin               ; pool deposit+  , ? 7: epoch               ; maximum epoch+  , ? 8: uint                ; n_opt: desired number of stake pools+  , ? 9: rational            ; pool pledge influence+  , ? 10: unit_interval      ; expansion rate+  , ? 11: unit_interval      ; treasury growth rate+  , ? 12: unit_interval      ; d. decentralization constant+  , ? 13: $nonce             ; extra entropy+  , ? 14: [protocol_version] ; protocol version+  , ? 15: coin               ; min utxo value+  }++transaction_witness_set =+  { ?0 => [* vkeywitness ]+  , ?1 => [* multisig_script ]+  , ?2 => [* bootstrap_witness ]+  ; In the future, new kinds of witnesses can be added like this:+  ; , ?3 => [* monetary_policy_script ]+  ; , ?4 => [* plutus_script ]+  }++transaction_metadatum =+    { * transaction_metadatum => transaction_metadatum }+  / [ * transaction_metadatum ]+  / int+  / bytes .size (0..64)+  / text .size (0..64)++transaction_metadatum_label = uint++transaction_metadata =+  { * transaction_metadatum_label => transaction_metadatum }++vkeywitness = [ $vkey, $signature ]++bootstrap_witness =+  [ public_key : $vkey+  , signature  : $signature+  , chain_code : bytes .size 32+  , attributes : bytes+  ]++multisig_script =+  [ multisig_pubkey+  // multisig_all+  // multisig_any+  // multisig_n_of_k+  ]++multisig_pubkey = (0, addr_keyhash)+multisig_all = (1, [ * multisig_script ])+multisig_any = (2, [ * multisig_script ])+multisig_n_of_k = (3, n: uint, [ * multisig_script ])++coin = uint+epoch = uint++addr_keyhash          = $hash28+genesis_delegate_hash = $hash28+pool_keyhash          = $hash28+genesishash           = $hash28++vrf_keyhash           = $hash32+metadata_hash         = $hash32++; To compute a script hash, note that you must prepend+; a tag to the bytes of the script before hashing.+; The tag is determined by the language.+; In the Shelley era there is only one such tag,+; namely "\x00" for multisig scripts.+scripthash            = $hash28++$nonce /= [ 0 // 1, bytes .size 32 ]++$hash28 /= bytes .size 28+$hash32 /= bytes .size 32++$vkey /= bytes .size 32++$vrf_vkey /= bytes .size 32+$vrf_cert /= [bytes, bytes .size 80]++$kes_vkey /= bytes .size 32+$kes_signature /= bytes .size 448+signkeyKES = bytes .size 64++$signature /= bytes .size 64++finite_set<a> = [* a]++;unit_interval = #6.30([uint, uint])+unit_interval = #6.30([1, 2])+  ; real unit_interval is: #6.30([uint, uint])+  ; but this produces numbers outside the unit interval+  ; and can also produce a zero in the denominator++rational = #6.30([uint, uint])++set<a> = [* a]++address = bytes++reward_account = bytes
+ example/cddl-files/validator.cddl view
@@ -0,0 +1,13 @@+negative = nint++anyfloat = f16 / f32 / f64++f16 = float16+f32 = float32+f64 = float64++bs = bstr / bytes+txt = tstr / text++my_bigint = #6.2(bstr)+my_any = any
+ example/cddl-files/validator/negative/args-to-postlude.cddl view
@@ -0,0 +1,1 @@+x = uint<3>
+ example/cddl-files/validator/negative/too-few-args.cddl view
@@ -0,0 +1,3 @@+foo<a, b> = [a, b]++x = foo<uint>
+ example/cddl-files/validator/negative/too-many-args.cddl view
@@ -0,0 +1,3 @@+foo<a> = [a]++x = foo<uint, uint>
+ example/cddl-files/validator/negative/unknown-name.cddl view
@@ -0,0 +1,1 @@+x = a
src/Codec/CBOR/Cuddle/CBOR/Gen.hs view
@@ -1,20 +1,26 @@-{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE CPP #-}+#if MIN_VERSION_random(1,3,0)+{-# OPTIONS_GHC -Wno-deprecations #-} -- Due to usage of `split`+#endif+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} -#if MIN_VERSION_random(1,3,0)-{-# OPTIONS_GHC -Wno-deprecations #-} -- Due to usage of `split`-#endif -- | Generate example CBOR given a CDDL specification module Codec.CBOR.Cuddle.CBOR.Gen (generateCBORTerm, generateCBORTerm') where +#if MIN_VERSION_random(1,3,0)+import System.Random.Stateful (+  SplitGen (..)+  )+#endif import Capability.Reader import Capability.Sink (HasSink) import Capability.Source (HasSource, MonadState (..))@@ -25,11 +31,12 @@   Value (..),   ValueVariant (..),  )-import Codec.CBOR.Cuddle.CDDL.CTree (CTree, CTreeRoot' (..))+import Codec.CBOR.Cuddle.CDDL.CBORGenerator (CBORGenerator (..), WrappedTerm (..))+import Codec.CBOR.Cuddle.CDDL.CTree (CTree (..), CTreeRoot (..), PTerm (..), foldCTree) import Codec.CBOR.Cuddle.CDDL.CTree qualified as CTree import Codec.CBOR.Cuddle.CDDL.CtlOp qualified as CtlOp-import Codec.CBOR.Cuddle.CDDL.Postlude (PTerm (..))-import Codec.CBOR.Cuddle.CDDL.Resolve (MonoRef (..))+import Codec.CBOR.Cuddle.CDDL.Resolve (MonoReferenced, XXCTree (..))+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..)) import Codec.CBOR.Term (Term (..)) import Codec.CBOR.Term qualified as CBOR import Codec.CBOR.Write qualified as CBOR@@ -39,16 +46,15 @@ import Control.Monad.State.Strict qualified as MTL import Data.Bifunctor (second) import Data.ByteString (ByteString)-import Data.ByteString.Base16 qualified as Base16 import Data.Functor ((<&>))-import Data.Functor.Identity (Identity (runIdentity)) import Data.List.NonEmpty qualified as NE import Data.Map.Strict qualified as Map import Data.Maybe (fromMaybe) import Data.Text (Text) import Data.Text qualified as T-import Data.Word (Word32, Word64)+import Data.Word (Word32) import GHC.Generics (Generic)+import GHC.Stack (HasCallStack) import System.Random.Stateful (   Random,   RandomGen (..),@@ -57,19 +63,25 @@   randomM,   uniformByteStringM,  )-#if MIN_VERSION_random(1,3,0)-import System.Random.Stateful (-  SplitGen (..)-  )-#endif +type data MonoDropGen++newtype instance XXCTree MonoDropGen = MDGRef Name+  deriving (Show)++instance IndexMappable CTree MonoReferenced MonoDropGen where+  mapIndex = foldCTree mapExt mapIndex+    where+      mapExt (MRuleRef n) = CTreeE $ MDGRef n+      mapExt (MGenerator _ x) = mapIndex x+ -------------------------------------------------------------------------------- -- Generator infrastructure --------------------------------------------------------------------------------  -- | Generator context, parametrised over the type of the random seed newtype GenEnv = GenEnv-  { cddl :: CTreeRoot' Identity MonoRef+  { cddl :: CTreeRoot MonoReferenced   }   deriving (Generic) @@ -121,8 +133,8 @@           ()           (MonadState (StateT (GenState g) (Reader GenEnv)))   deriving-    ( HasSource "cddl" (CTreeRoot' Identity MonoRef)-    , HasReader "cddl" (CTreeRoot' Identity MonoRef)+    ( HasSource "cddl" (CTreeRoot MonoReferenced)+    , HasReader "cddl" (CTreeRoot MonoReferenced)     )     via Field           "cddl"@@ -211,23 +223,14 @@ -- Kinds of terms -------------------------------------------------------------------------------- -data WrappedTerm-  = SingleTerm Term-  | PairTerm Term Term-  | GroupTerm [WrappedTerm]-  deriving (Eq, Show)- -- | Recursively flatten wrapped list. That is, expand any groups out to their -- individual entries. flattenWrappedList :: [WrappedTerm] -> [WrappedTerm] flattenWrappedList [] = []-flattenWrappedList (GroupTerm xxs : xs) =+flattenWrappedList (G xxs : xs) =   flattenWrappedList xxs <> flattenWrappedList xs flattenWrappedList (y : xs) = y : flattenWrappedList xs -pattern S :: Term -> WrappedTerm-pattern S t = SingleTerm t- -- | Convert a list of wrapped terms to a list of terms. If any 'PairTerm's are -- present, we just take their "value" part. singleTermList :: [WrappedTerm] -> Maybe [Term]@@ -236,9 +239,6 @@ singleTermList (P _ y : xs) = (y :) <$> singleTermList xs singleTermList _ = Nothing -pattern P :: Term -> Term -> WrappedTerm-pattern P t1 t2 = PairTerm t1 t2- -- | Convert a list of wrapped terms to a list of pairs of terms, or fail if any -- 'SingleTerm's are present. pairTermList :: [WrappedTerm] -> Maybe [(Term, Term)]@@ -246,18 +246,18 @@ pairTermList (P x y : xs) = ((x, y) :) <$> pairTermList xs pairTermList _ = Nothing -pattern G :: [WrappedTerm] -> WrappedTerm-pattern G xs = GroupTerm xs+showDropGen :: CTree MonoReferenced -> String+showDropGen = show . mapIndex @_ @_ @MonoDropGen  -------------------------------------------------------------------------------- -- Generator functions -------------------------------------------------------------------------------- -genForCTree :: RandomGen g => CTree MonoRef -> M g WrappedTerm+genForCTree :: (HasCallStack, RandomGen g) => CTree MonoReferenced -> M g WrappedTerm genForCTree (CTree.Literal v) = S <$> genValue v genForCTree (CTree.Postlude pt) = S <$> genPostlude pt genForCTree (CTree.Map nodes) = do-  items <- pairTermList . flattenWrappedList <$> traverse genForNode nodes+  items <- pairTermList . flattenWrappedList <$> traverse genForCTree nodes   case items of     Just ts ->       let@@ -270,61 +270,66 @@         pure . S $ TMap tsNodup     Nothing -> error "Single terms in map context" genForCTree (CTree.Array nodes) = do-  items <- singleTermList . flattenWrappedList <$> traverse genForNode nodes+  items <- singleTermList . flattenWrappedList <$> traverse genForCTree nodes   case items of     Just ts -> pure . S $ TList ts     Nothing -> error "Something weird happened which shouldn't be possible" genForCTree (CTree.Choice (NE.toList -> nodes)) = do   ix <- genUniformRM (0, length nodes - 1)-  genForNode $ nodes !! ix-genForCTree (CTree.Group nodes) = G <$> traverse genForNode nodes+  genForCTree $ nodes !! ix+genForCTree (CTree.Group nodes) = G <$> traverse genForCTree nodes genForCTree (CTree.KV key value _cut) = do-  kg <- genForNode key-  vg <- genForNode value+  kg <- genForCTree key+  vg <- genForCTree value   case (kg, vg) of     (S k, S v) -> pure $ P k v     _ ->       error $         "Non single-term generated outside of group context: "-          <> show key+          <> showDropGen key           <> " => "-          <> show value+          <> showDropGen value genForCTree (CTree.Occur item occurs) =-  applyOccurenceIndicator occurs (genForNode item)+  applyOccurenceIndicator occurs (genForCTree item) genForCTree (CTree.Range from to _bounds) = do   -- TODO Handle bounds correctly-  term1 <- genForNode from-  term2 <- genForNode to+  term1 <- genForCTree from+  term2 <- genForCTree to   case (term1, term2) of-    (S (TInt a), S (TInt b)) -> genUniformRM (a, b) <&> S . TInt-    (S (TInt a), S (TInteger b)) -> genUniformRM (fromIntegral a, b) <&> S . TInteger-    (S (TInteger a), S (TInteger b)) -> genUniformRM (a, b) <&> S . TInteger-    (S (THalf a), S (THalf b)) -> genUniformRM (a, b) <&> S . THalf-    (S (TFloat a), S (TFloat b)) -> genUniformRM (a, b) <&> S . TFloat-    (S (TDouble a), S (TDouble b)) -> genUniformRM (a, b) <&> S . TDouble-    x -> error $ "Cannot apply range operator to non-numeric types: " <> show x+    (S (TInt a), S (TInt b))+      | a <= b -> genUniformRM (a, b) <&> S . TInt+    (S (TInt a), S (TInteger b))+      | fromIntegral a <= b -> genUniformRM (fromIntegral a, b) <&> S . TInteger+    (S (TInteger a), S (TInteger b))+      | a <= b -> genUniformRM (a, b) <&> S . TInteger+    (S (THalf a), S (THalf b))+      | a <= b -> genUniformRM (a, b) <&> S . THalf+    (S (TFloat a), S (TFloat b))+      | a <= b -> genUniformRM (a, b) <&> S . TFloat+    (S (TDouble a), S (TDouble b))+      | a <= b -> genUniformRM (a, b) <&> S . TDouble+    (a, b) -> error $ "invalid range (a = " <> show a <> ", b = " <> show b <> ")" genForCTree (CTree.Control op target controller) = do-  tt <- resolveIfRef target-  ct <- resolveIfRef controller-  case (op, ct) of-    (CtlOp.Le, CTree.Literal (Value (VUInt n) _)) -> case tt of+  resolvedController <- case controller of+    CTreeE (MRuleRef n) -> resolveRef n+    x -> pure x+  case (op, resolvedController) of+    (CtlOp.Le, CTree.Literal (Value (VUInt n) _)) -> case target of       CTree.Postlude PTUInt -> S . TInteger <$> genUniformRM (0, fromIntegral n)       _ -> error "Cannot apply le operator to target"-    (CtlOp.Le, _) -> error $ "Invalid controller for .le operator: " <> show controller-    (CtlOp.Lt, CTree.Literal (Value (VUInt n) _)) -> case tt of+    (CtlOp.Le, _) -> error $ "Invalid controller for .le operator: " <> showDropGen controller+    (CtlOp.Lt, CTree.Literal (Value (VUInt n) _)) -> case target of       CTree.Postlude PTUInt -> S . TInteger <$> genUniformRM (0, fromIntegral n - 1)       _ -> error "Cannot apply lt operator to target"-    (CtlOp.Lt, _) -> error $ "Invalid controller for .lt operator: " <> show controller-    (CtlOp.Size, CTree.Literal (Value (VUInt n) _)) -> case tt of+    (CtlOp.Lt, _) -> error $ "Invalid controller for .lt operator: " <> showDropGen controller+    (CtlOp.Size, CTree.Literal (Value (VUInt n) _)) -> case target of       CTree.Postlude PTText -> S . TString <$> genText (fromIntegral n)       CTree.Postlude PTBytes -> S . TBytes <$> genBytes (fromIntegral n)       CTree.Postlude PTUInt -> S . TInteger <$> genUniformRM (0, 2 ^ n - 1)       _ -> error "Cannot apply size operator to target "     (CtlOp.Size, CTree.Range {CTree.from, CTree.to}) -> do-      f <- resolveIfRef from-      t <- resolveIfRef to-      case (f, t) of-        (CTree.Literal (Value (VUInt f1) _), CTree.Literal (Value (VUInt t1) _)) -> case tt of+      case (from, to) of+        (CTree.Literal (Value (VUInt f1) _), CTree.Literal (Value (VUInt t1) _)) -> case target of           CTree.Postlude PTText ->             genUniformRM (fromIntegral f1, fromIntegral t1)               >>= (fmap (S . TString) . genText)@@ -334,49 +339,49 @@           CTree.Postlude PTUInt ->             S . TInteger               <$> genUniformRM (fromIntegral f1, fromIntegral t1)-          _ -> error $ "Cannot apply size operator to target: " <> show tt+          _ -> error $ "Cannot apply size operator to target: " <> showDropGen target         _ ->           error $             "Invalid controller for .size operator: "-              <> show controller+              <> showDropGen controller     (CtlOp.Size, _) ->       error $         "Invalid controller for .size operator: "-          <> show controller+          <> showDropGen controller     (CtlOp.Cbor, _) -> do-      enc <- genForCTree ct+      enc <- genForCTree controller       case enc of         S x -> pure . S . TBytes . CBOR.toStrictByteString $ CBOR.encodeTerm x         _ -> error "Controller does not correspond to a single term"-    _ -> genForNode target-genForCTree (CTree.Enum node) = do-  tree <- resolveIfRef node+    _ -> genForCTree target+genForCTree (CTree.Enum tree) = do   case tree of-    CTree.Group nodes -> do-      ix <- genUniformRM (0, length nodes)-      genForNode $ nodes !! ix+    CTree.Group trees -> do+      ix <- genUniformRM (0, length trees - 1)+      genForCTree $ trees !! ix     _ -> error "Attempt to form an enum from something other than a group"-genForCTree (CTree.Unwrap node) = genForCTree =<< resolveIfRef node+genForCTree (CTree.Unwrap node) = genForCTree node genForCTree (CTree.Tag tag node) = do-  enc <- genForNode node+  enc <- genForCTree node   case enc of     S x -> pure $ S $ TTagged tag x     _ -> error "Tag controller does not correspond to a single term"+genForCTree (CTree.CTreeE (MRuleRef n)) = genForNode n+genForCTree (CTree.CTreeE (MGenerator (CBORGenerator gen) _)) = gen StateGenM -genForNode :: RandomGen g => CTree.Node MonoRef -> M g WrappedTerm-genForNode = genForCTree <=< resolveIfRef+genForNode :: (HasCallStack, RandomGen g) => Name -> M g WrappedTerm+genForNode = genForCTree <=< resolveRef --- | Take something which might be a reference and resolve it to the relevant--- Tree, following multiple links if necessary.-resolveIfRef :: RandomGen g => CTree.Node MonoRef -> M g (CTree MonoRef)-resolveIfRef (MIt a) = pure a-resolveIfRef (MRuleRef n) = do+-- | Take a reference and resolve it to the relevant Tree, following multiple+-- links if necessary.+resolveRef :: RandomGen g => Name -> M g (CTree MonoReferenced)+resolveRef n = do   (CTreeRoot cddl) <- ask @"cddl"   -- Since we follow a reference, we increase the 'depth' of the gen monad.   modify @"depth" (+ 1)   case Map.lookup n cddl of     Nothing -> error $ "Unbound reference: " <> show n-    Just val -> resolveIfRef $ runIdentity val+    Just val -> pure val  -- | Generate a CBOR Term corresponding to a top-level name. --@@ -386,13 +391,13 @@ -- This will throw an error if the generated item does not correspond to a -- single CBOR term (e.g. if the name resolves to a group, which cannot be -- generated outside a context).-genForName :: RandomGen g => Name -> M g Term+genForName :: (HasCallStack, RandomGen g) => Name -> M g Term genForName n = do   (CTreeRoot cddl) <- ask @"cddl"   case Map.lookup n cddl of     Nothing -> error $ "Unbound reference: " <> show n     Just val ->-      genForNode (runIdentity val) >>= \case+      genForCTree val >>= \case         S x -> pure x         _ ->           error $@@ -417,8 +422,10 @@   genDepthBiasedRM (1 :: Int, 10) >>= \i ->     G <$> replicateM i oldGen applyOccurenceIndicator (OIBounded mlb mub) oldGen =-  genDepthBiasedRM (fromMaybe 0 mlb :: Word64, fromMaybe 10 mub)+  genDepthBiasedRM (lo, fromMaybe (max 10 lo) mub)     >>= \i -> G <$> replicateM (fromIntegral i) oldGen+  where+    lo = fromMaybe 0 mlb  genValue :: RandomGen g => Value -> M g Term genValue (Value x _) = genValueVariant x@@ -431,22 +438,21 @@ genValueVariant (VFloat32 i) = pure . TFloat $ i genValueVariant (VFloat64 i) = pure . TDouble $ i genValueVariant (VText t) = pure $ TString t-genValueVariant (VBytes b) = case Base16.decode b of-  Right bHex -> pure $ TBytes bHex-  Left err -> error $ "Unable to parse hex encoded bytestring: " <> err+genValueVariant (VBytes b) = pure $ TBytes b genValueVariant (VBool b) = pure $ TBool b  -------------------------------------------------------------------------------- -- Generator functions -------------------------------------------------------------------------------- -generateCBORTerm :: RandomGen g => CTreeRoot' Identity MonoRef -> Name -> g -> Term+generateCBORTerm :: (HasCallStack, RandomGen g) => CTreeRoot MonoReferenced -> Name -> g -> Term generateCBORTerm cddl n stdGen =   let genEnv = GenEnv {cddl}       genState = GenState {randomSeed = stdGen, depth = 1}    in evalGen (genForName n) genEnv genState -generateCBORTerm' :: RandomGen g => CTreeRoot' Identity MonoRef -> Name -> g -> (Term, g)+generateCBORTerm' ::+  (HasCallStack, RandomGen g) => CTreeRoot MonoReferenced -> Name -> g -> (Term, g) generateCBORTerm' cddl n stdGen =   let genEnv = GenEnv {cddl}       genState = GenState {randomSeed = stdGen, depth = 1}
src/Codec/CBOR/Cuddle/CBOR/Validator.hs view
@@ -1,1009 +1,879 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}-{-# LANGUAGE ViewPatterns #-}-{-# OPTIONS_GHC -Wno-incomplete-patterns #-}--module Codec.CBOR.Cuddle.CBOR.Validator where--import Codec.CBOR.Cuddle.CDDL hiding (CDDL, Group, Rule)-import Codec.CBOR.Cuddle.CDDL.CTree-import Codec.CBOR.Cuddle.CDDL.CtlOp-import Codec.CBOR.Cuddle.CDDL.Postlude-import Codec.CBOR.Cuddle.CDDL.Resolve-import Codec.CBOR.Read-import Codec.CBOR.Term-import Control.Exception-import Control.Monad ((>=>))-import Control.Monad.Reader-import Data.Bifunctor-import Data.Bits hiding (And)-import Data.ByteString qualified as BS-import Data.ByteString.Lazy qualified as BSL-import Data.Function ((&))-import Data.Functor ((<&>))-import Data.Functor.Identity-import Data.IntSet qualified as IS-import Data.List.NonEmpty qualified as NE-import Data.Map.Strict qualified as Map-import Data.Maybe-import Data.Text qualified as T-import Data.Text.Lazy qualified as TL-import Data.Word-import GHC.Float-import System.Exit-import System.IO-import Text.Regex.TDFA--type CDDL = CTreeRoot' Identity MonoRef-type Rule = Node MonoRef-type ResolvedRule = CTree MonoRef--data CBORTermResult = CBORTermResult Term CDDLResult-  deriving (Show)--data CDDLResult-  = -- | The rule was valid-    Valid Rule-  | -- | All alternatives failed-    ChoiceFail-      -- | Rule we are trying-      Rule-      -- | The alternatives that arise from said rule-      (NE.NonEmpty Rule)-      -- | For each alternative, the result-      (NE.NonEmpty (Rule, CDDLResult))-  | -- | All expansions failed-    ---    -- An expansion is: Given a CBOR @TList@ of @N@ elements, we will expand the-    -- rules in a list spec to match the number of items in the list.-    ListExpansionFail-      -- | Rule we are trying-      Rule-      -- | List of expansions of rules-      [[Rule]]-      -- | For each expansion, for each of the rules in the expansion, the result-      [[(Rule, CBORTermResult)]]-  | -- | All expansions failed-    ---    -- An expansion is: Given a CBOR @TMap@ of @N@ elements, we will expand the-    -- rules in a map spec to match the number of items in the map.-    MapExpansionFail-      -- | Rule we are trying-      Rule-      -- | List of expansions-      [[Rule]]-      -- | A list of matched items @(key, value, rule)@ and the unmatched item-      [([AMatchedItem], ANonMatchedItem)]-  | -- | The rule was valid but the control failed-    InvalidControl-      -- | Control we are trying-      Rule-      -- | If it is a .cbor, the result of the underlying validation-      (Maybe CBORTermResult)-  | InvalidRule Rule-  | -- | A tagged was invalid-    InvalidTagged-      -- | Rule we are trying-      Rule-      -- | Either the tag is wrong, or the contents are wrong-      (Either Word64 CBORTermResult)-  | -- | The rule we are trying is not applicable to the CBOR term-    UnapplicableRule-      -- | Rule we are trying-      Rule-  deriving (Show)--data ANonMatchedItem = ANonMatchedItem-  { anmiKey :: Term-  , anmiValue :: Term-  , anmiResults :: [Either (Rule, CDDLResult) (Rule, CDDLResult, CDDLResult)]-  -- ^ For all the tried rules, either the key failed or the key succeeded and-  -- the value failed-  }-  deriving (Show)--data AMatchedItem = AMatchedItem-  { amiKey :: Term-  , amiValue :: Term-  , amiRule :: Rule-  }-  deriving (Show)------------------------------------------------------------------------------------- Main entry point--validateCBOR :: BS.ByteString -> Name -> CDDL -> IO ()-validateCBOR bs rule cddl =-  ( case validateCBOR' bs rule cddl of-      ok@(CBORTermResult _ (Valid _)) -> do-        putStrLn $ "Valid " ++ show ok-        exitSuccess-      err -> do-        hPutStrLn stderr $ "Invalid " ++ show err-        exitFailure-  )-    `catch` ( \(e :: PatternMatchFail) ->-                putStrLn $-                  "You uncovered a path we thought was impossible! Please submit your CDDL and CBOR to `https://github.com/input-output-hk/cuddle/issues` for us to investigate\n"-                    <> displayException e-            )--validateCBOR' ::-  BS.ByteString -> Name -> CDDL -> CBORTermResult-validateCBOR' bs rule cddl@(CTreeRoot tree) =-  case deserialiseFromBytes decodeTerm (BSL.fromStrict bs) of-    Left e -> error $ show e-    Right (rest, term) ->-      if BSL.null rest-        then runReader (validateTerm term (runIdentity $ tree Map.! rule)) cddl-        else runReader (validateTerm (TBytes bs) (runIdentity $ tree Map.! rule)) cddl------------------------------------------------------------------------------------- Terms---- | Core function that validates a CBOR term to a particular rule of the CDDL--- spec-validateTerm ::-  MonadReader CDDL m =>-  Term -> Rule -> m CBORTermResult-validateTerm term rule =-  let f = case term of-        TInt i -> validateInteger (fromIntegral i)-        TInteger i -> validateInteger i-        TBytes b -> validateBytes b-        TBytesI b -> validateBytes (BSL.toStrict b)-        TString s -> validateText s-        TStringI s -> validateText (TL.toStrict s)-        TList ts -> validateList ts-        TListI ts -> validateList ts-        TMap ts -> validateMap ts-        TMapI ts -> validateMap ts-        TTagged w t -> validateTagged w t-        TBool b -> validateBool b-        TNull -> validateNull-        TSimple s -> validateSimple s-        THalf h -> validateHalf h-        TFloat h -> validateFloat h-        TDouble d -> validateDouble d-   in CBORTermResult term <$> f rule------------------------------------------------------------------------------------- Ints and integers---- | Validation of an Int or Integer. CBOR categorizes every integral in `TInt`--- or `TInteger` but it can be the case that we are decoding something that is--- expected to be a `Word64` even if we get a `TInt`.------ > ghci> encodeWord64 15--- > [TkInt 15]--- > ghci> encodeWord64 maxBound--- > [TkInteger 18446744073709551615]------ For this reason, we cannot assume that bounds or literals are going to be--- Ints, so we convert everything to Integer.-validateInteger ::-  MonadReader CDDL m =>-  Integer -> Rule -> m CDDLResult-validateInteger i rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- echo "C24101" | xxd -r -p - example.cbor-      -- echo "foo = int" > a.cddl-      -- cddl a.cddl validate example.cbor-      ---      -- but-      ---      -- echo "C249010000000000000000"| xxd -r -p - example.cbor-      -- echo "foo = int" > a.cddl-      -- cddl a.cddl validate example.cbor-      ---      -- and they are both bigints?--      -- a = any-      Postlude PTAny -> pure Valid-      -- a = int-      Postlude PTInt -> pure Valid-      -- a = uint-      Postlude PTUInt -> pure $ check (i >= 0)-      -- a = nint-      Postlude PTNInt -> pure $ check (i <= 0)-      -- a = x-      Literal (Value (VUInt i') _) -> pure $ check $ i == fromIntegral i'-      -- a = -x-      Literal (Value (VNInt i') _) -> pure $ check $ -i == fromIntegral i'-      -- a = <big number>-      Literal (Value (VBignum i') _) -> pure $ check $ i == i'-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateInteger i) op tgt ctrl (controlInteger i)-      -- a = foo / bar-      Choice opts -> validateChoice (validateInteger i) opts-      -- a = x..y-      Range low high bound ->-        ((,) <$> getRule low <*> getRule high)-          <&> check . \case-            (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= i && range bound i m-            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> -n <= i && range bound i m-            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> -n <= i && range bound i (-m)-            (Literal (Value VUInt {} _), Literal (Value VNInt {} _)) -> False-            (Literal (Value (VBignum n) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= i && range bound i m-            (Literal (Value (VBignum n) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> n <= i && range bound i (-m)-            (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VBignum m) _)) -> n <= i && range bound i m-            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VBignum m) _)) -> (-n) <= i && range bound i m-      -- a = &(x, y, z)-      Enum g ->-        getRule g >>= \case-          Group g' -> validateInteger i (MIt (Choice (NE.fromList g'))) <&> replaceRule-      -- a = x: y-      -- Note KV cannot appear on its own, but we will use this when validating-      -- lists.-      KV _ v _ -> validateInteger i v <&> replaceRule-      Tag 2 (MIt (Postlude PTBytes)) -> pure Valid-      Tag 3 (MIt (Postlude PTBytes)) -> pure Valid-      _ -> pure UnapplicableRule---- | Controls for an Integer-controlInteger ::-  forall m. MonadReader CDDL m => Integer -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlInteger i Size ctrl =-  getRule ctrl <&> \case-    Literal (Value (VUInt sz) _) ->-      boolCtrl $ 0 <= i && i < 256 ^ sz-controlInteger i Bits ctrl = do-  indices <--    getRule ctrl >>= \case-      Literal (Value (VUInt i') _) -> pure [i']-      Choice nodes -> getIndicesOfChoice nodes-      Range ff tt incl -> getIndicesOfRange ff tt incl-      Enum g -> getIndicesOfEnum g-  pure $ boolCtrl $ go (IS.fromList (map fromIntegral indices)) i 0-  where-    go _ 0 _ = True-    go indices n idx =-      let bitSet = testBit n 0-          allowed = not bitSet || IS.member idx indices-       in (allowed && go indices (shiftR n 1) (idx + 1))-controlInteger i Lt ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VUInt i') _) -> i < fromIntegral i'-      Literal (Value (VNInt i') _) -> i < -fromIntegral i'-      Literal (Value (VBignum i') _) -> i < i'-controlInteger i Gt ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VUInt i') _) -> i > fromIntegral i'-      Literal (Value (VNInt i') _) -> i > -fromIntegral i'-      Literal (Value (VBignum i') _) -> i > i'-controlInteger i Le ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VUInt i') _) -> i <= fromIntegral i'-      Literal (Value (VNInt i') _) -> i <= -fromIntegral i'-      Literal (Value (VBignum i') _) -> i <= i'-controlInteger i Ge ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VUInt i') _) -> i >= fromIntegral i'-      Literal (Value (VNInt i') _) -> i >= -fromIntegral i'-      Literal (Value (VBignum i') _) -> i >= i'-controlInteger i Eq ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VUInt i') _) -> i == fromIntegral i'-      Literal (Value (VNInt i') _) -> i == -fromIntegral i'-      Literal (Value (VBignum i') _) -> i == i'-controlInteger i Ne ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VUInt i') _) -> i /= fromIntegral i'-      Literal (Value (VNInt i') _) -> i /= -fromIntegral i'-      Literal (Value (VBignum i') _) -> i /= i'------------------------------------------------------------------------------------- Floating point (Float16, Float32, Float64)------ As opposed to Integral types, there seems to be no ambiguity when encoding--- and decoding floating-point numbers.---- | Validating a `Float16`-validateHalf ::-  MonadReader CDDL m =>-  Float -> Rule -> m CDDLResult-validateHalf f rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = float16-      Postlude PTHalf -> pure Valid-      -- a = 0.5-      Literal (Value (VFloat16 f') _) -> pure $ check $ f == f'-      -- a = foo / bar-      Choice opts -> validateChoice (validateHalf f) opts-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateHalf f) op tgt ctrl (controlHalf f)-      -- a = x..y-      Range low high bound ->-        ((,) <$> getRule low <*> getRule high)-          <&> check . \case-            (Literal (Value (VFloat16 n) _), Literal (Value (VFloat16 m) _)) -> n <= f && range bound f m-      _ -> pure UnapplicableRule---- | Controls for `Float16`-controlHalf :: MonadReader CDDL m => Float -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlHalf f Eq ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VFloat16 f') _) -> f == f'-controlHalf f Ne ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VFloat16 f') _) -> f /= f'---- | Validating a `Float32`-validateFloat ::-  MonadReader CDDL m =>-  Float -> Rule -> m CDDLResult-validateFloat f rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = float32-      Postlude PTFloat -> pure Valid-      -- a = 0.000000005-      -- TODO: it is unclear if smaller floats should also validate-      Literal (Value (VFloat32 f') _) -> pure $ check $ f == f'-      -- a = foo / bar-      Choice opts -> validateChoice (validateFloat f) opts-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateFloat f) op tgt ctrl (controlFloat f)-      -- a = x..y-      -- TODO it is unclear if this should mix floating point types too-      Range low high bound ->-        ((,) <$> getRule low <*> getRule high)-          <&> check . \case-            (Literal (Value (VFloat16 n) _), Literal (Value (VFloat16 m) _)) -> n <= f && range bound f m-            (Literal (Value (VFloat32 n) _), Literal (Value (VFloat32 m) _)) -> n <= f && range bound f m-      _ -> pure UnapplicableRule---- | Controls for `Float32`-controlFloat :: MonadReader CDDL m => Float -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlFloat f Eq ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VFloat16 f') _) -> f == f'-      Literal (Value (VFloat32 f') _) -> f == f'-controlFloat f Ne ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VFloat16 f') _) -> f /= f'-      Literal (Value (VFloat32 f') _) -> f /= f'---- | Validating a `Float64`-validateDouble ::-  MonadReader CDDL m =>-  Double -> Rule -> m CDDLResult-validateDouble f rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = float64-      Postlude PTDouble -> pure Valid-      -- a = 0.0000000000000000000000000000000000000000000005-      -- TODO: it is unclear if smaller floats should also validate-      Literal (Value (VFloat64 f') _) -> pure $ check $ f == f'-      -- a = foo / bar-      Choice opts -> validateChoice (validateDouble f) opts-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateDouble f) op tgt ctrl (controlDouble f)-      -- a = x..y-      -- TODO it is unclear if this should mix floating point types too-      Range low high bound ->-        ((,) <$> getRule low <*> getRule high)-          <&> check . \case-            (Literal (Value (VFloat16 (float2Double -> n)) _), Literal (Value (VFloat16 (float2Double -> m)) _)) -> n <= f && range bound f m-            (Literal (Value (VFloat32 (float2Double -> n)) _), Literal (Value (VFloat32 (float2Double -> m)) _)) -> n <= f && range bound f m-            (Literal (Value (VFloat64 n) _), Literal (Value (VFloat64 m) _)) -> n <= f && range bound f m-      _ -> pure UnapplicableRule---- | Controls for `Float64`-controlDouble ::-  MonadReader CDDL m => Double -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlDouble f Eq ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VFloat16 f') _) -> f == float2Double f'-      Literal (Value (VFloat32 f') _) -> f == float2Double f'-      Literal (Value (VFloat64 f') _) -> f == f'-controlDouble f Ne ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VFloat16 f') _) -> f /= float2Double f'-      Literal (Value (VFloat32 f') _) -> f /= float2Double f'-      Literal (Value (VFloat64 f') _) -> f /= f'------------------------------------------------------------------------------------- Bool---- | Validating a boolean-validateBool ::-  MonadReader CDDL m =>-  Bool -> Rule -> m CDDLResult-validateBool b rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = bool-      Postlude PTBool -> pure Valid-      -- a = true-      Literal (Value (VBool b') _) -> pure $ check $ b == b'-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateBool b) op tgt ctrl (controlBool b)-      -- a = foo / bar-      Choice opts -> validateChoice (validateBool b) opts-      _ -> pure UnapplicableRule---- | Controls for `Bool`-controlBool :: MonadReader CDDL m => Bool -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlBool b Eq ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VBool b') _) -> b == b'-controlBool b Ne ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VBool b') _) -> b /= b'------------------------------------------------------------------------------------- Simple---- | Validating a `TSimple`. It is unclear if this is used for anything else than undefined.-validateSimple ::-  MonadReader CDDL m =>-  Word8 -> Rule -> m CDDLResult-validateSimple 23 rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = undefined-      Postlude PTUndefined -> pure Valid-      -- a = foo / bar-      Choice opts -> validateChoice (validateSimple 23) opts-      _ -> pure UnapplicableRule-validateSimple n _ = error $ "Found simple different to 23! please report this somewhere! Found: " <> show n------------------------------------------------------------------------------------- Null/nil---- | Validating nil-validateNull ::-  MonadReader CDDL m => Rule -> m CDDLResult-validateNull rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = nil-      Postlude PTNil -> pure Valid-      Choice opts -> validateChoice validateNull opts-      _ -> pure UnapplicableRule------------------------------------------------------------------------------------- Bytes---- | Validating a byte sequence-validateBytes ::-  MonadReader CDDL m =>-  BS.ByteString -> Rule -> m CDDLResult-validateBytes bs rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = bytes-      Postlude PTBytes -> pure Valid-      -- a = h'123456'-      Literal (Value (VBytes bs') _) -> pure $ check $ bs == bs'-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateBytes bs) op tgt ctrl (controlBytes bs)-      -- a = foo / bar-      Choice opts -> validateChoice (validateBytes bs) opts-      _ -> pure UnapplicableRule---- | Controls for byte strings-controlBytes ::-  forall m.-  MonadReader CDDL m => BS.ByteString -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlBytes bs Size ctrl =-  getRule ctrl >>= \case-    Literal (Value (VUInt (fromIntegral -> sz)) _) -> pure $ boolCtrl $ BS.length bs == sz-    Range low high bound ->-      let i = BS.length bs-       in ((,) <$> getRule low <*> getRule high)-            <&> boolCtrl . \case-              (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= i && range bound i m-              (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> -n <= i && range bound i m-              (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> -n <= i && range bound i (-m)-              (Literal (Value VUInt {} _), Literal (Value VNInt {} _)) -> False-controlBytes bs Bits ctrl = do-  indices <--    getRule ctrl >>= \case-      Literal (Value (VUInt i') _) -> pure [i']-      Choice nodes -> getIndicesOfChoice nodes-      Range ff tt incl -> getIndicesOfRange ff tt incl-      Enum g -> getIndicesOfEnum g-  pure $ boolCtrl $ bitsControlCheck (map fromIntegral indices)-  where-    bitsControlCheck :: [Int] -> Bool-    bitsControlCheck allowedBits =-      let allowedSet = IS.fromList allowedBits-          totalBits = BS.length bs * 8-          isAllowedBit n =-            let byteIndex = n `shiftR` 3-                bitIndex = n .&. 7-             in case BS.indexMaybe bs byteIndex of-                  Just byte -> not (testBit byte bitIndex) || IS.member n allowedSet-                  Nothing -> True-       in all isAllowedBit [0 .. totalBits - 1]-controlBytes bs Cbor ctrl =-  case deserialiseFromBytes decodeTerm (BSL.fromStrict bs) of-    Right (BSL.null -> True, term) ->-      validateTerm term ctrl >>= \case-        CBORTermResult _ (Valid _) -> pure $ Right ()-        err -> pure $ Left $ Just err-controlBytes bs Cborseq ctrl =-  case deserialiseFromBytes decodeTerm (BSL.fromStrict (BS.snoc (BS.cons 0x9f bs) 0xff)) of-    Right (BSL.null -> True, TListI terms) ->-      validateTerm (TList terms) (MIt (Array [MIt (Occur ctrl OIZeroOrMore)])) >>= \case-        CBORTermResult _ (Valid _) -> pure $ Right ()-        CBORTermResult _ err -> error $ show err------------------------------------------------------------------------------------- Text---- | Validating text strings-validateText ::-  MonadReader CDDL m =>-  T.Text -> Rule -> m CDDLResult-validateText txt rule =-  ($ rule) <$> do-    getRule rule >>= \case-      -- a = any-      Postlude PTAny -> pure Valid-      -- a = text-      Postlude PTText -> pure Valid-      -- a = "foo"-      Literal (Value (VText txt') _) -> pure $ check $ txt == txt'-      -- a = foo .ctrl bar-      Control op tgt ctrl -> ctrlDispatch (validateText txt) op tgt ctrl (controlText txt)-      -- a = foo / bar-      Choice opts -> validateChoice (validateText txt) opts-      _ -> pure UnapplicableRule---- | Controls for text strings-controlText :: MonadReader CDDL m => T.Text -> CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())-controlText bs Size ctrl =-  getRule ctrl >>= \case-    Literal (Value (VUInt (fromIntegral -> sz)) _) -> pure $ boolCtrl $ T.length bs == sz-    Range ff tt bound ->-      ((,) <$> getRule ff <*> getRule tt)-        <&> boolCtrl . \case-          (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= T.length bs && range bound (T.length bs) m-          (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> -n <= T.length bs && range bound (T.length bs) m-          (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> -n <= T.length bs && range bound (T.length bs) (-m)-controlText s Regexp ctrl =-  getRule ctrl-    <&> boolCtrl . \case-      Literal (Value (VText rxp) _) -> case s =~ rxp :: (T.Text, T.Text, T.Text) of-        ("", s', "") -> s == s'------------------------------------------------------------------------------------- Tagged values---- | Validating a `TTagged`-validateTagged ::-  MonadReader CDDL m =>-  Word64 -> Term -> Rule -> m CDDLResult-validateTagged tag term rule =-  ($ rule) <$> do-    getRule rule >>= \case-      Postlude PTAny -> pure Valid-      Tag tag' rule' ->-        -- If the tag does not match, this is a direct fail-        if tag == tag'-          then-            ask >>= \cddl ->-              case runReader (validateTerm term rule') cddl of-                CBORTermResult _ (Valid _) -> pure Valid-                err -> pure $ \r -> InvalidTagged r (Right err)-          else pure $ \r -> InvalidTagged r (Left tag)-      Choice opts -> validateChoice (validateTagged tag term) opts-      _ -> pure UnapplicableRule------------------------------------------------------------------------------------- Collection helpers---- | Groups might contain enums, or unwraps inside. This resolves all those to--- the top level of the group.-flattenGroup :: CDDL -> [Rule] -> [Rule]-flattenGroup cddl nodes =-  mconcat-    [ case resolveIfRef cddl rule of-        Literal {} -> [rule]-        Postlude {} -> [rule]-        Map {} -> [rule]-        Array {} -> [rule]-        Choice {} -> [rule]-        KV {} -> [rule]-        Occur {} -> [rule]-        Range {} -> [rule]-        Control {} -> [rule]-        Enum e -> case resolveIfRef cddl e of-          Group g -> flattenGroup cddl g-          _ -> error "Malformed cddl"-        Unwrap g -> case resolveIfRef cddl g of-          Map n -> flattenGroup cddl n-          Array n -> flattenGroup cddl n-          Tag _ n -> [n]-          _ -> error "Malformed cddl"-        Tag {} -> [rule]-        Group g -> flattenGroup cddl g-    | rule <- nodes-    ]---- | Expand rules to reach exactly the wanted length, which must be the number--- of items in the container. For example, if we want to validate 3 elements,--- and we have the following CDDL:------ > a = [* int, * bool]------ this will be expanded to `[int, int, int], [int, int, bool], [int, bool,--- bool], [bool, bool, bool]`.------ Essentially the rules we will parse is the choice among the expansions of the--- original rules.-expandRules :: Int -> [Rule] -> Reader CDDL [[Rule]]-expandRules remainingLen []-  | remainingLen /= 0 = pure []-expandRules _ [] = pure [[]]-expandRules remainingLen _-  | remainingLen < 0 = pure []-  | remainingLen == 0 = pure [[]]-expandRules remainingLen (x : xs) = do-  y <- expandRule remainingLen x-  concat-    <$> mapM-      ( \y' -> do-          suffixes <- expandRules (remainingLen - length y') xs-          pure [y' ++ ys' | ys' <- suffixes]-      )-      y--expandRule :: Int -> Rule -> Reader CDDL [[Rule]]-expandRule maxLen _-  | maxLen < 0 = pure []-expandRule maxLen rule =-  getRule rule >>= \case-    Occur o OIOptional -> pure $ [] : [[o] | maxLen > 0]-    Occur o OIZeroOrMore -> ([] :) <$> expandRule maxLen (MIt (Occur o OIOneOrMore))-    Occur o OIOneOrMore ->-      if maxLen > 0-        then ([o] :) . map (o :) <$> expandRule (maxLen - 1) (MIt (Occur o OIOneOrMore))-        else pure []-    Occur o (OIBounded low high) -> case (low, high) of-      (Nothing, Nothing) -> expandRule maxLen (MIt (Occur o OIZeroOrMore))-      (Just (fromIntegral -> low'), Nothing) ->-        if maxLen >= low'-          then map (replicate low' o ++) <$> expandRule (maxLen - low') (MIt (Occur o OIZeroOrMore))-          else pure []-      (Nothing, Just (fromIntegral -> high')) ->-        pure [replicate n o | n <- [0 .. min maxLen high']]-      (Just (fromIntegral -> low'), Just (fromIntegral -> high')) ->-        if maxLen >= low'-          then pure [replicate n o | n <- [low' .. min maxLen high']]-          else pure []-    _ -> pure [[rule | maxLen > 0]]---- | Which rules are optional?-isOptional :: MonadReader CDDL m => Rule -> m Bool-isOptional rule =-  getRule rule-    <&> \case-      Occur _ OIOptional -> True-      Occur _ OIZeroOrMore -> True-      Occur _ (OIBounded Nothing _) -> True-      Occur _ (OIBounded (Just 0) _) -> True-      _ -> False---- ----------------------------------------------------------------------------------- -- Lists--validateListWithExpandedRules ::-  forall m.-  MonadReader CDDL m =>-  [Term] -> [Rule] -> m [(Rule, CBORTermResult)]-validateListWithExpandedRules terms rules =-  go (zip terms rules)-  where-    go ::-      [(Term, Rule)] -> m [(Rule, CBORTermResult)]-    go [] = pure []-    go ((t, r) : ts) =-      getRule r >>= \case-        -- Should the rule be a KV, then we validate the rule for the value-        KV _ v _ ->-          -- We need to do this juggling because validateTerm has a different-          -- error type-          ask >>= \cddl ->-            case runReader (validateTerm t v) cddl of-              ok@(CBORTermResult _ (Valid _)) -> ((r, ok) :) <$> go ts-              err -> pure [(r, err)]-        _ ->-          ask >>= \cddl ->-            case runReader (validateTerm t r) cddl of-              ok@(CBORTermResult _ (Valid _)) -> ((r, ok) :) <$> go ts-              err -> pure [(r, err)]--validateExpandedList ::-  forall m.-  MonadReader CDDL m =>-  [Term] ->-  [[Rule]] ->-  m (Rule -> CDDLResult)-validateExpandedList terms rules = go rules-  where-    go :: [[Rule]] -> m (Rule -> CDDLResult)-    go [] = pure $ \r -> ListExpansionFail r rules []-    go (choice : choices) = do-      res <- validateListWithExpandedRules terms choice-      case res of-        [] -> pure Valid-        _ -> case last res of-          (_, CBORTermResult _ (Valid _)) -> pure Valid-          _ ->-            go choices-              >>= ( \case-                      Valid _ -> pure Valid-                      ListExpansionFail _ _ errors -> pure $ \r -> ListExpansionFail r rules (res : errors)-                  )-                . ($ dummyRule)--validateList ::-  MonadReader CDDL m => [Term] -> Rule -> m CDDLResult-validateList terms rule =-  ($ rule) <$> do-    getRule rule >>= \case-      Postlude PTAny -> pure Valid-      Array rules ->-        case terms of-          [] -> ifM (and <$> mapM isOptional rules) (pure Valid) (pure InvalidRule)-          _ ->-            ask >>= \cddl ->-              let sequencesOfRules =-                    runReader (expandRules (length terms) $ flattenGroup cddl rules) cddl-               in validateExpandedList terms sequencesOfRules-      Choice opts -> validateChoice (validateList terms) opts-      _ -> pure UnapplicableRule------------------------------------------------------------------------------------- Maps--validateMapWithExpandedRules ::-  forall m.-  MonadReader CDDL m =>-  [(Term, Term)] -> [Rule] -> m ([AMatchedItem], Maybe ANonMatchedItem)-validateMapWithExpandedRules =-  go-  where-    go ::-      [(Term, Term)] ->-      [Rule] ->-      m ([AMatchedItem], Maybe ANonMatchedItem)-    go [] [] = pure ([], Nothing)-    go ((tk, tv) : ts) rs = do-      go' tk tv rs >>= \case-        Left tt -> pure ([], Just tt)-        Right (res, rs') ->-          first (res :) <$> go ts rs'--    -- For each pair of terms, try to find some rule that can be applied here,-    -- and returns the others if there is a succesful match.-    go' :: Term -> Term -> [Rule] -> m (Either ANonMatchedItem (AMatchedItem, [Rule]))-    go' tk tv [] = pure $ Left $ ANonMatchedItem tk tv []-    go' tk tv (r : rs) =-      getRule r >>= \case-        KV k v _ ->-          ask >>= \cddl ->-            case runReader (validateTerm tk k) cddl of-              CBORTermResult _ r1@(Valid _) -> case runReader (validateTerm tv v) cddl of-                CBORTermResult _ (Valid _) -> pure (Right (AMatchedItem tk tv r, rs))-                CBORTermResult _ r2 ->-                  bimap (\anmi -> anmi {anmiResults = Right (r, r1, r2) : anmiResults anmi}) (second (r :))-                    <$> go' tk tv rs-              CBORTermResult _ r1 ->-                bimap (\anmi -> anmi {anmiResults = Left (r, r1) : anmiResults anmi}) (second (r :))-                  <$> go' tk tv rs--validateExpandedMap ::-  forall m.-  MonadReader CDDL m =>-  [(Term, Term)] ->-  [[Rule]] ->-  m (Rule -> CDDLResult)-validateExpandedMap terms rules = go rules-  where-    go :: [[Rule]] -> m (Rule -> CDDLResult)-    go [] = pure $ \r -> MapExpansionFail r rules []-    go (choice : choices) = do-      res <- validateMapWithExpandedRules terms choice-      case res of-        (_, Nothing) -> pure Valid-        (matches, Just notMatched) ->-          go choices-            >>= ( \case-                    Valid _ -> pure Valid-                    MapExpansionFail _ _ errors ->-                      pure $ \r -> MapExpansionFail r rules ((matches, notMatched) : errors)-                )-              . ($ dummyRule)--validateMap ::-  MonadReader CDDL m =>-  [(Term, Term)] -> Rule -> m CDDLResult-validateMap terms rule =-  ($ rule) <$> do-    getRule rule >>= \case-      Postlude PTAny -> pure Valid-      Map rules ->-        case terms of-          [] -> ifM (and <$> mapM isOptional rules) (pure Valid) (pure InvalidRule)-          _ ->-            ask >>= \cddl ->-              let sequencesOfRules =-                    runReader (expandRules (length terms) $ flattenGroup cddl rules) cddl-               in validateExpandedMap terms sequencesOfRules-      Choice opts -> validateChoice (validateMap terms) opts-      _ -> pure UnapplicableRule------------------------------------------------------------------------------------- Choices--validateChoice ::-  forall m. Monad m => (Rule -> m CDDLResult) -> NE.NonEmpty Rule -> m (Rule -> CDDLResult)-validateChoice v rules = go rules-  where-    go :: NE.NonEmpty Rule -> m (Rule -> CDDLResult)-    go (choice NE.:| xs) = do-      v choice >>= \case-        Valid _ -> pure Valid-        err -> case NE.nonEmpty xs of-          Nothing -> pure $ \r -> ChoiceFail r rules ((choice, err) NE.:| [])-          Just choices ->-            go choices-              >>= ( \case-                      Valid _ -> pure Valid-                      ChoiceFail _ _ errors -> pure $ \r -> ChoiceFail r rules ((choice, err) NE.<| errors)-                  )-                . ($ dummyRule)--dummyRule :: Rule-dummyRule = MRuleRef (Name "dummy" mempty)------------------------------------------------------------------------------------- Control helpers---- | Validate both rules-ctrlAnd ::-  Monad m =>-  (Rule -> m CDDLResult) -> Rule -> Rule -> m (Rule -> CDDLResult)-ctrlAnd v tgt ctrl =-  v tgt >>= \case-    Valid _ ->-      v ctrl <&> \case-        Valid _ -> Valid-        _ -> flip InvalidControl Nothing-    _ -> pure InvalidRule---- | Dispatch to the appropriate control-ctrlDispatch ::-  Monad m =>-  (Rule -> m CDDLResult) ->-  CtlOp ->-  Rule ->-  Rule ->-  (CtlOp -> Rule -> m (Either (Maybe CBORTermResult) ())) ->-  m (Rule -> CDDLResult)-ctrlDispatch v And tgt ctrl _ = ctrlAnd v tgt ctrl-ctrlDispatch v Within tgt ctrl _ = ctrlAnd v tgt ctrl-ctrlDispatch v op tgt ctrl vctrl =-  v tgt >>= \case-    Valid _ ->-      vctrl op ctrl <&> \case-        Left err -> flip InvalidControl err-        Right () -> Valid-    _ -> pure InvalidRule---- | A boolean control-boolCtrl :: Bool -> Either (Maybe CBORTermResult) ()-boolCtrl c = if c then Right () else Left Nothing------------------------------------------------------------------------------------- Bits control--getIndicesOfChoice :: MonadReader CDDL m => NE.NonEmpty Rule -> m [Word64]-getIndicesOfChoice nodes =-  mconcat-    . NE.toList-    <$> mapM-      ( getRule-          >=> ( \case-                  Literal (Value (VUInt v) _) -> pure [fromIntegral v]-                  KV _ v _ ->-                    getRule v-                      >>= \case-                        Literal (Value (VUInt v') _) -> pure [fromIntegral v']-                        somethingElse ->-                          error $-                            "Malformed value in KV in choice in .bits: "-                              <> show somethingElse-                  Range ff tt incl -> getIndicesOfRange ff tt incl-                  Enum g -> getIndicesOfEnum g-                  somethingElse ->-                    error $-                      "Malformed alternative in choice in .bits: "-                        <> show somethingElse-              )-      )-      nodes--getIndicesOfRange :: MonadReader CDDL m => Rule -> Rule -> RangeBound -> m [Word64]-getIndicesOfRange ff tt incl =-  ((,) <$> getRule ff <*> getRule tt) >>= \case-    (Literal (Value (VUInt ff') _), Literal (Value (VUInt tt') _)) ->-      pure $-        [ff' .. tt'] & case incl of-          ClOpen -> init-          Closed -> id-    somethingElse -> error $ "Malformed range in .bits: " <> show somethingElse--getIndicesOfEnum :: MonadReader CDDL m => Rule -> m [Word64]-getIndicesOfEnum g =-  getRule g >>= \case-    Group g' -> getIndicesOfChoice (fromJust $ NE.nonEmpty g')-    somethingElse -> error $ "Malformed enum in .bits: " <> show somethingElse------------------------------------------------------------------------------------- Resolving rules from the CDDL spec--resolveIfRef :: CDDL -> Rule -> ResolvedRule-resolveIfRef _ (MIt aa) = aa-resolveIfRef ct@(CTreeRoot cddl) (MRuleRef n) = do-  case Map.lookup n cddl of-    Nothing -> error $ "Unbound reference: " <> show n-    Just val -> resolveIfRef ct $ runIdentity val--getRule :: MonadReader CDDL m => Rule -> m ResolvedRule-getRule rule = asks (`resolveIfRef` rule)------------------------------------------------------------------------------------- Utils--replaceRule :: CDDLResult -> Rule -> CDDLResult-replaceRule (ChoiceFail _ a b) r = ChoiceFail r a b-replaceRule (ListExpansionFail _ a b) r = ListExpansionFail r a b-replaceRule (MapExpansionFail _ a b) r = MapExpansionFail r a b-replaceRule (InvalidTagged _ a) r = InvalidTagged r a-replaceRule InvalidRule {} r = InvalidRule r-replaceRule (InvalidControl _ a) r = InvalidControl r a-replaceRule UnapplicableRule {} r = UnapplicableRule r-replaceRule Valid {} r = Valid r--ifM :: Monad m => m Bool -> m a -> m a -> m a-ifM b t f = do b' <- b; if b' then t else f+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE ViewPatterns #-}++module Codec.CBOR.Cuddle.CBOR.Validator (+  validateCBOR,+  CDDLResult (..),+  CBORTermResult (..),+  ValidatorStage,+) where++import Codec.CBOR.Cuddle.CDDL hiding (CDDL, Group, Rule)+import Codec.CBOR.Cuddle.CDDL.CTree+import Codec.CBOR.Cuddle.CDDL.CtlOp+import Codec.CBOR.Cuddle.CDDL.Resolve (MonoReferenced, XXCTree (..))+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..))+import Codec.CBOR.Read+import Codec.CBOR.Term+import Data.Bits hiding (And)+import Data.ByteString qualified as BS+import Data.ByteString.Lazy qualified as BSL+import Data.IntSet qualified as IS+import Data.List.NonEmpty qualified as NE+import Data.Map.Strict qualified as Map+import Data.Maybe+import Data.Text qualified as T+import Data.Text.Lazy qualified as TL+import Data.Word+import Debug.Trace (trace, traceShow)+import GHC.Float+import GHC.Stack (HasCallStack)+import Text.Regex.TDFA++type data ValidatorStage++data instance XTerm ValidatorStage = ValidatorXTerm+  deriving (Show)++newtype instance XXCTree ValidatorStage = VRuleRef Name+  deriving (Show)++instance IndexMappable CTreeRoot MonoReferenced ValidatorStage where+  mapIndex (CTreeRoot m) = CTreeRoot $ mapIndex <$> m++instance IndexMappable CTree MonoReferenced ValidatorStage where+  mapIndex = foldCTree mapExt mapIndex+    where+      mapExt (MRuleRef n) = CTreeE $ VRuleRef n+      mapExt (MGenerator _ x) = mapIndex x++type CDDL = CTreeRoot ValidatorStage+type Rule = CTree ValidatorStage++data CBORTermResult = CBORTermResult+  { ctrTerm :: Term+  , ctrResult :: CDDLResult+  }+  deriving (Show)++data CDDLResult+  = -- | The rule was valid+    Valid Rule+  | -- | All alternatives failed+    ChoiceFail+      -- | Rule we are trying+      Rule+      -- | The alternatives that arise from said rule+      (NE.NonEmpty Rule)+      -- | For each alternative, the result+      (NE.NonEmpty (Rule, CDDLResult))+  | -- | All expansions failed+    --+    -- An expansion is: Given a CBOR @TList@ of @N@ elements, we will expand the+    -- rules in a list spec to match the number of items in the list.+    ListExpansionFail+      -- | Rule we are trying+      Rule+      -- | List of expansions of rules+      [[Rule]]+      -- | For each expansion, for each of the rules in the expansion, the result+      [[(Rule, CBORTermResult)]]+  | -- | All expansions failed+    --+    -- An expansion is: Given a CBOR @TMap@ of @N@ elements, we will expand the+    -- rules in a map spec to match the number of items in the map.+    MapExpansionFail+      -- | Rule we are trying+      Rule+      -- | List of expansions+      [[Rule]]+      -- | A list of matched items @(key, value, rule)@ and the unmatched item+      [([AMatchedItem], ANonMatchedItem)]+  | -- | The rule was valid but the control failed+    InvalidControl+      -- | Control we are trying+      Rule+      -- | If it is a .cbor, the result of the underlying validation+      (Maybe CBORTermResult)+  | InvalidRule Rule+  | -- | A tagged was invalid+    InvalidTagged+      -- | Rule we are trying+      Rule+      -- | Either the tag is wrong, or the contents are wrong+      (Either Word64 CBORTermResult)+  | -- | The rule we are trying is not applicable to the CBOR term+    UnapplicableRule+      -- | Extra information+      String+      -- | Rule we are trying+      Rule+  deriving (Show)++data ANonMatchedItem = ANonMatchedItem+  { anmiKey :: Term+  , anmiValue :: Term+  , anmiResults :: [Either (Rule, CDDLResult) (Rule, CDDLResult, CDDLResult)]+  -- ^ For all the tried rules, either the key failed or the key succeeded and+  -- the value failed+  }+  deriving (Show)++data AMatchedItem = AMatchedItem+  { amiKey :: Term+  , amiValue :: Term+  , amiRule :: Rule+  }+  deriving (Show)++--------------------------------------------------------------------------------+-- Main entry point++validateCBOR :: BS.ByteString -> Name -> CDDL -> CBORTermResult+validateCBOR bs rule cddl@(CTreeRoot tree) =+  case deserialiseFromBytes decodeTerm (BSL.fromStrict bs) of+    Left e -> error $ show e+    Right (rest, term)+      | BSL.null rest -> validateTerm cddl term (tree Map.! rule)+      | otherwise -> error $ "Leftover bytes in CBOR" <> show rest++--------------------------------------------------------------------------------+-- Terms++-- | Core function that validates a CBOR term to a particular rule of the CDDL+-- spec+validateTerm :: CDDL -> Term -> Rule -> CBORTermResult+validateTerm cddl term rule =+  CBORTermResult term $ case term of+    TInt i -> validateInteger cddl (fromIntegral i) rRule+    TInteger i -> validateInteger cddl i rRule+    TBytes b -> validateBytes cddl b rRule+    TBytesI b -> validateBytes cddl (BSL.toStrict b) rRule+    TString s -> validateText cddl s rRule+    TStringI s -> validateText cddl (TL.toStrict s) rRule+    TList ts -> validateList cddl ts rRule+    TListI ts -> validateList cddl ts rRule+    TMap ts -> validateMap cddl ts rRule+    TMapI ts -> validateMap cddl ts rRule+    TTagged w t -> validateTagged cddl w t rRule+    TBool b -> validateBool cddl b rRule+    TNull -> validateNull cddl rRule+    TSimple s -> validateSimple cddl s rRule+    THalf h -> validateHalf cddl h rRule+    TFloat h -> validateFloat cddl h rRule+    TDouble d -> validateDouble cddl d rRule+  where+    rRule = resolveIfRef cddl rule++--------------------------------------------------------------------------------+-- Ints and integers++-- | Validation of an Int or Integer. CBOR categorizes every integral in `TInt`+-- or `TInteger` but it can be the case that we are decoding something that is+-- expected to be a `Word64` even if we get a `TInt`.+--+-- > ghci> encodeWord64 15+-- > [TkInt 15]+-- > ghci> encodeWord64 maxBound+-- > [TkInteger 18446744073709551615]+--+-- For this reason, we cannot assume that bounds or literals are going to be+-- Ints, so we convert everything to Integer.+validateInteger :: HasCallStack => CDDL -> Integer -> Rule -> CDDLResult+validateInteger cddl i rule =+  case resolveIfRef cddl rule of+    -- echo "C24101" | xxd -r -p - example.cbor+    -- echo "foo = int" > a.cddl+    -- cddl a.cddl validate example.cbor+    --+    -- but+    --+    -- echo "C249010000000000000000"| xxd -r -p - example.cbor+    -- echo "foo = int" > a.cddl+    -- cddl a.cddl validate example.cbor+    --+    -- and they are both bigints?++    -- a = any+    Postlude PTAny -> Valid rule+    -- a = int+    Postlude PTInt -> Valid rule+    -- a = uint+    Postlude PTUInt -> check (i >= 0) rule+    -- a = nint+    Postlude PTNInt -> check (i <= 0) rule+    -- a = x+    Literal (Value (VUInt i') _) -> check (i == fromIntegral i') rule+    -- a = -x+    Literal (Value (VNInt i') _) -> check (-i == fromIntegral i') rule+    -- a = <big number>+    Literal (Value (VBignum i') _) -> check (i == i') rule+    -- a = foo .ctrl bar+    Control op tgt ctrl -> ctrlDispatch (validateInteger cddl i) op tgt ctrl (controlInteger cddl i) rule+    -- a = foo / bar+    Choice opts -> validateChoice (validateInteger cddl i) opts rule+    -- a = x..y+    Range low high bound ->+      check+        ( case (resolveIfRef cddl low, resolveIfRef cddl high) of+            (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= i && range bound i m+            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> -n <= i && range bound i m+            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> -n <= i && range bound i (-m)+            (Literal (Value VUInt {} _), Literal (Value VNInt {} _)) -> False+            (Literal (Value (VBignum n) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= i && range bound i m+            (Literal (Value (VBignum n) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> n <= i && range bound i (-m)+            (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VBignum m) _)) -> n <= i && range bound i m+            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VBignum m) _)) -> (-n) <= i && range bound i m+            x -> error $ "Unable to validate range: " <> show x+        )+        rule+    -- a = &(x, y, z)+    Enum g ->+      case resolveIfRef cddl g of+        Group g' -> replaceRule (validateInteger cddl i (Choice (NE.fromList g'))) rule+        _ -> error "Not yet implemented"+    -- a = x: y+    -- Note KV cannot appear on its own, but we will use this when validating+    -- lists.+    KV _ v _ -> replaceRule (validateInteger cddl i v) rule+    Tag 2 x -> validateBigInt x+    Tag 3 x -> validateBigInt x+    _ -> UnapplicableRule "validateInteger" rule+  where+    validateBigInt x = case resolveIfRef cddl x of+      Postlude PTBytes -> Valid rule+      Control op tgt@(Postlude PTBytes) ctrl ->+        ctrlDispatch (validateBytes cddl bs) op tgt ctrl (controlBytes cddl bs) rule+        where+          -- TODO figure out a way to turn Integer into bytes or figure out why+          -- tagged bigints are decoded as integers in the first place+          bs = mempty+      e -> error $ "Not yet implemented" <> show e++-- | Controls for an Integer+controlInteger ::+  HasCallStack => CDDL -> Integer -> CtlOp -> Rule -> Either (Maybe CBORTermResult) ()+controlInteger cddl i Size ctrl =+  case resolveIfRef cddl ctrl of+    Literal (Value (VUInt sz) _) ->+      boolCtrl $ 0 <= i && i < 256 ^ sz+    _ -> error "Not yet implemented"+controlInteger cddl i Bits ctrl = do+  let+    indices = case resolveIfRef cddl ctrl of+      Literal (Value (VUInt i') _) -> [i']+      Choice nodes -> getIndicesOfChoice cddl nodes+      Range ff tt incl -> getIndicesOfRange cddl ff tt incl+      Enum g -> getIndicesOfEnum cddl g+      _ -> error "Not yet implemented"+  boolCtrl $ go (IS.fromList (map fromIntegral indices)) i 0+  where+    go _ 0 _ = True+    go indices n idx =+      let bitSet = testBit n 0+          allowed = not bitSet || IS.member idx indices+       in (allowed && go indices (shiftR n 1) (idx + 1))+controlInteger cddl i Lt ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VUInt i') _) -> i < fromIntegral i'+    Literal (Value (VNInt i') _) -> i < -fromIntegral i'+    Literal (Value (VBignum i') _) -> i < i'+    _ -> error "Not yet implemented"+controlInteger cddl i Gt ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VUInt i') _) -> i > fromIntegral i'+    Literal (Value (VNInt i') _) -> i > -fromIntegral i'+    Literal (Value (VBignum i') _) -> i > i'+    _ -> error "Not yet implemented"+controlInteger cddl i Le ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VUInt i') _) -> i <= fromIntegral i'+    Literal (Value (VNInt i') _) -> i <= -fromIntegral i'+    Literal (Value (VBignum i') _) -> i <= i'+    _ -> error "Not yet implemented"+controlInteger cddl i Ge ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VUInt i') _) -> i >= fromIntegral i'+    Literal (Value (VNInt i') _) -> i >= -fromIntegral i'+    Literal (Value (VBignum i') _) -> i >= i'+    _ -> error "Not yet implemented"+controlInteger cddl i Eq ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VUInt i') _) -> i == fromIntegral i'+    Literal (Value (VNInt i') _) -> i == -fromIntegral i'+    Literal (Value (VBignum i') _) -> i == i'+    _ -> error "Not yet implemented"+controlInteger cddl i Ne ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VUInt i') _) -> i /= fromIntegral i'+    Literal (Value (VNInt i') _) -> i /= -fromIntegral i'+    Literal (Value (VBignum i') _) -> i /= i'+    _ -> error "Not yet implemented"+controlInteger _ _ _ _ = error "Not yet implemented"++--------------------------------------------------------------------------------+-- Floating point (Float16, Float32, Float64)+--+-- As opposed to Integral types, there seems to be no ambiguity when encoding+-- and decoding floating-point numbers.++-- | Validating a `Float16`+validateHalf :: HasCallStack => CDDL -> Float -> Rule -> CDDLResult+validateHalf cddl f rule =+  case resolveIfRef cddl rule of+    -- a = any+    Postlude PTAny -> Valid rule+    -- a = float16+    Postlude PTHalf -> Valid rule+    -- a = 0.5+    Literal (Value (VFloat16 f') _) -> check (f == f') rule+    -- a = foo / bar+    Choice opts -> validateChoice (validateHalf cddl f) opts rule+    -- a = foo .ctrl bar+    Control op tgt ctrl -> ctrlDispatch (validateHalf cddl f) op tgt ctrl (controlHalf cddl f) rule+    -- a = x..y+    Range low high bound ->+      check+        ( case (resolveIfRef cddl low, resolveIfRef cddl high) of+            (Literal (Value (VFloat16 n) _), Literal (Value (VFloat16 m) _)) -> n <= f && range bound f m+            _ -> error "Not yet implemented"+        )+        rule+    _ -> UnapplicableRule "validateHalf" rule++-- | Controls for `Float16`+controlHalf :: HasCallStack => CDDL -> Float -> CtlOp -> Rule -> Either (Maybe CBORTermResult) ()+controlHalf cddl f Eq ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VFloat16 f') _) -> f == f'+    _ -> error "Not yet implemented"+controlHalf cddl f Ne ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VFloat16 f') _) -> f /= f'+    _ -> error "Not yet implemented"+controlHalf _ _ _ _ = error "Not yet implemented"++-- | Validating a `Float32`+validateFloat :: HasCallStack => CDDL -> Float -> Rule -> CDDLResult+validateFloat cddl f rule =+  ($ rule) $ do+    case resolveIfRef cddl rule of+      -- a = any+      Postlude PTAny -> Valid+      -- a = float32+      Postlude PTFloat -> Valid+      -- a = 0.000000005+      -- TODO: it is unclear if smaller floats should also validate+      Literal (Value (VFloat32 f') _) -> check $ f == f'+      -- a = foo / bar+      Choice opts -> validateChoice (validateFloat cddl f) opts+      -- a = foo .ctrl bar+      Control op tgt ctrl -> ctrlDispatch (validateFloat cddl f) op tgt ctrl (controlFloat cddl f)+      -- a = x..y+      -- TODO it is unclear if this should mix floating point types too+      Range low high bound ->+        check $ case (resolveIfRef cddl low, resolveIfRef cddl high) of+          (Literal (Value (VFloat16 n) _), Literal (Value (VFloat16 m) _)) -> n <= f && range bound f m+          (Literal (Value (VFloat32 n) _), Literal (Value (VFloat32 m) _)) -> n <= f && range bound f m+          _ -> error "Not yet implemented"+      _ -> UnapplicableRule "validateFloat"++-- | Controls for `Float32`+controlFloat :: HasCallStack => CDDL -> Float -> CtlOp -> Rule -> Either (Maybe CBORTermResult) ()+controlFloat cddl f Eq ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VFloat16 f') _) -> f == f'+    Literal (Value (VFloat32 f') _) -> f == f'+    _ -> error "Not yet implemented"+controlFloat cddl f Ne ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VFloat16 f') _) -> f /= f'+    Literal (Value (VFloat32 f') _) -> f /= f'+    _ -> error "Not yet implemented"+controlFloat _ _ _ _ = error "Not yet implemented"++-- | Validating a `Float64`+validateDouble :: HasCallStack => CDDL -> Double -> Rule -> CDDLResult+validateDouble cddl f rule =+  ($ rule) $ do+    case resolveIfRef cddl rule of+      -- a = any+      Postlude PTAny -> Valid+      -- a = float64+      Postlude PTDouble -> Valid+      -- a = 0.0000000000000000000000000000000000000000000005+      -- TODO: it is unclear if smaller floats should also validate+      Literal (Value (VFloat64 f') _) -> check $ f == f'+      -- a = foo / bar+      Choice opts -> validateChoice (validateDouble cddl f) opts+      -- a = foo .ctrl bar+      Control op tgt ctrl -> ctrlDispatch (validateDouble cddl f) op tgt ctrl (controlDouble cddl f)+      -- a = x..y+      -- TODO it is unclear if this should mix floating point types too+      Range low high bound ->+        check $ case (resolveIfRef cddl low, resolveIfRef cddl high) of+          (Literal (Value (VFloat16 (float2Double -> n)) _), Literal (Value (VFloat16 (float2Double -> m)) _)) -> n <= f && range bound f m+          (Literal (Value (VFloat32 (float2Double -> n)) _), Literal (Value (VFloat32 (float2Double -> m)) _)) -> n <= f && range bound f m+          (Literal (Value (VFloat64 n) _), Literal (Value (VFloat64 m) _)) -> n <= f && range bound f m+          _ -> error "Not yet implemented"+      _ -> UnapplicableRule "validateDouble"++-- | Controls for `Float64`+controlDouble :: HasCallStack => CDDL -> Double -> CtlOp -> Rule -> Either (Maybe CBORTermResult) ()+controlDouble cddl f Eq ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VFloat16 f') _) -> f == float2Double f'+    Literal (Value (VFloat32 f') _) -> f == float2Double f'+    Literal (Value (VFloat64 f') _) -> f == f'+    _ -> error "Not yet implemented"+controlDouble cddl f Ne ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VFloat16 f') _) -> f /= float2Double f'+    Literal (Value (VFloat32 f') _) -> f /= float2Double f'+    Literal (Value (VFloat64 f') _) -> f /= f'+    _ -> error "Not yet implemented"+controlDouble _ _ _ _ = error "Not yet implmented"++--------------------------------------------------------------------------------+-- Bool++-- | Validating a boolean+validateBool :: CDDL -> Bool -> Rule -> CDDLResult+validateBool cddl b rule =+  ($ rule) $ do+    case resolveIfRef cddl rule of+      -- a = any+      Postlude PTAny -> Valid+      -- a = bool+      Postlude PTBool -> Valid+      -- a = true+      Literal (Value (VBool b') _) -> check $ b == b'+      -- a = foo .ctrl bar+      Control op tgt ctrl -> ctrlDispatch (validateBool cddl b) op tgt ctrl (controlBool cddl b)+      -- a = foo / bar+      Choice opts -> validateChoice (validateBool cddl b) opts+      _ -> UnapplicableRule "validateBool"++-- | Controls for `Bool`+controlBool :: HasCallStack => CDDL -> Bool -> CtlOp -> Rule -> Either (Maybe CBORTermResult) ()+controlBool cddl b Eq ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VBool b') _) -> b == b'+    _ -> error "Not yet implemented"+controlBool cddl b Ne ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VBool b') _) -> b /= b'+    _ -> error "Not yet implemented"+controlBool _ _ _ _ = error "Not yet implemented"++--------------------------------------------------------------------------------+-- Simple++-- | Validating a `TSimple`. It is unclear if this is used for anything else than undefined.+validateSimple :: CDDL -> Word8 -> Rule -> CDDLResult+validateSimple cddl 23 rule =+  do+    case resolveIfRef cddl rule of+      -- a = any+      Postlude PTAny -> Valid rule+      -- a = undefined+      Postlude PTUndefined -> Valid rule+      -- a = foo / bar+      Choice opts -> validateChoice (validateSimple cddl 23) opts rule+      _ -> UnapplicableRule "validateSimple" rule+validateSimple _ n _ = error $ "Found simple different to 23! please report this somewhere! Found: " <> show n++--------------------------------------------------------------------------------+-- Null/nil++-- | Validating nil+validateNull :: CDDL -> Rule -> CDDLResult+validateNull cddl rule =+  case resolveIfRef cddl rule of+    -- a = any+    Postlude PTAny -> Valid rule+    -- a = nil+    Postlude PTNil -> Valid rule+    Choice opts -> validateChoice (validateNull cddl) opts rule+    _ -> UnapplicableRule "validateNull" rule++--------------------------------------------------------------------------------+-- Bytes++-- | Validating a byte sequence+validateBytes :: CDDL -> BS.ByteString -> Rule -> CDDLResult+validateBytes cddl bs rule =+  case resolveIfRef cddl rule of+    -- a = any+    Postlude PTAny -> Valid rule+    -- a = bytes+    Postlude PTBytes -> Valid rule+    -- a = h'123456'+    Literal (Value (VBytes bs') _) -> check (bs == bs') rule+    -- a = foo .ctrl bar+    Control op tgt ctrl -> ctrlDispatch (validateBytes cddl bs) op tgt ctrl (controlBytes cddl bs) rule+    -- a = foo / bar+    Choice opts -> validateChoice (validateBytes cddl bs) opts rule+    _ -> UnapplicableRule "validateBytes" rule++-- | Controls for byte strings+controlBytes ::+  HasCallStack =>+  CDDL ->+  BS.ByteString ->+  CtlOp ->+  Rule ->+  Either (Maybe CBORTermResult) ()+controlBytes cddl bs Size ctrl =+  case resolveIfRef cddl ctrl of+    Literal (Value (VUInt (fromIntegral -> sz)) _) -> boolCtrl $ BS.length bs == sz+    Range low high bound ->+      let i = BS.length bs+       in boolCtrl $ case (resolveIfRef cddl low, resolveIfRef cddl high) of+            (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= i && range bound i m+            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> -n <= i && range bound i m+            (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> -n <= i && range bound i (-m)+            (Literal (Value VUInt {} _), Literal (Value VNInt {} _)) -> False+            _ -> error "Not yet implemented"+    _ -> error "Not yet implemented"+controlBytes cddl bs Bits ctrl = do+  let+    indices =+      case resolveIfRef cddl ctrl of+        Literal (Value (VUInt i') _) -> [i']+        Choice nodes -> getIndicesOfChoice cddl nodes+        Range ff tt incl -> getIndicesOfRange cddl ff tt incl+        Enum g -> getIndicesOfEnum cddl g+        _ -> error "Not yet implemented"+  boolCtrl $ bitsControlCheck (map fromIntegral indices)+  where+    bitsControlCheck :: [Int] -> Bool+    bitsControlCheck allowedBits =+      let allowedSet = IS.fromList allowedBits+          totalBits = BS.length bs * 8+          isAllowedBit n =+            let byteIndex = n `shiftR` 3+                bitIndex = n .&. 7+             in case BS.indexMaybe bs byteIndex of+                  Just byte -> not (testBit byte bitIndex) || IS.member n allowedSet+                  Nothing -> True+       in all isAllowedBit [0 .. totalBits - 1]+controlBytes cddl bs Cbor ctrl =+  case deserialiseFromBytes decodeTerm (BSL.fromStrict bs) of+    Right (BSL.null -> True, term) ->+      case validateTerm cddl term ctrl of+        CBORTermResult _ (Valid _) -> Right ()+        err -> Left $ Just err+    _ -> error "Not yet implemented"+controlBytes cddl bs Cborseq ctrl =+  case deserialiseFromBytes decodeTerm (BSL.fromStrict (BS.snoc (BS.cons 0x9f bs) 0xff)) of+    Right (BSL.null -> True, TListI terms) ->+      case validateTerm cddl (TList terms) (Array [Occur ctrl OIZeroOrMore]) of+        CBORTermResult _ (Valid _) -> Right ()+        CBORTermResult _ err -> error $ show err+    _ -> error "Not yet implemented"+controlBytes _ _ _ _ = error "Not yet implmented"++--------------------------------------------------------------------------------+-- Text++-- | Validating text strings+validateText :: CDDL -> T.Text -> Rule -> CDDLResult+validateText cddl txt rule =+  case resolveIfRef cddl rule of+    -- a = any+    Postlude PTAny -> Valid rule+    -- a = text+    Postlude PTText -> Valid rule+    -- a = "foo"+    Literal (Value (VText txt') _) -> check (txt == txt') rule+    -- a = foo .ctrl bar+    Control op tgt ctrl -> ctrlDispatch (validateText cddl txt) op tgt ctrl (controlText cddl txt) rule+    -- a = foo / bar+    Choice opts -> validateChoice (validateText cddl txt) opts rule+    _ -> UnapplicableRule "validateText" rule++-- | Controls for text strings+controlText :: HasCallStack => CDDL -> T.Text -> CtlOp -> Rule -> Either (Maybe CBORTermResult) ()+controlText cddl bs Size ctrl =+  case resolveIfRef cddl ctrl of+    Literal (Value (VUInt (fromIntegral -> sz)) _) -> boolCtrl $ T.length bs == sz+    Range ff tt bound ->+      boolCtrl $ case (resolveIfRef cddl ff, resolveIfRef cddl tt) of+        (Literal (Value (VUInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> n <= T.length bs && range bound (T.length bs) m+        (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VUInt (fromIntegral -> m)) _)) -> -n <= T.length bs && range bound (T.length bs) m+        (Literal (Value (VNInt (fromIntegral -> n)) _), Literal (Value (VNInt (fromIntegral -> m)) _)) -> -n <= T.length bs && range bound (T.length bs) (-m)+        _ -> error "Not yet implemented"+    _ -> error "Not yet implemented"+controlText cddl s Regexp ctrl =+  boolCtrl $ case resolveIfRef cddl ctrl of+    Literal (Value (VText rxp) _) -> case s =~ rxp :: (T.Text, T.Text, T.Text) of+      ("", s', "") -> s == s'+      _ -> error "Not yet implemented"+    _ -> error "Not yet implemented"+controlText _ _ _ _ = error "Not yet implemented"++--------------------------------------------------------------------------------+-- Tagged values++-- | Validating a `TTagged`+validateTagged :: CDDL -> Word64 -> Term -> Rule -> CDDLResult+validateTagged cddl tag term rule =+  case resolveIfRef cddl rule of+    Postlude PTAny -> Valid rule+    Tag tag' rule' ->+      -- If the tag does not match, this is a direct fail+      if tag == tag'+        then case validateTerm cddl term rule' of+          CBORTermResult _ (Valid _) -> Valid rule+          err -> InvalidTagged rule (Right err)+        else InvalidTagged rule (Left tag)+    Choice opts -> validateChoice (validateTagged cddl tag term) opts rule+    _ -> UnapplicableRule "validateTagged" rule++-- --------------------------------------------------------------------------------+-- -- Lists++isWithinBoundsInclusive :: Ord a => a -> Maybe a -> Maybe a -> Bool+isWithinBoundsInclusive x lb ub = maybe True (x >=) lb && maybe True (x <=) ub++isOptional :: CTree i -> Bool+isOptional (Occur _ oi) = case oi of+  OIOptional -> True+  OIZeroOrMore -> True+  OIBounded lb ub -> isWithinBoundsInclusive 0 lb ub+  _ -> False+isOptional _ = False++decrementBounds :: Maybe Word64 -> Maybe Word64 -> OccurrenceIndicator+decrementBounds lb ub = OIBounded (clampedPred <$> lb) (clampedPred <$> ub)+  where+    clampedPred 0 = 0+    clampedPred x = pred x++validateList :: CDDL -> [Term] -> Rule -> CDDLResult+validateList cddl terms rule =+  case resolveIfRef cddl rule of+    Postlude PTAny -> Valid rule+    Array rules -> validate terms rules+    Choice opts -> validateChoice (validateList cddl terms) opts rule+    r -> UnapplicableRule "validateList" r+  where+    validate :: [Term] -> [CTree ValidatorStage] -> CDDLResult+    validate [] [] = Valid rule+    validate _ [] = ListExpansionFail rule [] []+    validate [] (r : rs)+      | isOptional r = validate [] rs+      | otherwise = UnapplicableRule "validateList" r+    validate (t : ts) (r : rs) = case r of+      Occur ct oi -> case oi of+        OIOptional+          | (Valid {}, leftover) <- validateTermInList (t : ts) ct+          , res@Valid {} <- validate leftover rs ->+              res+          | otherwise -> validate (t : ts) rs+        OIZeroOrMore+          | (Valid {}, leftover) <- validateTermInList (t : ts) ct+          , res@Valid {} <- validate leftover (r : rs) ->+              res+          | otherwise -> validate (t : ts) rs+        OIOneOrMore -> case validateTermInList (t : ts) ct of+          (Valid {}, leftover) -> validate leftover (Occur ct OIZeroOrMore : rs)+          (err, _) -> err+        OIBounded _ (Just ub) | ub < 0 -> trace ("out of bounds: " <> show ub) $ ListExpansionFail rule [] []+        OIBounded lb ub+          | (Valid {}, leftover) <- validateTermInList (t : ts) ct ->+              validate leftover (Occur ct (decrementBounds lb ub) : rs)+          | isWithinBoundsInclusive 0 lb ub ->+              validate (t : ts) rs+          | otherwise -> trace "foo" $ UnapplicableRule "validateList" r+      _ -> case validateTermInList (t : ts) (resolveIfRef cddl r) of+        (Valid {}, leftover) -> validate leftover rs+        (err, _) -> err++    validateTermInList ts (KV _ v _) = validateTermInList ts v+    validateTermInList ts (Group grp) = case grp of+      (resolveIfRef cddl -> g) : gs+        | (Valid {}, leftover) <- validateTermInList ts g -> validateTermInList leftover (Group gs)+        | otherwise -> (UnapplicableRule "validateTermInList group" g, ts)+      [] -> (Valid rule, ts)+    validateTermInList (t : ts) r =+      let CBORTermResult _ res = validateTerm cddl t r+       in (res, ts)+    validateTermInList [] g = (validate [] [g], [])++--------------------------------------------------------------------------------+-- Maps++validateMap :: CDDL -> [(Term, Term)] -> Rule -> CDDLResult+validateMap cddl terms rule =+  case resolveIfRef cddl rule of+    Postlude PTAny -> Valid rule+    Map rules -> validate [] terms rules+    Choice opts -> validateChoice (validateMap cddl terms) opts rule+    r -> UnapplicableRule "validateMap" r+  where+    validate :: [Rule] -> [(Term, Term)] -> [Rule] -> CDDLResult+    validate [] [] [] = Valid rule+    validate exhausted _ [] = trace (unlines $ show <$> exhausted) $ MapExpansionFail rule [] []+    validate [] [] (r : rs)+      | isOptional r = validate [] [] rs+      | otherwise = UnapplicableRule "validateMap" r+    validate exhausted ((k, v) : ts) (r : rs) = case r of+      Occur ct oi -> case oi of+        OIOptional+          | (Valid {}, leftover) <- validateKVInMap ((k, v) : ts) ct+          , res@Valid {} <- validate [] leftover (exhausted <> rs) ->+              res+          | otherwise -> validate (r : exhausted) ((k, v) : ts) rs+        OIZeroOrMore+          | (Valid {}, leftover) <- validateKVInMap ((k, v) : ts) ct+          , res@Valid {} <- validate [] leftover (r : exhausted <> rs) ->+              res+          | otherwise -> validate (r : exhausted) ((k, v) : ts) rs+        OIOneOrMore -> case validateKVInMap ((k, v) : ts) ct of+          (Valid {}, leftover) -> validate [] leftover (Occur ct OIZeroOrMore : exhausted <> rs)+          (err, _) -> err+        OIBounded _ (Just ub) | 0 > ub -> traceShow ub $ MapExpansionFail rule [] []+        OIBounded lb ub+          | (Valid {}, leftover) <- validateKVInMap ((k, v) : ts) ct+          , not (isWithinBoundsInclusive 0 lb ub) ->+              validate [] leftover (Occur ct (decrementBounds lb ub) : exhausted <> rs)+          | isWithinBoundsInclusive 0 lb ub && not (isValidTerm ((k, v) : ts) ct) ->+              validate (r : exhausted) ((k, v) : ts) rs+          | otherwise -> UnapplicableRule "validateMap" r+      _ -> case validateKVInMap ((k, v) : ts) r of+        (Valid {}, leftover) -> validate [] leftover (exhausted <> rs)+        (err, _) -> err+    validate _ _ _ = error "Impossible happened"++    validateKVInMap ((tk, tv) : ts) (KV k v _) = case (validateTerm cddl tk k, validateTerm cddl tv v) of+      (CBORTermResult _ Valid {}, CBORTermResult _ x@Valid {}) -> (x, ts)+      (CBORTermResult _ Valid {}, CBORTermResult _ err) -> (err, ts)+      (CBORTermResult _ err, _) -> (err, ts)+    validateKVInMap [] _ = error "No remaining KV pairs"+    validateKVInMap _ x = error $ "Unexpected value in map: " <> show x+    isValidTerm ts r = case validateKVInMap ts r of+      (Valid {}, _) -> True+      _ -> False++--------------------------------------------------------------------------------+-- Choices++validateChoice :: (Rule -> CDDLResult) -> NE.NonEmpty Rule -> Rule -> CDDLResult+validateChoice v rules = go rules+  where+    go :: NE.NonEmpty Rule -> Rule -> CDDLResult+    go (choice NE.:| xs) rule = do+      case v choice of+        Valid _ -> Valid rule+        err -> case NE.nonEmpty xs of+          Nothing -> ChoiceFail rule rules ((choice, err) NE.:| [])+          Just choices ->+            case go choices rule of+              Valid _ -> Valid rule+              ChoiceFail _ _ errors -> ChoiceFail rule rules ((choice, err) NE.<| errors)+              _ -> error "Not yet implemented"++--------------------------------------------------------------------------------+-- Control helpers++-- | Validate both rules+ctrlAnd :: (Rule -> CDDLResult) -> Rule -> Rule -> Rule -> CDDLResult+ctrlAnd v tgt ctrl rule =+  case v tgt of+    Valid _ ->+      case v ctrl of+        Valid _ -> Valid rule+        _ -> InvalidControl rule Nothing+    _ -> InvalidRule rule++-- | Dispatch to the appropriate control+ctrlDispatch ::+  (Rule -> CDDLResult) ->+  CtlOp ->+  Rule ->+  Rule ->+  (CtlOp -> Rule -> Either (Maybe CBORTermResult) ()) ->+  Rule ->+  CDDLResult+ctrlDispatch v And tgt ctrl _ rule = ctrlAnd v tgt ctrl rule+ctrlDispatch v Within tgt ctrl _ rule = ctrlAnd v tgt ctrl rule+ctrlDispatch v op tgt ctrl vctrl rule =+  case v tgt of+    Valid _ ->+      case vctrl op ctrl of+        Left err -> InvalidControl rule err+        Right () -> Valid rule+    _ -> InvalidRule rule++-- | A boolean control+boolCtrl :: Bool -> Either (Maybe CBORTermResult) ()+boolCtrl c = if c then Right () else Left Nothing++--------------------------------------------------------------------------------+-- Bits control++getIndicesOfChoice :: CDDL -> NE.NonEmpty Rule -> [Word64]+getIndicesOfChoice cddl =+  concatMap $ \case+    Literal (Value (VUInt v) _) -> [fromIntegral v]+    KV _ v _ ->+      case resolveIfRef cddl v of+        Literal (Value (VUInt v') _) -> [fromIntegral v']+        somethingElse ->+          error $+            "Malformed value in KV in choice in .bits: "+              <> show somethingElse+    Range ff tt incl -> getIndicesOfRange cddl ff tt incl+    Enum g -> getIndicesOfEnum cddl g+    somethingElse ->+      error $+        "Malformed alternative in choice in .bits: "+          <> show somethingElse++getIndicesOfRange :: CDDL -> Rule -> Rule -> RangeBound -> [Word64]+getIndicesOfRange cddl ff tt incl =+  case (resolveIfRef cddl ff, resolveIfRef cddl tt) of+    (Literal (Value (VUInt ff') _), Literal (Value (VUInt tt') _)) ->+      case incl of+        ClOpen -> init rng+        Closed -> rng+      where+        rng = [ff' .. tt']+    somethingElse -> error $ "Malformed range in .bits: " <> show somethingElse++getIndicesOfEnum :: CDDL -> Rule -> [Word64]+getIndicesOfEnum cddl g =+  case resolveIfRef cddl g of+    Group g' -> getIndicesOfChoice cddl (fromJust $ NE.nonEmpty g')+    somethingElse -> error $ "Malformed enum in .bits: " <> show somethingElse++--------------------------------------------------------------------------------+-- Resolving rules from the CDDL spec++resolveIfRef :: CDDL -> Rule -> Rule+resolveIfRef ct@(CTreeRoot cddl) (CTreeE (VRuleRef n)) = do+  case Map.lookup n cddl of+    Nothing -> error $ "Unbound reference: " <> show n+    Just val -> resolveIfRef ct val+resolveIfRef _ r = r++--------------------------------------------------------------------------------+-- Utils++replaceRule :: CDDLResult -> Rule -> CDDLResult+replaceRule (ChoiceFail _ a b) r = ChoiceFail r a b+replaceRule (ListExpansionFail _ a b) r = ListExpansionFail r a b+replaceRule (MapExpansionFail _ a b) r = MapExpansionFail r a b+replaceRule (InvalidTagged _ a) r = InvalidTagged r a+replaceRule InvalidRule {} r = InvalidRule r+replaceRule (InvalidControl _ a) r = InvalidControl r a+replaceRule (UnapplicableRule m _) r = UnapplicableRule m r+replaceRule Valid {} r = Valid r  check :: Bool -> Rule -> CDDLResult check c = if c then Valid else InvalidRule
src/Codec/CBOR/Cuddle/CDDL.hs view
@@ -1,5 +1,9 @@+{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE OverloadedLabels #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}  -- | This module defined the data structure of CDDL as specified in --   https://datatracker.ietf.org/doc/rfc8610/@@ -7,16 +11,17 @@   CDDL (..),   sortCDDL,   cddlTopLevel,-  cddlRules,-  fromRules,   fromRule,+  fromRules,+  appendRules,   TopLevel (..),   Name (..),   Rule (..),   TypeOrGroup (..),   Assign (..),   GenericArg (..),-  GenericParam (..),+  GenericParameters (..),+  GenericParameter (..),   Type0 (..),   Type1 (..),   Type2 (..),@@ -33,67 +38,101 @@   GrpChoice (..),   unwrap,   compareRuleName,+  HasName (..),+  -- Extension+  ForAllExtensions,+  XCddl,+  XTerm,+  XRule,+  XXTopLevel,+  XXType2, ) where  import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp) import Codec.CBOR.Cuddle.Comments (CollectComments (..), Comment, HasComment (..)) import Data.ByteString qualified as B import Data.Default.Class (Default (..))-import Data.Function (on, (&))+import Data.Function (on) import Data.Hashable (Hashable)-import Data.List.NonEmpty (NonEmpty (..))+import Data.List.NonEmpty (NonEmpty (..), prependList) import Data.List.NonEmpty qualified as NE+import Data.Maybe (mapMaybe) import Data.String (IsString (..)) import Data.Text qualified as T import Data.TreeDiff (ToExpr) import Data.Word (Word64, Word8)+import GHC.Base (Constraint, Type) import GHC.Generics (Generic)-import Optics.Core ((%), (.~))-import Optics.Getter (view)-import Optics.Lens (lens)+import Optics.Core ((%), (%~), (&)) +data family XXTopLevel i++data family XCddl i++data family XTerm i++data family XRule i++data family XXType2 i++type ForAllExtensions i (c :: Type -> Constraint) =+  ( c (XCddl i)+  , c (XTerm i)+  , c (XRule i)+  , c (XXTopLevel i)+  , c (XXType2 i)+  )+ -- | The CDDL constructor takes three arguments: --     1. Top level comments that precede the first definition --     2. The root definition --     3. All the other top level comments and definitions --   This ensures that `CDDL` is correct by construction.-data CDDL = CDDL [Comment] Rule [TopLevel]-  deriving (Eq, Generic, Show, ToExpr)+data CDDL i = CDDL+  { rootDefinition :: Rule i+  , topLevelDefinitions :: [TopLevel i]+  , cddlExt :: [XXTopLevel i]+  -- ^ This extension is used for comments that appear before the root definition+  }+  deriving (Generic) +deriving instance ForAllExtensions i Eq => Eq (CDDL i)++deriving instance ForAllExtensions i Show => Show (CDDL i)++deriving instance ForAllExtensions i ToExpr => ToExpr (CDDL i)++ruleTopLevel :: TopLevel i -> Maybe (Rule i)+ruleTopLevel (TopLevelRule r) = Just r+ruleTopLevel _ = Nothing+ -- | Sort the CDDL Rules on the basis of their names--- Top level comments will be removed!-sortCDDL :: CDDL -> CDDL-sortCDDL = fromRules . NE.sortBy (compare `on` ruleName) . cddlRules+sortCDDL :: CDDL i -> NonEmpty (Rule i)+sortCDDL (CDDL r rs _) = NE.sortBy (compare `on` unName . ruleName) $ r :| mapMaybe ruleTopLevel rs -cddlTopLevel :: CDDL -> NonEmpty TopLevel-cddlTopLevel (CDDL cmts cHead cTail) =-  prependList (TopLevelComment <$> cmts) $ TopLevelRule cHead :| cTail-  where-    prependList [] l = l-    prependList (x : xs) (y :| ys) = prependList xs $ x :| (y : ys)+fromRules :: Monoid (XCddl i) => NonEmpty (Rule i) -> CDDL i+fromRules (x :| xs) = CDDL x (TopLevelRule <$> xs) mempty -cddlRules :: CDDL -> NonEmpty Rule-cddlRules (CDDL _ x tls) = x :| concatMap getRule tls-  where-    getRule (TopLevelRule r) = [r]-    getRule _ = mempty+fromRule :: Monoid (XCddl i) => Rule i -> CDDL i+fromRule x = CDDL x [] mempty -fromRules :: NonEmpty Rule -> CDDL-fromRules (x :| xs) = CDDL [] x $ TopLevelRule <$> xs+appendRules :: CDDL i -> [Rule i] -> CDDL i+appendRules cddl rs = cddl & #topLevelDefinitions %~ (<> fmap TopLevelRule rs) -fromRule :: Rule -> CDDL-fromRule x = CDDL [] x []+cddlTopLevel :: CDDL i -> NonEmpty (TopLevel i)+cddlTopLevel (CDDL r tls e) = prependList (XXTopLevel <$> e) $ TopLevelRule r :| tls -instance Semigroup CDDL where-  CDDL aComments aHead aTail <> CDDL bComments bHead bTail =-    CDDL aComments aHead $-      aTail <> fmap TopLevelComment bComments <> (TopLevelRule bHead : bTail)+data TopLevel i+  = TopLevelRule (Rule i)+  | XXTopLevel (XXTopLevel i)+  deriving (Generic) -data TopLevel-  = TopLevelRule Rule-  | TopLevelComment Comment-  deriving (Eq, Generic, Show, ToExpr)+deriving instance ForAllExtensions i Eq => Eq (TopLevel i) +deriving instance ForAllExtensions i Show => Show (TopLevel i)++deriving instance ForAllExtensions i ToExpr => ToExpr (TopLevel i)+ -- | --  A name can consist of any of the characters from the set {"A" to --  "Z", "a" to "z", "0" to "9", "_", "-", "@", ".", "$"}, starting@@ -117,24 +156,27 @@ -- --  *  Rule names (types or groups) do not appear in the actual CBOR --      encoding, but names used as "barewords" in member keys do.-data Name = Name-  { name :: T.Text-  , nameComment :: Comment-  }-  deriving (Eq, Generic, Ord, Show)-  deriving anyclass (ToExpr)+newtype Name = Name {unName :: T.Text}+  deriving (Generic)+  deriving (Eq, Ord, Show)+  deriving newtype (Semigroup, Monoid) -instance IsString Name where-  fromString x = Name (T.pack x) mempty+deriving anyclass instance ToExpr Name -instance HasComment Name where-  commentL = lens nameComment (\x y -> x {nameComment = y})+instance IsString Name where+  fromString = Name . T.pack  instance CollectComments Name where-  collectComments (Name _ c) = [c]+  collectComments _ = []  instance Hashable Name +class HasName a where+  getName :: a -> Name++instance HasName Name where+  getName = id+ -- | --   assignt = "=" / "/=" --   assigng = "=" / "//="@@ -168,18 +210,45 @@ -- --   Generic rules can be used for establishing names for both types and --   groups.-newtype GenericParam = GenericParam (NE.NonEmpty Name)-  deriving (Eq, Generic, Show)+newtype GenericParameters i = GenericParameters (NE.NonEmpty (GenericParameter i))+  deriving (Generic)   deriving newtype (Semigroup)-  deriving anyclass (ToExpr) -newtype GenericArg = GenericArg (NE.NonEmpty Type1)-  deriving (Eq, Generic, Show)+deriving instance Eq (XTerm i) => Eq (GenericParameters i)++deriving instance Show (XTerm i) => Show (GenericParameters i)++deriving anyclass instance ToExpr (XTerm i) => ToExpr (GenericParameters i)++data GenericParameter i = GenericParameter+  { gpName :: Name+  , gpExt :: XTerm i+  }+  deriving (Generic)++deriving instance Eq (XTerm i) => Eq (GenericParameter i)++deriving instance Show (XTerm i) => Show (GenericParameter i)++deriving anyclass instance ToExpr (XTerm i) => ToExpr (GenericParameter i)++instance CollectComments (XTerm i) => CollectComments (GenericParameter i)++instance HasComment (XTerm i) => HasComment (GenericParameter i) where+  commentL = #gpExt % commentL++newtype GenericArg i = GenericArg (NE.NonEmpty (Type1 i))+  deriving (Generic)   deriving newtype (Semigroup)-  deriving anyclass (ToExpr) -instance CollectComments GenericArg+deriving instance ForAllExtensions i Eq => Eq (GenericArg i) +deriving instance ForAllExtensions i Show => Show (GenericArg i)++deriving anyclass instance ForAllExtensions i ToExpr => ToExpr (GenericArg i)++instance ForAllExtensions i CollectComments => CollectComments (GenericArg i)+ -- | --  rule = typename [genericparm] S assignt S type --        / groupname [genericparm] S assigng S grpent@@ -203,20 +272,25 @@ --   clear immediately either whether "b" stands for a group or a type -- --   this semantic processing may need to span several levels of rule --   definitions before a determination can be made.)-data Rule = Rule+data Rule i = Rule   { ruleName :: Name-  , ruleGenParam :: Maybe GenericParam+  , ruleGenParam :: Maybe (GenericParameters i)   , ruleAssign :: Assign-  , ruleTerm :: TypeOrGroup-  , ruleComment :: Comment+  , ruleTerm :: TypeOrGroup i+  , ruleExt :: XRule i   }-  deriving (Eq, Generic, Show)-  deriving anyclass (ToExpr)+  deriving (Generic) -instance HasComment Rule where-  commentL = lens ruleComment (\x y -> x {ruleComment = y})+deriving instance ForAllExtensions i Eq => Eq (Rule i) -compareRuleName :: Rule -> Rule -> Ordering+deriving instance ForAllExtensions i Show => Show (Rule i)++deriving instance ForAllExtensions i ToExpr => ToExpr (Rule i)++instance HasComment (XRule i) => HasComment (Rule i) where+  commentL = #ruleExt % commentL++compareRuleName :: Ord (XTerm i) => Rule i -> Rule i -> Ordering compareRuleName = compare `on` ruleName  -- |@@ -235,12 +309,17 @@   deriving (Eq, Generic, Show)   deriving anyclass (ToExpr) -data TypeOrGroup = TOGType Type0 | TOGGroup GroupEntry-  deriving (Eq, Generic, Show)-  deriving anyclass (ToExpr)+data TypeOrGroup i = TOGType (Type0 i) | TOGGroup (GroupEntry i)+  deriving (Generic) -instance CollectComments TypeOrGroup+deriving instance ForAllExtensions i Eq => Eq (TypeOrGroup i) +deriving instance ForAllExtensions i Show => Show (TypeOrGroup i)++deriving instance ForAllExtensions i ToExpr => ToExpr (TypeOrGroup i)++instance ForAllExtensions i CollectComments => CollectComments (TypeOrGroup i)+ {-- |    The group that is used to define a map or an array can often be reused in the    definition of another map or array.  Similarly, a type defined as a tag@@ -290,7 +369,7 @@    described as "threading in" the group or type inside the referenced type,    which suggested the thread-like "~" character.) -}-unwrap :: TypeOrGroup -> Maybe Group+unwrap :: TypeOrGroup i -> Maybe (Group i) unwrap (TOGType (Type0 (Type1 t2 Nothing _ NE.:| []))) = case t2 of   T2Map g -> Just g   T2Array g -> Just g@@ -301,71 +380,84 @@ -- A type can be given as a choice between one or more types.  The --   choice matches a data item if the data item matches any one of the --   types given in the choice.-newtype Type0 = Type0 {t0Type1 :: NE.NonEmpty Type1}-  deriving (Eq, Generic, Show)+newtype Type0 i = Type0 {t0Type1 :: NE.NonEmpty (Type1 i)}+  deriving (Generic)   deriving newtype (Semigroup)-  deriving anyclass (ToExpr) -instance HasComment Type0 where-  commentL = lens (view commentL . t0Type1) (\(Type0 x) y -> Type0 $ x & commentL .~ y)+deriving instance ForAllExtensions i Eq => Eq (Type0 i) -instance CollectComments Type0+deriving instance ForAllExtensions i Show => Show (Type0 i) +deriving anyclass instance ForAllExtensions i ToExpr => ToExpr (Type0 i)++instance ForAllExtensions i CollectComments => CollectComments (Type0 i)+ -- | -- Two types can be combined with a range operator (see below)-data Type1 = Type1-  { t1Main :: Type2-  , t1TyOp :: Maybe (TyOp, Type2)-  , t1Comment :: Comment+data Type1 i = Type1+  { t1Main :: Type2 i+  , t1TyOp :: Maybe (TyOp, Type2 i)+  , t1Comment :: XTerm i   }-  deriving (Eq, Generic, Show)-  deriving anyclass (ToExpr, Default)+  deriving (Generic) -instance HasComment Type1 where-  commentL = lens t1Comment (\x y -> x {t1Comment = y})+deriving instance ForAllExtensions i Eq => Eq (Type1 i) -instance CollectComments Type1 where-  collectComments (Type1 m tyOp c) = c : collectComments m <> collectComments (fmap snd tyOp)+deriving instance ForAllExtensions i Show => Show (Type1 i) -data Type2+deriving instance ForAllExtensions i ToExpr => ToExpr (Type1 i)++instance HasComment (XTerm i) => HasComment (Type1 i) where+  commentL = #t1Comment % commentL++instance ForAllExtensions i CollectComments => CollectComments (Type1 i) where+  collectComments (Type1 m tyOp c) = collectComments c <> collectComments m <> collectComments (fmap snd tyOp)++data Type2 i   = -- | A type can be just a single value (such as 1 or "icecream" or     --   h'0815'), which matches only a data item with that specific value     --   (no conversions defined),     T2Value Value   | -- | or be defined by a rule giving a meaning to a name (possibly after     --   supplying generic arguments as required by the generic parameters)-    T2Name Name (Maybe GenericArg)+    T2Name Name (Maybe (GenericArg i))   | -- | or be defined in a parenthesized type expression (parentheses may be     --   necessary to override some operator precedence),-    T2Group Type0+    T2Group (Type0 i)   | -- | a map expression, which matches a valid CBOR map the key/value pairs     --  of which can be ordered in such a way that the resulting sequence     --  matches the group expression, or-    T2Map Group+    T2Map (Group i)   | -- | an array expression, which matches a CBOR array the elements of which     -- when taken as values and complemented by a wildcard (matches     -- anything) key each -- match the group, or-    T2Array Group+    T2Array (Group i)   | -- | an "unwrapped" group (see Section 3.7), which matches the group     --  inside a type defined as a map or an array by wrapping the group, or-    T2Unwrapped Name (Maybe GenericArg)+    T2Unwrapped Name (Maybe (GenericArg i))   | -- | an enumeration expression, which matches any value that is within the     --  set of values that the values of the group given can take, or-    T2Enum Group-  | T2EnumRef Name (Maybe GenericArg)+    T2Enum (Group i)+  | T2EnumRef Name (Maybe (GenericArg i))   | -- | a tagged data item, tagged with the "uint" given and containing the     --  type given as the tagged value, or-    T2Tag (Maybe Word64) Type0+    T2Tag (Maybe Word64) (Type0 i)   | -- | a data item of a major type (given by the DIGIT), optionally     --  constrained to the additional information given by the uint, or     T2DataItem Word8 (Maybe Word64)   | -- | Any data item     T2Any-  deriving (Eq, Generic, Show, Default)-  deriving anyclass (ToExpr)+  | XXType2 (XXType2 i)+  deriving (Generic) -instance CollectComments Type2+deriving instance ForAllExtensions i Eq => Eq (Type2 i) +deriving instance ForAllExtensions i Show => Show (Type2 i)++deriving instance ForAllExtensions i ToExpr => ToExpr (Type2 i)++instance ForAllExtensions i CollectComments => CollectComments (Type2 i)+ -- | --  An optional _occurrence_ indicator can be given in front of a group --  entry.  It is either (1) one of the characters "?" (optional), "*"@@ -393,30 +485,40 @@ -- | --   A group matches any sequence of key/value pairs that matches any of --   the choices given (again using PEG semantics).-newtype Group = Group {unGroup :: NE.NonEmpty GrpChoice}-  deriving (Eq, Generic, Show)+newtype Group i = Group {unGroup :: NE.NonEmpty (GrpChoice i)}+  deriving (Generic)   deriving newtype (Semigroup)-  deriving anyclass (ToExpr) -instance HasComment Group where-  commentL = lens unGroup (\x y -> x {unGroup = y}) % commentL+deriving instance ForAllExtensions i Eq => Eq (Group i) -instance CollectComments Group where+deriving instance ForAllExtensions i Show => Show (Group i)++deriving anyclass instance ForAllExtensions i ToExpr => ToExpr (Group i)++instance HasComment (XTerm i) => HasComment (Group i) where+  commentL = #unGroup % commentL++instance ForAllExtensions i CollectComments => CollectComments (Group i) where   collectComments (Group xs) = concatMap collectComments xs -data GrpChoice = GrpChoice-  { gcGroupEntries :: [GroupEntry]-  , gcComment :: Comment+data GrpChoice i = GrpChoice+  { gcGroupEntries :: [GroupEntry i]+  , gcComment :: XTerm i   }-  deriving (Eq, Generic, Show)-  deriving anyclass (ToExpr)+  deriving (Generic) -instance HasComment GrpChoice where-  commentL = lens gcComment (\x y -> x {gcComment = y})+deriving instance ForAllExtensions i Eq => Eq (GrpChoice i) -instance CollectComments GrpChoice where-  collectComments (GrpChoice ges c) = c : concatMap collectComments ges+deriving instance ForAllExtensions i Show => Show (GrpChoice i) +deriving instance ForAllExtensions i ToExpr => ToExpr (GrpChoice i)++instance HasComment (XTerm i) => HasComment (GrpChoice i) where+  commentL = #gcComment % commentL++instance ForAllExtensions i CollectComments => CollectComments (GrpChoice i) where+  collectComments (GrpChoice ges c) = collectComments c <> concatMap collectComments ges+ -- | --  A group entry can be given by a value type, which needs to be matched --  by the value part of a single element; and, optionally, a memberkey@@ -424,26 +526,38 @@ --  the memberkey is given.  If the memberkey is not given, the entry can --  only be used for matching arrays, not for maps.  (See below for how --  that is modified by the occurrence indicator.)-data GroupEntry = GroupEntry+data GroupEntry i = GroupEntry   { geOccurrenceIndicator :: Maybe OccurrenceIndicator-  , geComment :: Comment-  , geVariant :: GroupEntryVariant+  , geVariant :: GroupEntryVariant i+  , geExt :: XTerm i   }-  deriving (Eq, Show, Generic, ToExpr)+  deriving (Generic) -instance CollectComments GroupEntry where-  collectComments (GroupEntry _ c x) = c : collectComments x+deriving instance ForAllExtensions i Eq => Eq (GroupEntry i) -data GroupEntryVariant-  = GEType (Maybe MemberKey) Type0-  | GERef Name (Maybe GenericArg)-  | GEGroup Group-  deriving (Eq, Show, Generic, ToExpr)+deriving instance ForAllExtensions i Show => Show (GroupEntry i) -instance HasComment GroupEntry where-  commentL = lens geComment (\x y -> x {geComment = y})+deriving instance ForAllExtensions i ToExpr => ToExpr (GroupEntry i) -instance CollectComments GroupEntryVariant where+instance ForAllExtensions i CollectComments => CollectComments (GroupEntry i) where+  collectComments (GroupEntry _ c x) = collectComments c <> collectComments x++data GroupEntryVariant i+  = GEType (Maybe (MemberKey i)) (Type0 i)+  | GERef Name (Maybe (GenericArg i))+  | GEGroup (Group i)+  deriving (Generic)++deriving instance ForAllExtensions i Eq => Eq (GroupEntryVariant i)++deriving instance ForAllExtensions i Show => Show (GroupEntryVariant i)++deriving instance ForAllExtensions i ToExpr => ToExpr (GroupEntryVariant i)++instance HasComment (XTerm i) => HasComment (GroupEntry i) where+  commentL = #geExt % commentL++instance ForAllExtensions i CollectComments => CollectComments (GroupEntryVariant i) where   collectComments (GEType _ t0) = collectComments t0   collectComments (GERef n mga) = collectComments n <> collectComments mga   collectComments (GEGroup g) = collectComments g@@ -456,12 +570,17 @@ --  member of the key type, unless a cut preceding it in the group --  applies (see Section 3.5.4 for how map matching is influenced by the --  presence of the cuts denoted by "^" or ":" in previous entries).-data MemberKey-  = MKType Type1+data MemberKey i+  = MKType (Type1 i)   | MKBareword Name   | MKValue Value-  deriving (Eq, Generic, Show)-  deriving anyclass (ToExpr)+  deriving (Generic)++deriving instance ForAllExtensions i Eq => Eq (MemberKey i)++deriving instance ForAllExtensions i Show => Show (MemberKey i)++deriving instance ForAllExtensions i ToExpr => ToExpr (MemberKey i)  data Value = Value ValueVariant Comment   deriving (Eq, Generic, Show, Default)
+ src/Codec/CBOR/Cuddle/CDDL/CBORGenerator.hs view
@@ -0,0 +1,23 @@+module Codec.CBOR.Cuddle.CDDL.CBORGenerator (+  CBORGenerator (..),+  HasGenerator (..),+  WrappedTerm (..),+) where++import Codec.CBOR.Term (Term)+import Optics.Core (Lens')+import System.Random.Stateful (StatefulGen)++data WrappedTerm+  = -- | Single term+    S Term+  | -- | Pair term+    P Term Term+  | -- | Group term+    G [WrappedTerm]+  deriving (Eq, Show)++newtype CBORGenerator = CBORGenerator (forall g m. StatefulGen g m => g -> m WrappedTerm)++class HasGenerator a where+  generatorL :: Lens' a (Maybe CBORGenerator)
src/Codec/CBOR/Cuddle/CDDL/CTree.hs view
@@ -1,4 +1,9 @@ {-# LANGUAGE DataKinds #-}+{-# LANGUAGE DeriveAnyClass #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE UndecidableInstances #-}  module Codec.CBOR.Cuddle.CDDL.CTree where @@ -7,12 +12,20 @@   OccurrenceIndicator,   RangeBound,   Value,+  XCddl,+  XRule,+  XTerm,+  XXTopLevel,+  XXType2,  )+import Codec.CBOR.Cuddle.CDDL.CBORGenerator (CBORGenerator) import Codec.CBOR.Cuddle.CDDL.CtlOp-import Codec.CBOR.Cuddle.CDDL.Postlude (PTerm)+import Control.Monad.Identity (Identity (..))+import Data.Default.Class (Default) import Data.Hashable (Hashable) import Data.List.NonEmpty qualified as NE import Data.Map.Strict qualified as Map+import Data.Void (Void) import Data.Word (Word64) import GHC.Generics (Generic) @@ -26,66 +39,138 @@ -- to manipulate. -------------------------------------------------------------------------------- --- | CDDL Tree, parametrised over a functor------   We principally use this functor to represent references - thus, every 'f a'---   may be either an a or a reference to another CTree.-data CTree f+data family XXCTree i++type data CTreePhase++data instance XTerm CTreePhase = CTreeXTerm+  deriving (Generic, Show, Eq, Ord)+  deriving anyclass (Hashable, Default)++newtype instance XXTopLevel CTreePhase = CTreeXXTopLevel Void+  deriving (Generic, Show, Eq, Ord)++data instance XCddl CTreePhase = CTreeXCddl+  deriving (Generic, Show, Eq, Ord)++newtype instance XRule CTreePhase = CTreeXRule (Maybe CBORGenerator)+  deriving (Generic)++newtype instance XXType2 CTreePhase = CTreeXXType2 Void+  deriving (Generic, Show, Eq, Ord)+  deriving anyclass (Hashable)++data CTree i   = Literal Value   | Postlude PTerm-  | Map [Node f]-  | Array [Node f]-  | Choice (NE.NonEmpty (Node f))-  | Group [Node f]-  | KV {key :: Node f, value :: Node f, cut :: Bool}-  | Occur {item :: Node f, occurs :: OccurrenceIndicator}-  | Range {from :: Node f, to :: Node f, inclusive :: RangeBound}-  | Control {op :: CtlOp, target :: Node f, controller :: Node f}-  | Enum (Node f)-  | Unwrap (Node f)-  | Tag Word64 (Node f)+  | Map [CTree i]+  | Array [CTree i]+  | Choice (NE.NonEmpty (CTree i))+  | Group [CTree i]+  | KV {key :: CTree i, value :: CTree i, cut :: Bool}+  | Occur {item :: CTree i, occurs :: OccurrenceIndicator}+  | Range {from :: CTree i, to :: CTree i, inclusive :: RangeBound}+  | Control {op :: CtlOp, target :: CTree i, controller :: CTree i}+  | Enum (CTree i)+  | Unwrap (CTree i)+  | Tag Word64 (CTree i)+  | CTreeE (XXCTree i)   deriving (Generic) +deriving instance Eq (Node f) => Eq (CTree f)++deriving instance Show (Node f) => Show (CTree f)++instance Hashable (Node f) => Hashable (CTree f)+ -- | Traverse the CTree, carrying out the given operation at each node-traverseCTree :: Monad m => (Node f -> m (Node g)) -> CTree f -> m (CTree g)-traverseCTree _ (Literal a) = pure $ Literal a-traverseCTree _ (Postlude a) = pure $ Postlude a-traverseCTree atNode (Map xs) = Map <$> traverse atNode xs-traverseCTree atNode (Array xs) = Array <$> traverse atNode xs-traverseCTree atNode (Group xs) = Group <$> traverse atNode xs-traverseCTree atNode (Choice xs) = Choice <$> traverse atNode xs-traverseCTree atNode (KV k v c) = do+traverseCTree ::+  Monad m => (XXCTree i -> m (CTree j)) -> (CTree i -> m (CTree j)) -> CTree i -> m (CTree j)+traverseCTree _ _ (Literal a) = pure $ Literal a+traverseCTree _ _ (Postlude a) = pure $ Postlude a+traverseCTree _ atNode (Map xs) = Map <$> traverse atNode xs+traverseCTree _ atNode (Array xs) = Array <$> traverse atNode xs+traverseCTree _ atNode (Group xs) = Group <$> traverse atNode xs+traverseCTree _ atNode (Choice xs) = Choice <$> traverse atNode xs+traverseCTree _ atNode (KV k v c) = do   k' <- atNode k   v' <- atNode v   pure $ KV k' v' c-traverseCTree atNode (Occur i occ) = flip Occur occ <$> atNode i-traverseCTree atNode (Range f t inc) = do+traverseCTree _ atNode (Occur i occ) = flip Occur occ <$> atNode i+traverseCTree _ atNode (Range f t inc) = do   f' <- atNode f   t' <- atNode t   pure $ Range f' t' inc-traverseCTree atNode (Control o t c) = do+traverseCTree _ atNode (Control o t c) = do   t' <- atNode t   c' <- atNode c   pure $ Control o t' c'-traverseCTree atNode (Enum ref) = Enum <$> atNode ref-traverseCTree atNode (Unwrap ref) = Unwrap <$> atNode ref-traverseCTree atNode (Tag i ref) = Tag i <$> atNode ref+traverseCTree _ atNode (Enum ref) = Enum <$> atNode ref+traverseCTree _ atNode (Unwrap ref) = Unwrap <$> atNode ref+traverseCTree _ atNode (Tag i ref) = Tag i <$> atNode ref+traverseCTree atExt _ (CTreeE x) = atExt x -type Node f = f (CTree f)+foldCTree ::+  (XXCTree i -> CTree j) ->+  (CTree i -> CTree j) ->+  CTree i ->+  CTree j+foldCTree atExt atNode x = runIdentity $ traverseCTree (pure . atExt) (pure . atNode) x -newtype CTreeRoot' poly f-  = CTreeRoot-      (Map.Map Name (poly (Node f)))+type Node i = XXCTree i++newtype CTreeRoot i = CTreeRoot (Map.Map Name (CTree i))   deriving (Generic) -type CTreeRoot f = CTreeRoot' (ParametrisedWith [Name]) f+deriving instance Show (CTree i) => Show (CTreeRoot i) -data ParametrisedWith w a-  = Unparametrised {underlying :: a}-  | Parametrised-      { underlying :: a-      , params :: w-      }-  deriving (Eq, Functor, Generic, Foldable, Traversable, Show)+-- |+--+--  CDDL predefines a number of names.  This subsection summarizes these+--  names, but please see Appendix D for the exact definitions.+--+--  The following keywords for primitive datatypes are defined:+--+--  "bool"  Boolean value (major type 7, additional information 20+--    or 21).+--+--  "uint"  An unsigned integer (major type 0).+--+--  "nint"  A negative integer (major type 1).+--+--  "int"  An unsigned integer or a negative integer.+--+--  "float16"  A number representable as a half-precision float [IEEE754]+--    (major type 7, additional information 25).+--+--  "float32"  A number representable as a single-precision float+--    [IEEE754] (major type 7, additional information 26).+--+--+--  "float64"  A number representable as a double-precision float+--    [IEEE754] (major type 7, additional information 27).+--+--  "float"  One of float16, float32, or float64.+--+--  "bstr" or "bytes"  A byte string (major type 2).+--+--  "tstr" or "text"  Text string (major type 3).+--+--  (Note that there are no predefined names for arrays or maps; these+--  are defined with the syntax given below.)+data PTerm+  = PTBool+  | PTUInt+  | PTNInt+  | PTInt+  | PTHalf+  | PTFloat+  | PTDouble+  | PTBytes+  | PTText+  | PTAny+  | PTNil+  | PTUndefined+  deriving (Eq, Generic, Ord, Show) -instance (Hashable w, Hashable a) => Hashable (ParametrisedWith w a)+instance Hashable PTerm
src/Codec/CBOR/Cuddle/CDDL/Postlude.hs view
@@ -1,55 +1,73 @@+{-# LANGUAGE OverloadedStrings #-}+ module Codec.CBOR.Cuddle.CDDL.Postlude where -import Data.Hashable (Hashable)-import GHC.Generics (Generic)+import Codec.CBOR.Cuddle.CDDL (CDDL (..), TopLevel (..), XRule, XTerm, XXType2, appendRules)+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..))+import Codec.CBOR.Cuddle.Parser (ParserStage, pCDDL)+import Data.Maybe (mapMaybe)+import Text.Megaparsec (errorBundlePretty, parse) --- |------  CDDL predefines a number of names.  This subsection summarizes these---  names, but please see Appendix D for the exact definitions.------  The following keywords for primitive datatypes are defined:------  "bool"  Boolean value (major type 7, additional information 20---    or 21).------  "uint"  An unsigned integer (major type 0).------  "nint"  A negative integer (major type 1).------  "int"  An unsigned integer or a negative integer.------  "float16"  A number representable as a half-precision float [IEEE754]---    (major type 7, additional information 25).------  "float32"  A number representable as a single-precision float---    [IEEE754] (major type 7, additional information 26).---------  "float64"  A number representable as a double-precision float---    [IEEE754] (major type 7, additional information 27).------  "float"  One of float16, float32, or float64.------  "bstr" or "bytes"  A byte string (major type 2).------  "tstr" or "text"  Text string (major type 3).------  (Note that there are no predefined names for arrays or maps; these---  are defined with the syntax given below.)-data PTerm-  = PTBool-  | PTUInt-  | PTNInt-  | PTInt-  | PTHalf-  | PTFloat-  | PTDouble-  | PTBytes-  | PTText-  | PTAny-  | PTNil-  | PTUndefined-  deriving (Eq, Generic, Ord, Show)+-- TODO switch to quasiquotes+cddlPostlude :: CDDL ParserStage+cddlPostlude =+  either (error . errorBundlePretty) id $+    parse+      pCDDL+      "<HARDCODED>"+      " any = # \+      \ uint = #0 \+      \ nint = #1 \+      \ int = uint / nint \+      \ \+      \ bstr = #2 \+      \ bytes = bstr \+      \ tstr = #3 \+      \ text = tstr \+      \ \+      \ tdate = #6.0(tstr) \+      \ time = #6.1(number) \+      \ number = int / float \+      \ biguint = #6.2(bstr) \+      \ bignint = #6.3(bstr) \+      \ bigint = biguint / bignint \+      \ integer = int / bigint \+      \ unsigned = uint / biguint \+      \ decfrac = #6.4([e10: int, m: integer]) \+      \ bigfloat = #6.5([e2: int, m: integer]) \+      \ eb64url = #6.21(any) \+      \ eb64legacy = #6.22(any) \+      \ eb16 = #6.23(any) \+      \ encoded-cbor = #6.24(bstr) \+      \ uri = #6.32(tstr) \+      \ b64url = #6.33(tstr) \+      \ b64legacy = #6.34(tstr) \+      \ regexp = #6.35(tstr) \+      \ mime-message = #6.36(tstr) \+      \ cbor-any = #6.55799(any) \+      \ float16 = #7.25 \+      \ float32 = #7.26 \+      \ float64 = #7.27 \+      \ float16-32 = float16 / float32 \+      \ float32-64 = float32 / float64 \+      \ float = float16-32 / float64 \+      \  \+      \ false = #7.20 \+      \ true = #7.21 \+      \ bool = false / true \+      \ nil = #7.22 \+      \ null = nil \+      \ undefined = #7.23" -instance Hashable PTerm+appendPostlude ::+  ( IndexMappable XXType2 ParserStage i+  , IndexMappable XTerm ParserStage i+  , IndexMappable XRule ParserStage i+  ) =>+  CDDL i -> CDDL i+appendPostlude cddl = appendRules cddl $ mapIndex <$> (r : rs)+  where+    CDDL r tls _ = cddlPostlude+    f (TopLevelRule x) = Just x+    f _ = Nothing+    rs = mapMaybe f tls
− src/Codec/CBOR/Cuddle/CDDL/Prelude.hs
@@ -1,61 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}--module Codec.CBOR.Cuddle.CDDL.Prelude (prependPrelude) where--import Codec.CBOR.Cuddle.CDDL (CDDL (..))-import Codec.CBOR.Cuddle.Parser (pCDDL)-import Text.Megaparsec (errorBundlePretty, parse)---- TODO switch to quasiquotes-cddlPrelude :: CDDL-cddlPrelude =-  either (error . errorBundlePretty) id $-    parse-      pCDDL-      "<HARDCODED>"-      " any = # \-      \ uint = #0 \-      \ nint = #1 \-      \ int = uint / nint \-      \ \-      \ bstr = #2 \-      \ bytes = bstr \-      \ tstr = #3 \-      \ text = tstr \-      \ \-      \ tdate = #6.0(tstr) \-      \ time = #6.1(number) \-      \ number = int / float \-      \ biguint = #6.2(bstr) \-      \ bignint = #6.3(bstr) \-      \ bigint = biguint / bignint \-      \ integer = int / bigint \-      \ unsigned = uint / biguint \-      \ decfrac = #6.4([e10: int, m: integer]) \-      \ bigfloat = #6.5([e2: int, m: integer]) \-      \ eb64url = #6.21(any) \-      \ eb64legacy = #6.22(any) \-      \ eb16 = #6.23(any) \-      \ encoded-cbor = #6.24(bstr) \-      \ uri = #6.32(tstr) \-      \ b64url = #6.33(tstr) \-      \ b64legacy = #6.34(tstr) \-      \ regexp = #6.35(tstr) \-      \ mime-message = #6.36(tstr) \-      \ cbor-any = #6.55799(any) \-      \ float16 = #7.25 \-      \ float32 = #7.26 \-      \ float64 = #7.27 \-      \ float16-32 = float16 / float32 \-      \ float32-64 = float32 / float64 \-      \ float = float16-32 / float64 \-      \  \-      \ false = #7.20 \-      \ true = #7.21 \-      \ bool = false / true \-      \ nil = #7.22 \-      \ null = nil \-      \ undefined = #7.23"--prependPrelude :: CDDL -> CDDL-prependPrelude = (cddlPrelude <>)
src/Codec/CBOR/Cuddle/CDDL/Resolve.hs view
@@ -2,7 +2,10 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE DerivingVia #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-} @@ -29,8 +32,9 @@   asMap,   buildMonoCTree,   fullResolveCDDL,-  MonoRef (..),   NameResolutionFailure (..),+  MonoReferenced,+  XXCTree (..), ) where @@ -41,142 +45,161 @@ import Capability.Sink (HasSink) import Capability.Source (HasSource) import Capability.State (HasState, MonadState (..), modify)-import Codec.CBOR.Cuddle.CDDL+import Codec.CBOR.Cuddle.CDDL as CDDL import Codec.CBOR.Cuddle.CDDL.CTree (-  CTree,-  CTreeRoot,-  CTreeRoot' (CTreeRoot),-  ParametrisedWith (..),+  CTree (..),+  CTreePhase,+  CTreeRoot (..),+  PTerm (..),+  XRule (..),+  XXCTree,+  XXType2 (..),+  foldCTree,  ) import Codec.CBOR.Cuddle.CDDL.CTree qualified as CTree-import Codec.CBOR.Cuddle.CDDL.Postlude (PTerm (..)) import Control.Monad.Except (ExceptT (..), runExceptT) import Control.Monad.Reader (Reader, ReaderT (..), runReader) import Control.Monad.State.Strict (StateT (..))-import Data.Functor.Identity (Identity (..)) import Data.Generics.Product import Data.Generics.Sum import Data.Hashable #if __GLASGOW_HASKELL__ < 910 import Data.List (foldl') #endif+import Codec.CBOR.Cuddle.CDDL.CBORGenerator (CBORGenerator)+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..)) import Data.List.NonEmpty qualified as NE import Data.Map.Strict qualified as Map import Data.Text qualified as T+import Data.Void (absurd) import GHC.Generics (Generic) import Optics.Core +data ProvidedParameters a = ProvidedParameters+  { parameters :: [Name]+  , underlying :: a+  }+  deriving (Generic, Functor, Show, Eq, Foldable, Traversable)++instance Hashable a => Hashable (ProvidedParameters a)+ -------------------------------------------------------------------------------- -- 1. Rule extensions -------------------------------------------------------------------------------- -type CDDLMap = Map.Map Name (Parametrised TypeOrGroup)--type Parametrised a = ParametrisedWith [Name] a+newtype PartialCTreeRoot i = PartialCTreeRoot (Map.Map Name (ProvidedParameters (CTree i)))+  deriving (Generic) -toParametrised :: a -> Maybe GenericParam -> Parametrised a-toParametrised a Nothing = Unparametrised a-toParametrised a (Just (GenericParam gps)) = Parametrised a (NE.toList gps)+type CDDLMap =+  Map.Map Name (ProvidedParameters (TypeOrGroup CTreePhase), Maybe CBORGenerator) -parameters :: Parametrised a -> [Name]-parameters (Unparametrised _) = mempty-parameters (Parametrised _ ps) = ps+toParametrised ::+  TypeOrGroup CTreePhase ->+  Maybe (GenericParameters CTreePhase) ->+  ProvidedParameters (TypeOrGroup CTreePhase)+toParametrised a Nothing = ProvidedParameters [] a+toParametrised a (Just (GenericParameters gps)) = ProvidedParameters (gpName <$> NE.toList gps) a -asMap :: CDDL -> CDDLMap+asMap :: CDDL CTreePhase -> CDDLMap asMap cddl = foldl' go Map.empty rules   where     rules = cddlTopLevel cddl-    go x (TopLevelComment _) = x+    go x (XXTopLevel _) = x     go x (TopLevelRule r) = assignOrExtend x r -    assignOrExtend :: CDDLMap -> Rule -> CDDLMap-    assignOrExtend m (Rule n gps assign tog _) = case assign of+    assignOrExtend :: CDDLMap -> Rule CTreePhase -> CDDLMap+    assignOrExtend m (Rule n gps assign tog (CTreeXRule g)) = case assign of       -- Equals assignment-      AssignEq -> Map.insert n (toParametrised tog gps) m-      AssignExt -> Map.alter (extend tog gps) n m+      AssignEq -> Map.insert n (toParametrised tog gps, g) m+      AssignExt ->+        Map.alter (extend tog gps) n m      extend ::-      TypeOrGroup ->-      Maybe GenericParam ->-      Maybe (Parametrised TypeOrGroup) ->-      Maybe (Parametrised TypeOrGroup)-    extend tog _gps (Just existing) = case (underlying existing, tog) of+      TypeOrGroup CTreePhase ->+      Maybe (GenericParameters CTreePhase) ->+      Maybe (ProvidedParameters (TypeOrGroup CTreePhase), Maybe CBORGenerator) ->+      Maybe (ProvidedParameters (TypeOrGroup CTreePhase), Maybe CBORGenerator)+    extend tog _gps (Just (existing, gen)) = case (underlying existing, tog) of       (TOGType _, TOGType (Type0 new)) ->         Just $-          existing-            & field @"underlying"-            % _Ctor @"TOGType"-            % _Ctor @"Type0"-            %~ (<> new)+          ( existing+              & field @"underlying"+              % _Ctor @"TOGType"+              % _Ctor @"Type0"+              %~ (<> new)+          , gen+          )       -- From the CDDL spec, I don't see how one is meant to extend a group.       -- According to the description, it's meant to add a group choice, but the       -- assignment to a group takes a 'GrpEntry', not a Group, and there is no       -- ability to add a choice. For now, we simply ignore attempt at       -- extension.-      (TOGGroup _, TOGGroup _new) -> Just existing+      (TOGGroup _, TOGGroup _new) -> Just (existing, gen)       (TOGType _, _) -> error "Attempting to extend a type with a group"       (TOGGroup _, _) -> error "Attempting to extend a group with a type"-    extend tog gps Nothing = Just $ toParametrised tog gps+    extend tog gps Nothing = Just (toParametrised tog gps, Nothing)  -------------------------------------------------------------------------------- -- 2. Conversion to CTree -------------------------------------------------------------------------------- --- | Indicates that an item may be referenced rather than defined.-data OrRef a-  = -- | The item is inlined directly-    It a-  | -- | Reference to another node with possible generic arguments supplied-    Ref Name [CTree.Node OrRef]-  deriving (Show, Functor)+type data OrReferenced -type RefCTree = CTreeRoot OrRef+data instance XXCTree OrReferenced+  = -- | Reference to another node with possible generic arguments supplied+    OrRef Name [CTree OrReferenced]+  | OGenerator CBORGenerator (CTree OrReferenced) -deriving instance Show (CTree OrRef)+type data OrReferencedDropGen -deriving instance Show (CTreeRoot OrRef)+data instance XXCTree OrReferencedDropGen = DGOrRef Name [CTree OrReferencedDropGen]+  deriving (Eq, Show) +instance IndexMappable CTree OrReferenced OrReferencedDropGen where+  mapIndex = foldCTree mapExt mapIndex+    where+      mapExt (OrRef n xs) = CTreeE . DGOrRef n $ mapIndex <$> xs+      mapExt (OGenerator _ x) = mapIndex x+ -- | Build a CTree incorporating references. -- -- This translation cannot fail.-buildRefCTree :: CDDLMap -> RefCTree-buildRefCTree rules = CTreeRoot $ fmap toCTreeRule rules+buildRefCTree :: CDDLMap -> PartialCTreeRoot OrReferenced+buildRefCTree rules = PartialCTreeRoot $ uncurry toCTreeRule <$> rules   where     toCTreeRule ::-      Parametrised TypeOrGroup ->-      ParametrisedWith [Name] (CTree.Node OrRef)-    toCTreeRule = fmap toCTreeTOG+      ProvidedParameters (TypeOrGroup CTreePhase) ->+      Maybe CBORGenerator ->+      ProvidedParameters (CTree OrReferenced)+    toCTreeRule params gen = fmap (maybe id (\g x -> CTreeE $ OGenerator g x) gen . toCTreeTOG) params -    toCTreeTOG :: TypeOrGroup -> CTree.Node OrRef+    toCTreeTOG :: TypeOrGroup CTreePhase -> CTree OrReferenced     toCTreeTOG (TOGType t0) = toCTreeT0 t0     toCTreeTOG (TOGGroup ge) = toCTreeGroupEntry ge -    toCTreeT0 :: Type0 -> CTree.Node OrRef+    toCTreeT0 :: Type0 CTreePhase -> CTree OrReferenced     toCTreeT0 (Type0 (t1 NE.:| [])) = toCTreeT1 t1-    toCTreeT0 (Type0 xs) = It . CTree.Choice $ toCTreeT1 <$> xs+    toCTreeT0 (Type0 xs) = CTree.Choice $ toCTreeT1 <$> xs -    toCTreeT1 :: Type1 -> CTree.Node OrRef+    toCTreeT1 :: Type1 CTreePhase -> CTree OrReferenced     toCTreeT1 (Type1 t2 Nothing _) = toCTreeT2 t2     toCTreeT1 (Type1 t2 (Just (op, t2')) _) = case op of       RangeOp bound ->-        It $-          CTree.Range-            { CTree.from = toCTreeT2 t2-            , CTree.to = toCTreeT2 t2'-            , CTree.inclusive = bound-            }+        CTree.Range+          { CTree.from = toCTreeT2 t2+          , CTree.to = toCTreeT2 t2'+          , CTree.inclusive = bound+          }       CtrlOp ctlop ->-        It $-          CTree.Control-            { CTree.op = ctlop-            , CTree.target = toCTreeT2 t2-            , CTree.controller = toCTreeT2 t2'-            }+        CTree.Control+          { CTree.op = ctlop+          , CTree.target = toCTreeT2 t2+          , CTree.controller = toCTreeT2 t2'+          } -    toCTreeT2 :: Type2 -> CTree.Node OrRef-    toCTreeT2 (T2Value v) = It $ CTree.Literal v-    toCTreeT2 (T2Name n garg) =-      Ref n (fromGenArgs garg)+    toCTreeT2 :: Type2 CTreePhase -> CTree OrReferenced+    toCTreeT2 (T2Value v) = CTree.Literal v+    toCTreeT2 (T2Name n garg) = CTreeE $ OrRef n (fromGenArgs garg)     toCTreeT2 (T2Group t0) =       -- This behaviour seems questionable, but I don't really see how better to       -- interpret the spec here.@@ -184,113 +207,107 @@     toCTreeT2 (T2Map g) = toCTreeMap g     toCTreeT2 (T2Array g) = toCTreeArray g     toCTreeT2 (T2Unwrapped n margs) =-      It . CTree.Unwrap $-        Ref n (fromGenArgs margs)+      CTree.Unwrap . CTreeE $+        OrRef n (fromGenArgs margs)     toCTreeT2 (T2Enum g) = toCTreeEnum g-    toCTreeT2 (T2EnumRef n margs) = Ref n $ fromGenArgs margs+    toCTreeT2 (T2EnumRef n margs) = CTreeE . OrRef n $ fromGenArgs margs     toCTreeT2 (T2Tag Nothing t0) =       -- Currently not validating tags       toCTreeT0 t0     toCTreeT2 (T2Tag (Just tag) t0) =-      It . CTree.Tag tag $ toCTreeT0 t0+      CTree.Tag tag $ toCTreeT0 t0     toCTreeT2 (T2DataItem 7 (Just mmin)) =       toCTreeDataItem mmin     toCTreeT2 (T2DataItem _maj _mmin) =       -- We don't validate numerical items yet-      It $ CTree.Postlude PTAny-    toCTreeT2 T2Any = It $ CTree.Postlude PTAny+      CTree.Postlude PTAny+    toCTreeT2 T2Any = CTree.Postlude PTAny+    toCTreeT2 (XXType2 (CTreeXXType2 v)) = absurd v      toCTreeDataItem 20 =-      It . CTree.Literal $ Value (VBool False) mempty+      CTree.Literal $ Value (VBool False) mempty     toCTreeDataItem 21 =-      It . CTree.Literal $ Value (VBool True) mempty+      CTree.Literal $ Value (VBool True) mempty     toCTreeDataItem 25 =-      It $ CTree.Postlude PTHalf+      CTree.Postlude PTHalf     toCTreeDataItem 26 =-      It $ CTree.Postlude PTFloat+      CTree.Postlude PTFloat     toCTreeDataItem 27 =-      It $ CTree.Postlude PTDouble+      CTree.Postlude PTDouble     toCTreeDataItem 23 =-      It $ CTree.Postlude PTUndefined+      CTree.Postlude PTUndefined     toCTreeDataItem _ =-      It $ CTree.Postlude PTAny+      CTree.Postlude PTAny -    toCTreeGroupEntry :: GroupEntry -> CTree.Node OrRef-    toCTreeGroupEntry (GroupEntry (Just occi) _ (GEType mmkey t0)) =-      It $-        CTree.Occur-          { CTree.item = toKVPair mmkey t0-          , CTree.occurs = occi-          }-    toCTreeGroupEntry (GroupEntry Nothing _ (GEType mmkey t0)) = toKVPair mmkey t0-    toCTreeGroupEntry (GroupEntry (Just occi) _ (GERef n margs)) =-      It $-        CTree.Occur-          { CTree.item = Ref n (fromGenArgs margs)-          , CTree.occurs = occi-          }-    toCTreeGroupEntry (GroupEntry Nothing _ (GERef n margs)) = Ref n (fromGenArgs margs)-    toCTreeGroupEntry (GroupEntry (Just occi) _ (GEGroup g)) =-      It $-        CTree.Occur-          { CTree.item = groupToGroup g-          , CTree.occurs = occi-          }-    toCTreeGroupEntry (GroupEntry Nothing _ (GEGroup g)) = groupToGroup g+    toCTreeGroupEntry :: GroupEntry CTreePhase -> CTree OrReferenced+    toCTreeGroupEntry (GroupEntry (Just occi) (GEType mmkey t0) _) =+      CTree.Occur+        { CTree.item = toKVPair mmkey t0+        , CTree.occurs = occi+        }+    toCTreeGroupEntry (GroupEntry Nothing (GEType mmkey t0) _) = toKVPair mmkey t0+    toCTreeGroupEntry (GroupEntry (Just occi) (GERef n margs) _) =+      CTree.Occur+        { CTree.item = CTreeE $ OrRef n (fromGenArgs margs)+        , CTree.occurs = occi+        }+    toCTreeGroupEntry (GroupEntry Nothing (GERef n margs) _) = CTreeE $ OrRef n (fromGenArgs margs)+    toCTreeGroupEntry (GroupEntry (Just occi) (GEGroup g) _) =+      CTree.Occur+        { CTree.item = groupToGroup g+        , CTree.occurs = occi+        }+    toCTreeGroupEntry (GroupEntry Nothing (GEGroup g) _) = groupToGroup g -    fromGenArgs :: Maybe GenericArg -> [CTree.Node OrRef]+    fromGenArgs :: Maybe (GenericArg CTreePhase) -> [CTree OrReferenced]     fromGenArgs = maybe [] (\(GenericArg xs) -> NE.toList $ fmap toCTreeT1 xs)      -- Interpret a group as an enumeration. Note that we float out the     -- choice options-    toCTreeEnum :: Group -> CTree.Node OrRef-    toCTreeEnum (Group (a NE.:| [])) =-      It . CTree.Enum . It . CTree.Group $ toCTreeGroupEntry <$> gcGroupEntries a-    toCTreeEnum (Group xs) =-      It . CTree.Choice $-        It . CTree.Enum . It . CTree.Group . fmap toCTreeGroupEntry <$> groupEntries+    toCTreeEnum :: Group CTreePhase -> CTree OrReferenced+    toCTreeEnum (CDDL.Group (a NE.:| [])) =+      CTree.Enum . CTree.Group $ toCTreeGroupEntry <$> gcGroupEntries a+    toCTreeEnum (CDDL.Group xs) =+      CTree.Choice $ CTree.Enum . CTree.Group . fmap toCTreeGroupEntry <$> groupEntries       where         groupEntries = fmap gcGroupEntries xs      -- Embed a group in another group, again floating out the choice options-    groupToGroup :: Group -> CTree.Node OrRef-    groupToGroup (Group (a NE.:| [])) =-      It . CTree.Group $ fmap toCTreeGroupEntry (gcGroupEntries a)-    groupToGroup (Group xs) =-      It . CTree.Choice $-        fmap (It . CTree.Group . fmap toCTreeGroupEntry) (gcGroupEntries <$> xs)+    groupToGroup :: Group CTreePhase -> CTree OrReferenced+    groupToGroup (CDDL.Group (a NE.:| [])) =+      CTree.Group $ fmap toCTreeGroupEntry (gcGroupEntries a)+    groupToGroup (CDDL.Group xs) =+      CTree.Choice $ fmap (CTree.Group . fmap toCTreeGroupEntry) (gcGroupEntries <$> xs) -    toKVPair :: Maybe MemberKey -> Type0 -> CTree.Node OrRef+    toKVPair :: Maybe (MemberKey CTreePhase) -> Type0 CTreePhase -> CTree OrReferenced     toKVPair Nothing t0 = toCTreeT0 t0     toKVPair (Just mkey) t0 =-      It $-        CTree.KV-          { CTree.key = toCTreeMemberKey mkey-          , CTree.value = toCTreeT0 t0-          , -- TODO Handle cut semantics-            CTree.cut = False-          }+      CTree.KV+        { CTree.key = toCTreeMemberKey mkey+        , CTree.value = toCTreeT0 t0+        , -- TODO Handle cut semantics+          CTree.cut = False+        }      -- Interpret a group as a map. Note that we float out the choice options-    toCTreeMap :: Group -> CTree.Node OrRef-    toCTreeMap (Group (a NE.:| [])) = It . CTree.Map $ fmap toCTreeGroupEntry (gcGroupEntries a)-    toCTreeMap (Group xs) =-      It-        . CTree.Choice-        $ fmap (It . CTree.Map . fmap toCTreeGroupEntry) (gcGroupEntries <$> xs)+    toCTreeMap :: Group CTreePhase -> CTree OrReferenced+    toCTreeMap (CDDL.Group (a NE.:| [])) = CTree.Map $ fmap toCTreeGroupEntry (gcGroupEntries a)+    toCTreeMap (CDDL.Group xs) =+      CTree.Choice $+        fmap (CTree.Map . fmap toCTreeGroupEntry) (gcGroupEntries <$> xs)      -- Interpret a group as an array. Note that we float out the choice     -- options-    toCTreeArray :: Group -> CTree.Node OrRef-    toCTreeArray (Group (a NE.:| [])) =-      It . CTree.Array $ fmap toCTreeGroupEntry (gcGroupEntries a)-    toCTreeArray (Group xs) =-      It . CTree.Choice $-        fmap (It . CTree.Array . fmap toCTreeGroupEntry) (gcGroupEntries <$> xs)+    toCTreeArray :: Group CTreePhase -> CTree OrReferenced+    toCTreeArray (CDDL.Group (a NE.:| [])) =+      CTree.Array $ fmap toCTreeGroupEntry (gcGroupEntries a)+    toCTreeArray (CDDL.Group xs) =+      CTree.Choice $+        fmap (CTree.Array . fmap toCTreeGroupEntry) (gcGroupEntries <$> xs) -    toCTreeMemberKey :: MemberKey -> CTree.Node OrRef-    toCTreeMemberKey (MKValue v) = It $ CTree.Literal v-    toCTreeMemberKey (MKBareword (Name n _)) = It $ CTree.Literal (Value (VText n) mempty)+    toCTreeMemberKey :: MemberKey CTreePhase -> CTree OrReferenced+    toCTreeMemberKey (MKValue v) = CTree.Literal v+    toCTreeMemberKey (MKBareword n) = CTree.Literal (Value (VText $ unName n) mempty)     toCTreeMemberKey (MKType t1) = toCTreeT1 t1  --------------------------------------------------------------------------------@@ -300,116 +317,112 @@ data NameResolutionFailure   = UnboundReference Name   | MismatchingArgs Name [Name]-  | ArgsToPostlude PTerm [CTree.Node OrRef]-  deriving (Show)+  | ArgsToPostlude PTerm [CTree OrReferencedDropGen]+  deriving (Show, Eq)  postludeBinding :: Map.Map Name PTerm postludeBinding =   Map.fromList-    [ (Name "bool" mempty, PTBool)-    , (Name "uint" mempty, PTUInt)-    , (Name "nint" mempty, PTNInt)-    , (Name "int" mempty, PTInt)-    , (Name "half" mempty, PTHalf)-    , (Name "float" mempty, PTFloat)-    , (Name "double" mempty, PTDouble)-    , (Name "bytes" mempty, PTBytes)-    , (Name "bstr" mempty, PTBytes)-    , (Name "text" mempty, PTText)-    , (Name "tstr" mempty, PTText)-    , (Name "any" mempty, PTAny)-    , (Name "nil" mempty, PTNil)-    , (Name "null" mempty, PTNil)+    [ ("bool", PTBool)+    , ("uint", PTUInt)+    , ("nint", PTNInt)+    , ("int", PTInt)+    , ("half", PTHalf)+    , ("float", PTFloat)+    , ("double", PTDouble)+    , ("bytes", PTBytes)+    , ("bstr", PTBytes)+    , ("text", PTText)+    , ("tstr", PTText)+    , ("any", PTAny)+    , ("nil", PTNil)+    , ("null", PTNil)     ] -data BindingEnv poly f g = BindingEnv-  { global :: Map.Map Name (poly (CTree.Node f))+data BindingEnv i j = BindingEnv+  { global :: Map.Map (Name) (ProvidedParameters (CTree i))   -- ^ Global name bindings via 'RuleDef'-  , local :: Map.Map Name (CTree.Node g)+  , local :: Map.Map (Name) (CTree j)   -- ^ Local bindings for generic parameters   }   deriving (Generic) -data DistRef a-  = DIt a-  | -- | Reference to a generic parameter-    GenericRef Name-  | -- | Reference to a rule definition, possibly with generic arguments-    RuleRef Name [CTree.Node DistRef]-  deriving (Eq, Generic, Functor, Show)+type data DistReferenced -instance Hashable a => Hashable (DistRef a)+data DistRef i+  = -- | Reference to a generic parameter+    GenericRef (Name)+  | -- | Reference to a rule definition, possibly with generic arguments+    RuleRef (Name) [CTree i]+  deriving (Generic) -deriving instance Show (CTree DistRef)+deriving instance Eq (CTree.Node i) => Eq (DistRef i) -deriving instance Eq (CTree DistRef)+deriving instance Show (CTree.Node i) => Show (DistRef i) -instance Hashable (CTree DistRef)+instance Hashable (CTree.Node i) => Hashable (DistRef i) -deriving instance Show (CTreeRoot DistRef)+data instance XXCTree DistReferenced+  = DRef (DistRef DistReferenced)+  | DGenerator CBORGenerator (CTree DistReferenced) -deriving instance Eq (CTreeRoot DistRef)+type data DistReferencedNoGen -instance Hashable (CTreeRoot DistRef)+newtype instance XXCTree DistReferencedNoGen = DHRef (DistRef DistReferencedNoGen)+  deriving (Eq, Hashable)  resolveRef ::-  BindingEnv (ParametrisedWith [Name]) OrRef OrRef ->-  CTree.Node OrRef ->-  Either NameResolutionFailure (DistRef (CTree DistRef))-resolveRef env (It a) = DIt <$> resolveCTree env a-resolveRef env (Ref n args) = case Map.lookup n postludeBinding of+  BindingEnv OrReferenced OrReferenced ->+  CTree.Node OrReferenced ->+  Either NameResolutionFailure (CTree DistReferenced)+resolveRef env (OrRef n args) = case Map.lookup n postludeBinding of   Just pterm -> case args of-    [] -> Right . DIt $ CTree.Postlude pterm-    xs -> Left $ ArgsToPostlude pterm xs+    [] -> Right $ CTree.Postlude pterm+    xs -> Left . ArgsToPostlude pterm $ mapIndex <$> xs   Nothing -> case Map.lookup n (global env) of     Just (parameters -> params') ->       if length params' == length args         then           let localBinds = Map.fromList $ zip params' args-              newEnv = env & field @"local" %~ Map.union localBinds-           in RuleRef n <$> traverse (resolveRef newEnv) args+              newEnv = env & #local %~ Map.union localBinds+           in CTreeE . DRef . RuleRef n <$> traverse (resolveCTree newEnv) args         else Left $ MismatchingArgs n params'     Nothing -> case Map.lookup n (local env) of-      Just _ -> Right $ GenericRef n+      Just _ -> Right . CTreeE . DRef $ GenericRef n       Nothing -> Left $ UnboundReference n+resolveRef env (OGenerator g x) = CTreeE . DGenerator g <$> resolveCTree env x  resolveCTree ::-  BindingEnv (ParametrisedWith [Name]) OrRef OrRef ->-  CTree OrRef ->-  Either NameResolutionFailure (CTree DistRef)-resolveCTree e = CTree.traverseCTree (resolveRef e)+  BindingEnv OrReferenced OrReferenced ->+  CTree OrReferenced ->+  Either NameResolutionFailure (CTree DistReferenced)+resolveCTree e = CTree.traverseCTree (resolveRef e) (resolveCTree e)  buildResolvedCTree ::-  CTreeRoot OrRef ->-  Either NameResolutionFailure (CTreeRoot DistRef)-buildResolvedCTree (CTreeRoot ct) = CTreeRoot <$> traverse go ct+  PartialCTreeRoot OrReferenced ->+  Either NameResolutionFailure (PartialCTreeRoot DistReferenced)+buildResolvedCTree (PartialCTreeRoot ct) = PartialCTreeRoot <$> traverse go ct   where-    initBindingEnv = BindingEnv ct mempty     go pn =       let args = parameters pn-          localBinds = Map.fromList $ zip args (flip Ref [] <$> args)-          env = initBindingEnv & field @"local" %~ Map.union localBinds-       in traverse (resolveRef env) pn+          localBinds = Map.fromList $ zip args (CTreeE . flip OrRef [] <$> args)+          env = BindingEnv @OrReferenced @OrReferenced ct localBinds+       in traverse (resolveCTree env) pn  -------------------------------------------------------------------------------- -- 4. Monomorphisation -------------------------------------------------------------------------------- -data MonoRef a-  = MIt a-  | MRuleRef Name-  deriving (Functor, Show)--deriving instance Show (CTree MonoRef)+type data MonoReferenced -deriving instance-  Show (poly (CTree.Node MonoRef)) =>-  Show (CTreeRoot' poly MonoRef)+data instance XXCTree MonoReferenced+  = MRuleRef Name+  | MGenerator CBORGenerator (CTree MonoReferenced) -type MonoEnv = BindingEnv (ParametrisedWith [Name]) DistRef MonoRef+type MonoEnv = BindingEnv DistReferenced MonoReferenced  -- | We introduce additional bindings in the state-type MonoState = Map.Map Name (CTree.Node MonoRef)+type MonoState = Map.Map Name (CTree MonoReferenced)  -- | Monad to run the monomorphisation process. We need some additional -- capabilities for this, so 'Either' doesn't fully cut it anymore.@@ -431,10 +444,10 @@   deriving     ( HasSource         "local"-        (Map.Map Name (CTree.Node MonoRef))+        (Map.Map (Name) (CTree MonoReferenced))     , HasReader         "local"-        (Map.Map Name (CTree.Node MonoRef))+        (Map.Map (Name) (CTree MonoReferenced))     )     via Field           "local"@@ -448,10 +461,10 @@   deriving     ( HasSource         "global"-        (Map.Map Name (ParametrisedWith [Name] (CTree.Node DistRef)))+        (Map.Map (Name) (ProvidedParameters (CTree DistReferenced)))     , HasReader         "global"-        (Map.Map Name (ParametrisedWith [Name] (CTree.Node DistRef)))+        (Map.Map (Name) (ProvidedParameters (CTree DistReferenced)))     )     via Field           "global"@@ -477,87 +490,87 @@ throwNR = throw @"nameResolution"  -- | Synthesize a monomorphic rule definition, returning the name-synthMono :: Name -> [CTree.Node DistRef] -> MonoM Name-synthMono n@(Name origName _) args =-  let fresh =+synthMono :: Name -> [CTree DistReferenced] -> MonoM Name+synthMono origName args =+  let dropGenerator = fmap $ mapIndex @_ @_ @DistReferencedNoGen+      fresh =         -- % is not a valid CBOR name, so this should avoid conflict-        Name (origName <> "%" <> T.pack (show $ hash args)) mempty+        origName <> "%" <> Name (T.pack (show . hash $ dropGenerator args))    in do         -- Lookup the original name in the global bindings         globalBinds <- ask @"global"-        case Map.lookup n globalBinds of-          Just (Unparametrised _) -> throwNR $ MismatchingArgs n []-          Just (Parametrised r params') ->+        case Map.lookup origName globalBinds of+          Just (ProvidedParameters [] _) -> throwNR $ MismatchingArgs origName []+          Just (ProvidedParameters params' r) ->             if length params' == length args               then do-                rargs <- traverse resolveGenericRef args+                rargs <- traverse resolveGenericCTree args                 let localBinds = Map.fromList $ zip params' rargs                 Reader.local @"local" (Map.union localBinds) $ do-                  foo <- resolveGenericRef r+                  foo <- resolveGenericCTree r                   modify @"synth" $ Map.insert fresh foo-              else throwNR $ MismatchingArgs n params'-          Nothing -> throwNR $ UnboundReference n+              else throwNR $ MismatchingArgs origName params'+          Nothing -> throwNR $ UnboundReference origName         pure fresh  resolveGenericRef ::-  CTree.Node DistRef ->-  MonoM (MonoRef (CTree MonoRef))-resolveGenericRef (DIt a) = MIt <$> resolveGenericCTree a-resolveGenericRef (RuleRef n margs) =-  case margs of-    [] -> pure $ MRuleRef n-    args -> do-      fresh <- synthMono n args-      pure $ MRuleRef fresh-resolveGenericRef (GenericRef n) = do+  CTree.Node DistReferenced ->+  MonoM (CTree MonoReferenced)+resolveGenericRef (DRef (RuleRef n [])) = pure . CTreeE $ MRuleRef n+resolveGenericRef (DRef (RuleRef n args)) = do+  fresh <- synthMono n args+  pure . CTreeE $ MRuleRef fresh+resolveGenericRef (DRef (GenericRef n)) = do   localBinds <- ask @"local"   case Map.lookup n localBinds of     Just node -> pure node     Nothing -> throwNR $ UnboundReference n+resolveGenericRef (DGenerator g x) = CTreeE . MGenerator g <$> resolveGenericCTree x  resolveGenericCTree ::-  CTree DistRef ->-  MonoM (CTree MonoRef)-resolveGenericCTree = CTree.traverseCTree resolveGenericRef+  CTree DistReferenced ->+  MonoM (CTree MonoReferenced)+resolveGenericCTree = CTree.traverseCTree resolveGenericRef resolveGenericCTree  -- | Monomorphise the CTree -- -- Concretely, for each reference in the tree to a generic rule, we synthesize a -- new monomorphic instance of that rule at top-level with the correct -- parameters applied.-monoCTree ::-  CTreeRoot' Identity DistRef ->-  MonoM (CTreeRoot' Identity MonoRef)-monoCTree (CTreeRoot ct) = CTreeRoot <$> traverse go ct-  where-    go = traverse resolveGenericRef- buildMonoCTree ::-  CTreeRoot DistRef ->-  Either NameResolutionFailure (CTreeRoot' Identity MonoRef)-buildMonoCTree (CTreeRoot ct) = do-  let a1 = runExceptT $ runMonoM (monoCTree monoC)+  PartialCTreeRoot DistReferenced ->+  Either NameResolutionFailure (CTreeRoot MonoReferenced)+buildMonoCTree (PartialCTreeRoot ct) = do+  let a1 = runExceptT $ runMonoM (traverse resolveGenericCTree monoC)       a2 = runStateT a1 mempty-      (er, newBindings) = runReader a2 initBindingEnv-  CTreeRoot r <- er-  pure . CTreeRoot $ Map.union r $ fmap Identity newBindings+      (r, newBindings) = runReader a2 initBindingEnv+  CTreeRoot . (`Map.union` newBindings) <$> r   where     initBindingEnv = BindingEnv ct mempty     monoC =-      CTreeRoot $-        Map.mapMaybe-          ( \case-              Unparametrised f -> Just $ Identity f-              Parametrised _ _ -> Nothing-          )-          ct+      Map.mapMaybe+        ( \case+            ProvidedParameters [] f -> Just f+            _ -> Nothing+        )+        ct  -------------------------------------------------------------------------------- -- Combined resolution -------------------------------------------------------------------------------- -fullResolveCDDL :: CDDL -> Either NameResolutionFailure (CTreeRoot' Identity MonoRef)+fullResolveCDDL :: CDDL CTreePhase -> Either NameResolutionFailure (CTreeRoot MonoReferenced) fullResolveCDDL cddl = do   let refCTree = buildRefCTree (asMap cddl)   rCTree <- buildResolvedCTree refCTree   buildMonoCTree rCTree++instance IndexMappable CTree DistReferenced DistReferencedNoGen where+  mapIndex = foldCTree mapExt mapIndex+    where+      mapExt (DRef x) = CTreeE . DHRef $ mapIndex x+      mapExt (DGenerator _ x) = mapIndex x++instance IndexMappable DistRef DistReferenced DistReferencedNoGen where+  mapIndex (GenericRef n) = GenericRef n+  mapIndex (RuleRef n args) = RuleRef n $ mapIndex <$> args
src/Codec/CBOR/Cuddle/Comments.hs view
@@ -26,6 +26,7 @@ import Data.String (IsString (..)) import Data.Text qualified as T import Data.TreeDiff (ToExpr)+import Data.Void (Void, absurd) import Data.Word (Word16, Word32, Word64, Word8) import GHC.Generics (Generic (..), K1 (..), M1 (..), U1 (..), V1, (:*:) (..), (:+:) (..)) import Optics.Core (Lens', lens, view, (%~), (&), (.~), (^.))@@ -84,6 +85,10 @@   collectComments :: a -> [Comment]   default collectComments :: (Generic a, GCollectComments (Rep a)) => a -> [Comment]   collectComments = collectCommentsG . from++instance CollectComments Void where collectComments = absurd++instance CollectComments () where collectComments = mempty  instance CollectComments a => CollectComments (Maybe a) where   collectComments Nothing = []
src/Codec/CBOR/Cuddle/Huddle.hs view
@@ -2,7 +2,10 @@ {-# LANGUAGE DuplicateRecordFields #-} {-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TypeData #-} {-# LANGUAGE TypeFamilies #-}  -- | Module for building CDDL in Haskell@@ -16,11 +19,19 @@   Huddle,   HuddleItem (..),   huddleAugment,-  Rule,-  Named,+  Rule (..),+  GroupDef (..),   IsType0 (..),   Value (..), +  -- * AST extensions+  HuddleStage,+  C.XCddl (..),+  C.XTerm (..),+  C.XRule (..),+  C.XXTopLevel (..),+  C.XXType2 (..),+   -- * Rules and assignment   (=:=),   (=:~),@@ -55,6 +66,7 @@   bstr,   int,   text,+  bool,    -- * Ctl operators   IsConstrainable,@@ -71,12 +83,18 @@    -- * Generics   GRef,-  GRuleDef,-  GRuleCall,+  GRuleDef (..),+  GRuleCall (..),   binding,   binding2,   callToDef, +  -- * Generators+  withGenerator,++  -- * Name+  HasName (..),+   -- * Conversion to CDDL   collectFrom,   collectFromInit,@@ -85,20 +103,24 @@ ) where -import Codec.CBOR.Cuddle.CDDL (CDDL)+import Codec.CBOR.Cuddle.CDDL (CDDL, GenericParameter (..), HasName (..), Name (..), XRule) import Codec.CBOR.Cuddle.CDDL qualified as C+import Codec.CBOR.Cuddle.CDDL.CBORGenerator (CBORGenerator (..), HasGenerator (..), WrappedTerm) import Codec.CBOR.Cuddle.CDDL.CtlOp qualified as CtlOp+import Codec.CBOR.Cuddle.Comments (Comment (..), HasComment (..)) import Codec.CBOR.Cuddle.Comments qualified as C import Control.Monad (when)-import Control.Monad.State (MonadState (get), execState, modify)+import Control.Monad.State (MonadState (get), State, execState, modify) import Data.ByteString (ByteString)+import Data.ByteString.Base16 qualified as Base16 import Data.Default.Class (Default (..)) import Data.Function (on)-import Data.Generics.Product (HasField' (field'), field, getField)+import Data.Generics.Product (field, getField) import Data.List qualified as L import Data.List.NonEmpty qualified as NE import Data.Map.Ordered.Strict (OMap, (|<>)) import Data.Map.Ordered.Strict qualified as OMap+import Data.Set qualified as Set import Data.String (IsString (fromString)) import Data.Text qualified as T import Data.Tuple.Optics (Field2 (..))@@ -106,45 +128,90 @@ import Data.Word (Word64) import GHC.Exts (IsList (Item, fromList, toList)) import GHC.Generics (Generic)-import Optics.Core (lens, view, (%~), (&), (.~), (^.))+import Optics.Core (lens, view, (%), (%~), (&))+import Optics.Core qualified as L+import System.Random.Stateful (StatefulGen) import Prelude hiding ((/)) +type data HuddleStage++newtype instance C.XTerm HuddleStage = HuddleXTerm C.Comment+  deriving (Generic, Semigroup, Monoid, Show, Eq)++newtype instance C.XCddl HuddleStage = HuddleXCddl [C.Comment]+  deriving (Generic, Semigroup, Monoid, Show, Eq)++data instance C.XRule HuddleStage = HuddleXRule+  { hxrComment :: C.Comment+  , hxrGenerator :: Maybe CBORGenerator+  }+  deriving (Generic)++instance HasComment (C.XRule HuddleStage) where+  commentL = #hxrComment++instance Default (XRule HuddleStage)++newtype instance C.XXTopLevel HuddleStage = HuddleXXTopLevel C.Comment+  deriving (Generic, Semigroup, Monoid, Show, Eq)++newtype instance C.XXType2 HuddleStage = HuddleXXType2 Void+  deriving (Generic, Semigroup, Show, Eq)+ data Named a = Named-  { name :: T.Text+  { name :: Name   , value :: a-  , description :: Maybe T.Text   }-  deriving (Functor, Generic)+  deriving (Functor, Generic, Show)  -- | Add a description to a rule or group entry, to be included as a comment.-comment :: HasField' "description" a (Maybe T.Text) => T.Text -> a -> a-comment desc n = n & field' @"description" .~ Just desc+comment :: HasComment a => Comment -> a -> a+comment desc n = n & commentL %~ (<> desc) -instance Show (Named a) where-  show (Named n _ _) = T.unpack n+data Rule = Rule+  { ruleDefinition :: Named Type0+  , ruleExtra :: XRule HuddleStage+  }+  deriving (Generic) -type Rule = Named Type0+instance HasGenerator Rule where+  generatorL = #ruleExtra % #hxrGenerator +instance HasComment Rule where+  commentL = #ruleExtra % #hxrComment++instance HasName Rule where+  getName = getName . ruleDefinition++data GroupDef = GroupDef {gdNamed :: Named Group, gdExt :: XRule HuddleStage}+  deriving (Generic)++instance HasComment GroupDef where+  commentL = #gdExt % commentL++instance HasName GroupDef where+  getName = getName . gdNamed+ data HuddleItem   = HIRule Rule   | HIGRule GRuleDef-  | HIGroup (Named Group)-  deriving (Generic, Show)+  | HIGroup GroupDef+  deriving (Generic)  -- | Top-level Huddle type is a list of rules. data Huddle = Huddle   { roots :: [Rule]   -- ^ Root elements-  , items :: OMap T.Text HuddleItem+  , items :: OMap Name HuddleItem   }-  deriving (Generic, Show)+  deriving (Generic)  -- | Joins two `Huddle` values with a left-bias. This means that this function -- is not symmetric and that any rules that are present in both prefer the -- definition from the `Huddle` value on the left. huddleAugment :: Huddle -> Huddle -> Huddle huddleAugment (Huddle rootsL itemsL) (Huddle rootsR itemsR) =-  Huddle (L.nubBy ((==) `on` name) $ rootsL <> rootsR) (itemsL |<> itemsR)+  Huddle (L.nubBy ((==) `on` name . ruleDefinition) $ rootsL <> rootsR) (itemsL |<> itemsR)  -- | This semigroup instance: --   - Takes takes the roots from the RHS unless they are empty, in which case@@ -169,8 +236,8 @@ instance IsList Huddle where   type Item Huddle = Rule   fromList [] = Huddle mempty OMap.empty-  fromList (x : xs) =-    (field @"items" %~ (OMap.|> (x ^. field @"name", HIRule x))) $ fromList xs+  fromList (r@(Rule x _) : xs) =+    (#items %~ (OMap.|> (getName x, HIRule r))) $ fromList xs    toList = const [] @@ -193,7 +260,6 @@ data Key   = LiteralKey Literal   | TypeKey Type2-  deriving (Show)  -- | Instance for the very general case where we use text keys instance IsString Key where@@ -214,13 +280,12 @@   , quantifier :: Occurs   , meDescription :: C.Comment   }-  deriving (Generic, Show)+  deriving (Generic)  instance C.HasComment MapEntry where   commentL = lens meDescription (\x y -> x {meDescription = y})  newtype MapChoice = MapChoice {unMapChoice :: [MapEntry]}-  deriving (Show)  instance IsList MapChoice where   type Item MapChoice = MapEntry@@ -238,7 +303,7 @@   , quantifier :: Occurs   , aeDescription :: C.Comment   }-  deriving (Generic, Show)+  deriving (Generic)  instance C.HasComment ArrayEntry where   commentL = lens aeDescription (\x y -> x {aeDescription = y})@@ -260,7 +325,6 @@   { unArrayChoice :: [ArrayEntry]   , acComment :: C.Comment   }-  deriving (Show)  instance Semigroup ArrayChoice where   ArrayChoice x xc <> ArrayChoice y yc = ArrayChoice (x <> y) (xc <> yc)@@ -279,8 +343,8 @@  type Array = Choice ArrayChoice -newtype Group = Group {unGroup :: [ArrayEntry]}-  deriving (Show, Monoid, Semigroup)+newtype Group = Group {_unGroup :: [ArrayEntry]}+  deriving (Monoid, Semigroup)  instance IsList Group where   type Item Group = ArrayEntry@@ -294,13 +358,12 @@   | T2Map Map   | T2Array Array   | T2Tagged (Tagged Type0)-  | T2Ref (Named Type0)-  | T2Group (Named Group)+  | T2Ref Rule+  | T2Group GroupDef   | -- | Call to a generic rule, binding arguments     T2Generic GRuleCall   | -- | Reference to a generic parameter within the body of the definition     T2GenericRef GRef-  deriving (Show)  type Type0 = Choice Type2 @@ -362,17 +425,23 @@   LFloat :: Float -> LiteralVariant   LDouble :: Double -> LiteralVariant   LBytes :: ByteString -> LiteralVariant+  LBool :: Bool -> LiteralVariant   deriving (Show)  int :: Integer -> Literal int = inferInteger  bstr :: ByteString -> Literal-bstr x = Literal (LBytes x) mempty+bstr x = case Base16.decode x of+  Right bs -> Literal (LBytes bs) mempty+  Left e -> error $ "`bstr` expects a hex string, but received " <> show x <> " instead\n" <> e  text :: T.Text -> Literal text x = Literal (LText x) mempty +bool :: Bool -> Literal+bool x = Literal (LBool x) mempty+ inferInteger :: Integer -> Literal inferInteger i   | i >= 0 && i < fromIntegral (maxBound @Word64) = Literal (LInt (fromInteger i)) mempty@@ -390,7 +459,6 @@   = CValue (Value a)   | CRef (AnyRef a)   | CGRef GRef-  deriving (Show)  -- | Uninhabited type used as marker for the type of thing a CRef sizes data CRefType@@ -403,17 +471,15 @@ data Constrained where   Constrained ::     forall a.-    { value :: Constrainable a-    , constraint :: ValueConstraint a-    , refs :: [Rule]+    { _value :: Constrainable a+    , _constraint :: ValueConstraint a+    , _refs :: [Rule]     -- ^ Sometimes constraints reference rules. In this case we need to     -- collect the references in order to traverse them when collecting all     -- relevant rules.     } ->     Constrained -deriving instance Show Constrained- class IsConstrainable a x | a -> x where   toConstrainable :: a -> Constrainable x @@ -432,13 +498,10 @@ -- | A constraint on a 'Value' is something applied via CtlOp or RangeOp on a -- Type2, forming a Type1. data ValueConstraint a = ValueConstraint-  { applyConstraint :: C.Type2 -> C.Type1+  { applyConstraint :: C.Type2 HuddleStage -> C.Type1 HuddleStage   , showConstraint :: String   } -instance Show (ValueConstraint a) where-  show = showConstraint- instance Default (ValueConstraint a) where   def =     ValueConstraint@@ -462,7 +525,7 @@  -- | Things which can be used on the RHS of the '.size' operator. class IsSize a where-  sizeAsCDDL :: a -> C.Type2+  sizeAsCDDL :: a -> C.Type2 HuddleStage   sizeAsString :: a -> String  instance IsSize Word where@@ -516,16 +579,16 @@ instance IsCborable GRef  cbor :: (IsCborable b, IsConstrainable c b) => c -> Rule -> Constrained-cbor v r@(Named n _ _) =+cbor v r@(Rule (Named n _) _) =   Constrained     (toConstrainable v)     ValueConstraint       { applyConstraint = \t2 ->           C.Type1             t2-            (Just (C.CtrlOp CtlOp.Cbor, C.T2Name (C.Name n mempty) Nothing))+            (Just (C.CtrlOp CtlOp.Cbor, C.T2Name n Nothing))             mempty-      , showConstraint = ".cbor " <> T.unpack n+      , showConstraint = ".cbor " <> T.unpack (unName n)       }     [r] @@ -553,7 +616,6 @@ data RangeBound   = RangeBoundLiteral Literal   | RangeBoundRef (Named Type0)-  deriving (Show)  class IsRangeBound a where   toRangeBound :: a -> RangeBound@@ -567,15 +629,17 @@ instance IsRangeBound (Named Type0) where   toRangeBound = RangeBoundRef +instance IsRangeBound Rule where+  toRangeBound (Rule x _) = toRangeBound x+ data Ranged where   Ranged ::-    { lb :: RangeBound-    , ub :: RangeBound-    , bounds :: C.RangeBound+    { _lb :: RangeBound+    , _ub :: RangeBound+    , _bounds :: C.RangeBound     } ->     Ranged   Unranged :: Literal -> Ranged-  deriving (Show)  -- | Establish a closed range bound. (...) :: (IsRangeBound a, IsRangeBound b) => a -> b -> Ranged@@ -637,7 +701,7 @@ instance IsType0 (Value a) where   toType0 = NoChoice . T2Constrained . unconstrained -instance IsType0 (Named Group) where+instance IsType0 GroupDef where   toType0 = NoChoice . T2Group  instance IsType0 GRuleCall where@@ -654,7 +718,8 @@   toType0 (HIGroup g) = toType0 g   toType0 (HIGRule g) =     error $-      "Attempt to reference generic rule from HuddleItem not supported: " <> show g+      "Attempt to reference generic rule from HuddleItem not supported: "+        <> T.unpack (unName (getName g))  class CanQuantify a where   -- | Apply a lower bound@@ -719,13 +784,13 @@ infixl 8 ==>  -- | Assign a rule-(=:=) :: IsType0 a => T.Text -> a -> Rule-n =:= b = Named n (toType0 b) Nothing+(=:=) :: IsType0 a => Name -> a -> Rule+n =:= b = Rule (Named n (toType0 b)) def  infixl 1 =:= -(=:~) :: T.Text -> Group -> Named Group-n =:~ b = Named n b Nothing+(=:~) :: Name -> Group -> GroupDef+n =:~ b = GroupDef (Named n b) def  infixl 1 =:~ @@ -790,7 +855,7 @@ instance IsChoosable (Value a) Type2 where   toChoice = toChoice . T2Constrained . unconstrained -instance IsChoosable (Named Group) Type2 where+instance IsChoosable GroupDef Type2 where   toChoice = toChoice . T2Group  instance IsChoosable (Seal Array) Type2 where@@ -918,12 +983,20 @@   { args :: NE.NonEmpty a   , body :: Type0   }-  deriving (Show) -type GRuleCall = Named (GRule Type2)+data GRuleCall = GRuleCall+  { grcBody :: Named (GRule Type2)+  , grcExtra :: XRule HuddleStage+  } -type GRuleDef = Named (GRule GRef)+data GRuleDef = GRuleDef+  { grdBody :: Named (GRule GRef)+  , grdExtra :: XRule HuddleStage+  } +instance HasName GRuleDef where+  getName = getName . grdBody+ callToDef :: GRule Type2 -> GRule GRef callToDef gr = gr {args = refs}   where@@ -939,15 +1012,17 @@ -- | Bind a single variable into a generic call binding :: IsType0 t0 => (GRef -> Rule) -> t0 -> GRuleCall binding fRule t0 =-  Named-    (name rule)-    GRule-      { args = t2 NE.:| []-      , body = getField @"value" rule-      }-    Nothing+  GRuleCall+    ( Named+        (name ruleDefinition)+        GRule+          { args = t2 NE.:| []+          , body = getField @"value" ruleDefinition+          }+    )+    ruleExtra   where-    rule = fRule (freshName 0)+    Rule {..} = fRule (freshName 0)     t2 = case toType0 t0 of       NoChoice x -> x       _ -> error "Cannot use a choice of types as a generic argument"@@ -955,15 +1030,17 @@ -- | Bind two variables as a generic call binding2 :: (IsType0 t0, IsType0 t1) => (GRef -> GRef -> Rule) -> t0 -> t1 -> GRuleCall binding2 fRule t0 t1 =-  Named-    (name rule)-    GRule-      { args = t02 NE.:| [t12]-      , body = getField @"value" rule-      }-    Nothing+  GRuleCall+    ( Named+        (name ruleDefinition)+        GRule+          { args = t02 NE.:| [t12]+          , body = getField @"value" ruleDefinition+          }+    )+    ruleExtra   where-    rule = fRule (freshName 0) (freshName 1)+    Rule {..} = fRule (freshName 0) (freshName 1)     t02 = case toType0 t0 of       NoChoice x -> x       _ -> error "Cannot use a choice of types as a generic argument"@@ -979,10 +1056,10 @@ hiRule (HIRule r) = [r] hiRule _ = [] -hiName :: HuddleItem -> T.Text-hiName (HIRule (Named n _ _)) = n-hiName (HIGroup (Named n _ _)) = n-hiName (HIGRule (Named n _ _)) = n+instance HasName HuddleItem where+  getName (HIRule (Rule (Named n _) _)) = n+  getName (HIGroup (GroupDef (Named n _) _)) = n+  getName (HIGRule (GRuleDef (Named n _) _)) = n  -- | Collect all rules starting from a given point. This will also insert a --   single pseudo-rule as the first element which references the specified@@ -1001,8 +1078,9 @@         }     goHuddleItem (HIRule r) = goRule r     goHuddleItem (HIGroup g) = goNamedGroup g-    goHuddleItem (HIGRule (Named _ (GRule _ t0) _)) = goT0 t0-    goRule r@(Named n t0 _) = do+    goHuddleItem (HIGRule (GRuleDef (Named _ (GRule _ t0)) _)) = goT0 t0+    goRule :: Rule -> State (OMap Name HuddleItem) ()+    goRule r@(Rule (Named n t0) _) = do       items <- get       when (OMap.notMember n items) $ do         modify (OMap.|> (n, HIRule r))@@ -1010,15 +1088,15 @@     goChoice f (NoChoice x) = f x     goChoice f (ChoiceOf x xs) = f x >> goChoice f xs     goT0 = goChoice goT2-    goNamedGroup r@(Named n g _) = do+    goNamedGroup gd@(GroupDef (Named n g) _) = do       items <- get       when (OMap.notMember n items) $ do-        modify (OMap.|> (n, HIGroup r))+        modify (OMap.|> (n, HIGroup gd))         goGroup g-    goGRule r@(Named n g _) = do+    goGRule (GRuleCall r@(Named n g) extra) = do       items <- get       when (OMap.notMember n items) $ do-        modify (OMap.|> (n, HIGRule $ fmap callToDef r))+        modify (OMap.|> (n, HIGRule $ GRuleDef (fmap callToDef r) extra))         goT0 (body g)       -- Note that the parameters here may be different, so this doesn't live       -- under the guard@@ -1027,13 +1105,13 @@     goT2 (T2Map m) = goChoice (mapM_ goMapEntry . unMapChoice) m     goT2 (T2Array m) = goChoice (mapM_ goArrayEntry . unArrayChoice) m     goT2 (T2Tagged (Tagged _ t0)) = goT0 t0-    goT2 (T2Ref n) = goRule n+    goT2 (T2Ref r) = goRule r     goT2 (T2Group r) = goNamedGroup r     goT2 (T2Generic x) = goGRule x     goT2 (T2Constrained (Constrained c _ refs)) =       ( case c of           CValue _ -> pure ()-          CRef r -> goRule r+          CRef r -> goRule $ Rule r def           CGRef _ -> pure ()       )         >> mapM_ goRule refs@@ -1047,49 +1125,80 @@     goRanged (Unranged _) = pure ()     goRanged (Ranged lb ub _) = goRangeBound lb >> goRangeBound ub     goRangeBound (RangeBoundLiteral _) = pure ()-    goRangeBound (RangeBoundRef r) = goRule r+    goRangeBound (RangeBoundRef r) = goRule . Rule r $ HuddleXRule mempty Nothing  -- | Same as `collectFrom`, but the rules passed into this function will be put --   at the top of the Huddle, and all of their dependencies will be added at --   the end in depth-first order. collectFromInit :: [HuddleItem] -> Huddle collectFromInit rules =-  Huddle (concatMap hiRule rules) (OMap.fromList $ (\x -> (hiName x, x)) <$> rules)+  Huddle (concatMap hiRule rules) (OMap.fromList $ (\x -> (getName x, x)) <$> rules)     `huddleAugment` collectFrom rules  -------------------------------------------------------------------------------- -- Conversion to CDDL -------------------------------------------------------------------------------- +data HuddleConfig = HuddleConfig+  { hcMakePseudoRoot :: Bool+  , hcFailOnDuplicateDefinitions :: Bool+  }++defaultHuddleConfig :: HuddleConfig+defaultHuddleConfig =+  HuddleConfig+    { hcMakePseudoRoot = True+    , hcFailOnDuplicateDefinitions = True+    }+ -- | Convert from Huddle to CDDL, generating a top level root element.-toCDDL :: Huddle -> CDDL-toCDDL = toCDDL' True+toCDDL :: Huddle -> CDDL HuddleStage+toCDDL = toCDDL' defaultHuddleConfig  -- | Convert from Huddle to CDDL, skipping a root element.-toCDDLNoRoot :: Huddle -> CDDL-toCDDLNoRoot = toCDDL' False+toCDDLNoRoot :: Huddle -> CDDL HuddleStage+toCDDLNoRoot =+  toCDDL'+    defaultHuddleConfig+      { hcMakePseudoRoot = False+      }  -- | Convert from Huddle to CDDL for the purpose of pretty-printing.-toCDDL' :: Bool -> Huddle -> CDDL-toCDDL' mkPseudoRoot hdl =+toCDDL' :: HuddleConfig -> Huddle -> CDDL HuddleStage+toCDDL' HuddleConfig {..} hdl =   C.fromRules-    $ ( if mkPseudoRoot-          then (toTopLevelPseudoRoot (roots hdl) NE.<|)-          else id-      )+    . failOnDuplicate+    . makePseudoRoot     $ fmap toCDDLItem (NE.fromList $ fmap (view _2) $ toList $ items hdl)   where+    makePseudoRoot+      | hcMakePseudoRoot = (toTopLevelPseudoRoot (roots hdl) NE.<|)+      | otherwise = id++    failOnDuplicate rs+      | hcFailOnDuplicateDefinitions = go mempty $ toList rs+      | otherwise = rs+      where+        go _ [] = rs+        go s (x : xs)+          | n `Set.member` s = error . T.unpack $ "Duplicate definitions found for '" <> unName n <> "'"+          | otherwise = go (Set.insert n s) xs+          where+            n = C.ruleName x+     toCDDLItem (HIRule r) = toCDDLRule r-    toCDDLItem (HIGroup g) = toCDDLGroup g+    toCDDLItem (HIGroup g) = toCDDLGroupDef g     toCDDLItem (HIGRule g) = toGenRuleDef g-    toTopLevelPseudoRoot :: [Rule] -> C.Rule+    toTopLevelPseudoRoot :: [Rule] -> C.Rule HuddleStage     toTopLevelPseudoRoot topRs =       toCDDLRule $         comment "Pseudo-rule introduced by Cuddle to collect root elements" $           "huddle_root_defs" =:= arr (fromList (fmap a topRs))-    toCDDLRule :: Rule -> C.Rule-    toCDDLRule (Named n t0 c) =-      (\x -> C.Rule (C.Name n mempty) Nothing C.AssignEq x (foldMap C.Comment c))+    toCDDLRule :: Rule -> C.Rule HuddleStage+    toCDDLRule (Rule (Named n t0) extra) =+      ( \x ->+          C.Rule n Nothing C.AssignEq x extra+      )         . C.TOGType         . C.Type0         $ toCDDLType1 <$> choiceToNE t0@@ -1102,19 +1211,20 @@     toCDDLValue' (LDouble d) = C.VFloat64 d     toCDDLValue' (LText t) = C.VText t     toCDDLValue' (LBytes b) = C.VBytes b+    toCDDLValue' (LBool b) = C.VBool b -    mapToCDDLGroup :: Map -> C.Group+    mapToCDDLGroup :: Map -> C.Group HuddleStage     mapToCDDLGroup xs = C.Group $ mapChoiceToCDDL <$> choiceToNE xs -    mapChoiceToCDDL :: MapChoice -> C.GrpChoice+    mapChoiceToCDDL :: MapChoice -> C.GrpChoice HuddleStage     mapChoiceToCDDL (MapChoice entries) = C.GrpChoice (fmap mapEntryToCDDL entries) mempty -    mapEntryToCDDL :: MapEntry -> C.GroupEntry+    mapEntryToCDDL :: MapEntry -> C.GroupEntry HuddleStage     mapEntryToCDDL (MapEntry k v occ cmnt) =       C.GroupEntry         (toOccurrenceIndicator occ)-        cmnt         (C.GEType (Just $ toMemberKey k) (toCDDLType0 v))+        (HuddleXTerm cmnt)      toOccurrenceIndicator :: Occurs -> Maybe C.OccurrenceIndicator     toOccurrenceIndicator (Occurs Nothing Nothing) = Nothing@@ -1123,7 +1233,7 @@     toOccurrenceIndicator (Occurs (Just 1) Nothing) = Just C.OIOneOrMore     toOccurrenceIndicator (Occurs lb ub) = Just $ C.OIBounded lb ub -    toCDDLType1 :: Type2 -> C.Type1+    toCDDLType1 :: Type2 -> C.Type1 HuddleStage     toCDDLType1 = \case       T2Constrained (Constrained x constr _) ->         -- TODO Need to handle choices at the top level@@ -1137,51 +1247,51 @@       T2Array x -> C.Type1 (C.T2Array $ arrayToCDDLGroup x) Nothing mempty       T2Tagged (Tagged mmin x) ->         C.Type1 (C.T2Tag mmin $ toCDDLType0 x) Nothing mempty-      T2Ref (Named n _ _) -> C.Type1 (C.T2Name (C.Name n mempty) Nothing) Nothing mempty-      T2Group (Named n _ _) -> C.Type1 (C.T2Name (C.Name n mempty) Nothing) Nothing mempty+      T2Ref (Rule (Named n _) _) -> C.Type1 (C.T2Name n Nothing) Nothing mempty+      T2Group (GroupDef (Named n _) _) -> C.Type1 (C.T2Name n Nothing) Nothing mempty       T2Generic g -> C.Type1 (toGenericCall g) Nothing mempty-      T2GenericRef (GRef n) -> C.Type1 (C.T2Name (C.Name n mempty) Nothing) Nothing mempty+      T2GenericRef (GRef n) -> C.Type1 (C.T2Name (C.Name n) Nothing) Nothing mempty -    toMemberKey :: Key -> C.MemberKey-    toMemberKey (LiteralKey (Literal (LText t) _)) = C.MKBareword (C.Name t mempty)+    toMemberKey :: Key -> C.MemberKey HuddleStage+    toMemberKey (LiteralKey (Literal (LText t) _)) = C.MKBareword (C.Name t)     toMemberKey (LiteralKey v) = C.MKValue $ toCDDLValue v     toMemberKey (TypeKey t) = C.MKType (toCDDLType1 t) -    toCDDLType0 :: Type0 -> C.Type0+    toCDDLType0 :: Type0 -> C.Type0 HuddleStage     toCDDLType0 = C.Type0 . fmap toCDDLType1 . choiceToNE -    arrayToCDDLGroup :: Array -> C.Group+    arrayToCDDLGroup :: Array -> C.Group HuddleStage     arrayToCDDLGroup xs = C.Group $ arrayChoiceToCDDL <$> choiceToNE xs -    arrayChoiceToCDDL :: ArrayChoice -> C.GrpChoice-    arrayChoiceToCDDL (ArrayChoice entries cmt) = C.GrpChoice (fmap arrayEntryToCDDL entries) cmt+    arrayChoiceToCDDL :: ArrayChoice -> C.GrpChoice HuddleStage+    arrayChoiceToCDDL (ArrayChoice entries cmt) = C.GrpChoice (fmap arrayEntryToCDDL entries) (HuddleXTerm cmt) -    arrayEntryToCDDL :: ArrayEntry -> C.GroupEntry+    arrayEntryToCDDL :: ArrayEntry -> C.GroupEntry HuddleStage     arrayEntryToCDDL (ArrayEntry k v occ cmnt) =       C.GroupEntry         (toOccurrenceIndicator occ)-        cmnt         (C.GEType (fmap toMemberKey k) (toCDDLType0 v))+        (HuddleXTerm cmnt)      toCDDLPostlude :: Value a -> C.Name-    toCDDLPostlude VBool = C.Name "bool" mempty-    toCDDLPostlude VUInt = C.Name "uint" mempty-    toCDDLPostlude VNInt = C.Name "nint" mempty-    toCDDLPostlude VInt = C.Name "int" mempty-    toCDDLPostlude VHalf = C.Name "half" mempty-    toCDDLPostlude VFloat = C.Name "float" mempty-    toCDDLPostlude VDouble = C.Name "double" mempty-    toCDDLPostlude VBytes = C.Name "bytes" mempty-    toCDDLPostlude VText = C.Name "text" mempty-    toCDDLPostlude VAny = C.Name "any" mempty-    toCDDLPostlude VNil = C.Name "nil" mempty+    toCDDLPostlude VBool = C.Name "bool"+    toCDDLPostlude VUInt = C.Name "uint"+    toCDDLPostlude VNInt = C.Name "nint"+    toCDDLPostlude VInt = C.Name "int"+    toCDDLPostlude VHalf = C.Name "half"+    toCDDLPostlude VFloat = C.Name "float"+    toCDDLPostlude VDouble = C.Name "double"+    toCDDLPostlude VBytes = C.Name "bytes"+    toCDDLPostlude VText = C.Name "text"+    toCDDLPostlude VAny = C.Name "any"+    toCDDLPostlude VNil = C.Name "nil"      toCDDLConstrainable c = case c of       CValue v -> toCDDLPostlude v-      CRef r -> C.Name (name r) mempty-      CGRef (GRef n) -> C.Name n mempty+      CRef r -> name r+      CGRef (GRef n) -> C.Name n -    toCDDLRanged :: Ranged -> C.Type1+    toCDDLRanged :: Ranged -> C.Type1 HuddleStage     toCDDLRanged (Unranged x) =       C.Type1 (C.T2Value $ toCDDLValue x) Nothing mempty     toCDDLRanged (Ranged lb ub rop) =@@ -1190,18 +1300,18 @@         (Just (C.RangeOp rop, toCDDLRangeBound ub))         mempty -    toCDDLRangeBound :: RangeBound -> C.Type2+    toCDDLRangeBound :: RangeBound -> C.Type2 HuddleStage     toCDDLRangeBound (RangeBoundLiteral l) = C.T2Value $ toCDDLValue l-    toCDDLRangeBound (RangeBoundRef (Named n _ _)) = C.T2Name (C.Name n mempty) Nothing+    toCDDLRangeBound (RangeBoundRef (Named n _)) = C.T2Name n Nothing -    toCDDLGroup :: Named Group -> C.Rule-    toCDDLGroup (Named n (Group t0s) c) =+    toCDDLGroupDef :: GroupDef -> C.Rule HuddleStage+    toCDDLGroupDef (GroupDef (Named n (Group t0s)) extra) =       C.Rule-        (C.Name n mempty)+        n         Nothing         C.AssignEq         ( C.TOGGroup-            . C.GroupEntry Nothing mempty+            . (\x -> C.GroupEntry Nothing x mempty)             . C.GEGroup             . C.Group             . (NE.:| [])@@ -1210,25 +1320,32 @@               arrayEntryToCDDL               t0s         )-        (foldMap C.Comment c)+        extra -    toGenericCall :: GRuleCall -> C.Type2-    toGenericCall (Named n gr _) =+    toGenericCall :: GRuleCall -> C.Type2 HuddleStage+    toGenericCall (GRuleCall (Named n gr) _) =       C.T2Name-        (C.Name n mempty)+        n         (Just . C.GenericArg $ fmap toCDDLType1 (args gr)) -    toGenRuleDef :: GRuleDef -> C.Rule-    toGenRuleDef (Named n gr c) =+    toGenRuleDef :: GRuleDef -> C.Rule HuddleStage+    toGenRuleDef (GRuleDef (Named n gr) extra) =       C.Rule-        (C.Name n mempty)+        n         (Just gps)         C.AssignEq         ( C.TOGType             . C.Type0             $ toCDDLType1 <$> choiceToNE (body gr)         )-        (foldMap C.Comment c)+        extra       where         gps =-          C.GenericParam $ fmap (\(GRef t) -> C.Name t mempty) (args gr)+          C.GenericParameters $+            fmap (\(GRef t) -> GenericParameter (C.Name t) $ HuddleXTerm mempty) (args gr)++withGenerator :: HasGenerator a => (forall g m. StatefulGen g m => g -> m WrappedTerm) -> a -> a+withGenerator f = L.set generatorL (Just $ CBORGenerator f)++instance HasName (Named a) where+  getName = name
src/Codec/CBOR/Cuddle/Huddle/HuddleM.hs view
@@ -15,25 +15,25 @@ ) where +import Codec.CBOR.Cuddle.CDDL (Name) import Codec.CBOR.Cuddle.Huddle hiding (binding, (=:=), (=:~)) import Codec.CBOR.Cuddle.Huddle qualified as Huddle import Control.Monad.State.Strict (State, modify, runState) import Data.Default.Class (def) import Data.Generics.Product (HasField (..)) import Data.Map.Ordered.Strict qualified as OMap-import Data.Text qualified as T import Optics.Core (set, (%~), (^.))  type HuddleM = State Huddle  -- | Overridden version of assignment which also adds the rule to the state-(=:=) :: IsType0 a => T.Text -> a -> HuddleM Rule+(=:=) :: IsType0 a => Name -> a -> HuddleM Rule n =:= b = let r = n Huddle.=:= b in include r  infixl 1 =:=  -- | Overridden version of group assignment which adds the rule to the state-(=:~) :: T.Text -> Group -> HuddleM (Named Group)+(=:~) :: Name -> Group -> HuddleM GroupDef n =:~ b = let r = n Huddle.=:~ b in include r  infixl 1 =:~@@ -46,7 +46,7 @@ binding fRule = include (Huddle.binding fRule)  -- | Renamed version of Huddle's underlying '=:=' for use in generic bindings-(=::=) :: IsType0 a => T.Text -> a -> Rule+(=::=) :: IsType0 a => Name -> a -> Rule n =::= b = n Huddle.=:= b  infixl 1 =::=@@ -65,39 +65,39 @@   include :: a -> HuddleM a  instance Includable Rule where-  include r =-    modify (field @"items" %~ (OMap.|> (r ^. field @"name", HIRule r)))+  include r@(Rule x _) =+    modify (field @"items" %~ (OMap.|> (getName x, HIRule r)))       >> pure r -instance Includable (Named Group) where+instance Includable GroupDef where   include r =     modify       ( (field @"items")-          %~ (OMap.|> (r ^. field @"name", HIGroup r))+          %~ (OMap.|> (getName r, HIGroup r))       )       >> pure r  instance IsType0 t0 => Includable (t0 -> GRuleCall) where   include gr =     let fakeT0 = error "Attempting to unwrap fake value in generic call"-        grDef = callToDef <$> gr fakeT0-        n = grDef ^. field @"name"+        GRuleCall g extra = gr fakeT0+        grDef = callToDef <$> g+        n = getName grDef      in do-          modify (field @"items" %~ (OMap.|> (n, HIGRule grDef)))+          modify (field @"items" %~ (OMap.|> (n, HIGRule $ GRuleDef grDef extra)))           pure gr  instance Includable HuddleItem where   include x@(HIRule r) = include r >> pure x   include x@(HIGroup g) = include g >> pure x   include x@(HIGRule g) =-    let n = g ^. field @"name"-     in do-          modify (field @"items" %~ (OMap.|> (n, x)))-          pure x+    do+      modify (field @"items" %~ (OMap.|> (getName g, x)))+      pure x  unsafeIncludeFromHuddle ::   Huddle ->-  T.Text ->+  Name ->   HuddleM HuddleItem unsafeIncludeFromHuddle h name =   let items = h ^. field @"items"
− src/Codec/CBOR/Cuddle/Huddle/Optics.hs
@@ -1,26 +0,0 @@-{-# LANGUAGE DataKinds #-}---- | Optics for mutating Huddle rules-module Codec.CBOR.Cuddle.Huddle.Optics (commentL, nameL) where--import Codec.CBOR.Cuddle.Huddle-import Data.Generics.Product (HasField' (field'))-import Data.Text qualified as T-import Optics.Core--mcommentL ::-  HasField' "description" a (Maybe T.Text) =>-  Lens a a (Maybe T.Text) (Maybe T.Text)-mcommentL = field' @"description"---- | Traversal to the comment field of a description. Using this we can for---   example set the comment with 'a & commentL .~ "This is a comment"'-commentL ::-  HasField' "description" a (Maybe T.Text) =>-  AffineTraversal a a T.Text T.Text-commentL = mcommentL % _Just---- | Lens to the name of a rule (or other named entity). Using this we can---   for example append to the name with 'a & nameL %~ (<> "_1")'-nameL :: Lens (Named a) (Named a) T.Text T.Text-nameL = field' @"name"
+ src/Codec/CBOR/Cuddle/IndexMappable.hs view
@@ -0,0 +1,291 @@+{-# LANGUAGE DefaultSignatures #-}++module Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..), mapCDDLDropExt) where++import Codec.CBOR.Cuddle.CDDL (+  CDDL (..),+  GenericArg (..),+  GenericParameter (..),+  GenericParameters (..),+  Group (..),+  GroupEntry (..),+  GroupEntryVariant (..),+  GrpChoice (..),+  MemberKey (..),+  Rule (..),+  TopLevel (..),+  Type0 (..),+  Type1 (..),+  Type2 (..),+  TypeOrGroup (..),+  XCddl,+  XRule,+  XTerm,+  XXTopLevel,+  XXType2,+ )+import Codec.CBOR.Cuddle.CDDL.CTree (+  CTreePhase,+  XCddl (..),+  XRule (..),+  XTerm (..),+  XXType2 (..),+ )+import Codec.CBOR.Cuddle.Huddle (+  HuddleStage,+  XCddl (..),+  XRule (..),+  XTerm (..),+  XXTopLevel (..),+  XXType2 (..),+ )+import Codec.CBOR.Cuddle.Parser (+  ParserStage,+  XCddl (..),+  XRule (..),+  XTerm (..),+  XXTopLevel (..),+  XXType2 (..),+ )+import Codec.CBOR.Cuddle.Pretty (PrettyStage, XCddl (..), XRule (..), XTerm (..), XXTopLevel (..))+import Data.Bifunctor (Bifunctor (..))+import Data.Coerce (Coercible, coerce)+import Data.Void (absurd)++class IndexMappable f i j where+  mapIndex :: f i -> f j+  default mapIndex :: Coercible (f i) (f j) => f i -> f j+  mapIndex = coerce++mapCDDLDropExt ::+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  , IndexMappable XRule i j+  ) =>+  CDDL i ->+  CDDL j+mapCDDLDropExt (CDDL r tls _) = CDDL (mapIndex r) (foldMap mapTopLevelDropExt tls) []+  where+    mapTopLevelDropExt (TopLevelRule x) = [TopLevelRule $ mapIndex x]+    mapTopLevelDropExt (XXTopLevel _) = []++instance+  ( IndexMappable XCddl i j+  , IndexMappable XXTopLevel i j+  , IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  , IndexMappable XRule i j+  ) =>+  IndexMappable CDDL i j+  where+  mapIndex (CDDL r tls e) = CDDL (mapIndex r) (mapIndex <$> tls) (mapIndex <$> e)++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  , IndexMappable XRule i j+  ) =>+  IndexMappable Rule i j+  where+  mapIndex (Rule n mg a t c) = Rule n (mapIndex <$> mg) a (mapIndex t) (mapIndex c)++instance+  ( IndexMappable XXTopLevel i j+  , IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  , IndexMappable XRule i j+  ) =>+  IndexMappable TopLevel i j+  where+  mapIndex (TopLevelRule r) = TopLevelRule $ mapIndex r+  mapIndex (XXTopLevel e) = XXTopLevel $ mapIndex e++instance IndexMappable XTerm i j => IndexMappable GenericParameter i j where+  mapIndex (GenericParameter n e) = GenericParameter n $ mapIndex e++instance IndexMappable XTerm i j => IndexMappable GenericParameters i j where+  mapIndex (GenericParameters ns) = GenericParameters $ mapIndex <$> ns++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable TypeOrGroup i j+  where+  mapIndex (TOGType t) = TOGType $ mapIndex t+  mapIndex (TOGGroup g) = TOGGroup $ mapIndex g++instance+  ( IndexMappable XTerm i j+  , IndexMappable XXType2 i j+  ) =>+  IndexMappable GroupEntry i j+  where+  mapIndex (GroupEntry mo gev e) = GroupEntry mo (mapIndex gev) (mapIndex e)++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable GroupEntryVariant i j+  where+  mapIndex (GEType mk t) = GEType (mapIndex <$> mk) $ mapIndex t+  mapIndex (GERef n ma) = GERef n (mapIndex <$> ma)+  mapIndex (GEGroup g) = GEGroup (mapIndex g)++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable MemberKey i j+  where+  mapIndex (MKType t) = MKType $ mapIndex t+  mapIndex (MKBareword n) = MKBareword n+  mapIndex (MKValue x) = MKValue x++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable Type0 i j+  where+  mapIndex (Type0 ts) = Type0 $ mapIndex <$> ts++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable Type1 i j+  where+  mapIndex (Type1 t mo e) = Type1 (mapIndex t) (second mapIndex <$> mo) (mapIndex e)++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable Type2 i j+  where+  mapIndex (T2Value v) = T2Value v+  mapIndex (T2Name n mg) = T2Name n (mapIndex <$> mg)+  mapIndex (T2Group t) = T2Group $ mapIndex t+  mapIndex (T2Map g) = T2Map $ mapIndex g+  mapIndex (T2Array a) = T2Array $ mapIndex a+  mapIndex (T2Unwrapped n mg) = T2Unwrapped n (mapIndex <$> mg)+  mapIndex (T2Enum g) = T2Enum $ mapIndex g+  mapIndex (T2EnumRef n mg) = T2EnumRef n (mapIndex <$> mg)+  mapIndex (T2Tag mt t) = T2Tag mt $ mapIndex t+  mapIndex (T2DataItem t mt) = T2DataItem t mt+  mapIndex T2Any = T2Any+  mapIndex (XXType2 e) = XXType2 $ mapIndex e++instance+  ( IndexMappable XXType2 i j+  , IndexMappable XTerm i j+  ) =>+  IndexMappable GenericArg i j+  where+  mapIndex (GenericArg g) = GenericArg $ mapIndex <$> g++instance+  ( IndexMappable XTerm i j+  , IndexMappable XXType2 i j+  ) =>+  IndexMappable Group i j+  where+  mapIndex (Group g) = Group $ mapIndex <$> g++instance+  ( IndexMappable XTerm i j+  , IndexMappable XXType2 i j+  ) =>+  IndexMappable GrpChoice i j+  where+  mapIndex (GrpChoice gs e) = GrpChoice (mapIndex <$> gs) $ mapIndex e++-- ParserStage -> PrettyStage++instance IndexMappable XCddl ParserStage PrettyStage where+  mapIndex (ParserXCddl c) = PrettyXCddl c++instance IndexMappable XTerm ParserStage PrettyStage where+  mapIndex (ParserXTerm c) = PrettyXTerm c++instance IndexMappable XRule ParserStage PrettyStage where+  mapIndex (ParserXRule c) = PrettyXRule c++instance IndexMappable XXType2 ParserStage PrettyStage where+  mapIndex (ParserXXType2 v) = absurd v++instance IndexMappable XXTopLevel ParserStage PrettyStage where+  mapIndex (ParserXXTopLevel c) = PrettyXXTopLevel c++-- ParserStage -> CTreePhase++instance IndexMappable XCddl ParserStage CTreePhase where+  mapIndex _ = CTreeXCddl++instance IndexMappable XXType2 ParserStage CTreePhase where+  mapIndex (ParserXXType2 c) = CTreeXXType2 c++instance IndexMappable XTerm ParserStage CTreePhase where+  mapIndex _ = CTreeXTerm++instance IndexMappable XRule ParserStage CTreePhase where+  mapIndex _ = CTreeXRule Nothing++-- ParserStage -> HuddleStage++instance IndexMappable XCddl ParserStage HuddleStage where+  mapIndex (ParserXCddl c) = HuddleXCddl c++instance IndexMappable XXTopLevel ParserStage HuddleStage where+  mapIndex (ParserXXTopLevel c) = HuddleXXTopLevel c++instance IndexMappable XXType2 ParserStage HuddleStage where+  mapIndex (ParserXXType2 c) = HuddleXXType2 c++instance IndexMappable XTerm ParserStage HuddleStage where+  mapIndex (ParserXTerm c) = HuddleXTerm c++-- HuddleStage -> CTreePhase++instance IndexMappable XCddl HuddleStage CTreePhase where+  mapIndex _ = CTreeXCddl++instance IndexMappable XXType2 HuddleStage CTreePhase where+  mapIndex (HuddleXXType2 c) = CTreeXXType2 c++instance IndexMappable XTerm HuddleStage CTreePhase where+  mapIndex _ = CTreeXTerm++instance IndexMappable XRule HuddleStage CTreePhase where+  mapIndex (HuddleXRule _ g) = CTreeXRule g++-- HuddleStage -> PrettyStage++instance IndexMappable XCddl HuddleStage PrettyStage where+  mapIndex (HuddleXCddl c) = PrettyXCddl c++instance IndexMappable XXTopLevel HuddleStage PrettyStage where+  mapIndex (HuddleXXTopLevel c) = PrettyXXTopLevel c++instance IndexMappable XXType2 HuddleStage PrettyStage where+  mapIndex (HuddleXXType2 c) = absurd c++instance IndexMappable XTerm HuddleStage PrettyStage where+  mapIndex (HuddleXTerm c) = PrettyXTerm c++instance IndexMappable XRule HuddleStage PrettyStage where+  mapIndex (HuddleXRule c _) = PrettyXRule c++-- ParserStage -> ParserStage++instance IndexMappable XCddl ParserStage ParserStage++instance IndexMappable XXTopLevel ParserStage ParserStage++instance IndexMappable XXType2 ParserStage ParserStage++instance IndexMappable XTerm ParserStage ParserStage++instance IndexMappable XRule ParserStage ParserStage
src/Codec/CBOR/Cuddle/Parser.hs view
@@ -1,12 +1,23 @@ {-# LANGUAGE LambdaCase #-}+{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-}  module Codec.CBOR.Cuddle.Parser where  import Codec.CBOR.Cuddle.CDDL import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp) import Codec.CBOR.Cuddle.CDDL.CtlOp qualified as COp-import Codec.CBOR.Cuddle.Comments (Comment, WithComment (..), withComment, (!*>), (//-), (<*!))+import Codec.CBOR.Cuddle.Comments (+  Comment,+  HasComment (..),+  WithComment (..),+  withComment,+  (!*>),+  (//-),+  (<*!),+ ) import Codec.CBOR.Cuddle.Parser.Lexer (   Parser,   charInRange,@@ -14,41 +25,70 @@   space,  ) import Control.Applicative.Combinators.NonEmpty qualified as NE+import Data.ByteString.Base16 qualified as Base16 import Data.Foldable (Foldable (..)) import Data.Functor (void, ($>))-import Data.List.NonEmpty (NonEmpty)+import Data.List.NonEmpty (NonEmpty (..)) import Data.List.NonEmpty qualified as NE import Data.Maybe (isJust) import Data.Text (Text) import Data.Text qualified as T import Data.Text.Encoding (encodeUtf8)+import Data.TreeDiff (ToExpr)+import Data.Void (Void)+import GHC.Generics (Generic) import GHC.Word (Word64, Word8)+import Optics.Core ((&), (.~)) import Text.Megaparsec import Text.Megaparsec.Char hiding (space) import Text.Megaparsec.Char qualified as C import Text.Megaparsec.Char.Lexer qualified as L -pCDDL :: Parser CDDL+type data ParserStage++newtype instance XXTopLevel ParserStage = ParserXXTopLevel Comment+  deriving (Generic, Show, Eq, ToExpr)++newtype instance XXType2 ParserStage = ParserXXType2 Void+  deriving (Generic, Show, Eq, ToExpr)++newtype instance XTerm ParserStage = ParserXTerm {unParserXTerm :: Comment}+  deriving (Generic, Semigroup, Monoid, Show, Eq, ToExpr)++newtype instance XRule ParserStage = ParserXRule {unParserXRule :: Comment}+  deriving (Generic, Semigroup, Monoid, Show, Eq, ToExpr)++newtype instance XCddl ParserStage = ParserXCddl [Comment]+  deriving (Generic, Semigroup, Monoid, Show, Eq, ToExpr)++instance HasComment (XTerm ParserStage) where+  commentL = #unParserXTerm++instance HasComment (XRule ParserStage) where+  commentL = #unParserXRule++pCDDL :: Parser (CDDL ParserStage) pCDDL = do   initialComments <- many (try $ C.space *> pCommentBlock <* notFollowedBy pRule)   initialRuleComment <- C.space *> optional pCommentBlock   initialRule <- pRule   cddlTail <- many $ pTopLevel <* C.space-  eof $> CDDL initialComments (initialRule //- fold initialRuleComment) cddlTail+  eof+    $> CDDL (initialRule //- fold initialRuleComment) cddlTail (ParserXXTopLevel <$> initialComments) -pTopLevel :: Parser TopLevel+pTopLevel :: Parser (TopLevel ParserStage) pTopLevel = try tlRule <|> tlComment   where     tlRule = do       mCmt <- optional pCommentBlock       rule <- pRule       pure . TopLevelRule $ rule //- fold mCmt-    tlComment = TopLevelComment <$> pCommentBlock+    tlComment = XXTopLevel . ParserXXTopLevel <$> pCommentBlock -pRule :: Parser Rule+pRule :: Parser (Rule ParserStage) pRule = do   name <- pName-  genericParam <- optcomp pGenericParam+  genericParam <- optcomp pGenericParameters   cmt <- space   (assign, typeOrGrp) <-     choice@@ -59,13 +99,13 @@             <*> (TOGType <$> pType0 <* notFollowedBy (space >> (":" <|> "=>")))       , (,) <$> pAssignG <* space <*> (TOGGroup <$> pGrpEntry)       ]-  pure $ Rule name genericParam assign typeOrGrp cmt+  pure $ Rule name genericParam assign typeOrGrp (ParserXRule cmt)  pName :: Parser Name pName = label "name" $ do   fc <- firstChar   rest <- many midChar-  pure $ (`Name` mempty) . T.pack $ (fc : rest)+  pure $ Name . T.pack $ (fc : rest)   where     firstChar = letterChar <|> char '@' <|> char '_' <|> char '$'     midChar =@@ -89,20 +129,23 @@     , AssignExt <$ "//="     ] -pGenericParam :: Parser GenericParam-pGenericParam =-  GenericParam-    <$> between "<" ">" (NE.sepBy1 (space !*> pName <*! space) ",")+pGenericParameter :: Parser (GenericParameter ParserStage)+pGenericParameter = GenericParameter <$> pName <*> pure mempty -pGenericArg :: Parser GenericArg+pGenericParameters :: Parser (GenericParameters ParserStage)+pGenericParameters =+  GenericParameters+    <$> between "<" ">" (NE.sepBy1 (space !*> pGenericParameter <*! space) ",")++pGenericArg :: Parser (GenericArg ParserStage) pGenericArg =   GenericArg     <$> between "<" ">" (NE.sepBy1 (space !*> pType1 <*! space) ",") -pType0 :: Parser Type0+pType0 :: Parser (Type0 ParserStage) pType0 = Type0 <$> sepBy1' (space !*> pType1 <*! space) (try "/") -pType1 :: Parser Type1+pType1 :: Parser (Type1 ParserStage) pType1 = do   v <- pType2   rest <- optional $ do@@ -115,18 +158,18 @@     pure (cmtFst, tyOp, cmtSnd, w)   case rest of     Just (cmtFst, tyOp, cmtSnd, w) ->-      pure $ Type1 v (Just (tyOp, w)) $ cmtFst <> cmtSnd+      pure $ Type1 v (Just (tyOp, w)) . ParserXTerm $ cmtFst <> cmtSnd     Nothing -> pure $ Type1 v Nothing mempty -pType2 :: Parser Type2+pType2 :: Parser (Type2 ParserStage) pType2 =   choice     [ T2Value <$> pValue     , T2Name <$> pName <*> optional pGenericArg-    , T2Group <$> label "group" ("(" *> space !*> pType0 <*! space <* ")")+    , T2Group <$> label "group" ("(" *> pType0Cmt <* ")")     , T2Map <$> label "map" ("{" *> pGroup <* "}")     , T2Array <$> label "array" ("[" *> space !*> pGroup <*! space <* "]")-    , T2Unwrapped <$> ("~" *> space !*> pName) <*> optional pGenericArg+    , T2Unwrapped <$> ("~" *> space *> pName) <*> optional pGenericArg     , do         _ <- "&"         cmt <- space@@ -141,11 +184,17 @@             mminor <- optional ("." *> L.decimal)             let               pTag-                | major == 6 = T2Tag mminor <$> ("(" *> space !*> pType0 <*! space <* ")")+                | major == 6 = T2Tag mminor <$> ("(" *> pType0Cmt <* ")")                 | otherwise = empty             pTag <|> pure (T2DataItem major mminor)           Nothing -> pure T2Any     ]+  where+    pType0Cmt = do+      pre <- space+      Type0 (t :| ts) <- pType0+      post <- space+      pure . Type0 $ (t & commentL .~ (pre <> post)) :| ts  pHeadNumber :: Parser Word64 pHeadNumber = L.decimal@@ -176,13 +225,13 @@                 ]         ) -pGroup :: Parser Group+pGroup :: Parser (Group ParserStage) pGroup = Group <$> NE.sepBy1 (space !*> pGrpChoice) "//" -pGrpChoice :: Parser GrpChoice+pGrpChoice :: Parser (GrpChoice ParserStage) pGrpChoice = GrpChoice <$> many (space !*> pGrpEntry <*! pOptCom) <*> mempty -pGrpEntry :: Parser GroupEntry+pGrpEntry :: Parser (GroupEntry ParserStage) pGrpEntry = do   occur <- optcomp pOccur   cmt <- space@@ -195,9 +244,9 @@       , try $ withComment <$> (GERef <$> pName <*> optional pGenericArg)       , withComment . GEGroup <$> ("(" *> space !*> pGroup <*! space <* ")")       ]-  pure $ GroupEntry occur (cmt <> cmt') variant+  pure $ GroupEntry occur variant (ParserXTerm $ cmt <> cmt') -pMemberKey :: Parser (WithComment MemberKey)+pMemberKey :: Parser (WithComment (MemberKey ParserStage)) pMemberKey =   choice     [ try $ do@@ -238,6 +287,7 @@         , try pInt         , try pBytes         , pText+        , try pBool         ]   where     pSignedNum :: Num a => Parser a -> Parser (Bool, a)@@ -249,8 +299,12 @@     -- value.     pInt =       pSignedNum L.decimal >>= \case-        (False, val) -> pure $ VUInt val-        (True, val) -> pure $ VNInt val+        (False, val)+          | val < fromIntegral (maxBound @Word64) -> pure . VUInt $ fromIntegral val+          | otherwise -> pure $ VBignum val+        (True, val)+          | val < fromIntegral (maxBound @Word64) -> pure . VNInt $ fromIntegral val+          | otherwise -> pure . VBignum $ -val     pFloat =       pSignedNum L.float >>= \case         (False, val) -> pure $ VFloat64 val@@ -275,7 +329,15 @@           <*> pure x     pBytes = do       _qualifier <- optional ("h" <|> "b64")-      between "'" "'" $ VBytes . encodeUtf8 <$> pSByte+      bytes <- between "'" "'" pSByte+      case Base16.decode $ encodeUtf8 bytes of+        Right x -> pure $ VBytes x+        Left err -> fail err+    pBool = label "boolean" $ do+      b <-+        (True <$ string "true")+          <|> (False <$ string "false")+      pure $ VBool b  pTyOp :: Parser TyOp pTyOp =
src/Codec/CBOR/Cuddle/Pretty.hs view
@@ -1,13 +1,24 @@ {-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ViewPatterns #-} {-# OPTIONS_GHC -Wno-orphans #-} -module Codec.CBOR.Cuddle.Pretty where+module Codec.CBOR.Cuddle.Pretty (+  CommentRender (..),+  PrettyStage,+  XXTopLevel (..),+  XXType2 (..),+  XTerm (..),+  XCddl (..),+  XRule (..),+) where  import Codec.CBOR.Cuddle.CDDL import Codec.CBOR.Cuddle.CDDL.CtlOp (CtlOp)-import Codec.CBOR.Cuddle.Comments (CollectComments (..), Comment (..), unComment)+import Codec.CBOR.Cuddle.Comments (CollectComments (..), Comment (..), HasComment (..), unComment) import Codec.CBOR.Cuddle.Pretty.Columnar (   Cell (..),   CellAlign (..),@@ -21,22 +32,52 @@   singletonRow,  ) import Codec.CBOR.Cuddle.Pretty.Utils (renderedLen, softspace)+import Data.ByteString.Base16 qualified as B16 import Data.ByteString.Char8 qualified as BS+import Data.Default.Class (Default) import Data.Foldable (Foldable (..)) import Data.List.NonEmpty qualified as NE-import Data.String (fromString)+import Data.String (IsString, fromString) import Data.Text qualified as T+import Data.TreeDiff (ToExpr)+import Data.Void (Void, absurd)+import GHC.Generics (Generic)+import Optics.Core ((^.)) import Prettyprinter -instance Pretty CDDL where+type data PrettyStage++newtype instance XXTopLevel PrettyStage = PrettyXXTopLevel Comment+  deriving (Generic, CollectComments, ToExpr, Show, Eq)++newtype instance XXType2 PrettyStage = PrettyXXType2 Void+  deriving (Generic, CollectComments, ToExpr, Show, Eq)++newtype instance XTerm PrettyStage = PrettyXTerm {unPrettyXTerm :: Comment}+  deriving (Generic, CollectComments, Semigroup, Monoid, IsString, ToExpr, Show, Eq)++newtype instance XCddl PrettyStage = PrettyXCddl [Comment]+  deriving (Generic, CollectComments, ToExpr, Show, Eq)++newtype instance XRule PrettyStage = PrettyXRule {unPrettyXRule :: Comment}+  deriving (Generic, CollectComments, ToExpr, Show, Eq)+  deriving newtype (Default)++instance HasComment (XTerm PrettyStage) where+  commentL = #unPrettyXTerm++instance HasComment (XRule PrettyStage) where+  commentL = #unPrettyXRule++instance Pretty (CDDL PrettyStage) where   pretty = vsep . fmap pretty . NE.toList . cddlTopLevel -instance Pretty TopLevel where-  pretty (TopLevelComment cmt) = pretty cmt+instance Pretty (TopLevel PrettyStage) where+  pretty (XXTopLevel (PrettyXXTopLevel cmt)) = pretty cmt   pretty (TopLevelRule x) = pretty x <> hardline  instance Pretty Name where-  pretty (Name name cmt) = pretty name <> prettyCommentNoBreakWS cmt+  pretty (Name name) = pretty name  data CommentRender   = PreComment@@ -54,12 +95,12 @@   pretty (Comment "") = mempty   pretty c = prettyCommentNoBreak c <> hardline -type0Def :: Type0 -> Doc ann+type0Def :: Type0 PrettyStage -> Doc ann type0Def t = nest 2 $ line' <> pretty t -instance Pretty Rule where+instance Pretty (Rule PrettyStage) where   pretty (Rule n mgen assign tog cmt) =-    pretty cmt+    pretty (cmt ^. commentL)       <> groupIfNoComments         tog         ( pretty n <> pretty mgen <+> case tog of@@ -74,21 +115,24 @@         AssignEq -> "="         AssignExt -> "//=" -instance Pretty GenericArg where+instance Pretty (GenericArg PrettyStage) where   pretty (GenericArg (NE.toList -> l))     | null (collectComments l) = group . cEncloseSep "<" ">" "," $ fmap pretty l     | otherwise = columnarListing "<" ">" "," . Columnar $ singletonRow . pretty <$> l -instance Pretty GenericParam where-  pretty (GenericParam (NE.toList -> l))-    | null (collectComments l) = group . cEncloseSep "<" ">" "," $ fmap pretty l+instance Pretty (GenericParameter PrettyStage) where+  pretty (GenericParameter n (PrettyXTerm c)) = pretty n <> prettyCommentNoBreakWS c++instance Pretty (GenericParameters PrettyStage) where+  pretty (GenericParameters (NE.toList -> l))+    | null (collectComments l) = group . cEncloseSep "<" ">" "," $ pretty <$> l     | otherwise = columnarListing "<" ">" "," . Columnar $ singletonRow . pretty <$> l -instance Pretty Type0 where+instance Pretty (Type0 PrettyStage) where   pretty t0@(Type0 (NE.toList -> l)) =     groupIfNoComments t0 $ columnarSepBy "/" . Columnar $ type1ToRow <$> l     where-      type1ToRow (Type1 t2 tyOp cmt) =+      type1ToRow (Type1 t2 tyOp (PrettyXTerm cmt)) =         let           valCell = case tyOp of             Nothing -> cellL t2@@ -104,15 +148,15 @@   pretty (RangeOp Closed) = ".."   pretty (CtrlOp n) = "." <> pretty n -instance Pretty Type1 where-  pretty (Type1 t2 Nothing cmt) = groupIfNoComments t2 (pretty t2) <> prettyCommentNoBreakWS cmt-  pretty (Type1 t2 (Just (tyop, t2')) cmt) =+instance Pretty (Type1 PrettyStage) where+  pretty (Type1 t2 Nothing (PrettyXTerm cmt)) = groupIfNoComments t2 (pretty t2) <> prettyCommentNoBreakWS cmt+  pretty (Type1 t2 (Just (tyop, t2')) (PrettyXTerm cmt)) =     groupIfNoComments t2 (pretty t2)       <+> pretty tyop       <+> groupIfNoComments t2' (pretty t2')       <> prettyCommentNoBreakWS cmt -instance Pretty Type2 where+instance Pretty (Type2 PrettyStage) where   pretty (T2Value v) = pretty v   pretty (T2Name n mg) = pretty n <> pretty mg   pretty (T2Group g) = cEncloseSep "(" ")" mempty [pretty g]@@ -131,6 +175,7 @@       Nothing -> mempty       Just minor -> "." <> pretty minor   pretty T2Any = "#"+  pretty (XXType2 (PrettyXXType2 v)) = absurd v  instance Pretty OccurrenceIndicator where   pretty OIOptional = "?"@@ -144,7 +189,7 @@   | AsArray   | AsGroup -memberKeySep :: MemberKey -> Doc ann+memberKeySep :: MemberKey i -> Doc ann memberKeySep MKType {} = " => " memberKeySep _ = " : " @@ -165,10 +210,10 @@   | not (any (mempty /=) $ collectComments x) = group   | otherwise = id -columnarGroupChoice :: GrpChoice -> Columnar ann+columnarGroupChoice :: GrpChoice PrettyStage -> Columnar ann columnarGroupChoice (GrpChoice ges _cmt) = Columnar grpEntryRows   where-    groupEntryRow (GroupEntry oi cmt gev) =+    groupEntryRow (GroupEntry oi gev (PrettyXTerm cmt)) =       Row $         [maybe emptyCell (\x -> Cell (pretty x <> space) LeftAlign) oi]           <> groupEntryVariantCells gev@@ -179,7 +224,7 @@     groupEntryVariantCells (GEGroup g) = [Cell (prettyGroup AsGroup g) LeftAlign, emptyCell]     grpEntryRows = groupEntryRow <$> ges -prettyGroup :: GroupRender -> Group -> Doc ann+prettyGroup :: GroupRender -> Group PrettyStage -> Doc ann prettyGroup gr g@(Group (toList -> xs)) =   groupIfNoComments g . columnarListing (lEnc <> softspace) rEnc "// " . Columnar $     (\x -> singletonRow . groupIfNoComments x . columnarSepBy "," $ columnarGroupChoice x) <$> xs@@ -189,10 +234,10 @@       AsArray -> ("[", "]")       AsGroup -> ("(", ")") -instance Pretty GroupEntry where+instance Pretty (GroupEntry PrettyStage) where   pretty ge = prettyColumnar . columnarGroupChoice $ GrpChoice [ge] mempty -instance Pretty MemberKey where+instance Pretty (MemberKey PrettyStage) where   pretty (MKType t1) = pretty t1   pretty (MKBareword n) = pretty n   pretty (MKValue v) = pretty v@@ -208,6 +253,6 @@   pretty (VFloat32 i) = pretty i   pretty (VFloat64 i) = pretty i   pretty (VText t) = enclose "\"" "\"" $ pretty t-  pretty (VBytes b) = fromString $ "h" <> "'" <> BS.unpack b <> "'"+  pretty (VBytes b) = fromString $ "h" <> "'" <> BS.unpack (B16.encode b) <> "'"   pretty (VBool True) = "true"   pretty (VBool False) = "false"
test/Main.hs view
@@ -2,7 +2,9 @@  import System.IO (BufferMode (..), hSetBuffering, hSetEncoding, stdout, utf8) import Test.Codec.CBOR.Cuddle.CDDL.Examples qualified as Examples+import Test.Codec.CBOR.Cuddle.CDDL.GeneratorSpec qualified as Generator import Test.Codec.CBOR.Cuddle.CDDL.Parser (parserSpec)+import Test.Codec.CBOR.Cuddle.CDDL.Validator qualified as Validator import Test.Codec.CBOR.Cuddle.Huddle (huddleSpec) import Test.Hspec import Test.Hspec.Runner@@ -18,6 +20,8 @@   hSetBuffering stdout LineBuffering   hSetEncoding stdout utf8   hspecWith hspecConfig $ do-    describe "cddlParser" parserSpec+    describe "Parser" parserSpec     describe "Huddle" huddleSpec     describe "Examples" Examples.spec+    describe "Generator" Generator.spec+    describe "Validator" Validator.spec
test/Test/Codec/CBOR/Cuddle/CDDL/Examples.hs view
@@ -1,27 +1,63 @@+{-# LANGUAGE OverloadedStrings #-}+ module Test.Codec.CBOR.Cuddle.CDDL.Examples (spec) where -import Codec.CBOR.Cuddle.CDDL.Prelude (prependPrelude)-import Codec.CBOR.Cuddle.CDDL.Resolve (fullResolveCDDL)+import Codec.CBOR.Cuddle.CDDL (Value (..), ValueVariant (..))+import Codec.CBOR.Cuddle.CDDL.CTree (CTree (..), CTreeRoot, PTerm (..))+import Codec.CBOR.Cuddle.CDDL.Postlude (appendPostlude)+import Codec.CBOR.Cuddle.CDDL.Resolve (+  MonoReferenced,+  NameResolutionFailure (..),+  fullResolveCDDL,+ )+import Codec.CBOR.Cuddle.IndexMappable (mapCDDLDropExt) import Codec.CBOR.Cuddle.Parser (pCDDL)-import Data.Either (isRight) import Data.Text.IO qualified as T+import Paths_cuddle (getDataFileName)+import Test.HUnit (assertFailure) import Test.Hspec import Text.Megaparsec (parse) import Text.Megaparsec.Error (errorBundlePretty) -validateFile :: FilePath -> Spec-validateFile filePath = it ("Successfully validates " <> filePath) $ do-  contents <- T.readFile filePath+tryValidateFile :: FilePath -> IO (Either NameResolutionFailure (CTreeRoot MonoReferenced))+tryValidateFile filePath = do+  absoluteFilePath <- getDataFileName filePath+  contents <- T.readFile absoluteFilePath   cddl <- case parse pCDDL "" contents of-    Right x -> pure $ prependPrelude x+    Right x -> pure $ appendPostlude x     Left x -> fail $ "Failed to parse the file:\n" <> errorBundlePretty x-  fullResolveCDDL cddl `shouldSatisfy` isRight+  pure . fullResolveCDDL $ mapCDDLDropExt cddl +validateExpectSuccess :: FilePath -> Spec+validateExpectSuccess filePath = it ("Successfully validates " <> filePath) $ do+  res <- tryValidateFile filePath+  case res of+    Right _ -> pure ()+    Left err -> assertFailure $ "Failed to validate:\n" <> show err++validateExpectFailure :: FilePath -> NameResolutionFailure -> Spec+validateExpectFailure filePath expectedFailure = it ("Fails to validate " <> filePath) $ do+  res <- tryValidateFile filePath+  case res of+    Right _ -> assertFailure "Expected a failure, but succeeded instead"+    Left e -> e `shouldBe` expectedFailure+ spec :: Spec spec = do-  validateFile "example/cddl-files/byron.cddl"-  validateFile "example/cddl-files/conway.cddl"-  validateFile "example/cddl-files/shelley.cddl"---- TODO this one does not seem to terminate--- validateFile "example/cddl-files/basic_assign.cddl"+  describe "Validator" $ do+    describe "Positive" $ do+      validateExpectSuccess "example/cddl-files/byron.cddl"+      validateExpectSuccess "example/cddl-files/conway.cddl"+      validateExpectSuccess "example/cddl-files/shelley.cddl"+      validateExpectSuccess "example/cddl-files/basic_assign.cddl"+      validateExpectSuccess "example/cddl-files/issue80-min.cddl"+      validateExpectSuccess "example/cddl-files/pretty.cddl"+    describe "Negative" $ do+      validateExpectFailure "example/cddl-files/validator/negative/unknown-name.cddl" $+        UnboundReference "a"+      validateExpectFailure "example/cddl-files/validator/negative/too-few-args.cddl" $+        MismatchingArgs "foo" ["a", "b"]+      validateExpectFailure "example/cddl-files/validator/negative/too-many-args.cddl" $+        MismatchingArgs "foo" ["a"]+      validateExpectFailure "example/cddl-files/validator/negative/args-to-postlude.cddl" $+        ArgsToPostlude PTUInt [Literal (Value (VUInt 3) mempty)]
test/Test/Codec/CBOR/Cuddle/CDDL/Gen.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE ViewPatterns #-} {-# OPTIONS_GHC -Wno-orphans #-} @@ -7,6 +9,8 @@ import Codec.CBOR.Cuddle.CDDL import Codec.CBOR.Cuddle.CDDL.CtlOp import Codec.CBOR.Cuddle.Comments (Comment (..))+import Codec.CBOR.Cuddle.Parser (ParserStage, XTerm (..))+import Codec.CBOR.Cuddle.Pretty (PrettyStage, XRule (..), XTerm (..), XXTopLevel (..)) import Data.ByteString (ByteString) import Data.ByteString qualified as BS import Data.List.NonEmpty qualified as NE@@ -15,18 +19,26 @@ import Test.QuickCheck import Test.QuickCheck qualified as Gen -instance Arbitrary CDDL where+instance Arbitrary (CDDL PrettyStage) where   arbitrary = CDDL <$> arbitrary <*> arbitrary <*> arbitrary   shrink = genericShrink -instance Arbitrary TopLevel where+deriving newtype instance Arbitrary (XXTopLevel PrettyStage)++deriving newtype instance Arbitrary (XTerm PrettyStage)++deriving newtype instance Arbitrary (XRule PrettyStage)++instance Arbitrary (TopLevel PrettyStage) where   arbitrary =     Gen.oneof-      [ TopLevelComment <$> arbitrary+      [ XXTopLevel <$> arbitrary       , TopLevelRule <$> arbitrary       ]   shrink = genericShrink +deriving newtype instance Arbitrary (XTerm ParserStage)+ instance Arbitrary T.Text where   arbitrary = T.pack <$> arbitrary   shrink = fmap T.pack . shrink . T.unpack@@ -55,12 +67,10 @@           fstChar <- elements nameFstChars           midChar <- veryShortListOf . elements $ nameMidChars           lastChar <- elements nameEndChars-          pure $ Name (T.pack $ fstChar : midChar <> [lastChar]) mempty+          pure $ Name (T.pack $ fstChar : midChar <> [lastChar]) -  shrink (Name xs cmt) =-    Name-      <$> fmap T.pack (filter isValidName (shrink $ T.unpack xs))-      <*> shrink cmt+  shrink (Name xs) =+    Name <$> fmap T.pack (filter isValidName (shrink $ T.unpack xs))     where       isValidName [] = False       isValidName (h : tl) = h `elem` nameFstChars && isValidNameTail tl@@ -73,15 +83,24 @@   arbitrary = Gen.elements [AssignEq, AssignExt]   shrink = genericShrink -instance Arbitrary GenericParam where-  arbitrary = GenericParam <$> nonEmpty arbitrary-  shrink (GenericParam neName) = GenericParam <$> shrinkNE neName+instance Arbitrary (XTerm i) => Arbitrary (GenericParameter i) where+  arbitrary = GenericParameter <$> arbitrary <*> arbitrary -instance Arbitrary GenericArg where+instance (Monoid (XTerm i), Arbitrary (XTerm i)) => Arbitrary (GenericParameters i) where+  arbitrary = GenericParameters <$> nonEmpty arbitrary+  shrink (GenericParameters neName) = GenericParameters <$> shrinkNE neName++instance (Arbitrary (XTerm i), Monoid (XTerm i)) => Arbitrary (GenericArg i) where   arbitrary = GenericArg <$> nonEmpty arbitrary   shrink (GenericArg neArg) = GenericArg <$> shrinkNE neArg -instance Arbitrary Rule where+instance+  ( Monoid (XTerm i)+  , Arbitrary (XTerm i)+  , Arbitrary (XRule i)+  ) =>+  Arbitrary (Rule i)+  where   arbitrary =     Rule       <$> arbitrary@@ -103,7 +122,12 @@       ]   shrink = genericShrink -instance Arbitrary TypeOrGroup where+instance+  ( Arbitrary (XTerm i)+  , Monoid (XTerm i)+  ) =>+  Arbitrary (TypeOrGroup i)+  where   arbitrary =     Gen.oneof       [ TOGGroup <$> arbitrary@@ -111,15 +135,15 @@       ]   shrink = genericShrink -instance Arbitrary Type0 where+instance (Arbitrary (XTerm i), Monoid (XTerm i)) => Arbitrary (Type0 i) where   arbitrary = Type0 <$> nonEmpty arbitrary   shrink (Type0 neType1) = Type0 <$> shrinkNE neType1 -instance Arbitrary Type1 where+instance (Arbitrary (XTerm i), Monoid (XTerm i)) => Arbitrary (Type1 i) where   arbitrary = Type1 <$> arbitrary <*> arbitrary <*> arbitrary   shrink = genericShrink -instance Arbitrary Type2 where+instance (Monoid (XTerm i), Arbitrary (XTerm i)) => Arbitrary (Type2 i) where   arbitrary =     recursive       Gen.oneof@@ -138,7 +162,6 @@       [ T2Group <$> arbitrary       , T2Tag <$> arbitrary <*> arbitrary       ]-  shrink = genericShrink  instance Arbitrary OccurrenceIndicator where   arbitrary =@@ -153,15 +176,15 @@    shrink = genericShrink -instance Arbitrary Group where+instance (Monoid (XTerm i), Arbitrary (XTerm i)) => Arbitrary (Group i) where   arbitrary = Group <$> nonEmpty arbitrary   shrink (Group gr) = Group <$> shrinkNE gr -instance Arbitrary GrpChoice where+instance (Monoid (XTerm i), Arbitrary (XTerm i)) => Arbitrary (GrpChoice i) where   arbitrary = GrpChoice <$> listOf' arbitrary <*> pure mempty   shrink = genericShrink -instance Arbitrary GroupEntryVariant where+instance (Monoid (XTerm i), Arbitrary (XTerm i)) => Arbitrary (GroupEntryVariant i) where   arbitrary =     recursive       Gen.oneof@@ -176,15 +199,20 @@       ]   shrink = genericShrink -instance Arbitrary GroupEntry where+instance+  ( Arbitrary (XTerm i)+  , Monoid (XTerm i)+  ) =>+  Arbitrary (GroupEntry i)+  where   arbitrary =     GroupEntry       <$> arbitrary-      <*> pure mempty       <*> arbitrary+      <*> pure mempty   shrink = genericShrink -instance Arbitrary MemberKey where+instance (Monoid (XTerm i), Arbitrary (XTerm i)) => Arbitrary (MemberKey i) where   arbitrary =     recursive       Gen.oneof
+ test/Test/Codec/CBOR/Cuddle/CDDL/GeneratorSpec.hs view
@@ -0,0 +1,66 @@+{-# LANGUAGE OverloadedLists #-}+{-# LANGUAGE OverloadedStrings #-}++module Test.Codec.CBOR.Cuddle.CDDL.GeneratorSpec (spec) where++import Codec.CBOR.Cuddle.CBOR.Gen (generateCBORTerm)+import Codec.CBOR.Cuddle.CDDL.CBORGenerator (WrappedTerm (..))+import Codec.CBOR.Cuddle.CDDL.Resolve (fullResolveCDDL)+import Codec.CBOR.Cuddle.Huddle (+  Huddle,+  HuddleItem (..),+  a,+  arr,+  collectFrom,+  toCDDL,+  withGenerator,+  (=:=),+ )+import Codec.CBOR.Cuddle.Huddle qualified as H+import Codec.CBOR.Cuddle.IndexMappable (mapCDDLDropExt)+import Codec.CBOR.Term (Term)+import Codec.CBOR.Term qualified as C+import System.Random (mkStdGen)+import System.Random.Stateful (UniformRange (..))+import Test.Hspec (Expectation, Spec, describe, it, shouldBe)++foo :: H.Rule+foo = withGenerator (fmap (S . C.TInt) . uniformRM (4, 6)) $ "foo" =:= arr [1, 2, 3]++simpleTermExample :: Huddle+simpleTermExample =+  collectFrom+    [ HIRule foo+    ]++refTermExample :: Huddle+refTermExample =+  collectFrom+    [ HIRule foo+    , HIRule $ "bar" =:= arr [0, a foo]+    ]++bytesExample :: Huddle+bytesExample =+  collectFrom+    [ HIRule $ "foo" =:= H.bstr "010203ff"+    ]++huddleShouldGenerate :: Huddle -> Term -> Expectation+huddleShouldGenerate huddle term = do+  let g = mkStdGen 12345+  ct <- case fullResolveCDDL . mapCDDLDropExt $ toCDDL huddle of+    Right x -> pure x+    Left err -> fail $ "Failed to resolve CDDL: " <> show err+  generateCBORTerm ct "foo" g `shouldBe` term++spec :: Spec+spec = do+  describe "Custom generators" $ do+    describe "Huddle" $ do+      it "If a term has a custom generator then it is used" $+        simpleTermExample `huddleShouldGenerate` C.TInt 5+      it "Custom generator works when called via reference" $+        refTermExample `huddleShouldGenerate` C.TInt 5+      it "Bytes are generated correctly" $+        bytesExample `huddleShouldGenerate` C.TBytes "\x01\x02\x03\xff"
test/Test/Codec/CBOR/Cuddle/CDDL/Parser.hs view
@@ -4,11 +4,10 @@  import Codec.CBOR.Cuddle.CDDL import Codec.CBOR.Cuddle.CDDL.CtlOp qualified as CtlOp-import Codec.CBOR.Cuddle.Comments (Comment (..))+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..)) import Codec.CBOR.Cuddle.Parser import Codec.CBOR.Cuddle.Parser.Lexer (Parser)-import Codec.CBOR.Cuddle.Pretty ()-import Data.Default.Class (Default (..))+import Codec.CBOR.Cuddle.Pretty (PrettyStage) import Data.List.NonEmpty (NonEmpty (..)) import Data.Text qualified as T import Data.TreeDiff (ToExpr (..), ansiWlBgEditExprCompact, exprDiff)@@ -38,9 +37,9 @@ roundtripSpec = describe "Roundtripping should be id" $ do   it "Trip Name" $ trip pName   xit "Trip Value" $ trip pValue-  xit "Trip Type0" $ trip pType0-  xit "Trip GroupEntry" $ trip pGrpEntry-  xit "Trip Rule" $ trip pRule+  xit "Trip Type0" $ tripIndexed pType0+  xit "Trip GroupEntry" $ tripIndexed pGrpEntry+  xit "Trip Rule" $ tripIndexed pRule   where     -- We show that, for a printed CDDL document p, print (parse p) == p. Note     -- that we do not show that parse (print p) is p for a given generated@@ -60,6 +59,17 @@                 toExpr x `exprDiff` toExpr parsed             )             $ printed `shouldBe` printText parsed+    tripIndexed ::+      forall a.+      ( IndexMappable a ParserStage PrettyStage+      , Eq (a PrettyStage)+      , ToExpr (a PrettyStage)+      , Show (a PrettyStage)+      , Pretty (a PrettyStage)+      , Arbitrary (a PrettyStage)+      ) =>+      Parser (a ParserStage) -> Property+    tripIndexed = trip . fmap (mapIndex @a @ParserStage @PrettyStage)     printText :: Pretty a => a -> T.Text     printText = renderStrict . layoutPretty defaultLayoutOptions . pretty @@ -73,6 +83,9 @@     parse pValue "" "3.1415" `shouldParse` value (VFloat64 3.1415)   it "Parses text" $     parse pValue "" "\"Hello World\"" `shouldParse` value (VText "Hello World")+  it "Parses boolean" $ do+    parse pValue "" "true" `shouldParse` value (VBool True)+    parse pValue "" "false" `shouldParse` value (VBool False)  occurSpec :: Spec occurSpec = describe "pOccur" $ do@@ -95,11 +108,11 @@ nameSpec :: SpecWith () nameSpec = describe "pName" $ do   it "Parses a boring name" $-    parse pName "" "coin" `shouldParse` Name "coin" mempty+    parse pName "" "coin" `shouldParse` Name "coin"   it "Allows . in the middle" $-    parse pName "" "coin.me" `shouldParse` Name "coin.me" mempty+    parse pName "" "coin.me" `shouldParse` Name "coin.me"   it "Allows $ as the last character" $-    parse pName "" "coin.me$" `shouldParse` Name "coin.me$" mempty+    parse pName "" "coin.me$" `shouldParse` Name "coin.me$"   it "Doesn't allow . as a last character" $     parse pName "" "coin." `shouldFailWith` err 5 ueof @@ -108,14 +121,14 @@   it "Parses a simple value generic" $     parse pRule "" "a = b<0>"       `shouldParse` Rule-        (Name "a" mempty)+        (Name "a")         Nothing         AssignEq         ( TOGType             ( Type0                 ( Type1                     ( T2Name-                        (Name "b" mempty)+                        (Name "b")                         ( Just                             ( GenericArg                                 ( Type1@@ -137,14 +150,14 @@   it "Parses a range as a generic" $     parse pRule "" "a = b<0 ... 1>"       `shouldParse` Rule-        (Name "a" mempty)+        (Name "a")         Nothing         AssignEq         ( TOGType             ( Type0                 ( Type1                     ( T2Name-                        (Name "b" mempty)+                        (Name "b")                         ( Just                             ( GenericArg                                 ( Type1@@ -167,8 +180,12 @@ type2Spec :: SpecWith () type2Spec = describe "type2" $ do   describe "Value" $ do-    it "Parses a value" $+    it "Parses a value" $ do       parse pType2 "" "123" `shouldParse` T2Value (value $ VUInt 123)+      parse pType2 "" "true" `shouldParse` T2Value (value $ VBool True)+      parse pType2 "" "false" `shouldParse` T2Value (value $ VBool False)+      parse pType2 "" "h'0042ff'"+        `shouldParse` T2Value (value $ VBytes "\x00\x42\xff")   describe "Map" $ do     it "Parses a basic group" $       parse pType2 "" "{ int => string }"@@ -179,15 +196,15 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   ( Just                                       ( MKType                                           ( Type1-                                              { t1Main = T2Name (Name {name = "int", nameComment = Comment mempty}) Nothing+                                              { t1Main = T2Name "int" Nothing                                               , t1TyOp = Nothing-                                              , t1Comment = Comment mempty+                                              , t1Comment = mempty                                               }                                           )                                       )@@ -195,16 +212,16 @@                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "string", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "string" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| []               }@@ -218,15 +235,15 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Just OIZeroOrMore-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   ( Just                                       ( MKType                                           ( Type1-                                              { t1Main = T2Name (Name {name = "int", nameComment = Comment mempty}) Nothing+                                              { t1Main = T2Name "int" Nothing                                               , t1TyOp = Nothing-                                              , t1Comment = Comment mempty+                                              , t1Comment = mempty                                               }                                           )                                       )@@ -234,16 +251,16 @@                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "string", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "string" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| []               }@@ -257,18 +274,18 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   ( Just-                                      (MKType (Type1 {t1Main = T2Value (value $ VUInt 1), t1TyOp = Nothing, t1Comment = Comment mempty}))+                                      (MKType (Type1 {t1Main = T2Value (value $ VUInt 1), t1TyOp = Nothing, t1Comment = mempty}))                                   )                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "string", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "string" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }@@ -276,18 +293,18 @@                             }                         , GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   ( Just-                                      (MKType (Type1 {t1Main = T2Value (value $ VUInt 2), t1TyOp = Nothing, t1Comment = Comment mempty}))+                                      (MKType (Type1 {t1Main = T2Value (value $ VUInt 2), t1TyOp = Nothing, t1Comment = mempty}))                                   )                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "int", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "int" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }@@ -295,25 +312,25 @@                             }                         , GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   ( Just-                                      (MKType (Type1 {t1Main = T2Value (value $ VUInt 3), t1TyOp = Nothing, t1Comment = Comment mempty}))+                                      (MKType (Type1 {t1Main = T2Value (value $ VUInt 3), t1TyOp = Nothing, t1Comment = mempty}))                                   )                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "bytes", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "bytes" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| []               }@@ -328,45 +345,45 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   Nothing                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "int", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "int" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| [ GrpChoice                            { gcGroupEntries =                                [ GroupEntry                                    { geOccurrenceIndicator = Nothing-                                   , geComment = Comment mempty+                                   , geExt = mempty                                    , geVariant =                                        GEType                                          Nothing                                          ( Type0                                              { t0Type1 =                                                  Type1-                                                   { t1Main = T2Name (Name {name = "string", nameComment = Comment mempty}) Nothing+                                                   { t1Main = T2Name "string" Nothing                                                    , t1TyOp = Nothing-                                                   , t1Comment = Comment mempty+                                                   , t1Comment = mempty                                                    }                                                    :| []                                              }                                          )                                    }                                ]-                           , gcComment = Comment mempty+                           , gcComment = mempty                            }                        ]               }@@ -381,35 +398,35 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   Nothing                                   ( Type0                                       { t0Type1 =-                                          Type1 {t1Main = T2Value (value $ VUInt 0), t1TyOp = Nothing, t1Comment = Comment mempty} :| []+                                          Type1 {t1Main = T2Value (value $ VUInt 0), t1TyOp = Nothing, t1Comment = mempty} :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| [ GrpChoice                            { gcGroupEntries =                                [ GroupEntry                                    { geOccurrenceIndicator = Nothing-                                   , geComment = Comment mempty+                                   , geExt = mempty                                    , geVariant =                                        GEType                                          Nothing                                          ( Type0                                              { t0Type1 =-                                                 Type1 {t1Main = T2Value (value $ VUInt 1), t1TyOp = Nothing, t1Comment = Comment mempty} :| []+                                                 Type1 {t1Main = T2Value (value $ VUInt 1), t1TyOp = Nothing, t1Comment = mempty} :| []                                              }                                          )                                    }                                ]-                           , gcComment = Comment mempty+                           , gcComment = mempty                            }                        ]               }@@ -423,18 +440,18 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   Nothing                                   ( Type0                                       { t0Type1 =-                                          Type1 {t1Main = T2Value (value $ VUInt 1), t1TyOp = Nothing, t1Comment = Comment mempty} :| []+                                          Type1 {t1Main = T2Value (value $ VUInt 1), t1TyOp = Nothing, t1Comment = mempty} :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| []               }@@ -448,35 +465,35 @@                     { gcGroupEntries =                         [ GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   Nothing                                   ( Type0                                       { t0Type1 =-                                          Type1 {t1Main = T2Value (value $ VUInt 2), t1TyOp = Nothing, t1Comment = Comment mempty} :| []+                                          Type1 {t1Main = T2Value (value $ VUInt 2), t1TyOp = Nothing, t1Comment = mempty} :| []                                       }                                   )                             }                         , GroupEntry                             { geOccurrenceIndicator = Nothing-                            , geComment = Comment mempty+                            , geExt = mempty                             , geVariant =                                 GEType                                   Nothing                                   ( Type0                                       { t0Type1 =                                           Type1-                                            { t1Main = T2Name (Name {name = "soon", nameComment = Comment mempty}) Nothing+                                            { t1Main = T2Name "soon" Nothing                                             , t1TyOp = Nothing-                                            , t1Comment = Comment mempty+                                            , t1Comment = mempty                                             }                                             :| []                                       }                                   )                             }                         ]-                    , gcComment = Comment mempty+                    , gcComment = mempty                     }                     :| []               }@@ -488,16 +505,16 @@     parse pGrpEntry "" "int"       `shouldParse` GroupEntry         { geOccurrenceIndicator = Nothing-        , geComment = Comment mempty+        , geExt = mempty         , geVariant =             GEType               Nothing               ( Type0                   { t0Type1 =                       Type1-                        { t1Main = T2Name (Name {name = "int", nameComment = Comment mempty}) Nothing+                        { t1Main = T2Name "int" Nothing                         , t1TyOp = Nothing-                        , t1Comment = Comment mempty+                        , t1Comment = mempty                         }                         :| []                   }@@ -507,16 +524,16 @@     parse pGrpEntry "" "int // notConsideredHere"       `shouldParse` GroupEntry         { geOccurrenceIndicator = Nothing-        , geComment = Comment mempty+        , geExt = mempty         , geVariant =             GEType               Nothing               ( Type0                   { t0Type1 =                       Type1-                        { t1Main = T2Name (Name {name = "int", nameComment = Comment mempty}) Nothing+                        { t1Main = T2Name "int" Nothing                         , t1TyOp = Nothing-                        , t1Comment = Comment mempty+                        , t1Comment = mempty                         }                         :| []                   }@@ -526,7 +543,7 @@     parse pGrpEntry "" "a<0 ... #6(0)>"       `shouldParse` GroupEntry         { geOccurrenceIndicator = Nothing-        , geComment = Comment mempty+        , geExt = mempty         , geVariant =             GEType               Nothing@@ -535,7 +552,7 @@                       Type1                         { t1Main =                             T2Name-                              (Name {name = "a", nameComment = Comment mempty})+                              "a"                               ( Just                                   ( GenericArg                                       ( Type1@@ -547,18 +564,18 @@                                                     Nothing                                                     ( Type0                                                         { t0Type1 =-                                                            Type1 {t1Main = T2Value (value $ VUInt 0), t1TyOp = Nothing, t1Comment = Comment mempty} :| []+                                                            Type1 {t1Main = T2Value (value $ VUInt 0), t1TyOp = Nothing, t1Comment = mempty} :| []                                                         }                                                     )                                                 )-                                          , t1Comment = Comment mempty+                                          , t1Comment = mempty                                           }                                           :| []                                       )                                   )                               )                         , t1TyOp = Nothing-                        , t1Comment = Comment mempty+                        , t1Comment = mempty                         }                         :| []                   }@@ -568,28 +585,31 @@     parse pGrpEntry "" "0* a"       `shouldParse` GroupEntry         (Just (OIBounded (Just 0) Nothing))-        def         ( GEType             Nothing-            (Type0 (Type1 (T2Name (Name "a" mempty) Nothing) Nothing mempty :| []))+            (Type0 (Type1 (T2Name (Name "a") Nothing) Nothing mempty :| []))         )+        mempty  grpChoiceSpec :: SpecWith () grpChoiceSpec = describe "GroupChoice" $ do   it "Should parse part of a group alternative" $     parse pGrpChoice "" "int // string"       `shouldParse` GrpChoice-        [ GroupEntry Nothing mempty $-            GEType-              Nothing-              ( Type0-                  ( Type1-                      (T2Name (Name "int" mempty) Nothing)-                      Nothing-                      mempty-                      :| []-                  )-              )+        [ GroupEntry+            Nothing+            ( GEType+                Nothing+                ( Type0+                    ( Type1+                        (T2Name (Name "int") Nothing)+                        Nothing+                        mempty+                        :| []+                    )+                )+            )+            mempty         ]         mempty @@ -599,7 +619,7 @@     it "Should parse a basic control operator" $       parse pType1 "" "uint .size 3"         `shouldParse` Type1-          (T2Name (Name "uint" mempty) Nothing)+          (T2Name (Name "uint") Nothing)           (Just (CtrlOp CtlOp.Size, T2Value (value $ VUInt 3)))           mempty   describe "RangeOp" $ do@@ -629,36 +649,38 @@       Type1         { t1Main =             T2Map-              (Group {unGroup = GrpChoice {gcGroupEntries = [], gcComment = Comment mempty} :| []})+              (Group {unGroup = GrpChoice {gcGroupEntries = [], gcComment = mempty} :| []})         , t1TyOp =             Just               ( CtrlOp CtlOp.Ge               , T2EnumRef-                  (Name {name = "i", nameComment = Comment mempty})+                  "i"                   ( Just                       ( GenericArg                           ( Type1                               { t1Main =                                   T2Map-                                    (Group {unGroup = GrpChoice {gcGroupEntries = [], gcComment = Comment mempty} :| []})+                                    (Group {unGroup = GrpChoice {gcGroupEntries = [], gcComment = mempty} :| []})                               , t1TyOp = Nothing-                              , t1Comment = Comment mempty+                              , t1Comment = mempty                               }-                              :| [Type1 {t1Main = T2Value (value $ VUInt 3), t1TyOp = Nothing, t1Comment = Comment mempty}]+                              :| [Type1 {t1Main = T2Value (value $ VUInt 3), t1TyOp = Nothing, t1Comment = mempty}]                           )                       )                   )               )-        , t1Comment = Comment mempty+        , t1Comment = mempty         }     parseExample "S = 0* ()" pRule $       Rule-        (Name "S" mempty)+        (Name "S")         Nothing         AssignEq         ( TOGGroup-            ( GroupEntry (Just (OIBounded (Just 0) Nothing)) mempty $-                GEGroup (Group (GrpChoice mempty mempty :| []))+            ( GroupEntry+                (Just (OIBounded (Just 0) Nothing))+                (GEGroup (Group (GrpChoice mempty mempty :| [])))+                mempty             )         )         mempty@@ -666,16 +688,17 @@       "W = \"6 ybe2ddl8frq0vqa8zgrk07khrljq7p plrufpd1sff3p95\" : \"u\""       pRule       ( Rule-          (Name "W" mempty)+          (Name "W")           Nothing           AssignEq           ( TOGGroup               ( GroupEntry                   Nothing+                  ( GEType+                      (Just (MKValue (value $ VText "6 ybe2ddl8frq0vqa8zgrk07khrljq7p plrufpd1sff3p95")))+                      (Type0 (Type1 (T2Value (value $ VText "u")) Nothing mempty :| []))+                  )                   mempty-                  $ GEType-                    (Just (MKValue (value $ VText "6 ybe2ddl8frq0vqa8zgrk07khrljq7p plrufpd1sff3p95")))-                    (Type0 (Type1 (T2Value (value $ VText "u")) Nothing mempty :| []))               )           )           mempty
test/Test/Codec/CBOR/Cuddle/CDDL/Pretty.hs view
@@ -9,7 +9,7 @@ import Codec.CBOR.Cuddle.CDDL (   Assign (..),   CDDL,-  Group (Group),+  Group (..),   GroupEntry (..),   GroupEntryVariant (..),   GrpChoice (..),@@ -22,7 +22,11 @@   ValueVariant (..),   value,  )-import Codec.CBOR.Cuddle.Pretty ()+import Codec.CBOR.Cuddle.Huddle (HuddleItem (..), a, bstr, (<+), (=:=), (=:~))+import Codec.CBOR.Cuddle.Huddle qualified as H+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..))+import Codec.CBOR.Cuddle.Pretty (PrettyStage, XRule (..))+import Data.Default.Class (Default (..)) import Data.List.NonEmpty (NonEmpty (..)) import Data.Text qualified as T import Data.TreeDiff (ToExpr (..), prettyExpr)@@ -40,13 +44,13 @@   where     rendered = renderString (layoutPretty defaultLayoutOptions (pretty x)) -t2Name :: Type2-t2Name = T2Name (Name "a" mempty) mempty+t2Name :: Type2 PrettyStage+t2Name = T2Name (Name "a") mempty -t1Name :: Type1+t1Name :: Type1 PrettyStage t1Name = Type1 t2Name Nothing mempty -mkType0 :: Type2 -> Type0+mkType0 :: Type2 PrettyStage -> Type0 PrettyStage mkType0 t2 = Type0 $ Type1 t2 Nothing mempty :| []  spec :: Spec@@ -56,14 +60,14 @@  qcSpec :: Spec qcSpec = describe "QuickCheck" $ do-  xprop "CDDL prettyprinter leaves no trailing spaces" $ \(cddl :: CDDL) -> do+  xprop "CDDL prettyprinter leaves no trailing spaces" $ \(cddl :: CDDL PrettyStage) -> do     let       prettyStr = T.pack . renderString . layoutPretty defaultLayoutOptions $ pretty cddl       stripLines = T.unlines . fmap T.stripEnd . T.lines     counterexample (show . prettyExpr $ toExpr cddl) $       prettyStr `shouldBe` stripLines prettyStr -drep :: Rule+drep :: Rule PrettyStage drep =   Rule     "drep"@@ -77,37 +81,37 @@                         ( GrpChoice                             [ GroupEntry                                 Nothing-                                mempty                                 (GEType Nothing (Type0 $ Type1 (T2Value . value $ VUInt 0) Nothing mempty :| []))+                                mempty                             , GroupEntry                                 Nothing-                                mempty                                 (GEType Nothing (Type0 $ Type1 (T2Name "addr_keyhash" Nothing) Nothing mempty :| []))+                                mempty                             ]                             mempty                             :| [ GrpChoice                                    [ GroupEntry                                        Nothing-                                       mempty                                        (GEType Nothing (Type0 $ Type1 (T2Value . value $ VUInt 1) Nothing mempty :| []))+                                       mempty                                    , GroupEntry                                        Nothing-                                       mempty                                        (GEType Nothing (Type0 $ Type1 (T2Name "script_hash" Nothing) Nothing mempty :| []))+                                       mempty                                    ]                                    mempty                                , GrpChoice                                    [ GroupEntry                                        Nothing-                                       mempty                                        (GEType Nothing (Type0 $ Type1 (T2Value . value $ VUInt 2) Nothing mempty :| []))+                                       mempty                                    ]                                    mempty                                , GrpChoice                                    [ GroupEntry                                        Nothing-                                       mempty                                        (GEType Nothing (Type0 $ Type1 (T2Value . value $ VUInt 3) Nothing mempty :| []))+                                       mempty                                    ]                                    mempty                                ]@@ -120,68 +124,128 @@             )         )     )-    mempty+    def  unitSpec :: Spec unitSpec = describe "HUnit" $ do-  describe "Name" $ do-    it "names" $ Name "a" mempty `prettyPrintsTo` "a"-  describe "Type0" $ do-    it "name" $ Type0 (t1Name :| []) `prettyPrintsTo` "a"-  describe "Type1" $ do-    it "name" $ t1Name `prettyPrintsTo` "a"-  describe "Type2" $ do-    it "T2Name" $ t2Name `prettyPrintsTo` "a"-    describe "T2Array" $ do-      let groupEntryName = GroupEntry Nothing mempty $ GERef (Name "a" mempty) Nothing-      it "one element" $-        T2Array (Group (GrpChoice [groupEntryName] mempty :| [])) `prettyPrintsTo` "[a]"-      it "two elements" $-        T2Array-          ( Group-              ( GrpChoice-                  [ GroupEntry Nothing mempty $ GEType Nothing (mkType0 . T2Value . value $ VUInt 1)-                  , groupEntryName-                  ]-                  mempty-                  :| []-              )-          )-          `prettyPrintsTo` "[1, a]"-      it "two elements with comments" $-        T2Array-          ( Group-              ( GrpChoice-                  [ GroupEntry Nothing "one" $ GEType Nothing (mkType0 . T2Value . value $ VUInt 1)-                  , GroupEntry Nothing "two" $ GEType Nothing (mkType0 . T2Value . value $ VUInt 2)-                  ]-                  mempty-                  :| []-              )-          )-          `prettyPrintsTo` "[ 1 ; one\n, 2 ; two\n]"-      it "two elements with multiline comments" $-        T2Array-          ( Group-              ( GrpChoice-                  [ GroupEntry Nothing "first\nmultiline comment" $ GEType Nothing (mkType0 . T2Value . value $ VUInt 1)-                  , GroupEntry Nothing "second\nmultiline comment" $-                      GEType Nothing (mkType0 . T2Value . value $ VUInt 2)-                  ]-                  mempty-                  :| []-              )-          )-          `prettyPrintsTo` "[ 1 ; first\n    ; multiline comment\n, 2 ; second\n    ; multiline comment\n]"-  describe "Rule" $ do-    it "simple assignment" $-      Rule-        (Name "a" mempty)-        Nothing-        AssignEq-        (TOGType (Type0 (Type1 (T2Name (Name "b" mempty) mempty) Nothing mempty :| [])))-        mempty-        `prettyPrintsTo` "a = b"-    xit "drep" $-      drep-        `prettyPrintsTo` "drep = [0, addr_keyhash // 1, script_hash // 2 // 3]"+  describe "CDDL" $ do+    describe "Name" $ do+      it "names" $ Name "a" `prettyPrintsTo` "a"+    describe "Type0" $ do+      it "name" $ Type0 @PrettyStage (t1Name :| []) `prettyPrintsTo` "a"+    describe "Type1" $ do+      it "name" $ t1Name `prettyPrintsTo` "a"+    describe "Type2" $ do+      it "T2Name" $ t2Name `prettyPrintsTo` "a"+      describe "T2Array" $ do+        let groupEntryName = GroupEntry Nothing (GERef (Name "a") Nothing) ""+        it "one element" $+          T2Array (Group (GrpChoice [groupEntryName] mempty :| [])) `prettyPrintsTo` "[a]"+        it "two elements" $+          T2Array+            ( Group+                ( GrpChoice+                    [ GroupEntry Nothing (GEType Nothing (mkType0 . T2Value . value $ VUInt 1)) ""+                    , groupEntryName+                    ]+                    mempty+                    :| []+                )+            )+            `prettyPrintsTo` "[1, a]"+        it "two elements with comments" $+          T2Array+            ( Group+                ( GrpChoice+                    [ GroupEntry Nothing (GEType Nothing (mkType0 . T2Value . value $ VUInt 1)) "one"+                    , GroupEntry Nothing (GEType Nothing (mkType0 . T2Value . value $ VUInt 2)) "two"+                    ]+                    mempty+                    :| []+                )+            )+            `prettyPrintsTo` "[ 1 ; one\n, 2 ; two\n]"+        it "two elements with multiline comments" $+          T2Array+            ( Group+                ( GrpChoice+                    [ GroupEntry+                        Nothing+                        (GEType Nothing (mkType0 . T2Value . value $ VUInt 1))+                        "first\nmultiline comment"+                    , GroupEntry+                        Nothing+                        (GEType Nothing (mkType0 . T2Value . value $ VUInt 2))+                        "second\nmultiline comment"+                    ]+                    mempty+                    :| []+                )+            )+            `prettyPrintsTo` "[ 1 ; first\n    ; multiline comment\n, 2 ; second\n    ; multiline comment\n]"+    describe "Rule" $ do+      it "simple assignment" $+        Rule @PrettyStage+          (Name "a")+          Nothing+          AssignEq+          (TOGType (Type0 (Type1 (T2Name (Name "b") mempty) Nothing mempty :| [])))+          def+          `prettyPrintsTo` "a = b"+      it "simple assignment with comment" $+        Rule @PrettyStage+          (Name "a")+          Nothing+          AssignEq+          (TOGType (Type0 (Type1 (T2Name (Name "b") mempty) Nothing mempty :| [])))+          (PrettyXRule "comment")+          `prettyPrintsTo` "; comment\na = b"+      xit "drep" $+        drep+          `prettyPrintsTo` "drep = [0, addr_keyhash // 1, script_hash // 2 // 3]"+  describe "Huddle" $ do+    let+      huddlePrettyPrintsTo rs str =+        mapIndex @_ @_ @PrettyStage (H.toCDDLNoRoot $ H.collectFrom rs) `prettyPrintsTo` str+    describe "Rule" $ do+      -- TODO get rid of trailing newline+      it "simple assignment" $+        [HIRule $ "a" =:= H.bool True]+          `huddlePrettyPrintsTo` "a = true\n"+      it "simple assignment with comment" $+        [HIRule $ H.comment "comment" $ "a" =:= H.bool True]+          `huddlePrettyPrintsTo` "; comment\na = true\n"+      it "comment and reference" $+        let+          b = H.comment "this is rule 'b'" $ "b" =:= H.text "bee"+         in+          [ HIRule $ H.comment "comment" $ "a" =:= b+          ]+            `huddlePrettyPrintsTo` "; comment\na = b\n\n; this is rule 'b'\nb = \"bee\"\n"+      it "bstr expects hex, not bytes" $+        [ HIRule $ "a" =:= bstr "010200ff"+        ]+          `huddlePrettyPrintsTo` "a = h'010200ff'\n"+    describe "Generic rule" $ do+      it "comment and generic reference" $+        let+          b :: H.IsType0 a => a -> H.GRuleCall+          b = H.binding $ \x -> H.comment "bar" $ "b" =:= H.arr [0 <+ a x]+         in+          [ HIRule . H.comment "foo" $ "a" =:= b (H.bool True)+          ]+            `huddlePrettyPrintsTo` "; foo\na = b<true>\n\n; bar\nb<a0> = [* a0]\n"+    describe "GroupDef" $ do+      it "simple pair" $+        [HIGroup $ "a" =:~ [a $ H.bool True, a $ H.int 3]]+          `huddlePrettyPrintsTo` "a = (true, 3)\n"+      it "simple pair with comment" $+        [HIGroup $ H.comment "comment" $ "a" =:~ [a $ H.bool True, a $ H.int 3]]+          `huddlePrettyPrintsTo` "; comment\na = (true, 3)\n"+      it "comment and reference" $+        let+          b = H.comment "bar" $ "b" =:~ [a $ H.int 2, a $ H.text "bee"]+         in+          [ HIGroup . H.comment "foo" $ "a" =:~ [a $ H.bool True, a b]+          ]+            `huddlePrettyPrintsTo` "; foo\na = (true, b)\n\n; bar\nb = (2, \"bee\")\n"
+ test/Test/Codec/CBOR/Cuddle/CDDL/Validator.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE LambdaCase #-}++module Test.Codec.CBOR.Cuddle.CDDL.Validator (spec) where++import Codec.CBOR.Cuddle.CBOR.Gen (generateCBORTerm)+import Codec.CBOR.Cuddle.CBOR.Validator (+  CBORTermResult (..),+  CDDLResult (..),+  validateCBOR,+ )+import Codec.CBOR.Cuddle.CDDL (Name (..))+import Codec.CBOR.Cuddle.CDDL.CTree (CTreeRoot (..))+import Codec.CBOR.Cuddle.CDDL.CTree qualified as CTree+import Codec.CBOR.Cuddle.CDDL.Postlude (appendPostlude)+import Codec.CBOR.Cuddle.CDDL.Resolve (fullResolveCDDL)+import Codec.CBOR.Cuddle.IndexMappable (mapCDDLDropExt, mapIndex)+import Codec.CBOR.Cuddle.Parser (pCDDL)+import Codec.CBOR.Term (encodeTerm)+import Codec.CBOR.Write (toStrictByteString)+import Control.Monad (forM_)+import Data.Either (fromRight)+import Data.Map qualified as Map+import Data.Text qualified as T+import Data.Text.IO qualified as T+import Data.Text.Lazy qualified as LT+import Paths_cuddle (getDataFileName)+import Test.Hspec (Spec, describe, runIO, shouldSatisfy)+import Test.Hspec.QuickCheck+import Test.QuickCheck (counterexample, noShrinking)+import Test.QuickCheck.Random (mkQCGen)+import Text.Megaparsec (runParser)+import Text.Pretty.Simple (pShow)++genAndValidateFromFile :: FilePath -> Spec+genAndValidateFromFile path = do+  contents <- runIO $ T.readFile =<< getDataFileName path+  let+    cddl = fromRight (error "Failed to parse CDDL") $ runParser pCDDL path contents+    resolverError x =+      error $ "Failed to resolve the CDDL from file " <> show path <> ":\n" <> show x+    resolvedCddl@(CTreeRoot m) =+      either resolverError id . fullResolveCDDL . appendPostlude $+        mapCDDLDropExt cddl+    isRule CTree.Group {} = False+    isRule _ = True+  describe path $+    forM_ (Map.keys $ Map.filter isRule m) $ \name@(Name n) ->+      prop (T.unpack n) . noShrinking $ \seed -> do+        let+          gen = mkQCGen seed+          cborTerm = generateCBORTerm resolvedCddl name gen+          generatedCbor = toStrictByteString $ encodeTerm cborTerm+          res = validateCBOR generatedCbor name (mapIndex resolvedCddl)+          extraInfo =+            unlines+              [ "Term result:"+              , LT.unpack $ pShow res+              , "====="+              , "CBOR term:"+              , LT.unpack $ pShow cborTerm+              ]+        counterexample extraInfo $+          res `shouldSatisfy` \case+            CBORTermResult _ Valid {} -> True+            _ -> False++spec :: Spec+spec =+  describe "Generate and validate from file" $ do+    genAndValidateFromFile "example/cddl-files/basic_assign.cddl"+    genAndValidateFromFile "example/cddl-files/conway.cddl"+    genAndValidateFromFile "example/cddl-files/costmdls_min.cddl"+    genAndValidateFromFile "example/cddl-files/issue80-min.cddl"+    genAndValidateFromFile "example/cddl-files/pretty.cddl"+    genAndValidateFromFile "example/cddl-files/shelley.cddl"+    genAndValidateFromFile "example/cddl-files/validator.cddl"
test/Test/Codec/CBOR/Cuddle/Huddle.hs view
@@ -1,20 +1,73 @@ {-# LANGUAGE OverloadedLists #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE TypeData #-}+{-# LANGUAGE TypeFamilies #-}  {- HLINT ignore "Redundant bracket" -}  module Test.Codec.CBOR.Cuddle.Huddle where -import Codec.CBOR.Cuddle.CDDL (CDDL, sortCDDL)+import Codec.CBOR.Cuddle.CDDL (CDDL, fromRules, sortCDDL)+import Codec.CBOR.Cuddle.Comments (Comment) import Codec.CBOR.Cuddle.Huddle+import Codec.CBOR.Cuddle.IndexMappable (IndexMappable (..)) import Codec.CBOR.Cuddle.Parser import Data.Text qualified as T+import Data.Void (Void)+import GHC.Generics (Generic) import Test.Codec.CBOR.Cuddle.CDDL.Pretty qualified as Pretty import Test.Hspec import Test.Hspec.Megaparsec import Text.Megaparsec import Prelude hiding ((/)) +type data TestStage++newtype instance XCddl TestStage = TestXCddl [Comment]+  deriving (Generic, Show, Eq)++instance IndexMappable XCddl ParserStage TestStage where+  mapIndex (ParserXCddl x) = TestXCddl x++instance IndexMappable XCddl HuddleStage TestStage where+  mapIndex (HuddleXCddl x) = TestXCddl x++newtype instance XTerm TestStage = TestXTerm Comment+  deriving (Generic, Show, Eq)++instance IndexMappable XTerm ParserStage TestStage where+  mapIndex (ParserXTerm x) = TestXTerm x++instance IndexMappable XTerm HuddleStage TestStage where+  mapIndex (HuddleXTerm x) = TestXTerm x++newtype instance XRule TestStage = TestXRule Comment+  deriving (Generic, Show, Eq)++instance IndexMappable XRule ParserStage TestStage where+  mapIndex (ParserXRule x) = TestXRule x++instance IndexMappable XRule HuddleStage TestStage where+  mapIndex (HuddleXRule x _) = TestXRule x++newtype instance XXTopLevel TestStage = TestXXTopLevel Comment+  deriving (Generic, Show, Eq)++instance IndexMappable XXTopLevel ParserStage TestStage where+  mapIndex (ParserXXTopLevel x) = TestXXTopLevel x++instance IndexMappable XXTopLevel HuddleStage TestStage where+  mapIndex (HuddleXXTopLevel x) = TestXXTopLevel x++newtype instance XXType2 TestStage = TestXXType2 Void+  deriving (Generic, Show, Eq)++instance IndexMappable XXType2 ParserStage TestStage where+  mapIndex (ParserXXType2 x) = TestXXType2 x++instance IndexMappable XXType2 HuddleStage TestStage where+  mapIndex (HuddleXXType2 x) = TestXXType2 x+ huddleSpec :: Spec huddleSpec = describe "huddle" $ do   basicAssign@@ -37,6 +90,12 @@   -- it "Can assign a float" $   --   toSortedCDDL ["onepointone" =:= (1.1 :: Float)]   --     `shouldMatchParseCDDL` "onepointone = 1.1"+  it "Can assign `true` " $+    toSortedCDDL ["isValid" =:= (bool True)]+      `shouldMatchParseCDDL` "isValid = true"+  it "Can assign `false` " $+    toSortedCDDL ["isValid" =:= (bool False)]+      `shouldMatchParseCDDL` "isValid = false"   it "Can assign a text string" $     toSortedCDDL ["hello" =:= ("Hello World" :: T.Text)]       `shouldMatchParseCDDL` "hello = \"Hello World\""@@ -47,27 +106,27 @@ arraySpec :: Spec arraySpec = describe "Arrays" $ do   it "Can assign a small array" $-    toSortedCDDL ["asl" =:= arr [a VUInt, a VBool, a VText]]-      `shouldMatchParseCDDL` "asl = [ uint, bool, text ]"+    toSortedCDDL ["asl" =:= arr [a VUInt, a VBool, a VText, a (bool True)]]+      `shouldMatchParseCDDL` "asl = [ uint, bool, text, true ]"   it "Can quantify an upper bound" $     toSortedCDDL ["age" =:= arr [a VUInt +> 64]]       `shouldMatchParseCDDL` "age = [ *64 uint ]"   it "Can quantify an optional" $-    toSortedCDDL ["age" =:= arr [0 <+ a VUInt +> 1]]-      `shouldMatchParseCDDL` "age = [ ? uint ]"+    toSortedCDDL ["age" =:= arr [0 <+ a VUInt +> 1, 0 <+ a (bool False) +> 1]]+      `shouldMatchParseCDDL` "age = [ ? uint, ? false ]"   it "Can handle a choice" $     toSortedCDDL ["ageOrSex" =:= arr [a VUInt] / arr [a VBool]]       `shouldMatchParseCDDL` "ageOrSex = [ uint // bool ]"   it "Can handle choices of groups" $     toSortedCDDL       [ "asl"-          =:= arr [a VUInt, a VBool, a VText]+          =:= arr [a VUInt, a VBool, a VText, a (bool True)]           / arr             [ a (int 1)             , a ("Hello" :: T.Text)             ]       ]-      `shouldMatchParseCDDL` "asl = [ uint, bool, text // 1, \"Hello\" ]"+      `shouldMatchParseCDDL` "asl = [ uint, bool, text, true // 1, \"Hello\" ]"  mapSpec :: Spec mapSpec = describe "Maps" $ do@@ -90,9 +149,9 @@ grpSpec :: Spec grpSpec = describe "Groups" $ do   it "Can handle a choice in a group entry" $-    let g1 = "g1" =:~ grp [a (VUInt / VBytes), a VUInt]+    let g1 = "g1" =:~ grp [a (VUInt / VBytes), a VUInt, a (bool False)]      in toSortedCDDL (collectFrom [HIRule $ "a1" =:= arr [a g1]])-          `shouldMatchParseCDDL` "a1 = [g1]\n g1 = ( uint / bytes, uint )"+          `shouldMatchParseCDDL` "a1 = [g1]\n g1 = ( uint / bytes, uint, false)"   it "Can handle keys in a group entry" $     let g1 = "g1" =:~ grp ["bytes" ==> VBytes]      in toSortedCDDL (collectFrom [HIRule $ "a1" =:= arr [a g1]])@@ -155,10 +214,10 @@ shouldMatchParse x parseFun input = parse parseFun "" (T.pack input) `shouldParse` x  shouldMatchParseCDDL ::-  CDDL ->+  CDDL TestStage ->   String ->   Expectation-shouldMatchParseCDDL x = shouldMatchParse x pCDDL+shouldMatchParseCDDL x = shouldMatchParse x . fmap mapIndex $ pCDDL -toSortedCDDL :: Huddle -> CDDL-toSortedCDDL = sortCDDL . toCDDLNoRoot+toSortedCDDL :: Huddle -> CDDL TestStage+toSortedCDDL = mapIndex . fromRules . sortCDDL . toCDDLNoRoot