use super::read_ref;
use crate::diagnostic::Problem;
use crate::frame::{Packer, Unpacker};
use crate::model::borrowed::ValueRef;
use crate::model::value::{KindName, Ref, RefKey, Value};
use crate::schema::{Expected, Reader, Schema, Shape};
impl Schema for Ref {
fn shape() -> Shape {
Shape::Ref {
kinds: &[],
id: String::shape,
}
}
fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
if let ValueRef::Str(s) = v
&& !s.starts_with(crate::names::TYPED)
{
cx.expected(Expected::Reference, v);
return None;
}
read_ref(v, cx, &[])
}
fn write(&self) -> Value {
Value::Ref(self.clone())
}
fn write_text(&self, w: &mut crate::text::Writer) {
w.reference(self.kind.as_str(), self.id.as_str());
}
fn pack(&self, p: &mut Packer) {
p.put_str(self.kind.as_str());
p.put_str(self.id.as_str());
}
fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
let kind = KindName::new(u.str()?).ok()?;
let id = RefKey::new(u.str()?).ok()?;
Some(Ref::new(kind, id))
}
}
impl Schema for KindName {
fn shape() -> Shape {
Shape::Atom
}
fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
let ValueRef::Str(s) = v else {
cx.expected(Expected::Name, v);
return None;
};
KindName::new(s)
.map_err(|e| cx.problem_of(Problem::BadTyped, e.to_string()))
.ok()
}
fn write(&self) -> Value {
Value::Str(self.as_str().to_owned())
}
fn pack(&self, p: &mut Packer) {
self.atom().pack(p);
}
fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
KindName::new(crate::Atom::unpack(u)?.as_str()).ok()
}
}