1use 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 write_text(f: &F, w: &mut crate::text::Writer) {
62 w.value(&Self::write(f));
63 }
64 fn decode(d: &mut Decoder<'_>) -> Option<F> {
67 let arena = bumpalo::Bump::new();
68 let v = d.value_ref(&arena).ok()?;
69 let mut cx = Reader::new();
70 let f = Self::read(&v, &mut cx)?;
71 cx.problems.is_empty().then_some(f)
72 }
73 fn pack(f: &F, p: &mut Packer) {
76 let mut w = Writer::body();
77 Self::encode(f, &mut w);
78 p.put_bytes(&w.finish());
79 }
80 fn unpack(u: &mut Unpacker<'_>) -> Option<F> {
82 let mut d = Decoder::body(u.bytes()?);
83 let f = Self::decode(&mut d)?;
84 d.at_end().then_some(f)
85 }
86}
87
88#[derive(Debug)]
90pub struct RefTo<K>(PhantomData<K>);
91
92impl<K: Kinds> With<K::Id> for RefTo<K> {
93 fn shape() -> Shape {
94 super::ref_shape::<K>()
95 }
96 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<K::Id> {
97 super::read_id::<K>(v, cx)
98 }
99 fn write(f: &K::Id) -> Value {
100 Value::Ref(Ref::new(
101 K::first(),
102 crate::model::value::RefKey::spelled(&crate::schema::RefId::spell(f)),
103 ))
104 }
105 fn write_text(f: &K::Id, w: &mut crate::text::Writer) {
106 w.reference(K::first().as_str(), &crate::schema::RefId::spell(f));
107 }
108 fn pack(f: &K::Id, p: &mut Packer) {
109 f.pack(p);
110 }
111 fn unpack(u: &mut Unpacker<'_>) -> Option<K::Id> {
112 K::Id::unpack(u)
113 }
114}
115
116#[derive(Debug)]
120pub struct Spelled;
121
122impl With<String> for Spelled {
123 fn shape() -> Shape {
124 Shape::Str
125 }
126 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<String> {
127 if let ValueRef::Str(s) = v {
128 return Some(s.to_string());
129 }
130 let spelled = crate::typed::spelling(&v.to_value());
131 if spelled.is_none() {
132 cx.expected(super::Expected::Text, v);
133 }
134 spelled
135 }
136 fn write(f: &String) -> Value {
137 Value::Str(f.clone())
138 }
139 fn write_text(f: &String, w: &mut crate::text::Writer) {
140 w.str(f);
141 }
142}
143
144#[derive(Debug)]
146pub struct Opt<W>(PhantomData<W>);
147
148impl<F, W: With<F>> With<Option<F>> for Opt<W> {
149 fn shape() -> Shape {
150 Shape::Optional(W::shape)
151 }
152 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Option<F>> {
153 if v.is_null() {
154 Some(None)
155 } else {
156 W::read(v, cx).map(Some)
157 }
158 }
159 fn write(f: &Option<F>) -> Value {
160 f.as_ref().map_or(Value::Null, W::write)
161 }
162 fn write_text(f: &Option<F>, w: &mut crate::text::Writer) {
163 match f {
164 Some(f) => W::write_text(f, w),
165 None => {
166 w.null();
167 }
168 }
169 }
170 fn absent() -> Option<Option<F>> {
171 Some(None)
172 }
173 fn skip(f: &Option<F>) -> bool {
174 f.is_none()
175 }
176}
177
178#[derive(Debug)]
180pub struct List<W>(PhantomData<W>);
181
182impl<F, W: With<F>> With<Vec<F>> for List<W> {
183 fn shape() -> Shape {
184 Shape::List(W::shape)
185 }
186 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Vec<F>> {
187 let ValueRef::List(items) = v else {
188 cx.expected(super::Expected::List, v);
189 return None;
190 };
191 let mut out = Vec::with_capacity(items.len());
192 let mut ok = true;
193 for (i, item) in items.iter().enumerate() {
194 match cx.at(Seg::Index(i), |cx| W::read(item, cx)) {
195 Some(x) => out.push(x),
196 None => ok = false,
197 }
198 }
199 ok.then_some(out)
200 }
201 fn write(f: &Vec<F>) -> Value {
202 Value::List(f.iter().map(W::write).collect())
203 }
204 fn write_text(f: &Vec<F>, w: &mut crate::text::Writer) {
205 w.list(f.len());
206 for item in f {
207 W::write_text(item, w);
208 }
209 }
210}
211
212#[derive(Debug)]
214pub struct Values<W>(PhantomData<W>);
215
216impl<F, W: With<F>> With<BTreeMap<String, F>> for Values<W> {
217 fn shape() -> Shape {
218 Shape::Map(W::shape)
219 }
220 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<BTreeMap<String, F>> {
221 read_values::<F, W, _>(v, cx)
222 }
223 fn write(f: &BTreeMap<String, F>) -> Value {
224 write_values::<F, W>(f.iter())
225 }
226 fn write_text(f: &BTreeMap<String, F>, w: &mut crate::text::Writer) {
227 w.map(f.len());
228 for (k, v) in f {
229 w.key(k);
230 W::write_text(v, w);
231 }
232 }
233}
234
235impl<F, W: With<F>> With<HashMap<String, F>> for Values<W> {
236 fn shape() -> Shape {
237 Shape::Map(W::shape)
238 }
239 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<HashMap<String, F>> {
240 read_values::<F, W, _>(v, cx)
241 }
242 fn write(f: &HashMap<String, F>) -> Value {
243 write_values::<F, W>(f.iter())
244 }
245}
246
247fn read_values<F, W: With<F>, M: Default + Extend<(String, F)>>(
249 v: &ValueRef<'_>,
250 cx: &mut Reader<'_>,
251) -> Option<M> {
252 let map = cx.map(v)?;
253 let mut out = M::default();
254 let mut ok = true;
255 for (k, item) in map.iter().filter(|(k, _)| !is_metadata_key(k)) {
256 match cx.at(Seg::Key(k.to_string()), |cx| W::read(item, cx)) {
257 Some(x) => out.extend([(k.to_string(), x)]),
258 None => ok = false,
259 }
260 }
261 ok.then_some(out)
262}
263
264fn write_values<'a, F: 'a, W: With<F>>(
265 entries: impl Iterator<Item = (&'a String, &'a F)>,
266) -> Value {
267 Value::Map(
268 entries
269 .map(|(k, v)| (k.clone(), W::write(v)))
270 .collect::<Map>(),
271 )
272}
273
274#[derive(Debug)]
276pub struct Plain;
277
278impl<F: Schema> With<F> for Plain {
279 fn shape() -> Shape {
280 F::shape()
281 }
282 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<F> {
283 F::read(v, cx)
284 }
285 fn write(f: &F) -> Value {
286 f.write()
287 }
288 fn absent() -> Option<F> {
289 F::absent()
290 }
291 fn skip(f: &F) -> bool {
292 f.skip()
293 }
294 fn write_text(f: &F, w: &mut crate::text::Writer) {
295 f.write_text(w);
296 }
297 fn encode(f: &F, w: &mut Writer) {
298 f.encode(w);
299 }
300 fn decode(d: &mut Decoder<'_>) -> Option<F> {
301 F::decode(d)
302 }
303 fn pack(f: &F, p: &mut Packer) {
304 f.pack(p);
305 }
306 fn unpack(u: &mut Unpacker<'_>) -> Option<F> {
307 F::unpack(u)
308 }
309}
310
311#[derive(Debug)]
313pub struct Raw;
314
315impl With<Vec<u8>> for Raw {
316 fn shape() -> Shape {
317 Shape::Bytes
318 }
319 fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Vec<u8>> {
320 match v {
321 ValueRef::Bytes(b) => Some(b.to_vec()),
322 ValueRef::Str(s) => {
324 if let crate::typed::Spelled::Bytes(b) = crate::typed::classify(s)
325 .map_err(|e| cx.problem_of(crate::Problem::BadTyped, e.to_string()))
326 .ok()?
327 {
328 Some(b)
329 } else {
330 cx.expected(super::Expected::Bytes, v);
331 None
332 }
333 }
334 other => {
335 cx.expected(super::Expected::Bytes, other);
336 None
337 }
338 }
339 }
340 fn write(f: &Vec<u8>) -> Value {
341 Value::Bytes(f.clone())
342 }
343 fn write_text(f: &Vec<u8>, w: &mut crate::text::Writer) {
344 w.bytes(f);
345 }
346 fn encode(f: &Vec<u8>, w: &mut Writer) {
347 w.bytes(f);
348 }
349 fn decode(d: &mut Decoder<'_>) -> Option<Vec<u8>> {
350 d.bytes().map(<[u8]>::to_vec)
351 }
352 fn pack(f: &Vec<u8>, p: &mut Packer) {
353 p.put_bytes(f);
354 }
355 fn unpack(u: &mut Unpacker<'_>) -> Option<Vec<u8>> {
356 u.bytes().map(<[u8]>::to_vec)
357 }
358 fn absent() -> Option<Vec<u8>> {
359 Some(Vec::new())
360 }
361}