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 write_text(&self, w: &mut crate::text::Writer) {
31        w.reference(self.kind.as_str(), self.id.as_str());
32    }
33    fn pack(&self, p: &mut Packer) {
34        p.put_str(self.kind.as_str());
35        p.put_str(self.id.as_str());
36    }
37    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
38        let kind = KindName::new(u.str()?).ok()?;
39        let id = RefKey::new(u.str()?).ok()?;
40        Some(Ref::new(kind, id))
41    }
42}
43
44/// A kind's name as text: checked when it's read.
45impl Schema for KindName {
46    fn shape() -> Shape {
47        Shape::Atom
48    }
49    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
50        let ValueRef::Str(s) = v else {
51            cx.expected(Expected::Name, v);
52            return None;
53        };
54        KindName::new(s)
55            .map_err(|e| cx.problem_of(Problem::BadTyped, e.to_string()))
56            .ok()
57    }
58    fn write(&self) -> Value {
59        Value::Str(self.as_str().to_owned())
60    }
61    fn pack(&self, p: &mut Packer) {
62        self.atom().pack(p);
63    }
64    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
65        KindName::new(crate::Atom::unpack(u)?.as_str()).ok()
66    }
67}