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