Skip to main content

substrate_data/schema/refs/
untyped.rs

1//! The schemas of a reference of any kind and of a kind's name.
2
3use super::read_ref;
4use crate::diagnostic::Problem;
5use crate::frame::{Packer, Unpacker};
6use crate::model::borrowed::ValueRef;
7use crate::model::value::{KindName, Ref, RefKey, Value};
8use crate::schema::{Expected, Reader, Schema, Shape};
9
10/// A reference of any kind: in a frame, its kind and its id, as text.
11impl Schema for Ref {
12    fn shape() -> Shape {
13        Shape::Ref {
14            kinds: &[],
15            id: String::shape,
16        }
17    }
18    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
19        if let ValueRef::Str(s) = v
20            && !s.starts_with(crate::names::TYPED)
21        {
22            cx.expected(Expected::Reference, v);
23            return None;
24        }
25        read_ref(v, cx, &[])
26    }
27    fn write(&self) -> Value {
28        Value::Ref(self.clone())
29    }
30    fn pack(&self, p: &mut Packer) {
31        p.put_str(self.kind.as_str());
32        p.put_str(self.id.as_str());
33    }
34    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
35        let kind = KindName::new(u.str()?).ok()?;
36        let id = RefKey::new(u.str()?).ok()?;
37        Some(Ref::new(kind, id))
38    }
39}
40
41/// A kind's name as text: checked when it's read.
42impl Schema for KindName {
43    fn shape() -> Shape {
44        Shape::Atom
45    }
46    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
47        let ValueRef::Str(s) = v else {
48            cx.expected(Expected::Name, v);
49            return None;
50        };
51        KindName::new(s)
52            .map_err(|e| cx.problem_of(Problem::BadTyped, e.to_string()))
53            .ok()
54    }
55    fn write(&self) -> Value {
56        Value::Str(self.as_str().to_owned())
57    }
58    fn pack(&self, p: &mut Packer) {
59        self.atom().pack(p);
60    }
61    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
62        KindName::new(crate::Atom::unpack(u)?.as_str()).ok()
63    }
64}