The Concise Binary Object Representation (CBOR) is a data format whose design goals include the possibility of extremely small code size, fairly small message size, and extensibility without the need for version negotiation. These design goals make it different from earlier binary serializations such as ASN.1 and MessagePack.
Describes how to encode a data structure or a type into binary CBOR
encode : Encoder -> Bytes
Turn a CBOR Encoder
into Bytes
.
sequence : List Encoder -> Encoder
Combine a bunch of encoders sequentially.
maybe : (a -> Encoder) -> Maybe a -> Encoder
Optionally encode a value. Nothing
is encoded as null
.
keyValue : (a -> Encoder) -> (b -> Encoder) -> ( a, b ) -> Encoder
Encode a key-value pair as a sequence of a key and a value. This is merely a
shorthand for a sequence
on a 2-tuple.
E.keyValue E.string E.int ( "a", 14 )
== E.sequence
[ E.string "a"
, E.int 14
]
bool : Basics.Bool -> Encoder
Encode booleans.
E.bool False == Bytes<0xF4>
E.bool True == Bytes<0xF5>
int : Basics.Int -> Encoder
Encode integers from -9007199254740992
(-2⁵³
) to 9007199254740991
(2⁵³ - 1
).
E.int 0 == Bytes<0x00>
E.int 1337 == Bytes<0x19, 0x05, 0x39>
float : Basics.Float -> Encoder
Encode floating numbers with maximum precision (64-bit).
E.float 0 == Bytes<0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>
E.float -4.1 == Bytes<0xFB, 0xC0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66>
NOTE:
This is an alias for
float64
.
string : String -> Encoder
Encode a String
of fixed size as a (definite) CBOR text string.
E.string "" == Bytes<0x60>
E.string "IETF" == Bytes <0x64, 0x49, 0x45, 0x54, 0x46>
E.string "🌈" == Bytes<0x64, 0xF0, 0x9F, 0x8C, 0x88>
bytes : Bytes -> Encoder
Encode raw Bytes
of fixed size as a (definite) CBOR byte string.
E.bytes Bytes<> == Bytes<0x40>
E.bytes Bytes<0x01, 0x02, 0x03, 0x04> = Bytes<0x44, 0x01, 0x02, 0x03, 0x04>
null : Encoder
Create a CBOR null
value. This can be decoded using Cbor.decode.maybe
.
E.null == Bytes<0xF6>
undefined : Encoder
Create a CBOR undefined
value. This can be decoded using Cbor.decode.maybe
.
E.undefined == Bytes<0xF7>
float16 : Basics.Float -> Encoder
Encode floating numbers with half-precision (16-bit).
E.float16 0.0 == Bytes<0xF9, 0x00, 0x00>
E.float16 -0.0 == Bytes<0xF9, 0x80, 0x00>
E.float16 1.5 == Bytes<0xF9, 0x3E, 0x00>
float32 : Basics.Float -> Encoder
Encode floating numbers with simple precision (32-bit).
E.float32 0.0 == Bytes<0xFA, 0x00, 0x00, 0x00, 0x00>
E.float32 3.4028234663852886e38 == Bytes<0xFA, 0x7F, 0x7F, 0xFF, 0xFF>
float64 : Basics.Float -> Encoder
Encode floating numbers with double precision (64-bit).
E.float64 0 == Bytes<0xFB, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00>
E.float64 -4.1 == Bytes<0xFB, 0xC0, 0x10, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66>
list : (a -> Encoder) -> List a -> Encoder
Turn a List
into a (definite) CBOR array
E.list E.int [1,2,3] == Bytes<0x83, 0x01, 0x02, 0x03>
indefiniteList : (a -> Encoder) -> List a -> Encoder
Turn a List
into a (indefinite) CBOR array
length : Basics.Int -> Encoder
Encode a (definite) list length only. This may be useful to stream a definite list or simply, to have even more fine-grained control over the creation of a definite list.
E.sequence
[ E.length 2
, E.int 1
, E.int 2
]
== E.list E.int [ 1, 2 ]
associativeList : (k -> Encoder) -> (v -> Encoder) -> List ( k, v ) -> Encoder
Turn a (key, value)
associative list into a (definite) CBOR map. Note
that, if keys are comparable
, you should consider using a Dict
and
dict
instead.
dict : (k -> Encoder) -> (v -> Encoder) -> Dict k v -> Encoder
Turn a Dict
into a (definite) CBOR map.
E.dict E.string E.int (Dict.fromList [ ( "a", 1 ), ( "b", 2 ) ])
== Bytes<0xA2, 0x61, 0x61, 0x01, 0x61, 0x62, 0x02>
size : Basics.Int -> Encoder
Encode a (definite) dict size only. This may be useful to stream a definite dict or simply, to have even more fine-grained control over the creation of a definite dict.
An intermediate (opaque) step in the encoding of a record or tuple. See
record
or tuple
for more detail.
record : (k -> Encoder) -> (Step k record -> Step k record) -> record -> Encoder
Encode a record as a (definite) CBOR map. Keys in the map can be arbitrary CBOR but are expected to be homogeneous across the record.
type alias Album =
{ artist : String
, title : String
, label : Maybe String
}
-- In this example, we use compact integer as keys.
encodeAlbumCompact : Album -> E.Encoder
encodeAlbumCompact =
E.record E.int <|
E.fields
>> E.field 0 E.string .artist
>> E.field 1 E.string .title
>> E.optionalField 2 E.string .genre
-- In this example, we use more verbose string keys.
encodeAlbumVerbose : Album -> E.Encoder
encodeAlbumVerbose =
E.record E.string <|
E.fields
>> E.field "artist" E.string .artist
>> E.field "title" E.string .title
>> E.optionalField "label" E.string .genre
fields : Step k record -> Step k record
A helper that makes writing record encoders nicer. It is equivalent to
identity
, but let us align encoders to fight compulsory OCDs.
field : k -> (field -> Encoder) -> (record -> field) -> Step k record -> Step k record
Encode a field of record and step through the encoding. See record
for detail about usage.
optionalField : k -> (field -> Encoder) -> (record -> Maybe field) -> Step k record -> Step k record
Encode an optional field of record and step through the encoding. See record
for detail about usage.
NOTE:
When the value is
Nothing
, the field (and its key) is completely omitted from the final record.
tuple : (Step Basics.Never tuple -> Step Basics.Never tuple) -> tuple -> Encoder
Encode a record / tuple as a (definite) CBOR array.
type alias Track =
{ title : String
, duration : Int
}
encodeTrack : Track -> E.Encoder
encodeTrack =
E.tuple <|
E.elems
>> E.elem E.string .title
>> E.elem E.int .duration
elems : Step Basics.Never tuple -> Step Basics.Never tuple
A helper that makes writing tuple encoders nicer. It is equivalent to
identity
, but let us align encoders to fight compulsory OCDs.
elem : (elem -> Encoder) -> (tuple -> elem) -> Step Basics.Never tuple -> Step Basics.Never tuple
Encode an elements of a tuple and step through the encoding. See tuple
for detail about usage.
optionalElem : (elem -> Encoder) -> (tuple -> Maybe elem) -> Step Basics.Never tuple -> Step Basics.Never tuple
Optionally encode an element in a tuple. See tuple
for detail about usage.
Four CBOR items (arrays, maps, byte strings, and text strings) can be encoded with an indefinite length. This is useful if the encoding of the item needs to begin before the number of items inside the array or map, or the total length of the string, is known. (The application of this is often referred to as "streaming" within a data item.)
NOTE:
Indefinite-length arrays and maps are dealt with differently than indefinite-length byte strings and text strings.
beginString : Encoder
Encode a String
of indefinite length in chunks. This indicates the beginning of multiple calls
to string
, followed by a break
to signal the end of the
stream. For example:
E.sequence
[ E.beginString
, E.string "elm"
, E.string "rocks"
, E.string "!"
, E.break
]
beginBytes : Encoder
Encode a Bytes
of indefinite length in chunks. This indicates the beginning of multiple calls
to bytes
, followed by a break
to signal the end of the
stream. For example:
E.sequence
[ E.beginBytes
, E.bytes Bytes<0x01, 0x02>
, E.bytes Bytes<0x03, 0x04>
, E.break
]
beginList : Encoder
Encode a List
of indefinite length. This indicates the beginning of
multiple calls for encoding elements, followed by a break
to signal
the end of the stream. For example:
E.sequence
[ E.beginList
, E.string "elm"
, E.string "rocks"
, E.string "!"
, E.break
]
beginDict : Encoder
Encode a Dict
of indefinite length. This indicates the beginning of multiple calls for
encoding pairs of elements, followed by a break
to signal the end of
the stream. For example:
E.sequence
[ E.beginDict
, E.keyValue E.int E.string ( 1, "elm" )
, E.keyValue E.int E.string ( 2, "rocks" )
, E.keyValue E.int E.string ( 3, "!" )
, E.break
]
break : Encoder
Encode termination of an indefinite structure. See
beginString
, beginBytes
,
beginList
, beginDict
for detail about usage.
tag : Cbor.Tag.Tag -> Encoder
Encode a particular Tag
as a CBOR tag prefix.
tagged : Cbor.Tag.Tag -> (a -> Encoder) -> a -> Encoder
Helper to quickly a tagged value
E.tagged t encodeA a == E.sequence [ E.tag t, encodeA a ]
any : CborItem -> Encoder
Encode any generic CBOR item. This is particularly useful when dealing with heterogeneous data structures (e.g. tuples).
E.list E.any [ CborInt 42, CborBool True, CborString "awesome!" ]
raw : Bytes -> Encoder
Unsafe encoder to inject any arbitrary bytes into the encoding sequence. Do not use unless you know what you're doing, this may result in invalid CBOR encoding!