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};
12use core::fmt::Debug;
13
14mod debug;
15mod error;
16use alloc::borrow::Cow;
17pub use debug::InputDebug;
18
19pub use error::*;
20
21mod span;
22use facet_core::{
23 Characteristic, Def, Facet, FieldFlags, PointerType, ScalarAffinity, SequenceType, StructKind,
24 Type, UserType,
25};
26use owo_colors::OwoColorize;
27pub use span::*;
28
29use facet_reflect::{HeapValue, ReflectError, Wip};
30use log::trace;
31
32#[derive(PartialEq, Debug, Clone)]
33pub enum Scalar<'input> {
38 String(Cow<'input, str>),
40 U64(u64),
42 I64(i64),
44 F64(f64),
46 Bool(bool),
48 Null,
50}
51
52#[derive(PartialEq, Debug, Clone)]
53pub enum Expectation {
55 Value,
57 ObjectKeyOrObjectClose,
59 ObjectVal,
61 ListItemOrListClose,
63}
64
65#[derive(PartialEq, Debug, Clone)]
66pub enum Outcome<'input> {
68 Scalar(Scalar<'input>),
70 ListStarted,
72 ListEnded,
74 ObjectStarted,
76 ObjectEnded,
78}
79
80impl<'input> From<Scalar<'input>> for Outcome<'input> {
81 fn from(scalar: Scalar<'input>) -> Self {
82 Outcome::Scalar(scalar)
83 }
84}
85
86use core::fmt;
87
88impl fmt::Display for Outcome<'_> {
90 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
91 match self {
92 Outcome::Scalar(scalar) => write!(f, "scalar {}", scalar),
93 Outcome::ListStarted => write!(f, "list start"),
94 Outcome::ListEnded => write!(f, "list end"),
95 Outcome::ObjectStarted => write!(f, "object start"),
96 Outcome::ObjectEnded => write!(f, "object end"),
97 }
98 }
99}
100
101impl fmt::Display for Scalar<'_> {
103 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
104 match self {
105 Scalar::String(s) => write!(f, "string \"{}\"", s),
106 Scalar::U64(val) => write!(f, "u64 {}", val),
107 Scalar::I64(val) => write!(f, "i64 {}", val),
108 Scalar::F64(val) => write!(f, "f64 {}", val),
109 Scalar::Bool(val) => write!(f, "bool {}", val),
110 Scalar::Null => write!(f, "null"),
111 }
112 }
113}
114
115impl Outcome<'_> {
116 fn into_owned(self) -> Outcome<'static> {
117 match self {
118 Outcome::Scalar(scalar) => {
119 let owned_scalar = match scalar {
120 Scalar::String(cow) => Scalar::String(Cow::Owned(cow.into_owned())),
121 Scalar::U64(val) => Scalar::U64(val),
122 Scalar::I64(val) => Scalar::I64(val),
123 Scalar::F64(val) => Scalar::F64(val),
124 Scalar::Bool(val) => Scalar::Bool(val),
125 Scalar::Null => Scalar::Null,
126 };
127 Outcome::Scalar(owned_scalar)
128 }
129 Outcome::ListStarted => Outcome::ListStarted,
130 Outcome::ListEnded => Outcome::ListEnded,
131 Outcome::ObjectStarted => Outcome::ObjectStarted,
132 Outcome::ObjectEnded => Outcome::ObjectEnded,
133 }
134 }
135}
136
137pub struct NextData<'input, 'facet, 'shape, C = Cooked, I = [u8]>
140where
141 'input: 'facet,
142 I: ?Sized + 'input,
143{
144 start: usize,
146
147 runner: StackRunner<'input, C, I>,
149
150 pub wip: Wip<'facet, 'shape>,
152}
153
154impl<'input, 'facet, 'shape, C, I> NextData<'input, 'facet, 'shape, C, I>
155where
156 'input: 'facet,
157 I: ?Sized + 'input,
158{
159 pub fn input(&self) -> &'input I {
161 self.runner.input
162 }
163
164 pub fn start(&self) -> usize {
166 self.start
167 }
168}
169
170pub type NextResult<'input, 'facet, 'shape, T, E, C, I = [u8]> =
172 (NextData<'input, 'facet, 'shape, C, I>, Result<T, E>);
173
174pub trait Format {
177 type Input<'input>: ?Sized;
182
183 type SpanType: Debug + 'static;
185
186 fn source(&self) -> &'static str;
188
189 #[allow(clippy::type_complexity)]
191 fn next<'input, 'facet, 'shape>(
192 &mut self,
193 nd: NextData<'input, 'facet, 'shape, Self::SpanType, Self::Input<'input>>,
194 expectation: Expectation,
195 ) -> NextResult<
196 'input,
197 'facet,
198 'shape,
199 Spanned<Outcome<'input>, Self::SpanType>,
200 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
201 Self::SpanType,
202 Self::Input<'input>,
203 >
204 where
205 'shape: 'input;
206
207 #[allow(clippy::type_complexity)]
209 fn skip<'input, 'facet, 'shape>(
210 &mut self,
211 nd: NextData<'input, 'facet, 'shape, Self::SpanType, Self::Input<'input>>,
212 ) -> NextResult<
213 'input,
214 'facet,
215 'shape,
216 Span<Self::SpanType>,
217 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
218 Self::SpanType,
219 Self::Input<'input>,
220 >
221 where
222 'shape: 'input;
223}
224
225pub trait ToCooked<'input, F: Format> {
227 fn to_cooked(self, format: &F, input: &'input F::Input<'input>) -> Span<Cooked>;
229}
230
231impl<'input, F: Format> ToCooked<'input, F> for Span<Cooked> {
232 #[inline]
233 fn to_cooked(self, _format: &F, _input: &'input F::Input<'input>) -> Span<Cooked> {
234 self
235 }
236}
237
238impl<'input, F: Format<SpanType = Raw, Input<'input> = [&'input str]>> ToCooked<'input, F>
239 for Span<Raw>
240{
241 #[inline]
242 fn to_cooked(self, _format: &F, input: &'input [&'input str]) -> Span<Cooked> {
243 let mut start = 0;
245 for arg in input.iter().take(self.start) {
246 start += arg.len() + 1; }
248
249 let len = input[self.start].len();
251
252 Span::<Cooked>::new(start, len)
253 }
254}
255
256#[derive(Debug, Clone, Copy, PartialEq, Eq)]
258pub enum Instruction {
259 Value(ValueReason),
261 SkipValue,
263 Pop(PopReason),
265 ObjectKeyOrObjectClose,
267 ListItemOrListClose,
269}
270
271#[derive(Debug, Clone, Copy, PartialEq, Eq)]
273pub enum ValueReason {
274 TopLevel,
276 ObjectVal,
278}
279
280#[derive(Debug, Clone, Copy, PartialEq, Eq)]
282pub enum PopReason {
283 TopLevel,
285 ObjectVal,
287 ListVal,
289 Some,
291 SmartPointer,
293}
294
295mod deser_impl {
296 use super::*;
297
298 pub fn deserialize<'input, 'facet, 'shape, T, F>(
303 input: &'input F::Input<'input>,
304 format: &mut F,
305 ) -> Result<T, DeserError<'input, 'shape, Cooked>>
306 where
307 T: Facet<'facet>,
308 F: Format + 'shape,
309 F::Input<'input>: InputDebug,
310 F::SpanType: core::fmt::Debug,
311 Span<F::SpanType>: ToCooked<'input, F>,
312 'input: 'facet,
313 'shape: 'input,
314 {
315 let result: Result<T, DeserError<'input, 'shape, Cooked>> = {
317 let source = format.source();
318
319 let wip = match Wip::alloc_shape(T::SHAPE) {
321 Ok(wip) => wip,
322 Err(e) => {
323 let default_span = Span::<F::SpanType>::default();
324 let cooked_span = default_span.to_cooked(format, input);
326 return Err(DeserError::new_reflect(e, input, cooked_span, source));
327 }
328 };
329
330 let heap_value = match deserialize_wip(wip, input, format) {
332 Ok(val) => val,
333 Err(e) => {
334 let cooked_span = e.span.to_cooked(format, input);
335
336 let cooked_error = DeserError {
338 input: e.input,
339 span: cooked_span,
340 kind: e.kind,
341 source_id: e.source_id,
342 };
343
344 return Err(cooked_error);
345 }
346 };
347
348 match heap_value.materialize() {
350 Ok(val) => Ok(val),
351 Err(e) => {
352 let default_span = Span::<F::SpanType>::default();
353 let cooked_span = default_span.to_cooked(format, input);
354 return Err(DeserError::new_reflect(e, input, cooked_span, source));
355 }
356 }
357 };
358
359 match result {
361 Ok(value) => Ok(value),
362 Err(mut error) => {
363 let new_span = error.span.to_cooked(format, input);
364
365 if new_span != error.span {
366 error = DeserError {
367 input: error.input,
368 span: new_span,
369 kind: error.kind,
370 source_id: error.source_id,
371 };
372 }
373
374 Err(error)
375 }
376 }
377 }
378}
379
380pub fn deserialize<'input, 'facet, 'shape, T, F>(
385 input: &'input F::Input<'input>,
386 format: F,
387) -> Result<T, DeserError<'input, 'shape, Cooked>>
388where
389 T: Facet<'facet>,
390 F: Format + 'shape,
391 F::Input<'input>: InputDebug,
392 F::SpanType: core::fmt::Debug,
393 Span<F::SpanType>: ToCooked<'input, F>,
394 'input: 'facet,
395 'shape: 'input,
396{
397 let mut format_copy = format;
398 deser_impl::deserialize(input, &mut format_copy)
399}
400
401pub fn deserialize_wip<'input, 'facet, 'shape, F>(
404 mut wip: Wip<'facet, 'shape>,
405 input: &'input F::Input<'input>,
406 format: &mut F,
407) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape, Cooked>>
408where
409 F: Format + 'shape,
410 F::Input<'input>: InputDebug,
411 Span<F::SpanType>: ToCooked<'input, F>,
412 'input: 'facet,
413 'shape: 'input,
414{
415 let mut runner = StackRunner {
417 original_input: input,
418 input,
419 stack: vec![
420 Instruction::Pop(PopReason::TopLevel),
421 Instruction::Value(ValueReason::TopLevel),
422 ],
423 substack: Substack::new(),
424 last_span: Span::new(0, 0),
425 format_source: format.source(),
426 };
427
428 macro_rules! next {
429 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
430 let nd = NextData {
431 start: $runner.last_span.end(), runner: $runner,
433 wip: $wip,
434 };
435 let (nd, res) = format.next(nd, $expectation);
436 $runner = nd.runner;
437 $wip = nd.wip;
438 let outcome = res.map_err(|span_kind| {
439 $runner.last_span = span_kind.span;
440 let error = $runner.err(span_kind.node);
441 DeserError {
443 input: error.input,
444 span: error.span.to_cooked(format, input),
445 kind: error.kind,
446 source_id: error.source_id,
447 }
448 })?;
449 $runner.last_span = outcome.span;
450 $wip = $runner.$method($wip, outcome).map_err(|error| {
451 DeserError {
452 input: error.input,
453 span: error.span.to_cooked(format, input),
454 kind: error.kind,
455 source_id: error.source_id,
456 }
457 })?;
458 }};
459 }
460
461 loop {
462 let frame_count = wip.frames_count();
463 debug_assert!(
464 frame_count
465 >= runner
466 .stack
467 .iter()
468 .filter(|f| matches!(f, Instruction::Pop(_)))
469 .count()
470 );
471
472 let insn = match runner.stack.pop() {
473 Some(insn) => insn,
474 None => unreachable!("Instruction stack is empty"),
475 };
476
477 trace!("[{frame_count}] Instruction {:?}", insn.yellow());
478
479 match insn {
480 Instruction::Pop(reason) => {
481 wip = runner.pop(wip, reason).map_err(|error| {
482 DeserError {
484 input: error.input,
485 span: error.span.to_cooked(format, input),
486 kind: error.kind,
487 source_id: error.source_id,
488 }
489 })?;
490
491 if reason == PopReason::TopLevel {
492 return wip.build().map_err(|e| {
493 let reflect_error = runner.reflect_err(e);
494 DeserError {
496 input: reflect_error.input,
497 span: reflect_error.span.to_cooked(format, input),
498 kind: reflect_error.kind,
499 source_id: reflect_error.source_id,
500 }
501 });
502 } else {
503 wip = wip.pop().map_err(|e| {
504 let reflect_error = runner.reflect_err(e);
505 DeserError {
507 input: reflect_error.input,
508 span: reflect_error.span.to_cooked(format, input),
509 kind: reflect_error.kind,
510 source_id: reflect_error.source_id,
511 }
512 })?;
513 }
514 }
515 Instruction::Value(_why) => {
516 let expectation = match _why {
517 ValueReason::TopLevel => Expectation::Value,
518 ValueReason::ObjectVal => Expectation::ObjectVal,
519 };
520 next!(runner, wip, expectation, value);
521 }
522 Instruction::ObjectKeyOrObjectClose => {
523 next!(
524 runner,
525 wip,
526 Expectation::ObjectKeyOrObjectClose,
527 object_key_or_object_close
528 );
529 }
530 Instruction::ListItemOrListClose => {
531 next!(
532 runner,
533 wip,
534 Expectation::ListItemOrListClose,
535 list_item_or_list_close
536 );
537 }
538 Instruction::SkipValue => {
539 let nd = NextData {
541 start: runner.last_span.end(),
542 runner,
543 wip,
544 };
545 let (nd, res) = format.skip(nd);
546 runner = nd.runner;
547 wip = nd.wip;
548 let span = res.map_err(|span_kind| {
550 runner.last_span = span_kind.span;
551 let error = runner.err(span_kind.node);
552 DeserError {
554 input: error.input,
555 span: error.span.to_cooked(format, input),
556 kind: error.kind,
557 source_id: error.source_id,
558 }
559 })?;
560 runner.last_span = span;
562 }
563 }
564 }
565}
566
567#[doc(hidden)]
568pub struct StackRunner<'input, C = Cooked, I: ?Sized + 'input = [u8]> {
573 pub original_input: &'input I,
575
576 pub input: &'input I,
578
579 pub stack: Vec<Instruction>,
581
582 pub substack: Substack<C>,
584
585 pub last_span: Span<C>,
587
588 pub format_source: &'static str,
590}
591
592impl<'input, 'shape, C, I: ?Sized + 'input> StackRunner<'input, C, I>
593where
594 I: InputDebug,
595{
596 fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape, C> {
598 DeserError::new(
599 kind,
600 self.original_input,
601 self.last_span,
602 self.format_source,
603 )
604 }
605
606 fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape, C> {
609 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
610 }
611
612 pub fn pop<'facet>(
613 &mut self,
614 mut wip: Wip<'facet, 'shape>,
615 reason: PopReason,
616 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>> {
617 trace!("Popping because {:?}", reason.yellow());
618
619 let container_shape = wip.shape();
620 match container_shape.ty {
621 Type::User(UserType::Struct(sd)) => {
622 let mut has_unset = false;
623
624 trace!("Let's check all fields are initialized");
625 for (index, field) in sd.fields.iter().enumerate() {
626 let is_set = wip.is_field_set(index).map_err(|err| {
627 trace!("Error checking field set status: {:?}", err);
628 self.reflect_err(err)
629 })?;
630 if !is_set {
631 if field.flags.contains(FieldFlags::DEFAULT) {
632 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
633 if let Some(default_in_place_fn) = field.vtable.default_fn {
634 wip = wip
635 .put_from_fn(default_in_place_fn)
636 .map_err(|e| self.reflect_err(e))?;
637 trace!(
638 "Field #{} {} @ {} was set to default value (via custom fn)",
639 index.yellow(),
640 field.name.green(),
641 field.offset.blue(),
642 );
643 } else {
644 if !field.shape().is(Characteristic::Default) {
645 return Err(self.reflect_err(
646 ReflectError::DefaultAttrButNoDefaultImpl {
647 shape: field.shape(),
648 },
649 ));
650 }
651 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
652 trace!(
653 "Field #{} {} @ {} was set to default value (via default impl)",
654 index.yellow(),
655 field.name.green(),
656 field.offset.blue(),
657 );
658 }
659 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
660 } else {
661 trace!(
662 "Field #{} {} @ {} is not initialized",
663 index.yellow(),
664 field.name.green(),
665 field.offset.blue(),
666 );
667 has_unset = true;
668 }
669 }
670 }
671
672 if has_unset && container_shape.has_default_attr() {
673 let default_val = Wip::alloc_shape(container_shape)
675 .map_err(|e| self.reflect_err(e))?
676 .put_default()
677 .map_err(|e| self.reflect_err(e))?
678 .build()
679 .map_err(|e| self.reflect_err(e))?;
680 let peek = default_val.peek().into_struct().unwrap();
681
682 for (index, field) in sd.fields.iter().enumerate() {
683 let is_set = wip.is_field_set(index).map_err(|err| {
684 trace!("Error checking field set status: {:?}", err);
685 self.reflect_err(err)
686 })?;
687 if !is_set {
688 let address_of_field_from_default = peek.field(index).unwrap().data();
689 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
690 wip = wip
691 .put_shape(address_of_field_from_default, field.shape())
692 .map_err(|e| self.reflect_err(e))?;
693 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
694 }
695 }
696 }
697 }
698 Type::User(UserType::Enum(ed)) => {
699 trace!("Checking if enum is initialized correctly");
700
701 if let Some(variant) = wip.selected_variant() {
703 trace!("Variant {} is selected", variant.name.blue());
704
705 if !variant.data.fields.is_empty() {
707 let mut has_unset = false;
708
709 for (index, field) in variant.data.fields.iter().enumerate() {
710 let is_set = wip.is_field_set(index).map_err(|err| {
711 trace!("Error checking field set status: {:?}", err);
712 self.reflect_err(err)
713 })?;
714
715 if !is_set {
716 if field.flags.contains(FieldFlags::DEFAULT) {
717 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
718 if let Some(default_in_place_fn) = field.vtable.default_fn {
719 wip = wip
720 .put_from_fn(default_in_place_fn)
721 .map_err(|e| self.reflect_err(e))?;
722 trace!(
723 "Field #{} @ {} in variant {} was set to default value (via custom fn)",
724 index.yellow(),
725 field.offset.blue(),
726 variant.name
727 );
728 } else {
729 if !field.shape().is(Characteristic::Default) {
730 return Err(self.reflect_err(
731 ReflectError::DefaultAttrButNoDefaultImpl {
732 shape: field.shape(),
733 },
734 ));
735 }
736 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
737 trace!(
738 "Field #{} @ {} in variant {} was set to default value (via default impl)",
739 index.yellow(),
740 field.offset.blue(),
741 variant.name
742 );
743 }
744 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
745 } else {
746 trace!(
747 "Field #{} @ {} in variant {} is not initialized",
748 index.yellow(),
749 field.offset.blue(),
750 variant.name
751 );
752 has_unset = true;
753 }
754 }
755 }
756
757 if has_unset && container_shape.has_default_attr() {
758 trace!("Enum has DEFAULT attr but variant has uninitialized fields");
759 let default_val = Wip::alloc_shape(container_shape)
761 .map_err(|e| self.reflect_err(e))?
762 .put_default()
763 .map_err(|e| self.reflect_err(e))?
764 .build()
765 .map_err(|e| self.reflect_err(e))?;
766
767 let peek = default_val.peek();
768 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
769 let default_variant = peek_enum
770 .active_variant()
771 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
772
773 if default_variant == &variant {
774 for (index, field) in variant.data.fields.iter().enumerate() {
776 let is_set = wip.is_field_set(index).map_err(|err| {
777 trace!("Error checking field set status: {:?}", err);
778 self.reflect_err(err)
779 })?;
780 if !is_set {
781 if let Ok(Some(def_field)) = peek_enum.field(index) {
782 wip = wip
783 .field(index)
784 .map_err(|e| self.reflect_err(e))?;
785 wip = wip
786 .put_shape(def_field.data(), field.shape())
787 .map_err(|e| self.reflect_err(e))?;
788 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
789 }
790 }
791 }
792 }
793 }
794 }
795 } else if container_shape.has_default_attr() {
796 trace!("No variant selected but enum has DEFAULT attr; setting to default");
798 let default_val = Wip::alloc_shape(container_shape)
799 .map_err(|e| self.reflect_err(e))?
800 .put_default()
801 .map_err(|e| self.reflect_err(e))?
802 .build()
803 .map_err(|e| self.reflect_err(e))?;
804
805 let peek = default_val.peek();
806 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
807 let default_variant_idx = peek_enum
808 .variant_index()
809 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
810
811 wip = wip
813 .variant(default_variant_idx)
814 .map_err(|e| self.reflect_err(e))?;
815
816 let variant = &ed.variants[default_variant_idx];
818 for (index, field) in variant.data.fields.iter().enumerate() {
819 if let Ok(Some(def_field)) = peek_enum.field(index) {
820 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
821 wip = wip
822 .put_shape(def_field.data(), field.shape())
823 .map_err(|e| self.reflect_err(e))?;
824 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
825 }
826 }
827 }
828 }
829 _ => {
830 trace!(
831 "Thing being popped is not a container I guess (it's a {}, innermost is {})",
832 wip.shape(),
833 wip.innermost_shape()
834 );
835 }
836 }
837 Ok(wip)
838 }
839
840 fn handle_scalar<'facet>(
842 &self,
843 wip: Wip<'facet, 'shape>,
844 scalar: Scalar<'input>,
845 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
846 where
847 'input: 'facet, {
849 match scalar {
850 Scalar::String(cow) => {
851 match wip.innermost_shape().ty {
852 Type::User(UserType::Enum(_)) => {
853 if wip.selected_variant().is_some() {
854 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
856 } else {
857 match wip.find_variant(&cow) {
859 Some((variant_index, _)) => {
860 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
861 }
862 None => Err(self.err(DeserErrorKind::NoSuchVariant {
863 name: cow.to_string(),
864 enum_shape: wip.innermost_shape(),
865 })),
866 }
867 }
868 }
869 Type::Pointer(PointerType::Reference(_))
870 if wip.innermost_shape().is_type::<&str>() =>
871 {
872 match cow {
875 Cow::Borrowed(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
876 Cow::Owned(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
877 }
878 }
879 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
880 }
881 }
882 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
883 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
884 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
885 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
886 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
887 }
888 }
889
890 fn value<'facet>(
892 &mut self,
893 mut wip: Wip<'facet, 'shape>,
894 outcome: Spanned<Outcome<'input>, C>,
895 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
896 where
897 'input: 'facet, {
899 trace!(
900 "Handling value of type {} (innermost {})",
901 wip.shape().blue(),
902 wip.innermost_shape().yellow()
903 );
904
905 match outcome.node {
906 Outcome::Scalar(Scalar::Null) => {
907 return wip.put_default().map_err(|e| self.reflect_err(e));
908 }
909 _ => {
910 if matches!(wip.shape().def, Def::Option(_)) {
911 trace!("Starting Some(_) option for {}", wip.shape().blue());
912 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
913 self.stack.push(Instruction::Pop(PopReason::Some));
914 }
915 if let Def::SmartPointer(inner) = wip.shape().def {
916 trace!(
917 "Starting smart pointer for {} (inner is {:?})",
918 wip.shape().blue(),
919 inner.yellow()
920 );
921 wip = wip.push_pointee().map_err(|e| self.reflect_err(e))?;
922 self.stack.push(Instruction::Pop(PopReason::SmartPointer));
923 }
924 }
925 }
926
927 match outcome.node {
928 Outcome::Scalar(s) => {
929 wip = self.handle_scalar(wip, s)?;
930 }
931 Outcome::ListStarted => {
932 let shape = wip.innermost_shape();
933 match shape.def {
934 Def::Array(_) => {
935 trace!("Array starting for array ({})!", shape.blue());
936 }
939 Def::Slice(_) => {
940 trace!("Array starting for slice ({})!", shape.blue());
941 }
942 Def::List(_) => {
943 trace!("Array starting for list ({})!", shape.blue());
944 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
945 }
946 Def::Scalar(sd) => {
947 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
948 trace!("Empty tuple/scalar, nice");
949 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
950 } else {
951 return Err(self.err(DeserErrorKind::UnsupportedType {
952 got: shape,
953 wanted: "array, list, tuple, or slice",
954 }));
955 }
956 }
957 _ => {
958 if let Type::User(user_ty) = shape.ty {
960 match user_ty {
961 UserType::Enum(_) => {
962 trace!("Array starting for enum ({})!", shape.blue());
963 }
964 UserType::Struct(_) => {
965 trace!("Array starting for tuple struct ({})!", shape.blue());
966 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
967 }
968 _ => {
969 return Err(self.err(DeserErrorKind::UnsupportedType {
970 got: shape,
971 wanted: "array, list, tuple, or slice",
972 }));
973 }
974 }
975 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
976 trace!(
977 "Array starting for tuple ({}) with {} fields!",
978 shape.blue(),
979 tuple_type.fields.len()
980 );
981 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
983 } else {
986 return Err(self.err(DeserErrorKind::UnsupportedType {
987 got: shape,
988 wanted: "array, list, tuple, or slice",
989 }));
990 }
991 }
992 }
993 trace!("Beginning pushback");
994 self.stack.push(Instruction::ListItemOrListClose);
995 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
996 }
997 Outcome::ListEnded => {
998 trace!("List closing");
999 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1000 }
1001 Outcome::ObjectStarted => {
1002 let shape = wip.shape();
1003 match shape.def {
1004 Def::Map(_md) => {
1005 trace!("Object starting for map value ({})!", shape.blue());
1006 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1007 }
1008 _ => {
1009 if let Type::User(user_ty) = shape.ty {
1011 match user_ty {
1012 UserType::Enum(_) => {
1013 trace!("Object starting for enum value ({})!", shape.blue());
1014 }
1016 UserType::Struct(_) => {
1017 trace!("Object starting for struct value ({})!", shape.blue());
1018 }
1020 _ => {
1021 return Err(self.err(DeserErrorKind::UnsupportedType {
1022 got: shape,
1023 wanted: "map, enum, or struct",
1024 }));
1025 }
1026 }
1027 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
1028 trace!(
1031 "Object starting for tuple ({}) with {} fields - unusual but handling",
1032 shape.blue(),
1033 tuple_type.fields.len()
1034 );
1035 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1037 } else {
1038 return Err(self.err(DeserErrorKind::UnsupportedType {
1039 got: shape,
1040 wanted: "map, enum, struct, or tuple",
1041 }));
1042 }
1043 }
1044 }
1045
1046 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1047 }
1048 Outcome::ObjectEnded => todo!(),
1049 }
1050 Ok(wip)
1051 }
1052
1053 fn object_key_or_object_close<'facet>(
1054 &mut self,
1055 mut wip: Wip<'facet, 'shape>,
1056 outcome: Spanned<Outcome<'input>, C>,
1057 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1058 where
1059 'input: 'facet,
1060 {
1061 match outcome.node {
1062 Outcome::Scalar(Scalar::String(key)) => {
1063 trace!("Parsed object key: {}", key.cyan());
1064
1065 let mut ignore = false;
1066 let mut needs_pop = true;
1067 let mut handled_by_flatten = false;
1068
1069 let shape = wip.innermost_shape();
1070 match shape.ty {
1071 Type::User(UserType::Struct(sd)) => {
1072 if let Some(index) = wip.field_index(&key) {
1074 trace!("It's a struct field");
1075 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1076 } else {
1077 trace!(
1078 "Did not find direct field match in innermost shape {}",
1079 shape.blue()
1080 );
1081
1082 let mut found_in_flatten = false;
1084 for (index, field) in sd.fields.iter().enumerate() {
1085 if field.flags.contains(FieldFlags::FLATTEN) {
1086 trace!("Found flattened field #{}", index);
1087 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1089
1090 if let Some(subfield_index) = wip.field_index(&key) {
1092 trace!("Found key {} in flattened field", key);
1093 wip = wip
1094 .field(subfield_index)
1095 .map_err(|e| self.reflect_err(e))?;
1096 found_in_flatten = true;
1097 handled_by_flatten = true;
1098 break;
1099 } else if let Some((_variant_index, _variant)) =
1100 wip.find_variant(&key)
1101 {
1102 trace!("Found key {} in flattened field", key);
1103 wip = wip
1104 .variant_named(&key)
1105 .map_err(|e| self.reflect_err(e))?;
1106 found_in_flatten = true;
1107 break;
1108 } else {
1109 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1111 }
1112 }
1113 }
1114
1115 if !found_in_flatten {
1116 if wip.shape().has_deny_unknown_fields_attr() {
1117 trace!(
1118 "It's not a struct field AND we're denying unknown fields"
1119 );
1120 return Err(self.err(DeserErrorKind::UnknownField {
1121 field_name: key.to_string(),
1122 shape: wip.shape(),
1123 }));
1124 } else {
1125 trace!(
1126 "It's not a struct field and we're ignoring unknown fields"
1127 );
1128 ignore = true;
1129 }
1130 }
1131 }
1132 }
1133 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
1134 Some((index, variant)) => {
1135 trace!(
1136 "Selecting variant {}::{}",
1137 wip.shape().blue(),
1138 variant.name.yellow(),
1139 );
1140 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
1141
1142 if matches!(variant.data.kind, StructKind::Tuple)
1144 && variant.data.fields.len() == 1
1145 {
1146 trace!(
1147 "Tuple variant {}::{} encountered, pushing field 0",
1148 wip.shape().blue(),
1149 variant.name.yellow()
1150 );
1151 wip = wip.field(0).map_err(|e| self.reflect_err(e))?;
1152 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1153 }
1154
1155 needs_pop = false;
1156 }
1157 None => {
1158 if let Some(_variant_index) = wip.selected_variant() {
1159 trace!(
1160 "Already have a variant selected, treating {} as struct field of {}::{}",
1161 key,
1162 wip.shape().blue(),
1163 wip.selected_variant().unwrap().name.yellow(),
1164 );
1165 if let Some(index) = wip.field_index(&key) {
1167 trace!("Found field {} in selected variant", key.blue());
1168 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1169 } else if wip.shape().has_deny_unknown_fields_attr() {
1170 trace!("Unknown field in variant and denying unknown fields");
1171 return Err(self.err(DeserErrorKind::UnknownField {
1172 field_name: key.to_string(),
1173 shape: wip.shape(),
1174 }));
1175 } else {
1176 trace!(
1177 "Ignoring unknown field '{}' in variant '{}::{}'",
1178 key,
1179 wip.shape(),
1180 wip.selected_variant().unwrap().name
1181 );
1182 ignore = true;
1183 }
1184 } else {
1185 return Err(self.err(DeserErrorKind::NoSuchVariant {
1186 name: key.to_string(),
1187 enum_shape: wip.shape(),
1188 }));
1189 }
1190 }
1191 },
1192 _ => {
1193 if let Def::Map(_) = shape.def {
1195 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
1196 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
1197 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
1198 } else {
1199 return Err(self.err(DeserErrorKind::Unimplemented(
1200 "object key for non-struct/map",
1201 )));
1202 }
1203 }
1204 }
1205
1206 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1207 if ignore {
1208 self.stack.push(Instruction::SkipValue);
1209 } else {
1210 if needs_pop && !handled_by_flatten {
1211 trace!("Pushing Pop insn to stack (ObjectVal)");
1212 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1213 } else if handled_by_flatten {
1214 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1217 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1218 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1219 }
1220 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1221 }
1222 Ok(wip)
1223 }
1224 Outcome::ObjectEnded => {
1225 trace!("Object closing");
1226 Ok(wip)
1227 }
1228 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1229 got: outcome.node.into_owned(),
1230 wanted: "scalar or object close",
1231 })),
1232 }
1233 }
1234
1235 fn list_item_or_list_close<'facet>(
1236 &mut self,
1237 mut wip: Wip<'facet, 'shape>,
1238 outcome: Spanned<Outcome<'input>, C>,
1239 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1240 where
1241 'input: 'facet,
1242 {
1243 match outcome.node {
1244 Outcome::ListEnded => {
1245 trace!("List close");
1246 Ok(wip)
1247 }
1248 _ => {
1249 self.stack.push(Instruction::ListItemOrListClose);
1250 self.stack.push(Instruction::Pop(PopReason::ListVal));
1251
1252 trace!(
1253 "Expecting list item, doing a little push before doing value with outcome {}",
1254 outcome.magenta()
1255 );
1256 trace!("Before push, wip.shape is {}", wip.shape().blue());
1257
1258 let is_tuple = matches!(wip.shape().ty, Type::Sequence(SequenceType::Tuple(_)));
1260
1261 if is_tuple {
1262 trace!("Handling list item for a tuple type");
1263 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1265 } else {
1266 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1268 }
1269
1270 trace!(" After push, wip.shape is {}", wip.shape().cyan());
1271 wip = self.value(wip, outcome)?;
1272 Ok(wip)
1273 }
1274 }
1275 }
1276}