1#![cfg_attr(not(feature = "std"), no_std)]
2#![warn(missing_docs)]
3#![warn(clippy::std_instead_of_core)]
4#![warn(clippy::std_instead_of_alloc)]
5#![deny(unsafe_code)]
6#![doc = include_str!("../README.md")]
7
8extern crate alloc;
9
10use alloc::string::ToString;
11use alloc::{vec, vec::Vec};
12
13mod debug;
14mod error;
15use alloc::borrow::Cow;
16pub use debug::InputDebug;
17
18pub use error::*;
19
20mod span;
21use facet_core::{
22 Characteristic, Def, Facet, FieldFlags, PointerType, ScalarAffinity, SequenceType, StructKind,
23 Type, UserType,
24};
25use owo_colors::OwoColorize;
26pub use span::*;
27
28use facet_reflect::{HeapValue, ReflectError, Wip};
29use log::trace;
30
31#[derive(PartialEq, Debug, Clone)]
32pub enum Scalar<'input> {
37 String(Cow<'input, str>),
39 U64(u64),
41 I64(i64),
43 F64(f64),
45 Bool(bool),
47 Null,
49}
50
51#[derive(PartialEq, Debug, Clone)]
52pub enum Expectation {
54 Value,
56 ObjectKeyOrObjectClose,
58 ObjectVal,
60 ListItemOrListClose,
62}
63
64#[derive(PartialEq, Debug, Clone)]
65pub enum Outcome<'input> {
67 Scalar(Scalar<'input>),
69 ListStarted,
71 ListEnded,
73 ObjectStarted,
75 ObjectEnded,
77}
78
79impl<'input> From<Scalar<'input>> for Outcome<'input> {
80 fn from(scalar: Scalar<'input>) -> Self {
81 Outcome::Scalar(scalar)
82 }
83}
84
85use core::fmt;
86
87impl fmt::Display for Outcome<'_> {
89 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 match self {
91 Outcome::Scalar(scalar) => write!(f, "scalar {}", scalar),
92 Outcome::ListStarted => write!(f, "list start"),
93 Outcome::ListEnded => write!(f, "list end"),
94 Outcome::ObjectStarted => write!(f, "object start"),
95 Outcome::ObjectEnded => write!(f, "object end"),
96 }
97 }
98}
99
100impl fmt::Display for Scalar<'_> {
102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103 match self {
104 Scalar::String(s) => write!(f, "string \"{}\"", s),
105 Scalar::U64(val) => write!(f, "u64 {}", val),
106 Scalar::I64(val) => write!(f, "i64 {}", val),
107 Scalar::F64(val) => write!(f, "f64 {}", val),
108 Scalar::Bool(val) => write!(f, "bool {}", val),
109 Scalar::Null => write!(f, "null"),
110 }
111 }
112}
113
114impl Outcome<'_> {
115 fn into_owned(self) -> Outcome<'static> {
116 match self {
117 Outcome::Scalar(scalar) => {
118 let owned_scalar = match scalar {
119 Scalar::String(cow) => Scalar::String(Cow::Owned(cow.into_owned())),
120 Scalar::U64(val) => Scalar::U64(val),
121 Scalar::I64(val) => Scalar::I64(val),
122 Scalar::F64(val) => Scalar::F64(val),
123 Scalar::Bool(val) => Scalar::Bool(val),
124 Scalar::Null => Scalar::Null,
125 };
126 Outcome::Scalar(owned_scalar)
127 }
128 Outcome::ListStarted => Outcome::ListStarted,
129 Outcome::ListEnded => Outcome::ListEnded,
130 Outcome::ObjectStarted => Outcome::ObjectStarted,
131 Outcome::ObjectEnded => Outcome::ObjectEnded,
132 }
133 }
134}
135
136pub struct NextData<'input: 'facet, 'facet, 'shape, I: ?Sized + 'input = [u8]> {
139 start: usize,
141
142 runner: StackRunner<'input, I>,
144
145 pub wip: Wip<'facet, 'shape>,
147}
148
149impl<'input: 'facet, 'facet, 'shape, I: ?Sized + 'input> NextData<'input, 'facet, 'shape, I> {
150 pub fn input(&self) -> &'input I {
152 self.runner.input
153 }
154
155 pub fn start(&self) -> usize {
157 self.start
158 }
159}
160
161pub type NextResult<'input, 'facet, 'shape, T, E, I = [u8]> =
163 (NextData<'input, 'facet, 'shape, I>, Result<T, E>);
164
165pub trait Format {
168 type Input<'input>: ?Sized;
173
174 fn source(&self) -> &'static str;
176
177 fn next<'input, 'facet, 'shape>(
179 &mut self,
180 nd: NextData<'input, 'facet, 'shape, Self::Input<'input>>,
181 expectation: Expectation,
182 ) -> NextResult<
183 'input,
184 'facet,
185 'shape,
186 Spanned<Outcome<'input>>,
187 Spanned<DeserErrorKind<'shape>>,
188 Self::Input<'input>,
189 >
190 where
191 'shape: 'input;
192
193 fn skip<'input, 'facet, 'shape>(
195 &mut self,
196 nd: NextData<'input, 'facet, 'shape, Self::Input<'input>>,
197 ) -> NextResult<
198 'input,
199 'facet,
200 'shape,
201 Span,
202 Spanned<DeserErrorKind<'shape>>,
203 Self::Input<'input>,
204 >
205 where
206 'shape: 'input;
207}
208
209#[derive(Debug, Clone, Copy, PartialEq, Eq)]
211pub enum Instruction {
212 Value(ValueReason),
214 SkipValue,
216 Pop(PopReason),
218 ObjectKeyOrObjectClose,
220 ListItemOrListClose,
222}
223
224#[derive(Debug, Clone, Copy, PartialEq, Eq)]
226pub enum ValueReason {
227 TopLevel,
229 ObjectVal,
231}
232
233#[derive(Debug, Clone, Copy, PartialEq, Eq)]
235pub enum PopReason {
236 TopLevel,
238 ObjectVal,
240 ListVal,
242 Some,
244}
245
246pub fn deserialize<'input, 'facet, 'shape, T, F>(
251 input: &'input F::Input<'input>,
252 format: F,
253) -> Result<T, DeserError<'input, 'shape>>
254where
255 T: Facet<'facet>,
256 F: Format + 'shape,
257 F::Input<'input>: InputDebug,
258 'input: 'facet,
259 'shape: 'input,
260{
261 let source = format.source();
262 let wip = Wip::alloc_shape(T::SHAPE)
263 .map_err(|e| DeserError::new_reflect(e, input, Span { start: 0, len: 0 }, source))?;
264 deserialize_wip(wip, input, format)?
265 .materialize()
266 .map_err(|e| DeserError::new_reflect(e, input, Span { start: 0, len: 0 }, source))
267}
268
269pub fn deserialize_wip<'input, 'facet, 'shape, F>(
272 mut wip: Wip<'facet, 'shape>,
273 input: &'input F::Input<'input>,
274 mut format: F,
275) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape>>
276where
277 F: Format + 'shape,
278 F::Input<'input>: InputDebug,
279 'input: 'facet,
280 'shape: 'input,
281{
282 let mut runner = StackRunner {
284 original_input: input,
285 input,
286 stack: vec![
287 Instruction::Pop(PopReason::TopLevel),
288 Instruction::Value(ValueReason::TopLevel),
289 ],
290 last_span: Span::new(0, 0),
291 format_source: format.source(),
292 };
293
294 macro_rules! next {
295 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
296 let nd = NextData {
297 start: $runner.last_span.end(), runner: $runner,
299 wip: $wip,
300 };
301 let (nd, res) = format.next(nd, $expectation);
302 $runner = nd.runner;
303 $wip = nd.wip;
304 let outcome = res.map_err(|span_kind| {
305 $runner.last_span = span_kind.span;
306 $runner.err(span_kind.node)
307 })?;
308 $runner.last_span = outcome.span;
309 $wip = $runner.$method($wip, outcome)?;
310 }};
311 }
312
313 loop {
314 let frame_count = wip.frames_count();
315 debug_assert!(
316 frame_count
317 >= runner
318 .stack
319 .iter()
320 .filter(|f| matches!(f, Instruction::Pop(_)))
321 .count()
322 );
323
324 let insn = match runner.stack.pop() {
325 Some(insn) => insn,
326 None => unreachable!("Instruction stack is empty"),
327 };
328
329 trace!("[{frame_count}] Instruction {:?}", insn.yellow());
330
331 match insn {
332 Instruction::Pop(reason) => {
333 wip = runner.pop(wip, reason)?;
334
335 if reason == PopReason::TopLevel {
336 return wip.build().map_err(|e| runner.reflect_err(e));
337 } else {
338 wip = wip.pop().map_err(|e| runner.reflect_err(e))?;
339 }
340 }
341 Instruction::Value(_why) => {
342 let expectation = match _why {
343 ValueReason::TopLevel => Expectation::Value,
344 ValueReason::ObjectVal => Expectation::ObjectVal,
345 };
346 next!(runner, wip, expectation, value);
347 }
348 Instruction::ObjectKeyOrObjectClose => {
349 next!(
350 runner,
351 wip,
352 Expectation::ObjectKeyOrObjectClose,
353 object_key_or_object_close
354 );
355 }
356 Instruction::ListItemOrListClose => {
357 next!(
358 runner,
359 wip,
360 Expectation::ListItemOrListClose,
361 list_item_or_list_close
362 );
363 }
364 Instruction::SkipValue => {
365 let nd = NextData {
367 start: runner.last_span.end(),
368 runner,
369 wip,
370 };
371 let (nd, res) = format.skip(nd);
372 runner = nd.runner;
373 wip = nd.wip;
374 let span = res.map_err(|span_kind| {
376 runner.last_span = span_kind.span;
377 runner.err(span_kind.node)
378 })?;
379 runner.last_span = span;
381 }
382 }
383 }
384}
385
386#[doc(hidden)]
387pub struct StackRunner<'input, I: ?Sized + 'input = [u8]> {
392 pub original_input: &'input I,
394
395 pub input: &'input I,
397
398 pub stack: Vec<Instruction>,
400
401 pub last_span: Span,
403
404 pub format_source: &'static str,
406}
407
408impl<'input, 'shape, I: ?Sized + 'input> StackRunner<'input, I>
409where
410 I: InputDebug,
411{
412 fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape> {
414 DeserError::new(
415 kind,
416 self.original_input,
417 self.last_span,
418 self.format_source,
419 )
420 }
421
422 fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape> {
425 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
426 }
427
428 pub fn pop<'facet>(
429 &mut self,
430 mut wip: Wip<'facet, 'shape>,
431 reason: PopReason,
432 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape>> {
433 trace!("Popping because {:?}", reason.yellow());
434
435 let container_shape = wip.shape();
436 match container_shape.ty {
437 Type::User(UserType::Struct(sd)) => {
438 let mut has_unset = false;
439
440 trace!("Let's check all fields are initialized");
441 for (index, field) in sd.fields.iter().enumerate() {
442 let is_set = wip.is_field_set(index).map_err(|err| {
443 trace!("Error checking field set status: {:?}", err);
444 self.reflect_err(err)
445 })?;
446 if !is_set {
447 if field.flags.contains(FieldFlags::DEFAULT) {
448 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
449 if let Some(default_in_place_fn) = field.vtable.default_fn {
450 wip = wip
451 .put_from_fn(default_in_place_fn)
452 .map_err(|e| self.reflect_err(e))?;
453 trace!(
454 "Field #{} {} @ {} was set to default value (via custom fn)",
455 index.yellow(),
456 field.name.green(),
457 field.offset.blue(),
458 );
459 } else {
460 if !field.shape().is(Characteristic::Default) {
461 return Err(self.reflect_err(
462 ReflectError::DefaultAttrButNoDefaultImpl {
463 shape: field.shape(),
464 },
465 ));
466 }
467 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
468 trace!(
469 "Field #{} {} @ {} was set to default value (via default impl)",
470 index.yellow(),
471 field.name.green(),
472 field.offset.blue(),
473 );
474 }
475 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
476 } else {
477 trace!(
478 "Field #{} {} @ {} is not initialized",
479 index.yellow(),
480 field.name.green(),
481 field.offset.blue(),
482 );
483 has_unset = true;
484 }
485 }
486 }
487
488 if has_unset && container_shape.has_default_attr() {
489 let default_val = Wip::alloc_shape(container_shape)
491 .map_err(|e| self.reflect_err(e))?
492 .put_default()
493 .map_err(|e| self.reflect_err(e))?
494 .build()
495 .map_err(|e| self.reflect_err(e))?;
496 let peek = default_val.peek().into_struct().unwrap();
497
498 for (index, field) in sd.fields.iter().enumerate() {
499 let is_set = wip.is_field_set(index).map_err(|err| {
500 trace!("Error checking field set status: {:?}", err);
501 self.reflect_err(err)
502 })?;
503 if !is_set {
504 let address_of_field_from_default = peek.field(index).unwrap().data();
505 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
506 wip = wip
507 .put_shape(address_of_field_from_default, field.shape())
508 .map_err(|e| self.reflect_err(e))?;
509 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
510 }
511 }
512 }
513 }
514 Type::User(UserType::Enum(ed)) => {
515 trace!("Checking if enum is initialized correctly");
516
517 if let Some(variant) = wip.selected_variant() {
519 trace!("Variant {} is selected", variant.name.blue());
520
521 if !variant.data.fields.is_empty() {
523 let mut has_unset = false;
524
525 for (index, field) in variant.data.fields.iter().enumerate() {
526 let is_set = wip.is_field_set(index).map_err(|err| {
527 trace!("Error checking field set status: {:?}", err);
528 self.reflect_err(err)
529 })?;
530
531 if !is_set {
532 if field.flags.contains(FieldFlags::DEFAULT) {
533 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
534 if let Some(default_in_place_fn) = field.vtable.default_fn {
535 wip = wip
536 .put_from_fn(default_in_place_fn)
537 .map_err(|e| self.reflect_err(e))?;
538 trace!(
539 "Field #{} @ {} in variant {} was set to default value (via custom fn)",
540 index.yellow(),
541 field.offset.blue(),
542 variant.name
543 );
544 } else {
545 if !field.shape().is(Characteristic::Default) {
546 return Err(self.reflect_err(
547 ReflectError::DefaultAttrButNoDefaultImpl {
548 shape: field.shape(),
549 },
550 ));
551 }
552 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
553 trace!(
554 "Field #{} @ {} in variant {} was set to default value (via default impl)",
555 index.yellow(),
556 field.offset.blue(),
557 variant.name
558 );
559 }
560 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
561 } else {
562 trace!(
563 "Field #{} @ {} in variant {} is not initialized",
564 index.yellow(),
565 field.offset.blue(),
566 variant.name
567 );
568 has_unset = true;
569 }
570 }
571 }
572
573 if has_unset && container_shape.has_default_attr() {
574 trace!("Enum has DEFAULT attr but variant has uninitialized fields");
575 let default_val = Wip::alloc_shape(container_shape)
577 .map_err(|e| self.reflect_err(e))?
578 .put_default()
579 .map_err(|e| self.reflect_err(e))?
580 .build()
581 .map_err(|e| self.reflect_err(e))?;
582
583 let peek = default_val.peek();
584 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
585 let default_variant = peek_enum
586 .active_variant()
587 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
588
589 if default_variant == &variant {
590 for (index, field) in variant.data.fields.iter().enumerate() {
592 let is_set = wip.is_field_set(index).map_err(|err| {
593 trace!("Error checking field set status: {:?}", err);
594 self.reflect_err(err)
595 })?;
596 if !is_set {
597 if let Ok(Some(def_field)) = peek_enum.field(index) {
598 wip = wip
599 .field(index)
600 .map_err(|e| self.reflect_err(e))?;
601 wip = wip
602 .put_shape(def_field.data(), field.shape())
603 .map_err(|e| self.reflect_err(e))?;
604 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
605 }
606 }
607 }
608 }
609 }
610 }
611 } else if container_shape.has_default_attr() {
612 trace!("No variant selected but enum has DEFAULT attr; setting to default");
614 let default_val = Wip::alloc_shape(container_shape)
615 .map_err(|e| self.reflect_err(e))?
616 .put_default()
617 .map_err(|e| self.reflect_err(e))?
618 .build()
619 .map_err(|e| self.reflect_err(e))?;
620
621 let peek = default_val.peek();
622 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
623 let default_variant_idx = peek_enum
624 .variant_index()
625 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
626
627 wip = wip
629 .variant(default_variant_idx)
630 .map_err(|e| self.reflect_err(e))?;
631
632 let variant = &ed.variants[default_variant_idx];
634 for (index, field) in variant.data.fields.iter().enumerate() {
635 if let Ok(Some(def_field)) = peek_enum.field(index) {
636 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
637 wip = wip
638 .put_shape(def_field.data(), field.shape())
639 .map_err(|e| self.reflect_err(e))?;
640 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
641 }
642 }
643 }
644 }
645 _ => {
646 trace!(
647 "Thing being popped is not a container I guess (it's a {})",
648 wip.shape()
649 );
650 }
651 }
652 Ok(wip)
653 }
654
655 fn handle_scalar<'facet>(
657 &self,
658 wip: Wip<'facet, 'shape>,
659 scalar: Scalar<'input>,
660 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape>>
661 where
662 'input: 'facet, {
664 match scalar {
665 Scalar::String(cow) => {
666 match wip.innermost_shape().ty {
667 Type::User(UserType::Enum(_)) => {
668 if wip.selected_variant().is_some() {
669 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
671 } else {
672 match wip.find_variant(&cow) {
674 Some((variant_index, _)) => {
675 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
676 }
677 None => Err(self.err(DeserErrorKind::NoSuchVariant {
678 name: cow.to_string(),
679 enum_shape: wip.innermost_shape(),
680 })),
681 }
682 }
683 }
684 Type::Pointer(PointerType::Reference(_))
685 if wip.innermost_shape().is_type::<&str>() =>
686 {
687 match cow {
690 Cow::Borrowed(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
691 Cow::Owned(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
692 }
693 }
694 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
695 }
696 }
697 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
698 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
699 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
700 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
701 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
702 }
703 }
704
705 fn value<'facet>(
707 &mut self,
708 mut wip: Wip<'facet, 'shape>,
709 outcome: Spanned<Outcome<'input>>,
710 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape>>
711 where
712 'input: 'facet, {
714 trace!(
715 "Handling value at {} (innermost {})",
716 wip.shape().blue(),
717 wip.innermost_shape().yellow()
718 );
719
720 match outcome.node {
721 Outcome::Scalar(Scalar::Null) => {
722 return wip.put_default().map_err(|e| self.reflect_err(e));
723 }
724 _ => {
725 if matches!(wip.shape().def, Def::Option(_)) {
726 trace!("Starting Some(_) option for {}", wip.shape().blue());
728 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
729 self.stack.push(Instruction::Pop(PopReason::Some));
730 }
731 }
732 }
733
734 match outcome.node {
735 Outcome::Scalar(s) => {
736 wip = self.handle_scalar(wip, s)?;
737 }
738 Outcome::ListStarted => {
739 let shape = wip.innermost_shape();
740 match shape.def {
741 Def::Array(_) => {
742 trace!("Array starting for array ({})!", shape.blue());
743 }
746 Def::Slice(_) => {
747 trace!("Array starting for slice ({})!", shape.blue());
748 }
749 Def::List(_) => {
750 trace!("Array starting for list ({})!", shape.blue());
751 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
752 }
753 Def::Scalar(sd) => {
754 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
755 trace!("Empty tuple/scalar, nice");
756 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
757 } else {
758 return Err(self.err(DeserErrorKind::UnsupportedType {
759 got: shape,
760 wanted: "array, list, tuple, or slice",
761 }));
762 }
763 }
764 _ => {
765 if let Type::User(user_ty) = shape.ty {
767 match user_ty {
768 UserType::Enum(_) => {
769 trace!("Array starting for enum ({})!", shape.blue());
770 }
771 UserType::Struct(_) => {
772 trace!("Array starting for tuple struct ({})!", shape.blue());
773 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
774 }
775 _ => {
776 return Err(self.err(DeserErrorKind::UnsupportedType {
777 got: shape,
778 wanted: "array, list, tuple, or slice",
779 }));
780 }
781 }
782 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
783 trace!(
784 "Array starting for tuple ({}) with {} fields!",
785 shape.blue(),
786 tuple_type.fields.len()
787 );
788 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
790 } else {
793 return Err(self.err(DeserErrorKind::UnsupportedType {
794 got: shape,
795 wanted: "array, list, tuple, or slice",
796 }));
797 }
798 }
799 }
800 trace!("Beginning pushback");
801 self.stack.push(Instruction::ListItemOrListClose);
802 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
803 }
804 Outcome::ListEnded => {
805 trace!("List closing");
806 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
807 }
808 Outcome::ObjectStarted => {
809 let shape = wip.innermost_shape();
810 match shape.def {
811 Def::Map(_md) => {
812 trace!("Object starting for map value ({})!", shape.blue());
813 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
814 }
815 _ => {
816 if let Type::User(user_ty) = shape.ty {
818 match user_ty {
819 UserType::Enum(_) => {
820 trace!("Object starting for enum value ({})!", shape.blue());
821 }
823 UserType::Struct(_) => {
824 trace!("Object starting for struct value ({})!", shape.blue());
825 }
827 _ => {
828 return Err(self.err(DeserErrorKind::UnsupportedType {
829 got: shape,
830 wanted: "map, enum, or struct",
831 }));
832 }
833 }
834 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
835 trace!(
838 "Object starting for tuple ({}) with {} fields - unusual but handling",
839 shape.blue(),
840 tuple_type.fields.len()
841 );
842 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
844 } else {
845 return Err(self.err(DeserErrorKind::UnsupportedType {
846 got: shape,
847 wanted: "map, enum, struct, or tuple",
848 }));
849 }
850 }
851 }
852
853 self.stack.push(Instruction::ObjectKeyOrObjectClose);
854 }
855 Outcome::ObjectEnded => todo!(),
856 }
857 Ok(wip)
858 }
859
860 fn object_key_or_object_close<'facet>(
861 &mut self,
862 mut wip: Wip<'facet, 'shape>,
863 outcome: Spanned<Outcome<'input>>,
864 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape>>
865 where
866 'input: 'facet,
867 {
868 match outcome.node {
869 Outcome::Scalar(Scalar::String(key)) => {
870 trace!("Parsed object key: {}", key.cyan());
871
872 let mut ignore = false;
873 let mut needs_pop = true;
874 let mut handled_by_flatten = false;
875
876 let shape = wip.innermost_shape();
877 match shape.ty {
878 Type::User(UserType::Struct(sd)) => {
879 if let Some(index) = wip.field_index(&key) {
881 trace!("It's a struct field");
882 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
883 } else {
884 let mut found_in_flatten = false;
886 for (index, field) in sd.fields.iter().enumerate() {
887 if field.flags.contains(FieldFlags::FLATTEN) {
888 trace!("Found flattened field #{}", index);
889 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
891
892 if let Some(subfield_index) = wip.field_index(&key) {
894 trace!("Found key {} in flattened field", key);
895 wip = wip
896 .field(subfield_index)
897 .map_err(|e| self.reflect_err(e))?;
898 found_in_flatten = true;
899 handled_by_flatten = true;
900 break;
901 } else if let Some((_variant_index, _variant)) =
902 wip.find_variant(&key)
903 {
904 trace!("Found key {} in flattened field", key);
905 wip = wip
906 .variant_named(&key)
907 .map_err(|e| self.reflect_err(e))?;
908 found_in_flatten = true;
909 break;
910 } else {
911 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
913 }
914 }
915 }
916
917 if !found_in_flatten {
918 if wip.shape().has_deny_unknown_fields_attr() {
919 trace!(
920 "It's not a struct field AND we're denying unknown fields"
921 );
922 return Err(self.err(DeserErrorKind::UnknownField {
923 field_name: key.to_string(),
924 shape: wip.shape(),
925 }));
926 } else {
927 trace!(
928 "It's not a struct field and we're ignoring unknown fields"
929 );
930 ignore = true;
931 }
932 }
933 }
934 }
935 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
936 Some((index, variant)) => {
937 trace!(
938 "Selecting variant {}::{}",
939 wip.shape().blue(),
940 variant.name.yellow(),
941 );
942 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
943
944 if matches!(variant.data.kind, StructKind::Tuple)
946 && variant.data.fields.len() == 1
947 {
948 trace!(
949 "Tuple variant {}::{} encountered, pushing field 0",
950 wip.shape().blue(),
951 variant.name.yellow()
952 );
953 wip = wip.field(0).map_err(|e| self.reflect_err(e))?;
954 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
955 }
956
957 needs_pop = false;
958 }
959 None => {
960 if let Some(_variant_index) = wip.selected_variant() {
961 trace!(
962 "Already have a variant selected, treating {} as struct field of {}::{}",
963 key,
964 wip.shape().blue(),
965 wip.selected_variant().unwrap().name.yellow(),
966 );
967 if let Some(index) = wip.field_index(&key) {
969 trace!("Found field {} in selected variant", key.blue());
970 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
971 } else if wip.shape().has_deny_unknown_fields_attr() {
972 trace!("Unknown field in variant and denying unknown fields");
973 return Err(self.err(DeserErrorKind::UnknownField {
974 field_name: key.to_string(),
975 shape: wip.shape(),
976 }));
977 } else {
978 trace!(
979 "Ignoring unknown field '{}' in variant '{}::{}'",
980 key,
981 wip.shape(),
982 wip.selected_variant().unwrap().name
983 );
984 ignore = true;
985 }
986 } else {
987 return Err(self.err(DeserErrorKind::NoSuchVariant {
988 name: key.to_string(),
989 enum_shape: wip.shape(),
990 }));
991 }
992 }
993 },
994 _ => {
995 if let Def::Map(_) = shape.def {
997 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
998 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
999 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
1000 } else {
1001 return Err(self.err(DeserErrorKind::Unimplemented(
1002 "object key for non-struct/map",
1003 )));
1004 }
1005 }
1006 }
1007
1008 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1009 if ignore {
1010 self.stack.push(Instruction::SkipValue);
1011 } else {
1012 if needs_pop && !handled_by_flatten {
1013 trace!("Pushing Pop insn to stack (ObjectVal)");
1014 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1015 } else if handled_by_flatten {
1016 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1019 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1020 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1021 }
1022 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1023 }
1024 Ok(wip)
1025 }
1026 Outcome::ObjectEnded => {
1027 trace!("Object closing");
1028 Ok(wip)
1029 }
1030 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1031 got: outcome.node.into_owned(),
1032 wanted: "scalar or object close",
1033 })),
1034 }
1035 }
1036
1037 fn list_item_or_list_close<'facet>(
1038 &mut self,
1039 mut wip: Wip<'facet, 'shape>,
1040 outcome: Spanned<Outcome<'input>>,
1041 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape>>
1042 where
1043 'input: 'facet,
1044 {
1045 match outcome.node {
1046 Outcome::ListEnded => {
1047 trace!("List close");
1048 Ok(wip)
1049 }
1050 _ => {
1051 self.stack.push(Instruction::ListItemOrListClose);
1052 self.stack.push(Instruction::Pop(PopReason::ListVal));
1053
1054 trace!(
1055 "Expecting list item, doing a little push before doing value with outcome {}",
1056 outcome.magenta()
1057 );
1058 trace!("Before push, wip.shape is {}", wip.shape().blue());
1059
1060 let is_tuple = matches!(
1062 wip.innermost_shape().ty,
1063 Type::Sequence(SequenceType::Tuple(_))
1064 );
1065
1066 if is_tuple {
1067 trace!("Handling list item for a tuple type");
1068 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1070 } else {
1071 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1073 }
1074
1075 trace!(" After push, wip.shape is {}", wip.shape().cyan());
1076 wip = self.value(wip, outcome)?;
1077 Ok(wip)
1078 }
1079 }
1080 }
1081}