substrate_data/schema/plain/
one_or_list.rs1use crate::frame::{Packer, Unpacker};
6use crate::schema::{Reader, Schema, Shape};
7use crate::{Value, ValueRef};
8
9#[derive(Debug, Clone, PartialEq)]
12pub struct OneOrList<T>(pub Vec<T>);
13
14impl<T: Schema> Schema for OneOrList<T> {
15 fn shape() -> Shape {
16 Shape::List(T::shape)
17 }
18 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
19 match v {
20 ValueRef::List([]) => {
21 cx.problem("an empty list: at least one");
22 None
23 }
24 ValueRef::List(_) => Vec::<T>::read(v, cx).map(OneOrList),
25 _ => T::read(v, cx).map(|one| OneOrList(vec![one])),
26 }
27 }
28 fn write(&self) -> Value {
29 match self.0.as_slice() {
30 [one] => one.write(),
31 many => Value::List(many.iter().map(Schema::write).collect()),
32 }
33 }
34 fn pack(&self, p: &mut Packer) {
36 T::pack_list(&self.0, p);
37 }
38 fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
39 T::unpack_list(u)
40 .filter(|items| !items.is_empty())
41 .map(OneOrList)
42 }
43}