1use std::borrow::Cow;
2use std::collections::HashSet;
3use std::fmt;
4
5use eure::document::EureDocument;
6use eure::document::constructor::DocumentConstructor;
7use eure::document::identifier::Identifier;
8use eure::document::node::NodeValue;
9use eure::document::parse::VariantPath;
10use eure::document::path::{ArrayIndexKind, PathSegment};
11use eure::value::{ObjectKey, PrimitiveValue, Text, Tuple};
12use eure_schema::interop::VariantRepr;
13use eure_schema::{
14 SchemaDocument, SchemaNodeContent, SchemaNodeId, UnionSchema, UnknownFieldsPolicy,
15};
16use num_bigint::BigInt;
17use serde::Deserialize;
18use serde::de::Error as _;
19use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor};
20
21use crate::error::DeError;
22
23#[derive(Debug, Clone)]
24enum EureContent<'de> {
25 Bool(bool),
26 I8(i8),
27 I16(i16),
28 I32(i32),
29 I64(i64),
30 I128(i128),
31 U8(u8),
32 U16(u16),
33 U32(u32),
34 U64(u64),
35 U128(u128),
36 F32(f32),
37 F64(f64),
38 Char(char),
39 String(Cow<'de, str>),
40 Bytes(Cow<'de, [u8]>),
41 Unit,
42 Seq(Vec<EureContent<'de>>),
43 Map(Vec<(EureContent<'de>, EureContent<'de>)>),
44}
45
46impl<'de> Deserialize<'de> for EureContent<'de> {
47 fn deserialize<D>(de: D) -> Result<Self, D::Error>
48 where
49 D: serde::Deserializer<'de>,
50 {
51 de.deserialize_any(EureContentVisitor)
52 }
53}
54
55impl<'de> serde::Deserializer<'de> for EureContent<'de> {
56 type Error = DeError;
57
58 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
59 where
60 V: Visitor<'de>,
61 {
62 match self {
63 Self::Bool(value) => visitor.visit_bool(value),
64 Self::I8(value) => visitor.visit_i8(value),
65 Self::I16(value) => visitor.visit_i16(value),
66 Self::I32(value) => visitor.visit_i32(value),
67 Self::I64(value) => visitor.visit_i64(value),
68 Self::I128(value) => visitor.visit_i128(value),
69 Self::U8(value) => visitor.visit_u8(value),
70 Self::U16(value) => visitor.visit_u16(value),
71 Self::U32(value) => visitor.visit_u32(value),
72 Self::U64(value) => visitor.visit_u64(value),
73 Self::U128(value) => visitor.visit_u128(value),
74 Self::F32(value) => visitor.visit_f32(value),
75 Self::F64(value) => visitor.visit_f64(value),
76 Self::Char(value) => visitor.visit_char(value),
77 Self::String(Cow::Borrowed(value)) => visitor.visit_borrowed_str(value),
78 Self::String(Cow::Owned(value)) => visitor.visit_string(value),
79 Self::Bytes(Cow::Borrowed(value)) => visitor.visit_borrowed_bytes(value),
80 Self::Bytes(Cow::Owned(value)) => visitor.visit_byte_buf(value),
81 Self::Unit => visitor.visit_unit(),
82 Self::Seq(values) => visitor.visit_seq(EureContentSeqAccess {
83 iter: values.into_iter(),
84 }),
85 Self::Map(entries) => visitor.visit_map(EureContentMapAccess {
86 iter: entries.into_iter(),
87 pending_value: None,
88 }),
89 }
90 }
91
92 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
93 where
94 V: Visitor<'de>,
95 {
96 match self {
97 Self::Bool(value) => visitor.visit_bool(value),
98 other => Err(type_mismatch("boolean", eure_content_type(&other))),
99 }
100 }
101
102 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
103 where
104 V: Visitor<'de>,
105 {
106 match self {
107 Self::I8(value) => visitor.visit_i8(value),
108 other => Err(type_mismatch("integer", eure_content_type(&other))),
109 }
110 }
111
112 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
113 where
114 V: Visitor<'de>,
115 {
116 match self {
117 Self::I16(value) => visitor.visit_i16(value),
118 other => Err(type_mismatch("integer", eure_content_type(&other))),
119 }
120 }
121
122 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
123 where
124 V: Visitor<'de>,
125 {
126 match self {
127 Self::I32(value) => visitor.visit_i32(value),
128 other => Err(type_mismatch("integer", eure_content_type(&other))),
129 }
130 }
131
132 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
133 where
134 V: Visitor<'de>,
135 {
136 match self {
138 Self::I8(v) => visitor.visit_i8(v),
139 Self::I16(v) => visitor.visit_i16(v),
140 Self::I32(v) => visitor.visit_i32(v),
141 Self::I64(v) => visitor.visit_i64(v),
142 Self::I128(v) => visitor.visit_i128(v),
143 Self::U8(v) => visitor.visit_u8(v),
144 Self::U16(v) => visitor.visit_u16(v),
145 Self::U32(v) => visitor.visit_u32(v),
146 Self::U64(v) => visitor.visit_u64(v),
147 Self::U128(v) => visitor.visit_u128(v),
148 other => Err(type_mismatch("integer", eure_content_type(&other))),
149 }
150 }
151
152 fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
153 where
154 V: Visitor<'de>,
155 {
156 match self {
157 Self::I128(value) => visitor.visit_i128(value),
158 other => Err(type_mismatch("integer", eure_content_type(&other))),
159 }
160 }
161
162 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
163 where
164 V: Visitor<'de>,
165 {
166 match self {
167 Self::U8(value) => visitor.visit_u8(value),
168 other => Err(type_mismatch("integer", eure_content_type(&other))),
169 }
170 }
171
172 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
173 where
174 V: Visitor<'de>,
175 {
176 match self {
177 Self::U16(value) => visitor.visit_u16(value),
178 other => Err(type_mismatch("integer", eure_content_type(&other))),
179 }
180 }
181
182 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
183 where
184 V: Visitor<'de>,
185 {
186 match self {
187 Self::U32(value) => visitor.visit_u32(value),
188 other => Err(type_mismatch("integer", eure_content_type(&other))),
189 }
190 }
191
192 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
193 where
194 V: Visitor<'de>,
195 {
196 match self {
197 Self::U64(value) => visitor.visit_u64(value),
198 other => Err(type_mismatch("integer", eure_content_type(&other))),
199 }
200 }
201
202 fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
203 where
204 V: Visitor<'de>,
205 {
206 match self {
207 Self::U128(value) => visitor.visit_u128(value),
208 other => Err(type_mismatch("integer", eure_content_type(&other))),
209 }
210 }
211
212 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
213 where
214 V: Visitor<'de>,
215 {
216 match self {
217 Self::F32(value) => visitor.visit_f32(value),
218 other => Err(type_mismatch("float", eure_content_type(&other))),
219 }
220 }
221
222 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
223 where
224 V: Visitor<'de>,
225 {
226 match self {
227 Self::F32(v) => visitor.visit_f32(v),
228 Self::F64(v) => visitor.visit_f64(v),
229 Self::I8(v) => visitor.visit_f64(v as f64),
231 Self::I16(v) => visitor.visit_f64(v as f64),
232 Self::I32(v) => visitor.visit_f64(v as f64),
233 Self::I64(v) => visitor.visit_f64(v as f64),
234 Self::I128(v) => visitor.visit_f64(v as f64),
235 Self::U8(v) => visitor.visit_f64(v as f64),
236 Self::U16(v) => visitor.visit_f64(v as f64),
237 Self::U32(v) => visitor.visit_f64(v as f64),
238 Self::U64(v) => visitor.visit_f64(v as f64),
239 Self::U128(v) => visitor.visit_f64(v as f64),
240 other => Err(type_mismatch("float", eure_content_type(&other))),
241 }
242 }
243
244 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
245 where
246 V: Visitor<'de>,
247 {
248 match self {
249 Self::Char(value) => visitor.visit_char(value),
250 other => Err(type_mismatch("text", eure_content_type(&other))),
251 }
252 }
253
254 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
255 where
256 V: Visitor<'de>,
257 {
258 match self {
259 Self::String(Cow::Borrowed(value)) => visitor.visit_borrowed_str(value),
260 Self::String(Cow::Owned(value)) => visitor.visit_string(value),
261 other => Err(type_mismatch("text", eure_content_type(&other))),
262 }
263 }
264
265 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
266 where
267 V: Visitor<'de>,
268 {
269 self.deserialize_str(visitor)
270 }
271
272 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
273 where
274 V: Visitor<'de>,
275 {
276 match self {
277 Self::Bytes(Cow::Borrowed(value)) => visitor.visit_borrowed_bytes(value),
278 Self::Bytes(Cow::Owned(value)) => visitor.visit_byte_buf(value),
279 other => Err(type_mismatch("bytes", eure_content_type(&other))),
280 }
281 }
282
283 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
284 where
285 V: Visitor<'de>,
286 {
287 self.deserialize_bytes(visitor)
288 }
289
290 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
291 where
292 V: Visitor<'de>,
293 {
294 match self {
295 Self::Unit => visitor.visit_none(),
296 other => visitor.visit_some(other),
297 }
298 }
299
300 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
301 where
302 V: Visitor<'de>,
303 {
304 match self {
305 Self::Unit => visitor.visit_unit(),
306 other => Err(type_mismatch("null", eure_content_type(&other))),
307 }
308 }
309
310 fn deserialize_unit_struct<V>(
311 self,
312 _name: &'static str,
313 visitor: V,
314 ) -> Result<V::Value, Self::Error>
315 where
316 V: Visitor<'de>,
317 {
318 self.deserialize_unit(visitor)
319 }
320
321 fn deserialize_newtype_struct<V>(
322 self,
323 _name: &'static str,
324 visitor: V,
325 ) -> Result<V::Value, Self::Error>
326 where
327 V: Visitor<'de>,
328 {
329 visitor.visit_newtype_struct(self)
330 }
331
332 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
333 where
334 V: Visitor<'de>,
335 {
336 match self {
337 Self::Seq(values) => visitor.visit_seq(EureContentSeqAccess {
338 iter: values.into_iter(),
339 }),
340 other => Err(type_mismatch("array", eure_content_type(&other))),
341 }
342 }
343
344 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
345 where
346 V: Visitor<'de>,
347 {
348 self.deserialize_seq(visitor)
349 }
350
351 fn deserialize_tuple_struct<V>(
352 self,
353 _name: &'static str,
354 _len: usize,
355 visitor: V,
356 ) -> Result<V::Value, Self::Error>
357 where
358 V: Visitor<'de>,
359 {
360 self.deserialize_seq(visitor)
361 }
362
363 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
364 where
365 V: Visitor<'de>,
366 {
367 match self {
368 Self::Map(entries) => visitor.visit_map(EureContentMapAccess {
369 iter: entries.into_iter(),
370 pending_value: None,
371 }),
372 other => Err(type_mismatch("map", eure_content_type(&other))),
373 }
374 }
375
376 fn deserialize_struct<V>(
377 self,
378 _name: &'static str,
379 _fields: &'static [&'static str],
380 visitor: V,
381 ) -> Result<V::Value, Self::Error>
382 where
383 V: Visitor<'de>,
384 {
385 self.deserialize_map(visitor)
386 }
387
388 fn deserialize_enum<V>(
389 self,
390 _name: &'static str,
391 _variants: &'static [&'static str],
392 _visitor: V,
393 ) -> Result<V::Value, Self::Error>
394 where
395 V: Visitor<'de>,
396 {
397 Err(DeError::Custom(
398 "enum deserialization is unsupported for EureContent".to_string(),
399 ))
400 }
401
402 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
403 where
404 V: Visitor<'de>,
405 {
406 match self {
407 Self::String(Cow::Borrowed(value)) => visitor.visit_borrowed_str(value),
408 Self::String(Cow::Owned(value)) => visitor.visit_string(value),
409 Self::Char(value) => visitor.visit_string(value.to_string()),
410 other => Err(type_mismatch("text", eure_content_type(&other))),
411 }
412 }
413
414 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
415 where
416 V: Visitor<'de>,
417 {
418 visitor.visit_unit()
419 }
420}
421
422impl<'de> IntoDeserializer<'de, DeError> for EureContent<'de> {
423 type Deserializer = Self;
424
425 fn into_deserializer(self) -> Self::Deserializer {
426 self
427 }
428}
429
430struct EureContentVisitor;
431
432impl<'de> Visitor<'de> for EureContentVisitor {
433 type Value = EureContent<'de>;
434
435 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
436 formatter.write_str("any serde value")
437 }
438
439 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E> {
440 Ok(EureContent::Bool(value))
441 }
442
443 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E> {
444 Ok(EureContent::I8(value))
445 }
446
447 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E> {
448 Ok(EureContent::I16(value))
449 }
450
451 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E> {
452 Ok(EureContent::I32(value))
453 }
454
455 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E> {
456 Ok(EureContent::I64(value))
457 }
458
459 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E> {
460 Ok(EureContent::I128(value))
461 }
462
463 fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E> {
464 Ok(EureContent::U8(value))
465 }
466
467 fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E> {
468 Ok(EureContent::U16(value))
469 }
470
471 fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E> {
472 Ok(EureContent::U32(value))
473 }
474
475 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E> {
476 Ok(EureContent::U64(value))
477 }
478
479 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E> {
480 Ok(EureContent::U128(value))
481 }
482
483 fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E> {
484 Ok(EureContent::F32(value))
485 }
486
487 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E> {
488 Ok(EureContent::F64(value))
489 }
490
491 fn visit_char<E>(self, value: char) -> Result<Self::Value, E> {
492 Ok(EureContent::Char(value))
493 }
494
495 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E> {
496 Ok(EureContent::String(Cow::Borrowed(value)))
497 }
498
499 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
500 where
501 E: de::Error,
502 {
503 Ok(EureContent::String(Cow::Owned(value.to_owned())))
504 }
505
506 fn visit_string<E>(self, value: String) -> Result<Self::Value, E> {
507 Ok(EureContent::String(Cow::Owned(value)))
508 }
509
510 fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> Result<Self::Value, E> {
511 Ok(EureContent::Bytes(Cow::Borrowed(value)))
512 }
513
514 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
515 where
516 E: de::Error,
517 {
518 Ok(EureContent::Bytes(Cow::Owned(value.to_vec())))
519 }
520
521 fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E> {
522 Ok(EureContent::Bytes(Cow::Owned(value)))
523 }
524
525 fn visit_unit<E>(self) -> Result<Self::Value, E> {
526 Ok(EureContent::Unit)
527 }
528
529 fn visit_none<E>(self) -> Result<Self::Value, E> {
530 Ok(EureContent::Unit)
531 }
532
533 fn visit_some<D>(self, de: D) -> Result<Self::Value, D::Error>
534 where
535 D: serde::Deserializer<'de>,
536 {
537 EureContent::deserialize(de)
538 }
539
540 fn visit_newtype_struct<D>(self, de: D) -> Result<Self::Value, D::Error>
541 where
542 D: serde::Deserializer<'de>,
543 {
544 EureContent::deserialize(de)
545 }
546
547 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
548 where
549 A: SeqAccess<'de>,
550 {
551 let mut values = Vec::new();
552 while let Some(value) = seq.next_element::<EureContent<'de>>()? {
553 values.push(value);
554 }
555 Ok(EureContent::Seq(values))
556 }
557
558 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
559 where
560 A: MapAccess<'de>,
561 {
562 let mut entries = Vec::new();
563 while let Some((key, value)) = map.next_entry::<EureContent<'de>, EureContent<'de>>()? {
564 entries.push((key, value));
565 }
566 Ok(EureContent::Map(entries))
567 }
568}
569
570struct EureContentMapVisitor;
571
572impl<'de> Visitor<'de> for EureContentMapVisitor {
573 type Value = EureContent<'de>;
574
575 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
576 formatter.write_str("a map")
577 }
578
579 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
580 where
581 A: MapAccess<'de>,
582 {
583 let mut entries = Vec::new();
584 while let Some((key, value)) = map.next_entry::<EureContent<'de>, EureContent<'de>>()? {
588 entries.push((key, value));
589 }
590 Ok(EureContent::Map(entries))
591 }
592}
593
594struct EureContentSeqAccess<'de> {
595 iter: std::vec::IntoIter<EureContent<'de>>,
596}
597
598impl<'de> SeqAccess<'de> for EureContentSeqAccess<'de> {
599 type Error = DeError;
600
601 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
602 where
603 T: DeserializeSeed<'de>,
604 {
605 match self.iter.next() {
606 Some(value) => seed.deserialize(value).map(Some),
607 None => Ok(None),
608 }
609 }
610
611 fn size_hint(&self) -> Option<usize> {
612 Some(self.iter.len())
613 }
614}
615
616struct EureContentMapAccess<'de> {
617 iter: std::vec::IntoIter<(EureContent<'de>, EureContent<'de>)>,
618 pending_value: Option<EureContent<'de>>,
619}
620
621impl<'de> MapAccess<'de> for EureContentMapAccess<'de> {
622 type Error = DeError;
623
624 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
625 where
626 K: DeserializeSeed<'de>,
627 {
628 match self.iter.next() {
629 Some((key, value)) => {
630 self.pending_value = Some(value);
631 seed.deserialize(key).map(Some)
632 }
633 None => Ok(None),
634 }
635 }
636
637 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
638 where
639 V: DeserializeSeed<'de>,
640 {
641 let value = self.pending_value.take().ok_or_else(|| {
642 DeError::Custom("map value requested before reading a key".to_string())
643 })?;
644 seed.deserialize(value)
645 }
646
647 fn size_hint(&self) -> Option<usize> {
648 Some(self.iter.len() + usize::from(self.pending_value.is_some()))
649 }
650}
651
652pub struct EureDocumentSeed<'s> {
653 pub schema: &'s SchemaDocument,
654 pub schema_node_id: SchemaNodeId,
655 pub constructor: &'s mut DocumentConstructor,
656}
657
658impl<'de, 's> DeserializeSeed<'de> for EureDocumentSeed<'s> {
659 type Value = ();
660
661 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
662 where
663 D: serde::Deserializer<'de>,
664 {
665 let schema_node_id =
666 resolve_schema_node_id(self.schema, self.schema_node_id).map_err(D::Error::custom)?;
667
668 match &self.schema.node(schema_node_id).content {
669 SchemaNodeContent::Any => de.deserialize_any(AnyVisitor {
670 constructor: self.constructor,
671 }),
672 SchemaNodeContent::Text(_) => de.deserialize_str(TextVisitor {
673 constructor: self.constructor,
674 }),
675 SchemaNodeContent::Integer(_) => de.deserialize_i64(IntegerVisitor {
676 constructor: self.constructor,
677 }),
678 SchemaNodeContent::Float(_) => de.deserialize_f64(FloatVisitor {
679 constructor: self.constructor,
680 }),
681 SchemaNodeContent::Boolean => de.deserialize_bool(BoolVisitor {
682 constructor: self.constructor,
683 }),
684 SchemaNodeContent::Null => de.deserialize_unit(NullVisitor {
685 constructor: self.constructor,
686 }),
687 SchemaNodeContent::Array(s) => de.deserialize_seq(SeqVisitor {
688 schema: self.schema,
689 item_schema_id: s.item,
690 constructor: self.constructor,
691 }),
692 SchemaNodeContent::Tuple(s) => de.deserialize_seq(TupleVisitor {
693 schema: self.schema,
694 elements: &s.elements,
695 constructor: self.constructor,
696 }),
697 SchemaNodeContent::Map(s) => de.deserialize_map(MapVisitor {
698 schema: self.schema,
699 key_schema_id: s.key,
700 value_schema_id: s.value,
701 constructor: self.constructor,
702 }),
703 SchemaNodeContent::Record(s) => de.deserialize_map(RecordVisitor {
704 schema: self.schema,
705 record_schema: s,
706 constructor: self.constructor,
707 }),
708 SchemaNodeContent::Union(u) => {
709 deserialize_union(de, self.schema, u, schema_node_id, self.constructor)
710 }
711 SchemaNodeContent::Literal(_) => de.deserialize_any(AnyVisitor {
715 constructor: self.constructor,
716 }),
717 SchemaNodeContent::Reference(_) => unreachable!("references are resolved above"),
718 }
719 }
720}
721
722pub fn from_deserializer<'de, D: serde::Deserializer<'de>>(
723 de: D,
724 schema: &SchemaDocument,
725) -> Result<EureDocument, DeError> {
726 let mut constructor = DocumentConstructor::new();
727 EureDocumentSeed {
728 schema,
729 schema_node_id: schema.root,
730 constructor: &mut constructor,
731 }
732 .deserialize(de)
733 .map_err(DeError::custom)?;
734 Ok(constructor.finish())
735}
736
737struct AnySeed<'s> {
738 constructor: &'s mut DocumentConstructor,
739}
740
741impl<'de> DeserializeSeed<'de> for AnySeed<'_> {
742 type Value = ();
743
744 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
745 where
746 D: serde::Deserializer<'de>,
747 {
748 de.deserialize_any(AnyVisitor {
749 constructor: self.constructor,
750 })
751 }
752}
753
754struct AnyObjectKeySeed;
755
756impl<'de> DeserializeSeed<'de> for AnyObjectKeySeed {
757 type Value = ObjectKey;
758
759 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
760 where
761 D: serde::Deserializer<'de>,
762 {
763 de.deserialize_any(AnyObjectKeyVisitor)
764 }
765}
766
767struct ObjectKeySeed<'s> {
768 schema: &'s SchemaDocument,
769 schema_node_id: SchemaNodeId,
770}
771
772impl<'de> DeserializeSeed<'de> for ObjectKeySeed<'_> {
773 type Value = ObjectKey;
774
775 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
776 where
777 D: serde::Deserializer<'de>,
778 {
779 let schema_node_id =
780 resolve_schema_node_id(self.schema, self.schema_node_id).map_err(D::Error::custom)?;
781
782 match &self.schema.node(schema_node_id).content {
783 SchemaNodeContent::Any => de.deserialize_any(AnyObjectKeyVisitor),
784 SchemaNodeContent::Text(_) => de.deserialize_any(TextObjectKeyVisitor),
785 SchemaNodeContent::Integer(_) => de.deserialize_any(IntegerObjectKeyVisitor),
786 SchemaNodeContent::Boolean => de.deserialize_any(BoolObjectKeyVisitor),
787 SchemaNodeContent::Literal(expected) => {
788 de.deserialize_any(LiteralObjectKeyVisitor { expected })
789 }
790 SchemaNodeContent::Tuple(tuple_schema) => de.deserialize_seq(TupleObjectKeyVisitor {
791 schema: self.schema,
792 elements: &tuple_schema.elements,
793 }),
794 SchemaNodeContent::Union(union_schema) => de.deserialize_any(UnionObjectKeyVisitor {
795 schema: self.schema,
796 union_schema,
797 }),
798 SchemaNodeContent::Reference(_) => unreachable!("references are resolved above"),
799 SchemaNodeContent::Float(_)
800 | SchemaNodeContent::Null
801 | SchemaNodeContent::Array(_)
802 | SchemaNodeContent::Map(_)
803 | SchemaNodeContent::Record(_) => {
804 Err(D::Error::custom(unsupported_complex_map_keys().to_string()))
805 }
806 }
807 }
808}
809
810struct ArrayElementSeed<'s> {
811 schema: &'s SchemaDocument,
812 item_schema_id: SchemaNodeId,
813 constructor: &'s mut DocumentConstructor,
814}
815
816impl<'de> DeserializeSeed<'de> for ArrayElementSeed<'_> {
817 type Value = ();
818
819 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
820 where
821 D: serde::Deserializer<'de>,
822 {
823 let scope = self.constructor.begin_scope();
824 self.constructor
825 .navigate(PathSegment::ArrayIndex(ArrayIndexKind::Push))
826 .map_err(D::Error::custom)?;
827 EureDocumentSeed {
828 schema: self.schema,
829 schema_node_id: self.item_schema_id,
830 constructor: self.constructor,
831 }
832 .deserialize(de)?;
833 self.constructor
834 .end_scope(scope)
835 .map_err(D::Error::custom)?;
836 Ok(())
837 }
838}
839
840struct AnyArrayElementSeed<'s> {
841 constructor: &'s mut DocumentConstructor,
842}
843
844impl<'de> DeserializeSeed<'de> for AnyArrayElementSeed<'_> {
845 type Value = ();
846
847 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
848 where
849 D: serde::Deserializer<'de>,
850 {
851 let scope = self.constructor.begin_scope();
852 self.constructor
853 .navigate(PathSegment::ArrayIndex(ArrayIndexKind::Push))
854 .map_err(D::Error::custom)?;
855 AnySeed {
856 constructor: self.constructor,
857 }
858 .deserialize(de)?;
859 self.constructor
860 .end_scope(scope)
861 .map_err(D::Error::custom)?;
862 Ok(())
863 }
864}
865
866struct TupleElementSeed<'s> {
867 schema: &'s SchemaDocument,
868 element_schema_id: SchemaNodeId,
869 tuple_index: u8,
870 constructor: &'s mut DocumentConstructor,
871}
872
873impl<'de> DeserializeSeed<'de> for TupleElementSeed<'_> {
874 type Value = ();
875
876 fn deserialize<D>(self, de: D) -> Result<Self::Value, D::Error>
877 where
878 D: serde::Deserializer<'de>,
879 {
880 let scope = self.constructor.begin_scope();
881 self.constructor
882 .navigate(PathSegment::TupleIndex(self.tuple_index))
883 .map_err(D::Error::custom)?;
884 EureDocumentSeed {
885 schema: self.schema,
886 schema_node_id: self.element_schema_id,
887 constructor: self.constructor,
888 }
889 .deserialize(de)?;
890 self.constructor
891 .end_scope(scope)
892 .map_err(D::Error::custom)?;
893 Ok(())
894 }
895}
896
897struct AnyVisitor<'s> {
898 constructor: &'s mut DocumentConstructor,
899}
900
901impl<'de> Visitor<'de> for AnyVisitor<'_> {
902 type Value = ();
903
904 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
905 formatter.write_str("any Eure-compatible value")
906 }
907
908 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
909 where
910 E: de::Error,
911 {
912 bind_bool_value(self.constructor, value).map_err(E::custom)
913 }
914
915 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
916 where
917 E: de::Error,
918 {
919 self.visit_i64(i64::from(value))
920 }
921
922 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
923 where
924 E: de::Error,
925 {
926 self.visit_i64(i64::from(value))
927 }
928
929 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
930 where
931 E: de::Error,
932 {
933 self.visit_i64(i64::from(value))
934 }
935
936 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
937 where
938 E: de::Error,
939 {
940 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
941 }
942
943 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
944 where
945 E: de::Error,
946 {
947 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
948 }
949
950 fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
951 where
952 E: de::Error,
953 {
954 self.visit_u64(u64::from(value))
955 }
956
957 fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
958 where
959 E: de::Error,
960 {
961 self.visit_u64(u64::from(value))
962 }
963
964 fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
965 where
966 E: de::Error,
967 {
968 self.visit_u64(u64::from(value))
969 }
970
971 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
972 where
973 E: de::Error,
974 {
975 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
976 }
977
978 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
979 where
980 E: de::Error,
981 {
982 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
983 }
984
985 fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
986 where
987 E: de::Error,
988 {
989 bind_f32_value(self.constructor, value).map_err(E::custom)
990 }
991
992 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
993 where
994 E: de::Error,
995 {
996 bind_f64_value(self.constructor, value).map_err(E::custom)
997 }
998
999 fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
1000 where
1001 E: de::Error,
1002 {
1003 bind_text_value(self.constructor, value.to_string()).map_err(E::custom)
1004 }
1005
1006 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
1007 where
1008 E: de::Error,
1009 {
1010 bind_text_value(self.constructor, value.to_owned()).map_err(E::custom)
1011 }
1012
1013 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1014 where
1015 E: de::Error,
1016 {
1017 bind_text_value(self.constructor, value.to_owned()).map_err(E::custom)
1018 }
1019
1020 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
1021 where
1022 E: de::Error,
1023 {
1024 bind_text_value(self.constructor, value).map_err(E::custom)
1025 }
1026
1027 fn visit_borrowed_bytes<E>(self, value: &'de [u8]) -> Result<Self::Value, E>
1028 where
1029 E: de::Error,
1030 {
1031 bind_bytes_as_array(self.constructor, value).map_err(E::custom)
1032 }
1033
1034 fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
1035 where
1036 E: de::Error,
1037 {
1038 bind_bytes_as_array(self.constructor, value).map_err(E::custom)
1039 }
1040
1041 fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Self::Value, E>
1042 where
1043 E: de::Error,
1044 {
1045 bind_bytes_as_array(self.constructor, &value).map_err(E::custom)
1046 }
1047
1048 fn visit_unit<E>(self) -> Result<Self::Value, E>
1049 where
1050 E: de::Error,
1051 {
1052 bind_null_value(self.constructor).map_err(E::custom)
1053 }
1054
1055 fn visit_none<E>(self) -> Result<Self::Value, E>
1056 where
1057 E: de::Error,
1058 {
1059 bind_null_value(self.constructor).map_err(E::custom)
1060 }
1061
1062 fn visit_some<D>(self, de: D) -> Result<Self::Value, D::Error>
1063 where
1064 D: serde::Deserializer<'de>,
1065 {
1066 AnySeed {
1067 constructor: self.constructor,
1068 }
1069 .deserialize(de)
1070 }
1071
1072 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1073 where
1074 A: SeqAccess<'de>,
1075 {
1076 self.constructor
1077 .bind_empty_array()
1078 .map_err(A::Error::custom)?;
1079 while seq
1080 .next_element_seed(AnyArrayElementSeed {
1081 constructor: self.constructor,
1082 })?
1083 .is_some()
1084 {}
1085 Ok(())
1086 }
1087
1088 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
1089 where
1090 A: MapAccess<'de>,
1091 {
1092 self.constructor
1093 .bind_empty_map()
1094 .map_err(A::Error::custom)?;
1095 while let Some(key) = map.next_key_seed(AnyObjectKeySeed)? {
1096 let scope = self.constructor.begin_scope();
1097 self.constructor
1098 .navigate(PathSegment::Value(key))
1099 .map_err(A::Error::custom)?;
1100 map.next_value_seed(AnySeed {
1101 constructor: self.constructor,
1102 })?;
1103 self.constructor
1104 .end_scope(scope)
1105 .map_err(A::Error::custom)?;
1106 }
1107 Ok(())
1108 }
1109}
1110
1111struct TextVisitor<'s> {
1112 constructor: &'s mut DocumentConstructor,
1113}
1114
1115impl<'de> Visitor<'de> for TextVisitor<'_> {
1116 type Value = ();
1117
1118 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1119 formatter.write_str("text")
1120 }
1121
1122 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
1123 where
1124 E: de::Error,
1125 {
1126 bind_text_value(self.constructor, value.to_owned()).map_err(E::custom)
1127 }
1128
1129 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1130 where
1131 E: de::Error,
1132 {
1133 bind_text_value(self.constructor, value.to_owned()).map_err(E::custom)
1134 }
1135
1136 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
1137 where
1138 E: de::Error,
1139 {
1140 bind_text_value(self.constructor, value).map_err(E::custom)
1141 }
1142
1143 fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
1144 where
1145 E: de::Error,
1146 {
1147 bind_text_value(self.constructor, value.to_string()).map_err(E::custom)
1148 }
1149
1150 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
1151 where
1152 E: de::Error,
1153 {
1154 bind_text_value(self.constructor, value.to_string()).map_err(E::custom)
1155 }
1156
1157 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1158 where
1159 E: de::Error,
1160 {
1161 bind_text_value(self.constructor, value.to_string()).map_err(E::custom)
1162 }
1163
1164 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
1165 where
1166 E: de::Error,
1167 {
1168 bind_text_value(self.constructor, value.to_string()).map_err(E::custom)
1169 }
1170
1171 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
1172 where
1173 E: de::Error,
1174 {
1175 bind_text_value(self.constructor, value.to_string()).map_err(E::custom)
1176 }
1177}
1178
1179struct IntegerVisitor<'s> {
1180 constructor: &'s mut DocumentConstructor,
1181}
1182
1183impl<'de> Visitor<'de> for IntegerVisitor<'_> {
1184 type Value = ();
1185
1186 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1187 formatter.write_str("integer")
1188 }
1189
1190 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
1191 where
1192 E: de::Error,
1193 {
1194 self.visit_i64(i64::from(value))
1195 }
1196
1197 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
1198 where
1199 E: de::Error,
1200 {
1201 self.visit_i64(i64::from(value))
1202 }
1203
1204 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
1205 where
1206 E: de::Error,
1207 {
1208 self.visit_i64(i64::from(value))
1209 }
1210
1211 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
1212 where
1213 E: de::Error,
1214 {
1215 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
1216 }
1217
1218 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
1219 where
1220 E: de::Error,
1221 {
1222 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
1223 }
1224
1225 fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
1226 where
1227 E: de::Error,
1228 {
1229 self.visit_u64(u64::from(value))
1230 }
1231
1232 fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
1233 where
1234 E: de::Error,
1235 {
1236 self.visit_u64(u64::from(value))
1237 }
1238
1239 fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
1240 where
1241 E: de::Error,
1242 {
1243 self.visit_u64(u64::from(value))
1244 }
1245
1246 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1247 where
1248 E: de::Error,
1249 {
1250 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
1251 }
1252
1253 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
1254 where
1255 E: de::Error,
1256 {
1257 bind_integer_value(self.constructor, BigInt::from(value)).map_err(E::custom)
1258 }
1259
1260 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
1261 where
1262 E: de::Error,
1263 {
1264 let value = parse_bigint(value).map_err(E::custom)?;
1265 bind_integer_value(self.constructor, value).map_err(E::custom)
1266 }
1267
1268 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1269 where
1270 E: de::Error,
1271 {
1272 let value = parse_bigint(value).map_err(E::custom)?;
1273 bind_integer_value(self.constructor, value).map_err(E::custom)
1274 }
1275
1276 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
1277 where
1278 E: de::Error,
1279 {
1280 let value = parse_bigint(&value).map_err(E::custom)?;
1281 bind_integer_value(self.constructor, value).map_err(E::custom)
1282 }
1283}
1284
1285struct FloatVisitor<'s> {
1286 constructor: &'s mut DocumentConstructor,
1287}
1288
1289impl<'de> Visitor<'de> for FloatVisitor<'_> {
1290 type Value = ();
1291
1292 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1293 formatter.write_str("float")
1294 }
1295
1296 fn visit_f32<E>(self, value: f32) -> Result<Self::Value, E>
1297 where
1298 E: de::Error,
1299 {
1300 bind_f32_value(self.constructor, value).map_err(E::custom)
1301 }
1302
1303 fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
1304 where
1305 E: de::Error,
1306 {
1307 bind_f64_value(self.constructor, value).map_err(E::custom)
1308 }
1309
1310 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
1311 where
1312 E: de::Error,
1313 {
1314 bind_f64_value(self.constructor, value as f64).map_err(E::custom)
1315 }
1316
1317 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1318 where
1319 E: de::Error,
1320 {
1321 bind_f64_value(self.constructor, value as f64).map_err(E::custom)
1322 }
1323
1324 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
1325 where
1326 E: de::Error,
1327 {
1328 bind_f64_value(self.constructor, value as f64).map_err(E::custom)
1329 }
1330
1331 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
1332 where
1333 E: de::Error,
1334 {
1335 bind_f64_value(self.constructor, value as f64).map_err(E::custom)
1336 }
1337}
1338
1339struct BoolVisitor<'s> {
1340 constructor: &'s mut DocumentConstructor,
1341}
1342
1343impl<'de> Visitor<'de> for BoolVisitor<'_> {
1344 type Value = ();
1345
1346 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1347 formatter.write_str("boolean")
1348 }
1349
1350 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
1351 where
1352 E: de::Error,
1353 {
1354 bind_bool_value(self.constructor, value).map_err(E::custom)
1355 }
1356}
1357
1358struct NullVisitor<'s> {
1359 constructor: &'s mut DocumentConstructor,
1360}
1361
1362impl<'de> Visitor<'de> for NullVisitor<'_> {
1363 type Value = ();
1364
1365 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1366 formatter.write_str("null")
1367 }
1368
1369 fn visit_unit<E>(self) -> Result<Self::Value, E>
1370 where
1371 E: de::Error,
1372 {
1373 bind_null_value(self.constructor).map_err(E::custom)
1374 }
1375
1376 fn visit_none<E>(self) -> Result<Self::Value, E>
1377 where
1378 E: de::Error,
1379 {
1380 bind_null_value(self.constructor).map_err(E::custom)
1381 }
1382}
1383
1384struct SeqVisitor<'s> {
1385 schema: &'s SchemaDocument,
1386 item_schema_id: SchemaNodeId,
1387 constructor: &'s mut DocumentConstructor,
1388}
1389
1390impl<'de> Visitor<'de> for SeqVisitor<'_> {
1391 type Value = ();
1392
1393 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1394 formatter.write_str("array")
1395 }
1396
1397 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1398 where
1399 A: SeqAccess<'de>,
1400 {
1401 self.constructor
1402 .bind_empty_array()
1403 .map_err(A::Error::custom)?;
1404 while seq
1405 .next_element_seed(ArrayElementSeed {
1406 schema: self.schema,
1407 item_schema_id: self.item_schema_id,
1408 constructor: self.constructor,
1409 })?
1410 .is_some()
1411 {}
1412 Ok(())
1413 }
1414}
1415
1416struct TupleVisitor<'s> {
1417 schema: &'s SchemaDocument,
1418 elements: &'s [SchemaNodeId],
1419 constructor: &'s mut DocumentConstructor,
1420}
1421
1422impl<'de> Visitor<'de> for TupleVisitor<'_> {
1423 type Value = ();
1424
1425 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1426 formatter.write_str("tuple")
1427 }
1428
1429 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1430 where
1431 A: SeqAccess<'de>,
1432 {
1433 self.constructor
1434 .bind_empty_tuple()
1435 .map_err(A::Error::custom)?;
1436
1437 for (index, &element_schema_id) in self.elements.iter().enumerate() {
1438 let tuple_index = u8::try_from(index)
1439 .map_err(|_| A::Error::custom("tuple index out of range for Eure tuple"))?;
1440 let Some(()) = seq.next_element_seed(TupleElementSeed {
1441 schema: self.schema,
1442 element_schema_id,
1443 tuple_index,
1444 constructor: self.constructor,
1445 })?
1446 else {
1447 return Err(A::Error::custom(DeError::EndOfSequence.to_string()));
1448 };
1449 }
1450
1451 if seq.next_element::<de::IgnoredAny>()?.is_some() {
1452 return Err(A::Error::custom(format!(
1453 "tuple length mismatch: expected {}, got more elements",
1454 self.elements.len()
1455 )));
1456 }
1457
1458 Ok(())
1459 }
1460}
1461
1462struct MapVisitor<'s> {
1463 schema: &'s SchemaDocument,
1464 key_schema_id: SchemaNodeId,
1465 value_schema_id: SchemaNodeId,
1466 constructor: &'s mut DocumentConstructor,
1467}
1468
1469impl<'de> Visitor<'de> for MapVisitor<'_> {
1470 type Value = ();
1471
1472 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1473 formatter.write_str("map")
1474 }
1475
1476 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
1477 where
1478 A: MapAccess<'de>,
1479 {
1480 self.constructor
1481 .bind_empty_map()
1482 .map_err(A::Error::custom)?;
1483
1484 while let Some(key) = map.next_key_seed(ObjectKeySeed {
1485 schema: self.schema,
1486 schema_node_id: self.key_schema_id,
1487 })? {
1488 let scope = self.constructor.begin_scope();
1489 self.constructor
1490 .navigate(PathSegment::Value(key))
1491 .map_err(A::Error::custom)?;
1492 map.next_value_seed(EureDocumentSeed {
1493 schema: self.schema,
1494 schema_node_id: self.value_schema_id,
1495 constructor: self.constructor,
1496 })?;
1497 self.constructor
1498 .end_scope(scope)
1499 .map_err(A::Error::custom)?;
1500 }
1501
1502 Ok(())
1503 }
1504}
1505
1506fn collect_flatten_fields(
1509 schema: &SchemaDocument,
1510 node_id: SchemaNodeId,
1511 out: &mut std::collections::HashMap<String, (SchemaNodeId, bool)>,
1512) {
1513 let Ok(resolved) = resolve_schema_node_id(schema, node_id) else {
1514 return;
1515 };
1516
1517 match &schema.node(resolved).content {
1518 SchemaNodeContent::Record(rec) => {
1519 for (name, field) in &rec.properties {
1520 out.entry(name.clone())
1521 .or_insert((field.schema, field.optional));
1522 }
1523 for &inner in &rec.flatten {
1524 collect_flatten_fields(schema, inner, out);
1525 }
1526 }
1527 SchemaNodeContent::Union(_)
1528 | SchemaNodeContent::Any
1529 | SchemaNodeContent::Text(_)
1530 | SchemaNodeContent::Integer(_)
1531 | SchemaNodeContent::Float(_)
1532 | SchemaNodeContent::Boolean
1533 | SchemaNodeContent::Null
1534 | SchemaNodeContent::Literal(_)
1535 | SchemaNodeContent::Array(_)
1536 | SchemaNodeContent::Map(_)
1537 | SchemaNodeContent::Tuple(_)
1538 | SchemaNodeContent::Reference(_) => {}
1539 }
1540}
1541
1542struct RecordVisitor<'s> {
1543 schema: &'s SchemaDocument,
1544 record_schema: &'s eure_schema::RecordSchema,
1545 constructor: &'s mut DocumentConstructor,
1546}
1547
1548impl<'de> Visitor<'de> for RecordVisitor<'_> {
1549 type Value = ();
1550
1551 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1552 formatter.write_str("record")
1553 }
1554
1555 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
1556 where
1557 A: MapAccess<'de>,
1558 {
1559 let mut flatten_fields: std::collections::HashMap<String, (SchemaNodeId, bool)> =
1561 std::collections::HashMap::new();
1562 for &fid in &self.record_schema.flatten {
1563 collect_flatten_fields(self.schema, fid, &mut flatten_fields);
1564 }
1565
1566 self.constructor
1567 .bind_empty_map()
1568 .map_err(A::Error::custom)?;
1569 let mut seen = HashSet::new();
1570
1571 while let Some(key) = map.next_key::<String>()? {
1572 let schema_node_id = if let Some(field_schema) = self.record_schema.properties.get(&key)
1574 {
1575 Some(field_schema.schema)
1576 } else {
1577 flatten_fields.get(&key).map(|&(id, _opt)| id)
1578 };
1579
1580 if let Some(schema_node_id) = schema_node_id {
1581 let scope = self.constructor.begin_scope();
1582 self.constructor
1583 .navigate(PathSegment::Value(ObjectKey::String(key.clone())))
1584 .map_err(A::Error::custom)?;
1585 map.next_value_seed(EureDocumentSeed {
1586 schema: self.schema,
1587 schema_node_id,
1588 constructor: self.constructor,
1589 })?;
1590 self.constructor
1591 .end_scope(scope)
1592 .map_err(A::Error::custom)?;
1593 seen.insert(key);
1594 continue;
1595 }
1596
1597 match &self.record_schema.unknown_fields {
1598 UnknownFieldsPolicy::Deny => {
1599 return Err(A::Error::custom(format!("unknown field: {key}")));
1600 }
1601 UnknownFieldsPolicy::Allow => {
1602 let scope = self.constructor.begin_scope();
1603 self.constructor
1604 .navigate(PathSegment::Value(ObjectKey::String(key.clone())))
1605 .map_err(A::Error::custom)?;
1606 map.next_value_seed(AnySeed {
1607 constructor: self.constructor,
1608 })?;
1609 self.constructor
1610 .end_scope(scope)
1611 .map_err(A::Error::custom)?;
1612 }
1613 UnknownFieldsPolicy::Schema(schema_id) => {
1614 let scope = self.constructor.begin_scope();
1615 self.constructor
1616 .navigate(PathSegment::Value(ObjectKey::String(key.clone())))
1617 .map_err(A::Error::custom)?;
1618 map.next_value_seed(EureDocumentSeed {
1619 schema: self.schema,
1620 schema_node_id: *schema_id,
1621 constructor: self.constructor,
1622 })?;
1623 self.constructor
1624 .end_scope(scope)
1625 .map_err(A::Error::custom)?;
1626 }
1627 }
1628 }
1629
1630 for (name, field) in &self.record_schema.properties {
1631 if !field.optional && !seen.contains(name) {
1632 return Err(A::Error::custom(
1633 DeError::MissingField(name.clone()).to_string(),
1634 ));
1635 }
1636 }
1637 for (name, &(_id, optional)) in &flatten_fields {
1638 if !optional && !seen.contains(name) {
1639 return Err(A::Error::custom(
1640 DeError::MissingField(name.clone()).to_string(),
1641 ));
1642 }
1643 }
1644
1645 Ok(())
1646 }
1647}
1648
1649struct ExternalVariantVisitor<'s> {
1650 schema: &'s SchemaDocument,
1651 union_schema: &'s UnionSchema,
1652 constructor: &'s mut DocumentConstructor,
1653}
1654
1655impl<'de> Visitor<'de> for ExternalVariantVisitor<'_> {
1656 type Value = ();
1657
1658 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1659 formatter.write_str("an externally tagged union")
1660 }
1661
1662 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
1663 where
1664 A: MapAccess<'de>,
1665 {
1666 let variant_name: String = map
1667 .next_key()?
1668 .ok_or_else(|| A::Error::custom("expected variant map with one key"))?;
1669
1670 let Some(&variant_schema_id) = self.union_schema.variants.get(&variant_name) else {
1671 return Err(A::Error::custom(format!("unknown variant: {variant_name}")));
1672 };
1673
1674 self.constructor
1675 .set_variant(&variant_name)
1676 .map_err(A::Error::custom)?;
1677 map.next_value_seed(EureDocumentSeed {
1678 schema: self.schema,
1679 schema_node_id: variant_schema_id,
1680 constructor: self.constructor,
1681 })?;
1682
1683 if map.next_key::<de::IgnoredAny>()?.is_some() {
1684 return Err(A::Error::custom(
1685 "expected externally tagged union map with exactly one key",
1686 ));
1687 }
1688
1689 Ok(())
1690 }
1691
1692 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1693 where
1694 E: de::Error,
1695 {
1696 if self.union_schema.variants.contains_key(value) {
1697 self.constructor.set_variant(value).map_err(E::custom)?;
1698 self.constructor
1699 .bind_primitive(PrimitiveValue::Null)
1700 .map_err(E::custom)?;
1701 Ok(())
1702 } else {
1703 Err(E::custom(format!("unknown variant: {value}")))
1704 }
1705 }
1706
1707 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
1708 where
1709 E: de::Error,
1710 {
1711 self.visit_str(&value)
1712 }
1713}
1714
1715struct AnyObjectKeyVisitor;
1716
1717impl<'de> Visitor<'de> for AnyObjectKeyVisitor {
1718 type Value = ObjectKey;
1719
1720 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1721 formatter.write_str("a Eure-compatible map key")
1722 }
1723
1724 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
1725 where
1726 E: de::Error,
1727 {
1728 Ok(ObjectKey::from(value))
1729 }
1730
1731 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
1732 where
1733 E: de::Error,
1734 {
1735 self.visit_i64(i64::from(value))
1736 }
1737
1738 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
1739 where
1740 E: de::Error,
1741 {
1742 self.visit_i64(i64::from(value))
1743 }
1744
1745 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
1746 where
1747 E: de::Error,
1748 {
1749 self.visit_i64(i64::from(value))
1750 }
1751
1752 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
1753 where
1754 E: de::Error,
1755 {
1756 Ok(ObjectKey::Number(BigInt::from(value)))
1757 }
1758
1759 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
1760 where
1761 E: de::Error,
1762 {
1763 Ok(ObjectKey::Number(BigInt::from(value)))
1764 }
1765
1766 fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
1767 where
1768 E: de::Error,
1769 {
1770 self.visit_u64(u64::from(value))
1771 }
1772
1773 fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
1774 where
1775 E: de::Error,
1776 {
1777 self.visit_u64(u64::from(value))
1778 }
1779
1780 fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
1781 where
1782 E: de::Error,
1783 {
1784 self.visit_u64(u64::from(value))
1785 }
1786
1787 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1788 where
1789 E: de::Error,
1790 {
1791 Ok(ObjectKey::Number(BigInt::from(value)))
1792 }
1793
1794 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
1795 where
1796 E: de::Error,
1797 {
1798 Ok(ObjectKey::Number(BigInt::from(value)))
1799 }
1800
1801 fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
1802 where
1803 E: de::Error,
1804 {
1805 Ok(ObjectKey::String(value.to_string()))
1806 }
1807
1808 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
1809 where
1810 E: de::Error,
1811 {
1812 Ok(ObjectKey::String(value.to_owned()))
1813 }
1814
1815 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1816 where
1817 E: de::Error,
1818 {
1819 Ok(ObjectKey::String(value.to_owned()))
1820 }
1821
1822 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
1823 where
1824 E: de::Error,
1825 {
1826 Ok(ObjectKey::String(value))
1827 }
1828
1829 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
1830 where
1831 A: SeqAccess<'de>,
1832 {
1833 let mut elements = Vec::new();
1834 while let Some(value) = seq.next_element_seed(AnyObjectKeySeed)? {
1835 elements.push(value);
1836 }
1837 Ok(ObjectKey::Tuple(Tuple(elements)))
1838 }
1839}
1840
1841struct TextObjectKeyVisitor;
1842
1843impl<'de> Visitor<'de> for TextObjectKeyVisitor {
1844 type Value = ObjectKey;
1845
1846 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1847 formatter.write_str("a text map key")
1848 }
1849
1850 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
1851 where
1852 E: de::Error,
1853 {
1854 Ok(ObjectKey::String(if value {
1855 "true".to_string()
1856 } else {
1857 "false".to_string()
1858 }))
1859 }
1860
1861 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
1862 where
1863 E: de::Error,
1864 {
1865 Ok(ObjectKey::String(value.to_string()))
1866 }
1867
1868 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1869 where
1870 E: de::Error,
1871 {
1872 Ok(ObjectKey::String(value.to_string()))
1873 }
1874
1875 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
1876 where
1877 E: de::Error,
1878 {
1879 Ok(ObjectKey::String(value.to_string()))
1880 }
1881
1882 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
1883 where
1884 E: de::Error,
1885 {
1886 Ok(ObjectKey::String(value.to_string()))
1887 }
1888
1889 fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
1890 where
1891 E: de::Error,
1892 {
1893 Ok(ObjectKey::String(value.to_string()))
1894 }
1895
1896 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
1897 where
1898 E: de::Error,
1899 {
1900 Ok(ObjectKey::String(value.to_owned()))
1901 }
1902
1903 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
1904 where
1905 E: de::Error,
1906 {
1907 Ok(ObjectKey::String(value.to_owned()))
1908 }
1909
1910 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
1911 where
1912 E: de::Error,
1913 {
1914 Ok(ObjectKey::String(value))
1915 }
1916}
1917
1918struct IntegerObjectKeyVisitor;
1919
1920impl<'de> Visitor<'de> for IntegerObjectKeyVisitor {
1921 type Value = ObjectKey;
1922
1923 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1924 formatter.write_str("an integer map key")
1925 }
1926
1927 fn visit_i8<E>(self, value: i8) -> Result<Self::Value, E>
1928 where
1929 E: de::Error,
1930 {
1931 self.visit_i64(i64::from(value))
1932 }
1933
1934 fn visit_i16<E>(self, value: i16) -> Result<Self::Value, E>
1935 where
1936 E: de::Error,
1937 {
1938 self.visit_i64(i64::from(value))
1939 }
1940
1941 fn visit_i32<E>(self, value: i32) -> Result<Self::Value, E>
1942 where
1943 E: de::Error,
1944 {
1945 self.visit_i64(i64::from(value))
1946 }
1947
1948 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
1949 where
1950 E: de::Error,
1951 {
1952 Ok(ObjectKey::Number(BigInt::from(value)))
1953 }
1954
1955 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
1956 where
1957 E: de::Error,
1958 {
1959 Ok(ObjectKey::Number(BigInt::from(value)))
1960 }
1961
1962 fn visit_u8<E>(self, value: u8) -> Result<Self::Value, E>
1963 where
1964 E: de::Error,
1965 {
1966 self.visit_u64(u64::from(value))
1967 }
1968
1969 fn visit_u16<E>(self, value: u16) -> Result<Self::Value, E>
1970 where
1971 E: de::Error,
1972 {
1973 self.visit_u64(u64::from(value))
1974 }
1975
1976 fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
1977 where
1978 E: de::Error,
1979 {
1980 self.visit_u64(u64::from(value))
1981 }
1982
1983 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
1984 where
1985 E: de::Error,
1986 {
1987 Ok(ObjectKey::Number(BigInt::from(value)))
1988 }
1989
1990 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
1991 where
1992 E: de::Error,
1993 {
1994 Ok(ObjectKey::Number(BigInt::from(value)))
1995 }
1996
1997 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
1998 where
1999 E: de::Error,
2000 {
2001 Ok(ObjectKey::Number(parse_bigint(value).map_err(E::custom)?))
2002 }
2003
2004 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
2005 where
2006 E: de::Error,
2007 {
2008 Ok(ObjectKey::Number(parse_bigint(value).map_err(E::custom)?))
2009 }
2010
2011 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
2012 where
2013 E: de::Error,
2014 {
2015 Ok(ObjectKey::Number(parse_bigint(&value).map_err(E::custom)?))
2016 }
2017}
2018
2019struct BoolObjectKeyVisitor;
2020
2021impl<'de> Visitor<'de> for BoolObjectKeyVisitor {
2022 type Value = ObjectKey;
2023
2024 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
2025 formatter.write_str("a boolean map key")
2026 }
2027
2028 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
2029 where
2030 E: de::Error,
2031 {
2032 Ok(ObjectKey::from(value))
2033 }
2034
2035 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
2036 where
2037 E: de::Error,
2038 {
2039 match value {
2040 "true" => Ok(ObjectKey::String(value.to_owned())),
2041 "false" => Ok(ObjectKey::String(value.to_owned())),
2042 _ => Err(E::custom(type_mismatch("boolean", "text").to_string())),
2043 }
2044 }
2045
2046 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
2047 where
2048 E: de::Error,
2049 {
2050 self.visit_borrowed_str(value)
2051 }
2052
2053 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
2054 where
2055 E: de::Error,
2056 {
2057 self.visit_str(&value)
2058 }
2059}
2060
2061struct LiteralObjectKeyVisitor<'a> {
2062 expected: &'a EureDocument,
2063}
2064
2065impl<'de> Visitor<'de> for LiteralObjectKeyVisitor<'_> {
2066 type Value = ObjectKey;
2067
2068 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
2069 formatter.write_str("a literal map key")
2070 }
2071
2072 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
2073 where
2074 E: de::Error,
2075 {
2076 match expected_primitive(self.expected).map_err(E::custom)? {
2077 PrimitiveValue::Bool(expected) if *expected == value => Ok(ObjectKey::from(value)),
2078 PrimitiveValue::Bool(_) => Err(E::custom("literal mismatch")),
2079 primitive => Err(E::custom(type_mismatch(
2080 "boolean",
2081 primitive_type_name(primitive),
2082 ))),
2083 }
2084 }
2085
2086 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
2087 where
2088 E: de::Error,
2089 {
2090 literal_integer_key(self.expected, BigInt::from(value)).map_err(E::custom)
2091 }
2092
2093 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
2094 where
2095 E: de::Error,
2096 {
2097 literal_integer_key(self.expected, BigInt::from(value)).map_err(E::custom)
2098 }
2099
2100 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
2101 where
2102 E: de::Error,
2103 {
2104 literal_integer_key(self.expected, BigInt::from(value)).map_err(E::custom)
2105 }
2106
2107 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
2108 where
2109 E: de::Error,
2110 {
2111 literal_integer_key(self.expected, BigInt::from(value)).map_err(E::custom)
2112 }
2113
2114 fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
2115 where
2116 E: de::Error,
2117 {
2118 self.visit_string(value.to_string())
2119 }
2120
2121 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
2122 where
2123 E: de::Error,
2124 {
2125 literal_string_key(self.expected, value).map_err(E::custom)
2126 }
2127
2128 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
2129 where
2130 E: de::Error,
2131 {
2132 literal_string_key(self.expected, value).map_err(E::custom)
2133 }
2134
2135 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
2136 where
2137 E: de::Error,
2138 {
2139 literal_string_key(self.expected, &value).map_err(E::custom)
2140 }
2141}
2142
2143struct TupleObjectKeyVisitor<'s> {
2144 schema: &'s SchemaDocument,
2145 elements: &'s [SchemaNodeId],
2146}
2147
2148impl<'de> Visitor<'de> for TupleObjectKeyVisitor<'_> {
2149 type Value = ObjectKey;
2150
2151 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
2152 formatter.write_str("a tuple map key")
2153 }
2154
2155 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
2156 where
2157 A: SeqAccess<'de>,
2158 {
2159 let mut keys = Vec::with_capacity(self.elements.len());
2160
2161 for &element_schema_id in self.elements {
2162 let Some(key) = seq.next_element_seed(ObjectKeySeed {
2163 schema: self.schema,
2164 schema_node_id: element_schema_id,
2165 })?
2166 else {
2167 return Err(A::Error::custom(DeError::EndOfSequence.to_string()));
2168 };
2169 keys.push(key);
2170 }
2171
2172 if seq.next_element::<de::IgnoredAny>()?.is_some() {
2173 return Err(A::Error::custom(format!(
2174 "tuple length mismatch: expected {}, got more elements",
2175 self.elements.len()
2176 )));
2177 }
2178
2179 Ok(ObjectKey::Tuple(Tuple(keys)))
2180 }
2181}
2182
2183struct UnionObjectKeyVisitor<'s> {
2184 schema: &'s SchemaDocument,
2185 union_schema: &'s UnionSchema,
2186}
2187
2188impl<'de> Visitor<'de> for UnionObjectKeyVisitor<'_> {
2189 type Value = ObjectKey;
2190
2191 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
2192 formatter.write_str("a union-compatible map key")
2193 }
2194
2195 fn visit_bool<E>(self, value: bool) -> Result<Self::Value, E>
2196 where
2197 E: de::Error,
2198 {
2199 union_key_from_bool(self.schema, self.union_schema, value).map_err(E::custom)
2200 }
2201
2202 fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
2203 where
2204 E: de::Error,
2205 {
2206 union_key_from_integer(self.schema, self.union_schema, BigInt::from(value))
2207 .map_err(E::custom)
2208 }
2209
2210 fn visit_i128<E>(self, value: i128) -> Result<Self::Value, E>
2211 where
2212 E: de::Error,
2213 {
2214 union_key_from_integer(self.schema, self.union_schema, BigInt::from(value))
2215 .map_err(E::custom)
2216 }
2217
2218 fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
2219 where
2220 E: de::Error,
2221 {
2222 union_key_from_integer(self.schema, self.union_schema, BigInt::from(value))
2223 .map_err(E::custom)
2224 }
2225
2226 fn visit_u128<E>(self, value: u128) -> Result<Self::Value, E>
2227 where
2228 E: de::Error,
2229 {
2230 union_key_from_integer(self.schema, self.union_schema, BigInt::from(value))
2231 .map_err(E::custom)
2232 }
2233
2234 fn visit_char<E>(self, value: char) -> Result<Self::Value, E>
2235 where
2236 E: de::Error,
2237 {
2238 self.visit_string(value.to_string())
2239 }
2240
2241 fn visit_borrowed_str<E>(self, value: &'de str) -> Result<Self::Value, E>
2242 where
2243 E: de::Error,
2244 {
2245 union_key_from_string(self.schema, self.union_schema, value).map_err(E::custom)
2246 }
2247
2248 fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
2249 where
2250 E: de::Error,
2251 {
2252 union_key_from_string(self.schema, self.union_schema, value).map_err(E::custom)
2253 }
2254
2255 fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
2256 where
2257 E: de::Error,
2258 {
2259 union_key_from_string(self.schema, self.union_schema, &value).map_err(E::custom)
2260 }
2261}
2262
2263fn deserialize_union<'de, D: serde::Deserializer<'de>>(
2264 de: D,
2265 schema: &SchemaDocument,
2266 union_schema: &UnionSchema,
2267 _schema_node_id: SchemaNodeId,
2268 constructor: &mut DocumentConstructor,
2269) -> Result<(), D::Error> {
2270 let repr = union_schema
2271 .interop
2272 .variant_repr
2273 .as_ref()
2274 .unwrap_or(&VariantRepr::External);
2275
2276 match repr {
2277 VariantRepr::External => de.deserialize_map(ExternalVariantVisitor {
2278 schema,
2279 union_schema,
2280 constructor,
2281 }),
2282 VariantRepr::Internal { tag } => {
2283 let content = de
2284 .deserialize_map(EureContentMapVisitor)
2285 .map_err(D::Error::custom)?;
2286 deserialize_internal_tagged(content, schema, union_schema, tag, constructor)
2287 .map_err(D::Error::custom)
2288 }
2289 VariantRepr::Adjacent {
2290 tag,
2291 content: content_key,
2292 } => {
2293 let content = de
2294 .deserialize_map(EureContentMapVisitor)
2295 .map_err(D::Error::custom)?;
2296 deserialize_adjacent_tagged(
2297 content,
2298 schema,
2299 union_schema,
2300 tag,
2301 content_key,
2302 constructor,
2303 )
2304 .map_err(D::Error::custom)
2305 }
2306 VariantRepr::Untagged => {
2307 let content = EureContent::deserialize(de).map_err(D::Error::custom)?;
2309 deserialize_untagged(content, schema, union_schema, constructor)
2310 .map_err(D::Error::custom)
2311 }
2312 }
2313}
2314
2315fn deserialize_internal_tagged<'de>(
2316 content: EureContent<'de>,
2317 schema: &SchemaDocument,
2318 union_schema: &UnionSchema,
2319 tag: &str,
2320 constructor: &mut DocumentConstructor,
2321) -> Result<(), DeError> {
2322 let entries = match content {
2323 EureContent::Map(entries) => entries,
2324 other => return Err(type_mismatch("map", eure_content_type(&other))),
2325 };
2326
2327 let mut variant_name = None;
2328 let mut remaining = Vec::new();
2329
2330 for (key, value) in entries {
2331 if content_key_matches(&key, tag) {
2332 if variant_name.is_some() {
2333 return Err(DeError::Custom(format!("duplicate field: {tag}")));
2334 }
2335 variant_name = Some(content_as_variant_name(value)?);
2336 } else {
2337 remaining.push((key, value));
2338 }
2339 }
2340
2341 let variant_name = variant_name.ok_or_else(|| DeError::MissingField(tag.to_string()))?;
2342 let variant_schema_id = *union_schema
2343 .variants
2344 .get(&variant_name)
2345 .ok_or_else(|| DeError::InvalidVariantName(variant_name.clone()))?;
2346
2347 constructor.set_variant(&variant_name)?;
2348
2349 let resolved_variant_id = resolve_schema_node_id(schema, variant_schema_id)?;
2350 let variant_content = if remaining.is_empty()
2351 && matches!(
2352 schema.node(resolved_variant_id).content,
2353 SchemaNodeContent::Null
2354 ) {
2355 EureContent::Unit
2356 } else {
2357 EureContent::Map(remaining)
2358 };
2359
2360 EureDocumentSeed {
2361 schema,
2362 schema_node_id: variant_schema_id,
2363 constructor,
2364 }
2365 .deserialize(variant_content)
2366}
2367
2368fn deserialize_adjacent_tagged<'de>(
2369 content: EureContent<'de>,
2370 schema: &SchemaDocument,
2371 union_schema: &UnionSchema,
2372 tag: &str,
2373 content_key: &str,
2374 constructor: &mut DocumentConstructor,
2375) -> Result<(), DeError> {
2376 let entries = match content {
2377 EureContent::Map(entries) => entries,
2378 other => return Err(type_mismatch("map", eure_content_type(&other))),
2379 };
2380
2381 let mut variant_name = None;
2382 let mut variant_content = None;
2383 let mut remaining = Vec::new();
2384
2385 for (key, value) in entries {
2386 if content_key_matches(&key, tag) {
2387 if variant_name.is_some() {
2388 return Err(DeError::Custom(format!("duplicate field: {tag}")));
2389 }
2390 variant_name = Some(content_as_variant_name(value)?);
2391 } else if content_key_matches(&key, content_key) {
2392 if variant_content.is_some() {
2393 return Err(DeError::Custom(format!("duplicate field: {content_key}")));
2394 }
2395 variant_content = Some(value);
2396 } else {
2397 remaining.push((key, value));
2398 }
2399 }
2400
2401 let variant_name = variant_name.ok_or_else(|| DeError::MissingField(tag.to_string()))?;
2402 let variant_schema_id = *union_schema
2403 .variants
2404 .get(&variant_name)
2405 .ok_or_else(|| DeError::InvalidVariantName(variant_name.clone()))?;
2406 let resolved_variant_id = resolve_schema_node_id(schema, variant_schema_id)?;
2407 let is_null_variant = matches!(
2409 schema.node(resolved_variant_id).content,
2410 SchemaNodeContent::Null
2411 );
2412 let variant_content = if is_null_variant {
2413 variant_content.unwrap_or(EureContent::Unit)
2414 } else {
2415 variant_content.ok_or_else(|| DeError::MissingField(content_key.to_string()))?
2416 };
2417 let variant_content = merge_adjacent_variant_content(
2418 variant_content,
2419 remaining,
2420 &schema.node(resolved_variant_id).content,
2421 )?;
2422
2423 constructor.set_variant(&variant_name)?;
2424 EureDocumentSeed {
2425 schema,
2426 schema_node_id: variant_schema_id,
2427 constructor,
2428 }
2429 .deserialize(variant_content)
2430}
2431
2432fn try_untagged_variant<'de>(
2439 content: EureContent<'de>,
2440 schema: &SchemaDocument,
2441 variant_schema_id: SchemaNodeId,
2442) -> Option<(EureDocument, Option<VariantPath>)> {
2443 let mut temp_constructor = DocumentConstructor::new();
2444 let attempt = EureDocumentSeed {
2445 schema,
2446 schema_node_id: variant_schema_id,
2447 constructor: &mut temp_constructor,
2448 }
2449 .deserialize(content.into_deserializer());
2450
2451 if attempt.is_ok() {
2452 let mut temp_doc = temp_constructor.finish();
2453 let root_id = temp_doc.get_root_id();
2454 let inner_variant_path = extract_variant_path(&temp_doc, root_id).ok()?;
2455 temp_doc
2456 .node_mut(root_id)
2457 .extensions
2458 .remove_ordered(&Identifier::VARIANT);
2459 Some((temp_doc, inner_variant_path))
2460 } else {
2461 None
2462 }
2463}
2464
2465fn deserialize_untagged<'de>(
2466 content: EureContent<'de>,
2467 schema: &SchemaDocument,
2468 union_schema: &UnionSchema,
2469 constructor: &mut DocumentConstructor,
2470) -> Result<(), DeError> {
2471 for (variant_name, &variant_schema_id) in &union_schema.variants {
2474 if union_schema.deny_untagged.contains(variant_name)
2475 || union_schema.unambiguous.contains(variant_name)
2476 {
2477 continue;
2478 }
2479
2480 if let Some((temp_doc, inner_variant_path)) =
2481 try_untagged_variant(content.clone(), schema, variant_schema_id)
2482 {
2483 let root_id = temp_doc.get_root_id();
2484 constructor.set_variant(variant_name)?;
2485 if let Some(inner_variant_path) = inner_variant_path
2486 && !inner_variant_path.is_empty()
2487 {
2488 constructor.set_variant(&inner_variant_path.to_string())?;
2489 }
2490 constructor.write_subtree(&temp_doc, root_id)?;
2491 return Ok(());
2492 }
2493 }
2494
2495 let mut unambiguous_match: Option<(&str, EureDocument, Option<VariantPath>)> = None;
2498 for (variant_name, &variant_schema_id) in &union_schema.variants {
2499 if union_schema.deny_untagged.contains(variant_name)
2500 || !union_schema.unambiguous.contains(variant_name)
2501 {
2502 continue;
2503 }
2504 if let Some((doc, inner_path)) =
2505 try_untagged_variant(content.clone(), schema, variant_schema_id)
2506 {
2507 if unambiguous_match.is_some() {
2508 return Err(DeError::Custom(
2509 "ambiguous untagged union: multiple variants match".to_string(),
2510 ));
2511 }
2512 unambiguous_match = Some((variant_name, doc, inner_path));
2513 }
2514 }
2515 if let Some((variant_name, temp_doc, inner_variant_path)) = unambiguous_match {
2516 let root_id = temp_doc.get_root_id();
2517 constructor.set_variant(variant_name)?;
2518 if let Some(inner_variant_path) = inner_variant_path
2519 && !inner_variant_path.is_empty()
2520 {
2521 constructor.set_variant(&inner_variant_path.to_string())?;
2522 }
2523 constructor.write_subtree(&temp_doc, root_id)?;
2524 return Ok(());
2525 }
2526
2527 Err(DeError::NoVariantMatched)
2528}
2529
2530fn merge_adjacent_variant_content<'de>(
2531 content: EureContent<'de>,
2532 mut sibling_entries: Vec<(EureContent<'de>, EureContent<'de>)>,
2533 schema_content: &SchemaNodeContent,
2534) -> Result<EureContent<'de>, DeError> {
2535 if sibling_entries.is_empty() {
2536 return Ok(content);
2537 }
2538
2539 match schema_content {
2540 SchemaNodeContent::Record(_) | SchemaNodeContent::Map(_) | SchemaNodeContent::Union(_) => {
2541 match content {
2542 EureContent::Map(mut entries) => {
2543 entries.append(&mut sibling_entries);
2544 Ok(EureContent::Map(entries))
2545 }
2546 other => Err(DeError::TypeMismatch {
2547 expected: "map",
2548 actual: eure_content_type(&other).to_string(),
2549 }),
2550 }
2551 }
2552 _ => Err(DeError::Custom(
2553 "adjacent-tagged extra sibling fields require map-like variant content".to_string(),
2554 )),
2555 }
2556}
2557
2558fn bind_text_value(constructor: &mut DocumentConstructor, value: String) -> Result<(), DeError> {
2559 constructor
2560 .bind_primitive(PrimitiveValue::Text(Text::plaintext(value)))
2561 .map_err(Into::into)
2562}
2563
2564fn bind_integer_value(constructor: &mut DocumentConstructor, value: BigInt) -> Result<(), DeError> {
2565 constructor
2566 .bind_primitive(PrimitiveValue::Integer(value))
2567 .map_err(Into::into)
2568}
2569
2570fn bind_f32_value(constructor: &mut DocumentConstructor, value: f32) -> Result<(), DeError> {
2571 constructor
2572 .bind_primitive(PrimitiveValue::F32(value))
2573 .map_err(Into::into)
2574}
2575
2576fn bind_f64_value(constructor: &mut DocumentConstructor, value: f64) -> Result<(), DeError> {
2577 constructor
2578 .bind_primitive(PrimitiveValue::F64(value))
2579 .map_err(Into::into)
2580}
2581
2582fn bind_bool_value(constructor: &mut DocumentConstructor, value: bool) -> Result<(), DeError> {
2583 constructor
2584 .bind_primitive(PrimitiveValue::Bool(value))
2585 .map_err(Into::into)
2586}
2587
2588fn bind_null_value(constructor: &mut DocumentConstructor) -> Result<(), DeError> {
2589 constructor
2590 .bind_primitive(PrimitiveValue::Null)
2591 .map_err(Into::into)
2592}
2593
2594fn bind_bytes_as_array(constructor: &mut DocumentConstructor, bytes: &[u8]) -> Result<(), DeError> {
2595 constructor.bind_empty_array()?;
2596 for &byte in bytes {
2597 let scope = constructor.begin_scope();
2598 constructor.navigate(PathSegment::ArrayIndex(ArrayIndexKind::Push))?;
2599 constructor.bind_primitive(PrimitiveValue::Integer(BigInt::from(byte)))?;
2600 constructor.end_scope(scope)?;
2601 }
2602 Ok(())
2603}
2604
2605fn parse_bigint(value: &str) -> Result<BigInt, DeError> {
2606 BigInt::parse_bytes(value.as_bytes(), 10).ok_or_else(|| type_mismatch("integer", "text"))
2607}
2608
2609fn resolve_schema_node_id(
2610 schema: &SchemaDocument,
2611 mut schema_node_id: SchemaNodeId,
2612) -> Result<SchemaNodeId, DeError> {
2613 for _ in 0..schema.nodes.len() {
2614 match &schema.node(schema_node_id).content {
2615 SchemaNodeContent::Reference(type_ref) => {
2616 if let Some(namespace) = &type_ref.namespace {
2617 return Err(DeError::Custom(format!(
2618 "cross-schema references are unsupported: {namespace}.{}",
2619 type_ref.name
2620 )));
2621 }
2622 schema_node_id = schema.types.get(&type_ref.name).copied().ok_or_else(|| {
2623 DeError::Custom(format!("undefined type reference: {}", type_ref.name))
2624 })?;
2625 }
2626 _ => return Ok(schema_node_id),
2627 }
2628 }
2629
2630 Err(DeError::Custom(
2631 "schema reference cycle detected".to_string(),
2632 ))
2633}
2634
2635fn extract_variant_path(
2636 doc: &EureDocument,
2637 node_id: eure::document::NodeId,
2638) -> Result<Option<VariantPath>, DeError> {
2639 let Some(variant_id) = doc
2640 .node(node_id)
2641 .extensions
2642 .get(&Identifier::VARIANT)
2643 .copied()
2644 else {
2645 return Ok(None);
2646 };
2647 let value = match &doc.node(variant_id).content {
2648 NodeValue::Primitive(PrimitiveValue::Text(text)) => text.as_str(),
2649 other => {
2650 return Err(DeError::TypeMismatch {
2651 expected: "text",
2652 actual: primitive_or_node_type_name(other).to_string(),
2653 });
2654 }
2655 };
2656
2657 VariantPath::parse(value)
2658 .map(Some)
2659 .map_err(|_| DeError::InvalidVariantName(value.to_string()))
2660}
2661
2662fn primitive_or_node_type_name(value: &NodeValue) -> &'static str {
2663 match value {
2664 NodeValue::Hole(_) => "hole",
2665 NodeValue::Primitive(PrimitiveValue::Null) => "null",
2666 NodeValue::Primitive(PrimitiveValue::Bool(_)) => "boolean",
2667 NodeValue::Primitive(PrimitiveValue::Integer(_)) => "integer",
2668 NodeValue::Primitive(PrimitiveValue::F32(_))
2669 | NodeValue::Primitive(PrimitiveValue::F64(_)) => "float",
2670 NodeValue::Primitive(PrimitiveValue::Text(_)) => "text",
2671 NodeValue::Array(_) => "array",
2672 NodeValue::Map(_) => "map",
2673 NodeValue::Tuple(_) => "tuple",
2674 NodeValue::PartialMap(_) => "partial-map",
2675 }
2676}
2677
2678fn content_key_matches(content: &EureContent<'_>, expected: &str) -> bool {
2679 match content {
2680 EureContent::String(value) => value.as_ref() == expected,
2681 EureContent::Char(value) => {
2682 let mut chars = expected.chars();
2683 chars.next() == Some(*value) && chars.next().is_none()
2684 }
2685 _ => false,
2686 }
2687}
2688
2689fn content_as_variant_name(content: EureContent<'_>) -> Result<String, DeError> {
2690 match content {
2691 EureContent::String(value) => Ok(value.into_owned()),
2692 EureContent::Char(value) => Ok(value.to_string()),
2693 other => Err(type_mismatch("text", eure_content_type(&other))),
2694 }
2695}
2696
2697fn type_mismatch(expected: &'static str, actual: impl Into<String>) -> DeError {
2698 DeError::TypeMismatch {
2699 expected,
2700 actual: actual.into(),
2701 }
2702}
2703
2704fn primitive_type_name(primitive: &PrimitiveValue) -> &'static str {
2705 match primitive {
2706 PrimitiveValue::Null => "null",
2707 PrimitiveValue::Bool(_) => "boolean",
2708 PrimitiveValue::Integer(_) => "integer",
2709 PrimitiveValue::F32(_) | PrimitiveValue::F64(_) => "float",
2710 PrimitiveValue::Text(_) => "text",
2711 }
2712}
2713
2714fn eure_content_type(content: &EureContent<'_>) -> String {
2715 match content {
2716 EureContent::Bool(_) => "boolean".to_string(),
2717 EureContent::I8(_)
2718 | EureContent::I16(_)
2719 | EureContent::I32(_)
2720 | EureContent::I64(_)
2721 | EureContent::I128(_)
2722 | EureContent::U8(_)
2723 | EureContent::U16(_)
2724 | EureContent::U32(_)
2725 | EureContent::U64(_)
2726 | EureContent::U128(_) => "integer".to_string(),
2727 EureContent::F32(_) | EureContent::F64(_) => "float".to_string(),
2728 EureContent::Char(_) | EureContent::String(_) => "text".to_string(),
2729 EureContent::Bytes(_) => "bytes".to_string(),
2730 EureContent::Unit => "null".to_string(),
2731 EureContent::Seq(_) => "array".to_string(),
2732 EureContent::Map(_) => "map".to_string(),
2733 }
2734}
2735
2736fn expected_primitive(expected: &EureDocument) -> Result<&PrimitiveValue, DeError> {
2737 expected
2738 .root()
2739 .as_primitive()
2740 .ok_or_else(unsupported_complex_literal_key)
2741}
2742
2743fn unsupported_complex_map_keys() -> DeError {
2744 DeError::Custom("complex map keys are unsupported in serde-eure v1".to_string())
2745}
2746
2747fn unsupported_complex_literal_key() -> DeError {
2748 DeError::Custom("complex literal map keys are unsupported in serde-eure v1".to_string())
2749}
2750
2751fn literal_integer_key(expected: &EureDocument, actual: BigInt) -> Result<ObjectKey, DeError> {
2752 match expected_primitive(expected)? {
2753 PrimitiveValue::Integer(expected_value) if expected_value == &actual => {
2754 Ok(ObjectKey::Number(actual))
2755 }
2756 PrimitiveValue::Integer(_) => Err(DeError::Custom("literal mismatch".to_string())),
2757 primitive => Err(type_mismatch("integer", primitive_type_name(primitive))),
2758 }
2759}
2760
2761fn literal_string_key(expected: &EureDocument, actual: &str) -> Result<ObjectKey, DeError> {
2762 match expected_primitive(expected)? {
2763 PrimitiveValue::Text(expected_value) if expected_value.as_str() == actual => {
2764 Ok(ObjectKey::String(actual.to_owned()))
2765 }
2766 PrimitiveValue::Text(_) => Err(DeError::Custom("literal mismatch".to_string())),
2767 PrimitiveValue::Integer(expected_value) => {
2768 let parsed = parse_bigint(actual)?;
2769 if expected_value == &parsed {
2770 Ok(ObjectKey::Number(parsed))
2771 } else {
2772 Err(DeError::Custom("literal mismatch".to_string()))
2773 }
2774 }
2775 PrimitiveValue::Bool(expected_value) => {
2776 let expected_text = if *expected_value { "true" } else { "false" };
2777 if actual == expected_text {
2778 Ok(ObjectKey::String(actual.to_owned()))
2779 } else {
2780 Err(DeError::Custom("literal mismatch".to_string()))
2781 }
2782 }
2783 PrimitiveValue::Null | PrimitiveValue::F32(_) | PrimitiveValue::F64(_) => {
2784 Err(unsupported_complex_literal_key())
2785 }
2786 }
2787}
2788
2789fn object_key_from_string_for_schema(
2790 schema: &SchemaDocument,
2791 schema_node_id: SchemaNodeId,
2792 value: &str,
2793) -> Result<ObjectKey, DeError> {
2794 let schema_node_id = resolve_schema_node_id(schema, schema_node_id)?;
2795
2796 match &schema.node(schema_node_id).content {
2797 SchemaNodeContent::Any | SchemaNodeContent::Text(_) => {
2798 Ok(ObjectKey::String(value.to_owned()))
2799 }
2800 SchemaNodeContent::Integer(_) => Ok(ObjectKey::Number(parse_bigint(value)?)),
2801 SchemaNodeContent::Boolean => match value {
2802 "true" | "false" => Ok(ObjectKey::String(value.to_owned())),
2803 _ => Err(type_mismatch("boolean", "text")),
2804 },
2805 SchemaNodeContent::Literal(expected) => literal_string_key(expected, value),
2806 SchemaNodeContent::Tuple(_)
2807 | SchemaNodeContent::Float(_)
2808 | SchemaNodeContent::Null
2809 | SchemaNodeContent::Array(_)
2810 | SchemaNodeContent::Map(_)
2811 | SchemaNodeContent::Record(_) => Err(unsupported_complex_map_keys()),
2812 SchemaNodeContent::Union(union_schema) => {
2813 union_key_from_string(schema, union_schema, value)
2814 }
2815 SchemaNodeContent::Reference(_) => unreachable!("references are resolved above"),
2816 }
2817}
2818
2819fn object_key_from_integer_for_schema(
2820 schema: &SchemaDocument,
2821 schema_node_id: SchemaNodeId,
2822 value: &BigInt,
2823) -> Result<ObjectKey, DeError> {
2824 let schema_node_id = resolve_schema_node_id(schema, schema_node_id)?;
2825
2826 match &schema.node(schema_node_id).content {
2827 SchemaNodeContent::Any | SchemaNodeContent::Integer(_) => {
2828 Ok(ObjectKey::Number(value.clone()))
2829 }
2830 SchemaNodeContent::Text(_) => Ok(ObjectKey::String(value.to_string())),
2831 SchemaNodeContent::Literal(expected) => literal_integer_key(expected, value.clone()),
2832 SchemaNodeContent::Union(union_schema) => {
2833 union_key_from_integer(schema, union_schema, value.clone())
2834 }
2835 SchemaNodeContent::Boolean
2836 | SchemaNodeContent::Tuple(_)
2837 | SchemaNodeContent::Float(_)
2838 | SchemaNodeContent::Null
2839 | SchemaNodeContent::Array(_)
2840 | SchemaNodeContent::Map(_)
2841 | SchemaNodeContent::Record(_) => Err(unsupported_complex_map_keys()),
2842 SchemaNodeContent::Reference(_) => unreachable!("references are resolved above"),
2843 }
2844}
2845
2846fn object_key_from_bool_for_schema(
2847 schema: &SchemaDocument,
2848 schema_node_id: SchemaNodeId,
2849 value: bool,
2850) -> Result<ObjectKey, DeError> {
2851 let schema_node_id = resolve_schema_node_id(schema, schema_node_id)?;
2852
2853 match &schema.node(schema_node_id).content {
2854 SchemaNodeContent::Any | SchemaNodeContent::Text(_) | SchemaNodeContent::Boolean => {
2855 Ok(ObjectKey::from(value))
2856 }
2857 SchemaNodeContent::Literal(expected) => match expected_primitive(expected)? {
2858 PrimitiveValue::Bool(expected_value) if *expected_value == value => {
2859 Ok(ObjectKey::from(value))
2860 }
2861 PrimitiveValue::Bool(_) => Err(DeError::Custom("literal mismatch".to_string())),
2862 primitive => Err(type_mismatch("boolean", primitive_type_name(primitive))),
2863 },
2864 SchemaNodeContent::Union(union_schema) => union_key_from_bool(schema, union_schema, value),
2865 SchemaNodeContent::Integer(_)
2866 | SchemaNodeContent::Tuple(_)
2867 | SchemaNodeContent::Float(_)
2868 | SchemaNodeContent::Null
2869 | SchemaNodeContent::Array(_)
2870 | SchemaNodeContent::Map(_)
2871 | SchemaNodeContent::Record(_) => Err(unsupported_complex_map_keys()),
2872 SchemaNodeContent::Reference(_) => unreachable!("references are resolved above"),
2873 }
2874}
2875
2876fn union_key_from_string(
2877 schema: &SchemaDocument,
2878 union_schema: &UnionSchema,
2879 value: &str,
2880) -> Result<ObjectKey, DeError> {
2881 if union_schema.variants.contains_key(value) {
2882 return Ok(ObjectKey::String(value.to_owned()));
2883 }
2884
2885 for &variant_schema_id in union_schema.variants.values() {
2886 if let Ok(key) = object_key_from_string_for_schema(schema, variant_schema_id, value) {
2887 return Ok(key);
2888 }
2889 }
2890
2891 Err(type_mismatch("map-key", "text"))
2892}
2893
2894fn union_key_from_integer(
2895 schema: &SchemaDocument,
2896 union_schema: &UnionSchema,
2897 value: BigInt,
2898) -> Result<ObjectKey, DeError> {
2899 for &variant_schema_id in union_schema.variants.values() {
2900 if let Ok(key) = object_key_from_integer_for_schema(schema, variant_schema_id, &value) {
2901 return Ok(key);
2902 }
2903 }
2904
2905 Err(type_mismatch("map-key", "integer"))
2906}
2907
2908fn union_key_from_bool(
2909 schema: &SchemaDocument,
2910 union_schema: &UnionSchema,
2911 value: bool,
2912) -> Result<ObjectKey, DeError> {
2913 for &variant_schema_id in union_schema.variants.values() {
2914 if let Ok(key) = object_key_from_bool_for_schema(schema, variant_schema_id, value) {
2915 return Ok(key);
2916 }
2917 }
2918
2919 Err(type_mismatch("map-key", "boolean"))
2920}
2921
2922#[cfg(test)]
2923mod tests {
2924 use eure::eure;
2925 use eure_schema::TextSchema;
2926 use eure_schema::interop::{UnionInterop, VariantRepr};
2927 use eure_schema::{
2928 IntegerSchema, RecordFieldSchema, RecordSchema, SchemaDocument, SchemaNodeContent,
2929 UnionSchema, UnknownFieldsPolicy,
2930 };
2931 use serde_json::Deserializer;
2932
2933 use super::from_deserializer;
2934
2935 fn make_record_schema() -> SchemaDocument {
2936 let mut schema = SchemaDocument::new();
2937 let text_id = schema.create_node(SchemaNodeContent::Text(TextSchema::default()));
2938 let int_id = schema.create_node(SchemaNodeContent::Integer(IntegerSchema::default()));
2939 let record_id = schema.create_node(SchemaNodeContent::Record(RecordSchema {
2940 properties: [
2941 (
2942 "name".to_string(),
2943 RecordFieldSchema {
2944 schema: text_id,
2945 optional: false,
2946 binding_style: None,
2947 field_codegen: Default::default(),
2948 },
2949 ),
2950 (
2951 "age".to_string(),
2952 RecordFieldSchema {
2953 schema: int_id,
2954 optional: false,
2955 binding_style: None,
2956 field_codegen: Default::default(),
2957 },
2958 ),
2959 ]
2960 .into_iter()
2961 .collect(),
2962 flatten: Vec::new(),
2963 unknown_fields: UnknownFieldsPolicy::Deny,
2964 }));
2965 schema.root = record_id;
2966 schema
2967 }
2968
2969 fn make_union_schema(variant_repr: VariantRepr) -> SchemaDocument {
2970 let mut schema = SchemaDocument::new();
2971 let text_id = schema.create_node(SchemaNodeContent::Text(TextSchema::default()));
2972 let success_record_id = schema.create_node(SchemaNodeContent::Record(RecordSchema {
2973 properties: [(
2974 "message".to_string(),
2975 RecordFieldSchema {
2976 schema: text_id,
2977 optional: false,
2978 binding_style: None,
2979 field_codegen: Default::default(),
2980 },
2981 )]
2982 .into_iter()
2983 .collect(),
2984 flatten: Vec::new(),
2985 unknown_fields: UnknownFieldsPolicy::Deny,
2986 }));
2987 let union_id = schema.create_node(SchemaNodeContent::Union(UnionSchema {
2988 variants: [("success".to_string(), success_record_id)]
2989 .into_iter()
2990 .collect(),
2991 unambiguous: Default::default(),
2992 interop: UnionInterop {
2993 variant_repr: Some(variant_repr),
2994 },
2995 deny_untagged: Default::default(),
2996 }));
2997 schema.root = union_id;
2998 schema
2999 }
3000
3001 #[test]
3002 fn deserializes_json_object_into_record_document() {
3003 let schema = make_record_schema();
3004 let mut de = Deserializer::from_str(r#"{ "name": "Alice", "age": 30 }"#);
3005
3006 let actual = from_deserializer(&mut de, &schema).unwrap();
3007 let expected = eure!({
3008 name = "Alice",
3009 age = 30,
3010 });
3011
3012 assert_eq!(actual, expected);
3013 }
3014
3015 #[test]
3016 fn deserializes_external_variant_into_document() {
3017 let schema = make_union_schema(VariantRepr::External);
3018 let mut de = Deserializer::from_str(r#"{ "success": { "message": "ok" } }"#);
3019
3020 let actual = from_deserializer(&mut de, &schema).unwrap();
3021 let expected = eure!({
3022 message = "ok",
3023 %variant = "success",
3024 });
3025
3026 assert_eq!(actual, expected);
3027 }
3028
3029 #[test]
3030 fn deserializes_internal_variant_into_document() {
3031 let schema = make_union_schema(VariantRepr::Internal {
3032 tag: "type".to_string(),
3033 });
3034 let mut de = Deserializer::from_str(r#"{ "type": "success", "message": "ok" }"#);
3035
3036 let actual = from_deserializer(&mut de, &schema).unwrap();
3037 let expected = eure!({
3038 message = "ok",
3039 %variant = "success",
3040 });
3041
3042 assert_eq!(actual, expected);
3043 }
3044}