Skip to main content

Module dag_cbor

Module dag_cbor 

Source
Expand description

The DAG-CBOR encoding, which is the canonical form a record is hashed in.

CBOR by itself has many encodings of the same value: an integer can be written in five widths, an array can be indefinite-length, a map can be in any order. DAG-CBOR is the profile that removes all of that, and a record’s identity is the sha-256 of these bytes, so “several encodings” would mean “several identities for one record”.

The rules, all of which are enforced here rather than left to a caller:

  • Shortest-form counts. A length or an integer is written in the smallest of the five widths that holds it. 23 is one byte, never two.
  • Definite lengths only. Every string, list and map declares its length up front. The indefinite-length forms are not emitted.
  • Map keys are sorted length-first, then bytewise within a length. This is the ordering the atproto fixtures use and it is not the ordering a BTreeMap<String, _> iterates in — integer sorts before unicode either way, but bool sorts before array only under this rule. Sorting is done here, at the encoder, so that no caller can hold a map in the wrong order to begin with.
  • No floats. Value has no float variant; see its documentation.
  • Links are tag 42, carrying a byte string that is a zero byte — the identity multibase prefix — followed by the CID’s binary form.

Encoding cannot fail. Everything that could go wrong went wrong earlier, in Value::from_json, and a Value that exists has an encoding by construction.

§The other direction

decode reads a block back, and it is the harder half: an encoder has to emit the canonical form, while a decoder has to refuse every other one. It exists because a Merkle search tree that arrived from somewhere else — in a CAR file, in a firehose frame — is a pile of blocks, and reading it means reading them. See decode for what it refuses and why each refusal matters.

Modules§

read 🔒
Reading a block back, which is a stricter job than writing one.

Enums§

CborError
Why a block is not a value in this data model.

Constants§

IDENTITY_MULTIBASE 🔒
The multibase prefix inside a link’s byte string: identity, meaning the bytes are the CID itself and not a text encoding of it.
MAJOR_BYTES 🔒
CBOR major type 2: a byte string.
MAJOR_LIST 🔒
CBOR major type 4: a list.
MAJOR_MAP 🔒
CBOR major type 5: a map.
MAJOR_NEGATIVE 🔒
CBOR major type 1: a negative integer, stored as -1 - n.
MAJOR_SIMPLE 🔒
CBOR major type 7: the simple values, of which DAG-CBOR uses three.
MAJOR_TAG 🔒
CBOR major type 6: a tag.
MAJOR_TEXT 🔒
CBOR major type 3: a UTF-8 string.
MAJOR_UNSIGNED 🔒
CBOR major type 0: a non-negative integer.
MAX_DEPTH
How deep a value may nest before it is refused.
TAG_LINK 🔒
The tag that marks a link. 42 is the IPLD CID tag, and it is the only tag DAG-CBOR permits.

Functions§

cid
Encodes a value and returns the CID naming that block.
decode
Decodes one block into the data model.
encode
Encodes a value into its one DAG-CBOR form.
header 🔒
Writes a major type and its argument in the shortest form that holds it.
header_byte 🔒
A major type and a small argument in one byte.
key_order 🔒
The DAG-CBOR map key ordering: shorter keys first, then bytewise.
write 🔒
Writes one value.