//! The DAG-CBOR wire schema for MST nodes. //! //! ```text //! { //! l: Cid | null // subtree left of the first entry //! e: [ //! { p: uint // bytes shared with the previous key in this node //! , k: bytes // the rest of this key //! , v: Cid // the record this key points at //! , t: Cid | null // subtree between this key and the next //! } //! ... //! ] //! } //! ``` //! //! note: `l` and `t` are nullable, not optional. //! //! Prefix compression resets per node: the first entry has `p = 0` and carries //! its whole key. use serde::{Deserialize, Serialize}; use crate::cid::{Cid, Codec}; /// Fields are declared in canonical DAG-CBOR map order (`k`, `p`, `t`, `v`), /// so the encoding is canonical whether or not the codec sorts for us (but... /// to even be DAG-CBOR it has to sort??) #[derive(Debug, Serialize, Deserialize)] pub(crate) struct EntryData { #[serde(rename = "k", with = "serde_bytes")] pub key_suffix: Vec, #[serde(rename = "p")] pub prefix_len: usize, #[serde(rename = "t")] pub right: Option, #[serde(rename = "v")] pub value: Cid, } /// Canonical map order again: `e` before `l`. #[derive(Debug, Serialize, Deserialize)] pub(crate) struct NodeData { #[serde(rename = "e")] pub entries: Vec, #[serde(rename = "l")] pub left: Option, } /// The CID of a block of DAG-CBOR, which is how every MST node is addressed. pub(crate) fn cid_for(block: &[u8]) -> Cid { Cid::digest_sha2(Codec::Drisl, block) }