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