Skip to main content

substrate_data/schema/
format.rs

1//! [`Schema`]: a format, a type that reads, writes, encodes, packs and describes itself.
2
3use super::{Reader, Shape, read_ref_value};
4use crate::binary::{Decoder, Writer};
5use crate::frame::{Packer, Unpacker};
6use crate::model::borrowed::ValueRef;
7use crate::model::value::Value;
8
9/// A format: a type that reads, writes, encodes, packs and describes itself.
10pub trait Schema: Sized {
11    /// What the format looks like.
12    fn shape() -> Shape;
13
14    /// Reads `v`. Problems go to `cx` at its current path; `None` when the
15    /// value couldn't be read (the problem is in `cx`).
16    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self>;
17
18    /// The value, as the format writes it.
19    fn write(&self) -> Value;
20
21    /// The value of a field that isn't there — `None`: the field is required.
22    #[must_use]
23    fn absent() -> Option<Self> {
24        None
25    }
26
27    /// Whether a struct leaves this field out when writing it.
28    fn skip(&self) -> bool {
29        false
30    }
31
32    /// Writes itself in the binary form, straight — [`Schema::write`]'s
33    /// value encoded, unless the type knows better (derived ones do).
34    fn encode(&self, w: &mut Writer) {
35        w.value(&self.write());
36    }
37
38    /// Reads itself from the binary form, straight; `None` when it isn't
39    /// what [`Schema::encode`] writes — then [`read_bytes`](crate::schema::read_bytes) reads the slow
40    /// way, which says what's wrong. Through a value unless the type knows
41    /// better (derived ones do).
42    fn decode(d: &mut Decoder<'_>) -> Option<Self> {
43        let arena = bumpalo::Bump::new();
44        let v = d.value_ref(&arena).ok()?;
45        read_ref_value(&v).ok()
46    }
47
48    /// Packs itself into a frame ([`crate::frame`]): its binary form as
49    /// bytes, unless the type packs itself (derived ones and plain types do).
50    fn pack(&self, p: &mut Packer) {
51        p.put_tagged(self);
52    }
53
54    /// Reads itself out of a frame; `None` if the bytes aren't what
55    /// [`Schema::pack`] writes.
56    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
57        u.tagged()
58    }
59
60    /// A list of these packed: a count, then each one (floats raw).
61    fn pack_list(items: &[Self], p: &mut Packer) {
62        let at = p.begin_list(items.len());
63        for item in items {
64            item.pack(p);
65        }
66        p.end(at);
67    }
68
69    /// A list of these out of a frame.
70    fn unpack_list(u: &mut Unpacker<'_>) -> Option<Vec<Self>> {
71        let (n, end) = u.list()?;
72        let mut out = Vec::with_capacity(n);
73        for _ in 0..n {
74            out.push(Self::unpack(u)?);
75        }
76        u.skip_to(end)?;
77        Some(out)
78    }
79
80    /// A list of these written straight (numbers pack theirs).
81    fn encode_list(items: &[Self], w: &mut Writer) {
82        w.list(items.len());
83        for item in items {
84            item.encode(w);
85        }
86    }
87
88    /// A list of these read straight.
89    fn decode_list(d: &mut Decoder<'_>) -> Option<Vec<Self>> {
90        let n = d.list()?;
91        let mut out = Vec::with_capacity(n);
92        for _ in 0..n {
93            out.push(Self::decode(d)?);
94        }
95        d.leave();
96        Some(out)
97    }
98}