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, I: ?Sized + 'input = [u8]> {
139 start: usize,
141
142 runner: StackRunner<'input, I>,
144
145 pub wip: Wip<'facet>,
147}
148
149impl<'input: 'facet, 'facet, I: ?Sized + 'input> NextData<'input, 'facet, 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, T, E, I = [u8]> = (NextData<'input, 'facet, I>, Result<T, E>);
163
164pub trait Format {
167 type Input<'input>: ?Sized;
172
173 fn source(&self) -> &'static str;
175
176 fn next<'input, 'facet>(
178 &mut self,
179 nd: NextData<'input, 'facet, Self::Input<'input>>,
180 expectation: Expectation,
181 ) -> NextResult<
182 'input,
183 'facet,
184 Spanned<Outcome<'input>>,
185 Spanned<DeserErrorKind>,
186 Self::Input<'input>,
187 >;
188
189 fn skip<'input, 'facet>(
191 &mut self,
192 nd: NextData<'input, 'facet, Self::Input<'input>>,
193 ) -> NextResult<'input, 'facet, Span, Spanned<DeserErrorKind>, Self::Input<'input>>;
194}
195
196#[derive(Debug, Clone, Copy, PartialEq, Eq)]
198pub enum Instruction {
199 Value(ValueReason),
201 SkipValue,
203 Pop(PopReason),
205 ObjectKeyOrObjectClose,
207 ListItemOrListClose,
209}
210
211#[derive(Debug, Clone, Copy, PartialEq, Eq)]
213pub enum ValueReason {
214 TopLevel,
216 ObjectVal,
218}
219
220#[derive(Debug, Clone, Copy, PartialEq, Eq)]
222pub enum PopReason {
223 TopLevel,
225 ObjectVal,
227 ListVal,
229 Some,
231}
232
233pub fn deserialize<'input, 'facet, T, F>(
238 input: &'input F::Input<'input>,
239 format: F,
240) -> Result<T, DeserError<'input>>
241where
242 T: Facet<'facet>,
243 F: Format,
244 F::Input<'input>: InputDebug,
245 'input: 'facet,
246{
247 let source = format.source();
248 let wip = Wip::alloc_shape(T::SHAPE)
249 .map_err(|e| DeserError::new_reflect(e, input, Span { start: 0, len: 0 }, source))?;
250 deserialize_wip(wip, input, format)?
251 .materialize()
252 .map_err(|e| DeserError::new_reflect(e, input, Span { start: 0, len: 0 }, source))
253}
254
255pub fn deserialize_wip<'input, 'facet, F>(
258 mut wip: Wip<'facet>,
259 input: &'input F::Input<'input>,
260 mut format: F,
261) -> Result<HeapValue<'facet>, DeserError<'input>>
262where
263 F: Format,
264 F::Input<'input>: InputDebug,
265 'input: 'facet,
266{
267 let mut runner = StackRunner {
269 original_input: input,
270 input,
271 stack: vec![
272 Instruction::Pop(PopReason::TopLevel),
273 Instruction::Value(ValueReason::TopLevel),
274 ],
275 last_span: Span::new(0, 0),
276 format_source: format.source(),
277 };
278
279 macro_rules! next {
280 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
281 let nd = NextData {
282 start: $runner.last_span.end(), runner: $runner,
284 wip: $wip,
285 };
286 let (nd, res) = format.next(nd, $expectation);
287 $runner = nd.runner;
288 $wip = nd.wip;
289 let outcome = res.map_err(|span_kind| {
290 $runner.last_span = span_kind.span;
291 $runner.err(span_kind.node)
292 })?;
293 $runner.last_span = outcome.span;
294 $wip = $runner.$method($wip, outcome)?;
295 }};
296 }
297
298 loop {
299 let frame_count = wip.frames_count();
300 debug_assert!(
301 frame_count
302 >= runner
303 .stack
304 .iter()
305 .filter(|f| matches!(f, Instruction::Pop(_)))
306 .count()
307 );
308
309 let insn = match runner.stack.pop() {
310 Some(insn) => insn,
311 None => unreachable!("Instruction stack is empty"),
312 };
313
314 trace!("[{frame_count}] Instruction {:?}", insn.yellow());
315
316 match insn {
317 Instruction::Pop(reason) => {
318 wip = runner.pop(wip, reason)?;
319
320 if reason == PopReason::TopLevel {
321 return wip.build().map_err(|e| runner.reflect_err(e));
322 } else {
323 wip = wip.pop().map_err(|e| runner.reflect_err(e))?;
324 }
325 }
326 Instruction::Value(_why) => {
327 let expectation = match _why {
328 ValueReason::TopLevel => Expectation::Value,
329 ValueReason::ObjectVal => Expectation::ObjectVal,
330 };
331 next!(runner, wip, expectation, value);
332 }
333 Instruction::ObjectKeyOrObjectClose => {
334 next!(
335 runner,
336 wip,
337 Expectation::ObjectKeyOrObjectClose,
338 object_key_or_object_close
339 );
340 }
341 Instruction::ListItemOrListClose => {
342 next!(
343 runner,
344 wip,
345 Expectation::ListItemOrListClose,
346 list_item_or_list_close
347 );
348 }
349 Instruction::SkipValue => {
350 let nd = NextData {
352 start: runner.last_span.end(),
353 runner,
354 wip,
355 };
356 let (nd, res) = format.skip(nd);
357 runner = nd.runner;
358 wip = nd.wip;
359 let span = res.map_err(|span_kind| {
361 runner.last_span = span_kind.span;
362 runner.err(span_kind.node)
363 })?;
364 runner.last_span = span;
366 }
367 }
368 }
369}
370
371#[doc(hidden)]
372pub struct StackRunner<'input, I: ?Sized + 'input = [u8]> {
377 pub original_input: &'input I,
379 pub input: &'input I,
381
382 pub stack: Vec<Instruction>,
384 pub last_span: Span,
386 pub format_source: &'static str,
388}
389
390impl<'input, I: ?Sized + 'input> StackRunner<'input, I>
391where
392 I: InputDebug,
393{
394 fn err(&self, kind: DeserErrorKind) -> DeserError<'input> {
396 DeserError::new(
397 kind,
398 self.original_input,
399 self.last_span,
400 self.format_source,
401 )
402 }
403
404 fn reflect_err(&self, err: ReflectError) -> DeserError<'input> {
407 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
408 }
409
410 pub fn pop<'facet>(
411 &mut self,
412 mut wip: Wip<'facet>,
413 reason: PopReason,
414 ) -> Result<Wip<'facet>, DeserError<'input>> {
415 trace!("Popping because {:?}", reason.yellow());
416
417 let container_shape = wip.shape();
418 match container_shape.ty {
419 Type::User(UserType::Struct(sd)) => {
420 let mut has_unset = false;
421
422 trace!("Let's check all fields are initialized");
423 for (index, field) in sd.fields.iter().enumerate() {
424 let is_set = wip.is_field_set(index).map_err(|err| {
425 trace!("Error checking field set status: {:?}", err);
426 self.reflect_err(err)
427 })?;
428 if !is_set {
429 if field.flags.contains(FieldFlags::DEFAULT) {
430 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
431 if let Some(default_in_place_fn) = field.vtable.default_fn {
432 wip = wip
433 .put_from_fn(default_in_place_fn)
434 .map_err(|e| self.reflect_err(e))?;
435 trace!(
436 "Field #{} {} @ {} was set to default value (via custom fn)",
437 index.yellow(),
438 field.name.green(),
439 field.offset.blue(),
440 );
441 } else {
442 if !field.shape().is(Characteristic::Default) {
443 return Err(self.reflect_err(
444 ReflectError::DefaultAttrButNoDefaultImpl {
445 shape: field.shape(),
446 },
447 ));
448 }
449 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
450 trace!(
451 "Field #{} {} @ {} was set to default value (via default impl)",
452 index.yellow(),
453 field.name.green(),
454 field.offset.blue(),
455 );
456 }
457 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
458 } else {
459 trace!(
460 "Field #{} {} @ {} is not initialized",
461 index.yellow(),
462 field.name.green(),
463 field.offset.blue(),
464 );
465 has_unset = true;
466 }
467 }
468 }
469
470 if has_unset && container_shape.has_default_attr() {
471 let default_val = Wip::alloc_shape(container_shape)
473 .map_err(|e| self.reflect_err(e))?
474 .put_default()
475 .map_err(|e| self.reflect_err(e))?
476 .build()
477 .map_err(|e| self.reflect_err(e))?;
478 let peek = default_val.peek().into_struct().unwrap();
479
480 for (index, field) in sd.fields.iter().enumerate() {
481 let is_set = wip.is_field_set(index).map_err(|err| {
482 trace!("Error checking field set status: {:?}", err);
483 self.reflect_err(err)
484 })?;
485 if !is_set {
486 let address_of_field_from_default = peek.field(index).unwrap().data();
487 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
488 wip = wip
489 .put_shape(address_of_field_from_default, field.shape())
490 .map_err(|e| self.reflect_err(e))?;
491 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
492 }
493 }
494 }
495 }
496 Type::User(UserType::Enum(ed)) => {
497 trace!("Checking if enum is initialized correctly");
498
499 if let Some(variant) = wip.selected_variant() {
501 trace!("Variant {} is selected", variant.name.blue());
502
503 if !variant.data.fields.is_empty() {
505 let mut has_unset = false;
506
507 for (index, field) in variant.data.fields.iter().enumerate() {
508 let is_set = wip.is_field_set(index).map_err(|err| {
509 trace!("Error checking field set status: {:?}", err);
510 self.reflect_err(err)
511 })?;
512
513 if !is_set {
514 if field.flags.contains(FieldFlags::DEFAULT) {
515 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
516 if let Some(default_in_place_fn) = field.vtable.default_fn {
517 wip = wip
518 .put_from_fn(default_in_place_fn)
519 .map_err(|e| self.reflect_err(e))?;
520 trace!(
521 "Field #{} @ {} in variant {} was set to default value (via custom fn)",
522 index.yellow(),
523 field.offset.blue(),
524 variant.name
525 );
526 } else {
527 if !field.shape().is(Characteristic::Default) {
528 return Err(self.reflect_err(
529 ReflectError::DefaultAttrButNoDefaultImpl {
530 shape: field.shape(),
531 },
532 ));
533 }
534 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
535 trace!(
536 "Field #{} @ {} in variant {} was set to default value (via default impl)",
537 index.yellow(),
538 field.offset.blue(),
539 variant.name
540 );
541 }
542 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
543 } else {
544 trace!(
545 "Field #{} @ {} in variant {} is not initialized",
546 index.yellow(),
547 field.offset.blue(),
548 variant.name
549 );
550 has_unset = true;
551 }
552 }
553 }
554
555 if has_unset && container_shape.has_default_attr() {
556 trace!("Enum has DEFAULT attr but variant has uninitialized fields");
557 let default_val = Wip::alloc_shape(container_shape)
559 .map_err(|e| self.reflect_err(e))?
560 .put_default()
561 .map_err(|e| self.reflect_err(e))?
562 .build()
563 .map_err(|e| self.reflect_err(e))?;
564
565 let peek = default_val.peek();
566 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
567 let default_variant = peek_enum
568 .active_variant()
569 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
570
571 if default_variant == &variant {
572 for (index, field) in variant.data.fields.iter().enumerate() {
574 let is_set = wip.is_field_set(index).map_err(|err| {
575 trace!("Error checking field set status: {:?}", err);
576 self.reflect_err(err)
577 })?;
578 if !is_set {
579 if let Ok(Some(def_field)) = peek_enum.field(index) {
580 wip = wip
581 .field(index)
582 .map_err(|e| self.reflect_err(e))?;
583 wip = wip
584 .put_shape(def_field.data(), field.shape())
585 .map_err(|e| self.reflect_err(e))?;
586 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
587 }
588 }
589 }
590 }
591 }
592 }
593 } else if container_shape.has_default_attr() {
594 trace!("No variant selected but enum has DEFAULT attr; setting to default");
596 let default_val = Wip::alloc_shape(container_shape)
597 .map_err(|e| self.reflect_err(e))?
598 .put_default()
599 .map_err(|e| self.reflect_err(e))?
600 .build()
601 .map_err(|e| self.reflect_err(e))?;
602
603 let peek = default_val.peek();
604 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
605 let default_variant_idx = peek_enum
606 .variant_index()
607 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
608
609 wip = wip
611 .variant(default_variant_idx)
612 .map_err(|e| self.reflect_err(e))?;
613
614 let variant = &ed.variants[default_variant_idx];
616 for (index, field) in variant.data.fields.iter().enumerate() {
617 if let Ok(Some(def_field)) = peek_enum.field(index) {
618 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
619 wip = wip
620 .put_shape(def_field.data(), field.shape())
621 .map_err(|e| self.reflect_err(e))?;
622 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
623 }
624 }
625 }
626 }
627 _ => {
628 trace!(
629 "Thing being popped is not a container I guess (it's a {})",
630 wip.shape()
631 );
632 }
633 }
634 Ok(wip)
635 }
636
637 fn handle_scalar<'facet>(
639 &self,
640 wip: Wip<'facet>,
641 scalar: Scalar<'input>,
642 ) -> Result<Wip<'facet>, DeserError<'input>>
643 where
644 'input: 'facet, {
646 match scalar {
647 Scalar::String(cow) => {
648 match wip.innermost_shape().ty {
649 Type::User(UserType::Enum(_)) => {
650 if wip.selected_variant().is_some() {
651 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
653 } else {
654 match wip.find_variant(&cow) {
656 Some((variant_index, _)) => {
657 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
658 }
659 None => Err(self.err(DeserErrorKind::NoSuchVariant {
660 name: cow.to_string(),
661 enum_shape: wip.innermost_shape(),
662 })),
663 }
664 }
665 }
666 Type::Pointer(PointerType::Reference(_))
667 if wip.innermost_shape().is_type::<&str>() =>
668 {
669 match cow {
672 Cow::Borrowed(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
673 Cow::Owned(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
674 }
675 }
676 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
677 }
678 }
679 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
680 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
681 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
682 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
683 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
684 }
685 }
686
687 fn value<'facet>(
689 &mut self,
690 mut wip: Wip<'facet>,
691 outcome: Spanned<Outcome<'input>>,
692 ) -> Result<Wip<'facet>, DeserError<'input>>
693 where
694 'input: 'facet, {
696 trace!(
697 "Handling value at {} (innermost {})",
698 wip.shape().blue(),
699 wip.innermost_shape().yellow()
700 );
701
702 match outcome.node {
703 Outcome::Scalar(Scalar::Null) => {
704 return wip.put_default().map_err(|e| self.reflect_err(e));
705 }
706 _ => {
707 if matches!(wip.shape().def, Def::Option(_)) {
708 trace!("Starting Some(_) option for {}", wip.shape().blue());
710 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
711 self.stack.push(Instruction::Pop(PopReason::Some));
712 }
713 }
714 }
715
716 match outcome.node {
717 Outcome::Scalar(s) => {
718 wip = self.handle_scalar(wip, s)?;
719 }
720 Outcome::ListStarted => {
721 let shape = wip.innermost_shape();
722 match shape.def {
723 Def::Array(_) => {
724 trace!("Array starting for array ({})!", shape.blue());
725 }
728 Def::Slice(_) => {
729 trace!("Array starting for slice ({})!", shape.blue());
730 }
731 Def::List(_) => {
732 trace!("Array starting for list ({})!", shape.blue());
733 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
734 }
735 Def::Scalar(sd) => {
736 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
737 trace!("Empty tuple/scalar, nice");
738 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
739 } else {
740 return Err(self.err(DeserErrorKind::UnsupportedType {
741 got: shape,
742 wanted: "array, list, tuple, or slice",
743 }));
744 }
745 }
746 _ => {
747 if let Type::User(user_ty) = shape.ty {
749 match user_ty {
750 UserType::Enum(_) => {
751 trace!("Array starting for enum ({})!", shape.blue());
752 }
753 UserType::Struct(_) => {
754 trace!("Array starting for tuple struct ({})!", shape.blue());
755 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
756 }
757 _ => {
758 return Err(self.err(DeserErrorKind::UnsupportedType {
759 got: shape,
760 wanted: "array, list, tuple, or slice",
761 }));
762 }
763 }
764 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
765 trace!(
766 "Array starting for tuple ({}) with {} fields!",
767 shape.blue(),
768 tuple_type.fields.len()
769 );
770 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
772 } else {
775 return Err(self.err(DeserErrorKind::UnsupportedType {
776 got: shape,
777 wanted: "array, list, tuple, or slice",
778 }));
779 }
780 }
781 }
782 trace!("Beginning pushback");
783 self.stack.push(Instruction::ListItemOrListClose);
784 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
785 }
786 Outcome::ListEnded => {
787 trace!("List closing");
788 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
789 }
790 Outcome::ObjectStarted => {
791 let shape = wip.innermost_shape();
792 match shape.def {
793 Def::Map(_md) => {
794 trace!("Object starting for map value ({})!", shape.blue());
795 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
796 }
797 _ => {
798 if let Type::User(user_ty) = shape.ty {
800 match user_ty {
801 UserType::Enum(_) => {
802 trace!("Object starting for enum value ({})!", shape.blue());
803 }
805 UserType::Struct(_) => {
806 trace!("Object starting for struct value ({})!", shape.blue());
807 }
809 _ => {
810 return Err(self.err(DeserErrorKind::UnsupportedType {
811 got: shape,
812 wanted: "map, enum, or struct",
813 }));
814 }
815 }
816 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
817 trace!(
820 "Object starting for tuple ({}) with {} fields - unusual but handling",
821 shape.blue(),
822 tuple_type.fields.len()
823 );
824 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
826 } else {
827 return Err(self.err(DeserErrorKind::UnsupportedType {
828 got: shape,
829 wanted: "map, enum, struct, or tuple",
830 }));
831 }
832 }
833 }
834
835 self.stack.push(Instruction::ObjectKeyOrObjectClose);
836 }
837 Outcome::ObjectEnded => todo!(),
838 }
839 Ok(wip)
840 }
841
842 fn object_key_or_object_close<'facet>(
843 &mut self,
844 mut wip: Wip<'facet>,
845 outcome: Spanned<Outcome<'input>>,
846 ) -> Result<Wip<'facet>, DeserError<'input>>
847 where
848 'input: 'facet,
849 {
850 match outcome.node {
851 Outcome::Scalar(Scalar::String(key)) => {
852 trace!("Parsed object key: {}", key.cyan());
853
854 let mut ignore = false;
855 let mut needs_pop = true;
856 let mut handled_by_flatten = false;
857
858 let shape = wip.innermost_shape();
859 match shape.ty {
860 Type::User(UserType::Struct(sd)) => {
861 if let Some(index) = wip.field_index(&key) {
863 trace!("It's a struct field");
864 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
865 } else {
866 let mut found_in_flatten = false;
868 for (index, field) in sd.fields.iter().enumerate() {
869 if field.flags.contains(FieldFlags::FLATTEN) {
870 trace!("Found flattened field #{}", index);
871 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
873
874 if let Some(subfield_index) = wip.field_index(&key) {
876 trace!("Found key {} in flattened field", key);
877 wip = wip
878 .field(subfield_index)
879 .map_err(|e| self.reflect_err(e))?;
880 found_in_flatten = true;
881 handled_by_flatten = true;
882 break;
883 } else if let Some((_variant_index, _variant)) =
884 wip.find_variant(&key)
885 {
886 trace!("Found key {} in flattened field", key);
887 wip = wip
888 .variant_named(&key)
889 .map_err(|e| self.reflect_err(e))?;
890 found_in_flatten = true;
891 break;
892 } else {
893 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
895 }
896 }
897 }
898
899 if !found_in_flatten {
900 if wip.shape().has_deny_unknown_fields_attr() {
901 trace!(
902 "It's not a struct field AND we're denying unknown fields"
903 );
904 return Err(self.err(DeserErrorKind::UnknownField {
905 field_name: key.to_string(),
906 shape: wip.shape(),
907 }));
908 } else {
909 trace!(
910 "It's not a struct field and we're ignoring unknown fields"
911 );
912 ignore = true;
913 }
914 }
915 }
916 }
917 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
918 Some((index, variant)) => {
919 trace!(
920 "Selecting variant {}::{}",
921 wip.shape().blue(),
922 variant.name.yellow(),
923 );
924 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
925
926 if matches!(variant.data.kind, StructKind::Tuple)
928 && variant.data.fields.len() == 1
929 {
930 trace!(
931 "Tuple variant {}::{} encountered, pushing field 0",
932 wip.shape().blue(),
933 variant.name.yellow()
934 );
935 wip = wip.field(0).map_err(|e| self.reflect_err(e))?;
936 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
937 }
938
939 needs_pop = false;
940 }
941 None => {
942 if let Some(_variant_index) = wip.selected_variant() {
943 trace!(
944 "Already have a variant selected, treating {} as struct field of {}::{}",
945 key,
946 wip.shape().blue(),
947 wip.selected_variant().unwrap().name.yellow(),
948 );
949 if let Some(index) = wip.field_index(&key) {
951 trace!("Found field {} in selected variant", key.blue());
952 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
953 } else if wip.shape().has_deny_unknown_fields_attr() {
954 trace!("Unknown field in variant and denying unknown fields");
955 return Err(self.err(DeserErrorKind::UnknownField {
956 field_name: key.to_string(),
957 shape: wip.shape(),
958 }));
959 } else {
960 trace!(
961 "Ignoring unknown field '{}' in variant '{}::{}'",
962 key,
963 wip.shape(),
964 wip.selected_variant().unwrap().name
965 );
966 ignore = true;
967 }
968 } else {
969 return Err(self.err(DeserErrorKind::NoSuchVariant {
970 name: key.to_string(),
971 enum_shape: wip.shape(),
972 }));
973 }
974 }
975 },
976 _ => {
977 if let Def::Map(_) = shape.def {
979 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
980 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
981 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
982 } else {
983 return Err(self.err(DeserErrorKind::Unimplemented(
984 "object key for non-struct/map",
985 )));
986 }
987 }
988 }
989
990 self.stack.push(Instruction::ObjectKeyOrObjectClose);
991 if ignore {
992 self.stack.push(Instruction::SkipValue);
993 } else {
994 if needs_pop && !handled_by_flatten {
995 trace!("Pushing Pop insn to stack (ObjectVal)");
996 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
997 } else if handled_by_flatten {
998 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1001 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1002 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1003 }
1004 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1005 }
1006 Ok(wip)
1007 }
1008 Outcome::ObjectEnded => {
1009 trace!("Object closing");
1010 Ok(wip)
1011 }
1012 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1013 got: outcome.node.into_owned(),
1014 wanted: "scalar or object close",
1015 })),
1016 }
1017 }
1018
1019 fn list_item_or_list_close<'facet>(
1020 &mut self,
1021 mut wip: Wip<'facet>,
1022 outcome: Spanned<Outcome<'input>>,
1023 ) -> Result<Wip<'facet>, DeserError<'input>>
1024 where
1025 'input: 'facet,
1026 {
1027 match outcome.node {
1028 Outcome::ListEnded => {
1029 trace!("List close");
1030 Ok(wip)
1031 }
1032 _ => {
1033 self.stack.push(Instruction::ListItemOrListClose);
1034 self.stack.push(Instruction::Pop(PopReason::ListVal));
1035
1036 trace!(
1037 "Expecting list item, doing a little push before doing value with outcome {}",
1038 outcome.magenta()
1039 );
1040 trace!("Before push, wip.shape is {}", wip.shape().blue());
1041
1042 let is_tuple = matches!(
1044 wip.innermost_shape().ty,
1045 Type::Sequence(SequenceType::Tuple(_))
1046 );
1047
1048 if is_tuple {
1049 trace!("Handling list item for a tuple type");
1050 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1052 } else {
1053 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1055 }
1056
1057 trace!(" After push, wip.shape is {}", wip.shape().cyan());
1058 wip = self.value(wip, outcome)?;
1059 Ok(wip)
1060 }
1061 }
1062 }
1063}