substrate_data/schema/
named_type.rs1use super::{Reader, Schema, Shape, ShapeFn};
5use crate::ValueRef;
6
7pub trait NamedType: Sized {
13 const NAME: &'static str;
15 type Stored: Schema;
17 fn to_stored(&self) -> Self::Stored;
19 fn from_stored(stored: Self::Stored) -> Option<Self>;
21}
22
23#[derive(Debug, Clone, Copy)]
25pub struct NamedShape {
26 name: &'static str,
27 stored: ShapeFn,
28}
29
30impl NamedShape {
31 #[must_use]
33 pub fn of<T: NamedType>() -> NamedShape {
34 NamedShape {
35 name: T::NAME,
36 stored: <T::Stored as Schema>::shape,
37 }
38 }
39
40 #[must_use]
42 pub fn name(&self) -> &'static str {
43 self.name
44 }
45
46 #[must_use]
48 pub fn stored(&self) -> Shape {
49 (self.stored)()
50 }
51}
52
53pub fn read_named<T: NamedType>(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<T> {
55 let stored = T::Stored::read(v, cx)?;
56 T::from_stored(stored).or_else(|| {
57 cx.problem(format!("not a valid {}", T::NAME));
58 None
59 })
60}
61
62#[macro_export]
65macro_rules! named_schema {
66 ($t:ty) => {
67 impl $crate::Schema for $t {
68 fn shape() -> $crate::Shape {
69 $crate::Shape::named::<$t>()
70 }
71 fn read(
72 v: &$crate::ValueRef<'_>,
73 cx: &mut $crate::Reader<'_>,
74 ) -> ::std::option::Option<Self> {
75 $crate::schema::read_named::<$t>(v, cx)
76 }
77 fn write(&self) -> $crate::Value {
78 $crate::Schema::write(&$crate::schema::NamedType::to_stored(self))
79 }
80 fn encode(&self, w: &mut $crate::binary::Writer) {
81 $crate::Schema::encode(&$crate::schema::NamedType::to_stored(self), w);
82 }
83 fn decode(d: &mut $crate::binary::Decoder<'_>) -> ::std::option::Option<Self> {
84 <<$t as $crate::schema::NamedType>::Stored as $crate::Schema>::decode(d)
85 .and_then(<$t as $crate::schema::NamedType>::from_stored)
86 }
87 fn pack(&self, p: &mut $crate::frame::Packer) {
88 $crate::Schema::pack(&$crate::schema::NamedType::to_stored(self), p);
89 }
90 fn unpack(u: &mut $crate::frame::Unpacker<'_>) -> ::std::option::Option<Self> {
91 <<$t as $crate::schema::NamedType>::Stored as $crate::Schema>::unpack(u)
92 .and_then(<$t as $crate::schema::NamedType>::from_stored)
93 }
94 }
95 };
96}