Safe Haskell | None |
---|---|
Language | GHC2021 |
Codec.CBOR.Cuddle.Huddle
Description
Module for building CDDL in Haskell
Compared to the builders, this is less about creating a DSL for CDDL in Haskell as about using Haskell's higher-level capabilities to express CDDL constraints. So we ditch a bunch of CDDL concepts where we can instead use Haskell's capabilities there.
Synopsis
- data Huddle
- data HuddleItem
- huddleAugment :: Huddle -> Huddle -> Huddle
- type Rule = Named Type0
- data Named a
- class IsType0 a where
- toType0 :: a -> Type0
- data Value a where
- (=:=) :: IsType0 a => Text -> a -> Rule
- (=:~) :: Text -> Group -> Named Group
- comment :: HasField' "description" a (Maybe Text) => Text -> a -> a
- (==>) :: (IsType0 a, IsEntryLike me) => Key -> a -> me
- mp :: MapChoice -> MapChoice
- asKey :: IsType0 r => r -> Key
- idx :: Word64 -> Key
- a :: (IsType0 a, IsGroupOrArrayEntry e) => a -> e
- arr :: ArrayChoice -> ArrayChoice
- data Group
- grp :: Group -> Group
- class CanQuantify a where
- opt :: CanQuantify a => a -> a
- (/) :: (IsChoosable a c, IsChoosable b c) => a -> b -> Choice c
- seal :: a -> Seal a
- sarr :: ArrayChoice -> Seal Array
- smp :: MapChoice -> Seal Map
- data Literal
- bstr :: ByteString -> Literal
- int :: Integer -> Literal
- text :: Text -> Literal
- class IsConstrainable a x | a -> x
- class IsSizeable (a :: k)
- sized :: forall c a s. (IsSizeable a, IsSize s, IsConstrainable c a) => c -> s -> Constrained
- cbor :: (IsCborable b, IsConstrainable c b) => c -> Rule -> Constrained
- le :: (IsComparable a, IsConstrainable c a) => c -> Word64 -> Constrained
- (...) :: (IsRangeBound a, IsRangeBound b) => a -> b -> Ranged
- tag :: Word64 -> a -> Tagged a
- data GRef
- type GRuleDef = Named (GRule GRef)
- type GRuleCall = Named (GRule Type2)
- binding :: IsType0 t0 => (GRef -> Rule) -> t0 -> GRuleCall
- binding2 :: (IsType0 t0, IsType0 t1) => (GRef -> GRef -> Rule) -> t0 -> t1 -> GRuleCall
- callToDef :: GRule Type2 -> GRule GRef
- collectFrom :: [HuddleItem] -> Huddle
- collectFromInit :: [HuddleItem] -> Huddle
- toCDDL :: Huddle -> CDDL
- toCDDLNoRoot :: Huddle -> CDDL
Core Types
Top-level Huddle type is a list of rules.
Instances
Semigroup Huddle Source # | This semigroup instance: - Takes takes the roots from the RHS unless they are empty, in which case it takes the roots from the LHS - Uses the RHS to override items on the LHS where they share a name. The value from the RHS is taken, but the index from the LHS is used. Note that this allows replacing items in the middle of a tree without updating higher-level items which make use of them - that is, we do not need to "close over" higher-level terms, since by the time they have been built into a huddle structure, the references have been converted to keys. | ||||
Generic Huddle Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle Associated Types
| |||||
IsList Huddle Source # | This instance is mostly used for testing | ||||
Show Huddle Source # | |||||
Default Huddle Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle | |||||
type Rep Huddle Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle type Rep Huddle = D1 ('MetaData "Huddle" "Codec.CBOR.Cuddle.Huddle" "cuddle-0.5.0.0-H0bbRBZdSvH43WSgb38tp7" 'False) (C1 ('MetaCons "Huddle" 'PrefixI 'True) (S1 ('MetaSel ('Just "roots") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 [Rule]) :*: S1 ('MetaSel ('Just "items") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (OMap Text HuddleItem)))) | |||||
type Item Huddle Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle |
data HuddleItem Source #
Instances
Instances
Functor Named Source # | |||||
IsType0 GRuleCall Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle | |||||
IsType0 Rule Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle | |||||
Generic (Named a) Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle Associated Types
| |||||
Show (Named a) Source # | |||||
IsType0 (Named Group) Source # | |||||
type Rep (Named a) Source # | |||||
Defined in Codec.CBOR.Cuddle.Huddle type Rep (Named a) = D1 ('MetaData "Named" "Codec.CBOR.Cuddle.Huddle" "cuddle-0.5.0.0-H0bbRBZdSvH43WSgb38tp7" 'False) (C1 ('MetaCons "Named" 'PrefixI 'True) (S1 ('MetaSel ('Just "name") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text) :*: (S1 ('MetaSel ('Just "value") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a) :*: S1 ('MetaSel ('Just "description") 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 (Maybe Text))))) |
class IsType0 a where Source #
Instances
IsType0 ByteString Source # | |
Defined in Codec.CBOR.Cuddle.Huddle Methods toType0 :: ByteString -> Type0 Source # | |
IsType0 GRef Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 GRuleCall Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 HuddleItem Source # | |
Defined in Codec.CBOR.Cuddle.Huddle Methods toType0 :: HuddleItem -> Type0 Source # | |
IsType0 Literal Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 Rule Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 Text Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 Integer Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 Double Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 Float Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsType0 (Named Group) Source # | |
IsType0 (Value a) Source # | |
Defined in Codec.CBOR.Cuddle.Huddle |
Type-parametrised value type handling CBOR primitives. This is used to constrain the set of constraints which can apply to a given postlude type.
Constructors
VBool :: Value Bool | |
VUInt :: Value Int | |
VNInt :: Value Int | |
VInt :: Value Int | |
VHalf :: Value Float | |
VFloat :: Value Float | |
VDouble :: Value Double | |
VBytes :: Value ByteString | |
VText :: Value Text | |
VAny :: Value Void | |
VNil :: Value Void |
Instances
Show (Value a) Source # | |
IsType0 (Value a) Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsConstrainable (Value a) a Source # | |
Defined in Codec.CBOR.Cuddle.Huddle Methods toConstrainable :: Value a -> Constrainable a |
Rules and assignment
comment :: HasField' "description" a (Maybe Text) => Text -> a -> a Source #
Add a description to a rule or group entry, to be included as a comment.
Maps
Arrays
a :: (IsType0 a, IsGroupOrArrayEntry e) => a -> e Source #
Explicitly cast an item in an Array as an ArrayEntry.
arr :: ArrayChoice -> ArrayChoice Source #
This function is used solely to resolve type inference by explicitly identifying something as an array.
Groups
Quantification
class CanQuantify a where Source #
opt :: CanQuantify a => a -> a Source #
Choices
(/) :: (IsChoosable a c, IsChoosable b c) => a -> b -> Choice c infixl 9 Source #
Allow choices between constructions
in CDDL, /
a choice between types (concretely, between Type1 values, to
make a Type0). //
allows choice between groups. We can illustrate the
difference with the following snippet:
foo = [ 0 1, uint 2 3, tstr ]
This construction would match either of the following:
[0, 3] [2, "Hello World"]
In other words, the //
binds less strongly than comma (',') in CDDL.
In Haskell, of course, we cannot have syntax inside an array which binds
stronger than the comma. so we have to do things a little differently. The
way this is handled at the moment is that /
has special treatment for
arrays/groups, where it will, instead of creating a type-level choice, merge
the two arraysgroupsmaps into a single one containing a group choice.
If one instead wants the behaviour corresponding to the CDDL /
for arrays,
maps or groups, one can "seal" the array or group using the seal
, sarr
or
smp
functions. For example:
"foo" =:= sarr [0, a VUInt] / sarr [1, a VText]
Generates a choice (at the Type0
) level between two arrays, whereas
"foo" =:= arr [0, a VUInt] / arr [1, a VUInt]
will generate a single array containing a group choice between two groups.
As such, there is no //
operator in Huddle.
Seal an array or map, indicating that it will no longer absorb (//). This is needed if you wish to include an array or map inside a top-level choice.
sarr :: ArrayChoice -> Seal Array Source #
Create and seal an array, marking it as accepting no additional choices
smp :: MapChoice -> Seal Map Source #
Create and seal a map, marking it as accepting no additional choices.
Literals
bstr :: ByteString -> Literal Source #
Ctl operators
class IsConstrainable a x | a -> x Source #
Minimal complete definition
toConstrainable
Instances
IsConstrainable (Value a) a Source # | |
Defined in Codec.CBOR.Cuddle.Huddle Methods toConstrainable :: Value a -> Constrainable a |
class IsSizeable (a :: k) Source #
Marker that we can apply the size CtlOp to something. Not intended for export.
Instances
IsSizeable ByteString Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsSizeable Text Source # | |
Defined in Codec.CBOR.Cuddle.Huddle | |
IsSizeable Int Source # | |
Defined in Codec.CBOR.Cuddle.Huddle |
sized :: forall c a s. (IsSizeable a, IsSize s, IsConstrainable c a) => c -> s -> Constrained Source #
Declare a size constraint on an int-style type or reference. Since 0.3.4 this has worked for reference types as well as values.
cbor :: (IsCborable b, IsConstrainable c b) => c -> Rule -> Constrained Source #
le :: (IsComparable a, IsConstrainable c a) => c -> Word64 -> Constrained Source #
Ranged
(...) :: (IsRangeBound a, IsRangeBound b) => a -> b -> Ranged infixl 9 Source #
Establish a closed range bound.
Tagging
tag :: Word64 -> a -> Tagged a Source #
Tag a CBOR item with a CDDL minor type. Thus, `tag n x` is equivalent to `#6.n(x)` in CDDL.
Generics
binding :: IsType0 t0 => (GRef -> Rule) -> t0 -> GRuleCall Source #
Bind a single variable into a generic call
binding2 :: (IsType0 t0, IsType0 t1) => (GRef -> GRef -> Rule) -> t0 -> t1 -> GRuleCall Source #
Bind two variables as a generic call
Conversion to CDDL
collectFrom :: [HuddleItem] -> Huddle Source #
Collect all rules starting from a given point. This will also insert a single pseudo-rule as the first element which references the specified top-level rules.
collectFromInit :: [HuddleItem] -> Huddle Source #
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.
toCDDLNoRoot :: Huddle -> CDDL Source #
Convert from Huddle to CDDL, skipping a root element.