Skip to main content

substrate_data/schema/plain/
lists.rs

1//! The schemas of lists, sets, boxed slices and arrays.
2
3use crate::binary::{Decoder, Writer};
4use crate::frame::{Packer, Unpacker};
5use crate::model::borrowed::ValueRef;
6use crate::model::value::{Seg, Value};
7use crate::schema::{Expected, Reader, Schema, Shape};
8
9impl<T: Schema> Schema for Vec<T> {
10    fn shape() -> Shape {
11        Shape::List(T::shape)
12    }
13    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
14        let ValueRef::List(items) = v else {
15            cx.expected(Expected::List, v);
16            return None;
17        };
18        let mut out = Vec::with_capacity(items.len());
19        let mut ok = true;
20        for (i, item) in items.iter().enumerate() {
21            match cx.at(Seg::Index(i), |cx| T::read(item, cx)) {
22                Some(x) => out.push(x),
23                None => ok = false,
24            }
25        }
26        ok.then_some(out)
27    }
28    fn write(&self) -> Value {
29        Value::List(self.iter().map(T::write).collect())
30    }
31    fn encode(&self, w: &mut Writer) {
32        T::encode_list(self, w);
33    }
34    fn decode(d: &mut Decoder<'_>) -> Option<Self> {
35        T::decode_list(d)
36    }
37    fn pack(&self, p: &mut Packer) {
38        T::pack_list(self, p);
39    }
40    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
41        T::unpack_list(u)
42    }
43}
44
45/// A set: a list, in order, each once.
46impl<T: Schema + Ord + Clone> Schema for std::collections::BTreeSet<T> {
47    fn shape() -> Shape {
48        Shape::List(T::shape)
49    }
50    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
51        Vec::<T>::read(v, cx).map(Self::from_iter)
52    }
53    fn write(&self) -> Value {
54        Value::List(self.iter().map(T::write).collect())
55    }
56    fn encode(&self, w: &mut Writer) {
57        // As a list of them is written (numbers packed).
58        T::encode_list(&self.iter().cloned().collect::<Vec<_>>(), w);
59    }
60    fn decode(d: &mut Decoder<'_>) -> Option<Self> {
61        Vec::<T>::decode(d).map(Self::from_iter)
62    }
63    /// In a frame it's a list, as its shape says.
64    fn pack(&self, p: &mut Packer) {
65        T::pack_list(&self.iter().cloned().collect::<Vec<_>>(), p);
66    }
67    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
68        T::unpack_list(u).map(Self::from_iter)
69    }
70}
71
72/// A string that won't change: a pointer and a length, no spare capacity
73/// (`String`'s third word) — what big tables of names keep.
74/// A list that won't change: no spare capacity.
75impl<T: Schema> Schema for Box<[T]> {
76    fn shape() -> Shape {
77        Shape::List(T::shape)
78    }
79    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
80        Vec::<T>::read(v, cx).map(Vec::into_boxed_slice)
81    }
82    fn write(&self) -> Value {
83        Value::List(self.iter().map(T::write).collect())
84    }
85    fn encode(&self, w: &mut Writer) {
86        T::encode_list(self, w);
87    }
88    fn decode(d: &mut Decoder<'_>) -> Option<Self> {
89        T::decode_list(d).map(Vec::into_boxed_slice)
90    }
91    fn pack(&self, p: &mut Packer) {
92        T::pack_list(self, p);
93    }
94    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
95        T::unpack_list(u).map(Vec::into_boxed_slice)
96    }
97}
98
99impl<T: Schema, const N: usize> Schema for [T; N] {
100    fn shape() -> Shape {
101        Shape::List(T::shape)
102    }
103    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
104        let items = Vec::<T>::read(v, cx)?;
105        let len = items.len();
106        items.try_into().ok().or_else(|| {
107            cx.problem(format!("expected {N} items, found {len}"));
108            None
109        })
110    }
111    fn write(&self) -> Value {
112        Value::List(self.iter().map(T::write).collect())
113    }
114    fn encode(&self, w: &mut Writer) {
115        T::encode_list(self, w);
116    }
117    fn decode(d: &mut Decoder<'_>) -> Option<Self> {
118        T::decode_list(d)?.try_into().ok()
119    }
120    fn pack(&self, p: &mut Packer) {
121        T::pack_list(self, p);
122    }
123    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
124        T::unpack_list(u)?.try_into().ok()
125    }
126}