substrate_data/schema/
with.rs1use std::collections::{BTreeMap, HashMap};
28use std::marker::PhantomData;
29
30use crate::binary::{Decoder, Writer};
31use crate::frame::{Packer, Unpacker};
32use crate::model::borrowed::ValueRef;
33use crate::model::value::{Map, Ref, Seg, Value};
34use crate::schema::{Kinds, Reader, Schema, Shape, is_metadata_key};
35
36pub trait With<F> {
38 fn shape() -> Shape;
40 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<F>;
42 fn write(f: &F) -> Value;
44 #[must_use]
46 fn absent() -> Option<F> {
47 None
48 }
49 fn skip(_f: &F) -> bool {
51 false
52 }
53 fn encode(f: &F, w: &mut Writer) {
56 w.value(&Self::write(f));
57 }
58 fn decode(d: &mut Decoder<'_>) -> Option<F> {
61 let arena = bumpalo::Bump::new();
62 let v = d.value_ref(&arena).ok()?;
63 let mut cx = Reader::new();
64 let f = Self::read(&v, &mut cx)?;
65 cx.problems.is_empty().then_some(f)
66 }
67 fn pack(f: &F, p: &mut Packer) {
70 let mut w = Writer::body();
71 Self::encode(f, &mut w);
72 p.put_bytes(&w.finish());
73 }
74 fn unpack(u: &mut Unpacker<'_>) -> Option<F> {
76 let mut d = Decoder::body(u.bytes()?);
77 let f = Self::decode(&mut d)?;
78 d.at_end().then_some(f)
79 }
80}
81
82#[derive(Debug)]
84pub struct RefTo<K>(PhantomData<K>);
85
86impl<K: Kinds> With<K::Id> for RefTo<K> {
87 fn shape() -> Shape {
88 super::ref_shape::<K>()
89 }
90 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<K::Id> {
91 super::read_id::<K>(v, cx)
92 }
93 fn write(f: &K::Id) -> Value {
94 Value::Ref(Ref::new(
95 K::first(),
96 crate::model::value::RefKey::spelled(&crate::schema::RefId::spell(f)),
97 ))
98 }
99 fn pack(f: &K::Id, p: &mut Packer) {
100 f.pack(p);
101 }
102 fn unpack(u: &mut Unpacker<'_>) -> Option<K::Id> {
103 K::Id::unpack(u)
104 }
105}
106
107#[derive(Debug)]
111pub struct Spelled;
112
113impl With<String> for Spelled {
114 fn shape() -> Shape {
115 Shape::Str
116 }
117 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<String> {
118 if let ValueRef::Str(s) = v {
119 return Some(s.to_string());
120 }
121 let spelled = crate::typed::spelling(&v.to_value());
122 if spelled.is_none() {
123 cx.expected(super::Expected::Text, v);
124 }
125 spelled
126 }
127 fn write(f: &String) -> Value {
128 Value::Str(f.clone())
129 }
130}
131
132#[derive(Debug)]
134pub struct Opt<W>(PhantomData<W>);
135
136impl<F, W: With<F>> With<Option<F>> for Opt<W> {
137 fn shape() -> Shape {
138 Shape::Optional(W::shape)
139 }
140 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Option<F>> {
141 if v.is_null() {
142 Some(None)
143 } else {
144 W::read(v, cx).map(Some)
145 }
146 }
147 fn write(f: &Option<F>) -> Value {
148 f.as_ref().map_or(Value::Null, W::write)
149 }
150 fn absent() -> Option<Option<F>> {
151 Some(None)
152 }
153 fn skip(f: &Option<F>) -> bool {
154 f.is_none()
155 }
156}
157
158#[derive(Debug)]
160pub struct List<W>(PhantomData<W>);
161
162impl<F, W: With<F>> With<Vec<F>> for List<W> {
163 fn shape() -> Shape {
164 Shape::List(W::shape)
165 }
166 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Vec<F>> {
167 let ValueRef::List(items) = v else {
168 cx.expected(super::Expected::List, v);
169 return None;
170 };
171 let mut out = Vec::with_capacity(items.len());
172 let mut ok = true;
173 for (i, item) in items.iter().enumerate() {
174 match cx.at(Seg::Index(i), |cx| W::read(item, cx)) {
175 Some(x) => out.push(x),
176 None => ok = false,
177 }
178 }
179 ok.then_some(out)
180 }
181 fn write(f: &Vec<F>) -> Value {
182 Value::List(f.iter().map(W::write).collect())
183 }
184}
185
186#[derive(Debug)]
188pub struct Values<W>(PhantomData<W>);
189
190impl<F, W: With<F>> With<BTreeMap<String, F>> for Values<W> {
191 fn shape() -> Shape {
192 Shape::Map(W::shape)
193 }
194 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<BTreeMap<String, F>> {
195 read_values::<F, W, _>(v, cx)
196 }
197 fn write(f: &BTreeMap<String, F>) -> Value {
198 write_values::<F, W>(f.iter())
199 }
200}
201
202impl<F, W: With<F>> With<HashMap<String, F>> for Values<W> {
203 fn shape() -> Shape {
204 Shape::Map(W::shape)
205 }
206 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<HashMap<String, F>> {
207 read_values::<F, W, _>(v, cx)
208 }
209 fn write(f: &HashMap<String, F>) -> Value {
210 write_values::<F, W>(f.iter())
211 }
212}
213
214fn read_values<F, W: With<F>, M: Default + Extend<(String, F)>>(
216 v: &ValueRef<'_>,
217 cx: &mut Reader<'_>,
218) -> Option<M> {
219 let map = cx.map(v)?;
220 let mut out = M::default();
221 let mut ok = true;
222 for (k, item) in map.iter().filter(|(k, _)| !is_metadata_key(k)) {
223 match cx.at(Seg::Key(k.to_string()), |cx| W::read(item, cx)) {
224 Some(x) => out.extend([(k.to_string(), x)]),
225 None => ok = false,
226 }
227 }
228 ok.then_some(out)
229}
230
231fn write_values<'a, F: 'a, W: With<F>>(
232 entries: impl Iterator<Item = (&'a String, &'a F)>,
233) -> Value {
234 Value::Map(
235 entries
236 .map(|(k, v)| (k.clone(), W::write(v)))
237 .collect::<Map>(),
238 )
239}
240
241#[derive(Debug)]
243pub struct Plain;
244
245impl<F: Schema> With<F> for Plain {
246 fn shape() -> Shape {
247 F::shape()
248 }
249 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<F> {
250 F::read(v, cx)
251 }
252 fn write(f: &F) -> Value {
253 f.write()
254 }
255 fn absent() -> Option<F> {
256 F::absent()
257 }
258 fn skip(f: &F) -> bool {
259 f.skip()
260 }
261 fn encode(f: &F, w: &mut Writer) {
262 f.encode(w);
263 }
264 fn decode(d: &mut Decoder<'_>) -> Option<F> {
265 F::decode(d)
266 }
267 fn pack(f: &F, p: &mut Packer) {
268 f.pack(p);
269 }
270 fn unpack(u: &mut Unpacker<'_>) -> Option<F> {
271 F::unpack(u)
272 }
273}
274
275#[derive(Debug)]
277pub struct Raw;
278
279impl With<Vec<u8>> for Raw {
280 fn shape() -> Shape {
281 Shape::Bytes
282 }
283 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Vec<u8>> {
284 match v {
285 ValueRef::Bytes(b) => Some(b.to_vec()),
286 ValueRef::Str(s) => {
288 if let crate::typed::Spelled::Bytes(b) = crate::typed::classify(s)
289 .map_err(|e| cx.problem_of(crate::Problem::BadTyped, e.to_string()))
290 .ok()?
291 {
292 Some(b)
293 } else {
294 cx.expected(super::Expected::Bytes, v);
295 None
296 }
297 }
298 other => {
299 cx.expected(super::Expected::Bytes, other);
300 None
301 }
302 }
303 }
304 fn write(f: &Vec<u8>) -> Value {
305 Value::Bytes(f.clone())
306 }
307 fn encode(f: &Vec<u8>, w: &mut Writer) {
308 w.bytes(f);
309 }
310 fn decode(d: &mut Decoder<'_>) -> Option<Vec<u8>> {
311 d.bytes().map(<[u8]>::to_vec)
312 }
313 fn pack(f: &Vec<u8>, p: &mut Packer) {
314 p.put_bytes(f);
315 }
316 fn unpack(u: &mut Unpacker<'_>) -> Option<Vec<u8>> {
317 u.bytes().map(<[u8]>::to_vec)
318 }
319 fn absent() -> Option<Vec<u8>> {
320 Some(Vec::new())
321 }
322}