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}
292
293mod deser_impl {
294 use super::*;
295
296 pub fn deserialize<'input, 'facet, 'shape, T, F>(
301 input: &'input F::Input<'input>,
302 format: &mut F,
303 ) -> Result<T, DeserError<'input, 'shape, Cooked>>
304 where
305 T: Facet<'facet>,
306 F: Format + 'shape,
307 F::Input<'input>: InputDebug,
308 F::SpanType: core::fmt::Debug,
309 Span<F::SpanType>: ToCooked<'input, F>,
310 'input: 'facet,
311 'shape: 'input,
312 {
313 let result: Result<T, DeserError<'input, 'shape, Cooked>> = {
315 let source = format.source();
316
317 let wip = match Wip::alloc_shape(T::SHAPE) {
319 Ok(wip) => wip,
320 Err(e) => {
321 let default_span = Span::<F::SpanType>::default();
322 let cooked_span = default_span.to_cooked(format, input);
324 return Err(DeserError::new_reflect(e, input, cooked_span, source));
325 }
326 };
327
328 let heap_value = match deserialize_wip(wip, input, format) {
330 Ok(val) => val,
331 Err(e) => {
332 let cooked_span = e.span.to_cooked(format, input);
333
334 let cooked_error = DeserError {
336 input: e.input,
337 span: cooked_span,
338 kind: e.kind,
339 source_id: e.source_id,
340 };
341
342 return Err(cooked_error);
343 }
344 };
345
346 match heap_value.materialize() {
348 Ok(val) => Ok(val),
349 Err(e) => {
350 let default_span = Span::<F::SpanType>::default();
351 let cooked_span = default_span.to_cooked(format, input);
352 return Err(DeserError::new_reflect(e, input, cooked_span, source));
353 }
354 }
355 };
356
357 match result {
359 Ok(value) => Ok(value),
360 Err(mut error) => {
361 let new_span = error.span.to_cooked(format, input);
362
363 if new_span != error.span {
364 error = DeserError {
365 input: error.input,
366 span: new_span,
367 kind: error.kind,
368 source_id: error.source_id,
369 };
370 }
371
372 Err(error)
373 }
374 }
375 }
376}
377
378pub fn deserialize<'input, 'facet, 'shape, T, F>(
383 input: &'input F::Input<'input>,
384 format: F,
385) -> Result<T, DeserError<'input, 'shape, Cooked>>
386where
387 T: Facet<'facet>,
388 F: Format + 'shape,
389 F::Input<'input>: InputDebug,
390 F::SpanType: core::fmt::Debug,
391 Span<F::SpanType>: ToCooked<'input, F>,
392 'input: 'facet,
393 'shape: 'input,
394{
395 let mut format_copy = format;
396 deser_impl::deserialize(input, &mut format_copy)
397}
398
399pub fn deserialize_wip<'input, 'facet, 'shape, F>(
402 mut wip: Wip<'facet, 'shape>,
403 input: &'input F::Input<'input>,
404 format: &mut F,
405) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape, Cooked>>
406where
407 F: Format + 'shape,
408 F::Input<'input>: InputDebug,
409 Span<F::SpanType>: ToCooked<'input, F>,
410 'input: 'facet,
411 'shape: 'input,
412{
413 let mut runner = StackRunner {
415 original_input: input,
416 input,
417 stack: vec![
418 Instruction::Pop(PopReason::TopLevel),
419 Instruction::Value(ValueReason::TopLevel),
420 ],
421 last_span: Span::new(0, 0),
422 format_source: format.source(),
423 };
424
425 macro_rules! next {
426 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
427 let nd = NextData {
428 start: $runner.last_span.end(), runner: $runner,
430 wip: $wip,
431 };
432 let (nd, res) = format.next(nd, $expectation);
433 $runner = nd.runner;
434 $wip = nd.wip;
435 let outcome = res.map_err(|span_kind| {
436 $runner.last_span = span_kind.span;
437 let error = $runner.err(span_kind.node);
438 DeserError {
440 input: error.input,
441 span: error.span.to_cooked(format, input),
442 kind: error.kind,
443 source_id: error.source_id,
444 }
445 })?;
446 $runner.last_span = outcome.span;
447 $wip = $runner.$method($wip, outcome).map_err(|error| {
448 DeserError {
449 input: error.input,
450 span: error.span.to_cooked(format, input),
451 kind: error.kind,
452 source_id: error.source_id,
453 }
454 })?;
455 }};
456 }
457
458 loop {
459 let frame_count = wip.frames_count();
460 debug_assert!(
461 frame_count
462 >= runner
463 .stack
464 .iter()
465 .filter(|f| matches!(f, Instruction::Pop(_)))
466 .count()
467 );
468
469 let insn = match runner.stack.pop() {
470 Some(insn) => insn,
471 None => unreachable!("Instruction stack is empty"),
472 };
473
474 trace!("[{frame_count}] Instruction {:?}", insn.yellow());
475
476 match insn {
477 Instruction::Pop(reason) => {
478 wip = runner.pop(wip, reason).map_err(|error| {
479 DeserError {
481 input: error.input,
482 span: error.span.to_cooked(format, input),
483 kind: error.kind,
484 source_id: error.source_id,
485 }
486 })?;
487
488 if reason == PopReason::TopLevel {
489 return wip.build().map_err(|e| {
490 let reflect_error = runner.reflect_err(e);
491 DeserError {
493 input: reflect_error.input,
494 span: reflect_error.span.to_cooked(format, input),
495 kind: reflect_error.kind,
496 source_id: reflect_error.source_id,
497 }
498 });
499 } else {
500 wip = wip.pop().map_err(|e| {
501 let reflect_error = runner.reflect_err(e);
502 DeserError {
504 input: reflect_error.input,
505 span: reflect_error.span.to_cooked(format, input),
506 kind: reflect_error.kind,
507 source_id: reflect_error.source_id,
508 }
509 })?;
510 }
511 }
512 Instruction::Value(_why) => {
513 let expectation = match _why {
514 ValueReason::TopLevel => Expectation::Value,
515 ValueReason::ObjectVal => Expectation::ObjectVal,
516 };
517 next!(runner, wip, expectation, value);
518 }
519 Instruction::ObjectKeyOrObjectClose => {
520 next!(
521 runner,
522 wip,
523 Expectation::ObjectKeyOrObjectClose,
524 object_key_or_object_close
525 );
526 }
527 Instruction::ListItemOrListClose => {
528 next!(
529 runner,
530 wip,
531 Expectation::ListItemOrListClose,
532 list_item_or_list_close
533 );
534 }
535 Instruction::SkipValue => {
536 let nd = NextData {
538 start: runner.last_span.end(),
539 runner,
540 wip,
541 };
542 let (nd, res) = format.skip(nd);
543 runner = nd.runner;
544 wip = nd.wip;
545 let span = res.map_err(|span_kind| {
547 runner.last_span = span_kind.span;
548 let error = runner.err(span_kind.node);
549 DeserError {
551 input: error.input,
552 span: error.span.to_cooked(format, input),
553 kind: error.kind,
554 source_id: error.source_id,
555 }
556 })?;
557 runner.last_span = span;
559 }
560 }
561 }
562}
563
564#[doc(hidden)]
565pub struct StackRunner<'input, C = Cooked, I: ?Sized + 'input = [u8]> {
570 pub original_input: &'input I,
572
573 pub input: &'input I,
575
576 pub stack: Vec<Instruction>,
578
579 pub last_span: Span<C>,
581
582 pub format_source: &'static str,
584}
585
586impl<'input, 'shape, C, I: ?Sized + 'input> StackRunner<'input, C, I>
587where
588 I: InputDebug,
589{
590 fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape, C> {
592 DeserError::new(
593 kind,
594 self.original_input,
595 self.last_span,
596 self.format_source,
597 )
598 }
599
600 fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape, C> {
603 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
604 }
605
606 pub fn pop<'facet>(
607 &mut self,
608 mut wip: Wip<'facet, 'shape>,
609 reason: PopReason,
610 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>> {
611 trace!("Popping because {:?}", reason.yellow());
612
613 let container_shape = wip.shape();
614 match container_shape.ty {
615 Type::User(UserType::Struct(sd)) => {
616 let mut has_unset = false;
617
618 trace!("Let's check all fields are initialized");
619 for (index, field) in sd.fields.iter().enumerate() {
620 let is_set = wip.is_field_set(index).map_err(|err| {
621 trace!("Error checking field set status: {:?}", err);
622 self.reflect_err(err)
623 })?;
624 if !is_set {
625 if field.flags.contains(FieldFlags::DEFAULT) {
626 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
627 if let Some(default_in_place_fn) = field.vtable.default_fn {
628 wip = wip
629 .put_from_fn(default_in_place_fn)
630 .map_err(|e| self.reflect_err(e))?;
631 trace!(
632 "Field #{} {} @ {} was set to default value (via custom fn)",
633 index.yellow(),
634 field.name.green(),
635 field.offset.blue(),
636 );
637 } else {
638 if !field.shape().is(Characteristic::Default) {
639 return Err(self.reflect_err(
640 ReflectError::DefaultAttrButNoDefaultImpl {
641 shape: field.shape(),
642 },
643 ));
644 }
645 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
646 trace!(
647 "Field #{} {} @ {} was set to default value (via default impl)",
648 index.yellow(),
649 field.name.green(),
650 field.offset.blue(),
651 );
652 }
653 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
654 } else {
655 trace!(
656 "Field #{} {} @ {} is not initialized",
657 index.yellow(),
658 field.name.green(),
659 field.offset.blue(),
660 );
661 has_unset = true;
662 }
663 }
664 }
665
666 if has_unset && container_shape.has_default_attr() {
667 let default_val = Wip::alloc_shape(container_shape)
669 .map_err(|e| self.reflect_err(e))?
670 .put_default()
671 .map_err(|e| self.reflect_err(e))?
672 .build()
673 .map_err(|e| self.reflect_err(e))?;
674 let peek = default_val.peek().into_struct().unwrap();
675
676 for (index, field) in sd.fields.iter().enumerate() {
677 let is_set = wip.is_field_set(index).map_err(|err| {
678 trace!("Error checking field set status: {:?}", err);
679 self.reflect_err(err)
680 })?;
681 if !is_set {
682 let address_of_field_from_default = peek.field(index).unwrap().data();
683 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
684 wip = wip
685 .put_shape(address_of_field_from_default, field.shape())
686 .map_err(|e| self.reflect_err(e))?;
687 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
688 }
689 }
690 }
691 }
692 Type::User(UserType::Enum(ed)) => {
693 trace!("Checking if enum is initialized correctly");
694
695 if let Some(variant) = wip.selected_variant() {
697 trace!("Variant {} is selected", variant.name.blue());
698
699 if !variant.data.fields.is_empty() {
701 let mut has_unset = false;
702
703 for (index, field) in variant.data.fields.iter().enumerate() {
704 let is_set = wip.is_field_set(index).map_err(|err| {
705 trace!("Error checking field set status: {:?}", err);
706 self.reflect_err(err)
707 })?;
708
709 if !is_set {
710 if field.flags.contains(FieldFlags::DEFAULT) {
711 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
712 if let Some(default_in_place_fn) = field.vtable.default_fn {
713 wip = wip
714 .put_from_fn(default_in_place_fn)
715 .map_err(|e| self.reflect_err(e))?;
716 trace!(
717 "Field #{} @ {} in variant {} was set to default value (via custom fn)",
718 index.yellow(),
719 field.offset.blue(),
720 variant.name
721 );
722 } else {
723 if !field.shape().is(Characteristic::Default) {
724 return Err(self.reflect_err(
725 ReflectError::DefaultAttrButNoDefaultImpl {
726 shape: field.shape(),
727 },
728 ));
729 }
730 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
731 trace!(
732 "Field #{} @ {} in variant {} was set to default value (via default impl)",
733 index.yellow(),
734 field.offset.blue(),
735 variant.name
736 );
737 }
738 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
739 } else {
740 trace!(
741 "Field #{} @ {} in variant {} is not initialized",
742 index.yellow(),
743 field.offset.blue(),
744 variant.name
745 );
746 has_unset = true;
747 }
748 }
749 }
750
751 if has_unset && container_shape.has_default_attr() {
752 trace!("Enum has DEFAULT attr but variant has uninitialized fields");
753 let default_val = Wip::alloc_shape(container_shape)
755 .map_err(|e| self.reflect_err(e))?
756 .put_default()
757 .map_err(|e| self.reflect_err(e))?
758 .build()
759 .map_err(|e| self.reflect_err(e))?;
760
761 let peek = default_val.peek();
762 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
763 let default_variant = peek_enum
764 .active_variant()
765 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
766
767 if default_variant == &variant {
768 for (index, field) in variant.data.fields.iter().enumerate() {
770 let is_set = wip.is_field_set(index).map_err(|err| {
771 trace!("Error checking field set status: {:?}", err);
772 self.reflect_err(err)
773 })?;
774 if !is_set {
775 if let Ok(Some(def_field)) = peek_enum.field(index) {
776 wip = wip
777 .field(index)
778 .map_err(|e| self.reflect_err(e))?;
779 wip = wip
780 .put_shape(def_field.data(), field.shape())
781 .map_err(|e| self.reflect_err(e))?;
782 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
783 }
784 }
785 }
786 }
787 }
788 }
789 } else if container_shape.has_default_attr() {
790 trace!("No variant selected but enum has DEFAULT attr; setting to default");
792 let default_val = Wip::alloc_shape(container_shape)
793 .map_err(|e| self.reflect_err(e))?
794 .put_default()
795 .map_err(|e| self.reflect_err(e))?
796 .build()
797 .map_err(|e| self.reflect_err(e))?;
798
799 let peek = default_val.peek();
800 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
801 let default_variant_idx = peek_enum
802 .variant_index()
803 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
804
805 wip = wip
807 .variant(default_variant_idx)
808 .map_err(|e| self.reflect_err(e))?;
809
810 let variant = &ed.variants[default_variant_idx];
812 for (index, field) in variant.data.fields.iter().enumerate() {
813 if let Ok(Some(def_field)) = peek_enum.field(index) {
814 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
815 wip = wip
816 .put_shape(def_field.data(), field.shape())
817 .map_err(|e| self.reflect_err(e))?;
818 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
819 }
820 }
821 }
822 }
823 _ => {
824 trace!(
825 "Thing being popped is not a container I guess (it's a {})",
826 wip.shape()
827 );
828 }
829 }
830 Ok(wip)
831 }
832
833 fn handle_scalar<'facet>(
835 &self,
836 wip: Wip<'facet, 'shape>,
837 scalar: Scalar<'input>,
838 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
839 where
840 'input: 'facet, {
842 match scalar {
843 Scalar::String(cow) => {
844 match wip.innermost_shape().ty {
845 Type::User(UserType::Enum(_)) => {
846 if wip.selected_variant().is_some() {
847 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
849 } else {
850 match wip.find_variant(&cow) {
852 Some((variant_index, _)) => {
853 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
854 }
855 None => Err(self.err(DeserErrorKind::NoSuchVariant {
856 name: cow.to_string(),
857 enum_shape: wip.innermost_shape(),
858 })),
859 }
860 }
861 }
862 Type::Pointer(PointerType::Reference(_))
863 if wip.innermost_shape().is_type::<&str>() =>
864 {
865 match cow {
868 Cow::Borrowed(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
869 Cow::Owned(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
870 }
871 }
872 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
873 }
874 }
875 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
876 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
877 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
878 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
879 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
880 }
881 }
882
883 fn value<'facet>(
885 &mut self,
886 mut wip: Wip<'facet, 'shape>,
887 outcome: Spanned<Outcome<'input>, C>,
888 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
889 where
890 'input: 'facet, {
892 trace!(
893 "Handling value at {} (innermost {})",
894 wip.shape().blue(),
895 wip.innermost_shape().yellow()
896 );
897
898 match outcome.node {
899 Outcome::Scalar(Scalar::Null) => {
900 return wip.put_default().map_err(|e| self.reflect_err(e));
901 }
902 _ => {
903 if matches!(wip.shape().def, Def::Option(_)) {
904 trace!("Starting Some(_) option for {}", wip.shape().blue());
906 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
907 self.stack.push(Instruction::Pop(PopReason::Some));
908 }
909 }
910 }
911
912 match outcome.node {
913 Outcome::Scalar(s) => {
914 wip = self.handle_scalar(wip, s)?;
915 }
916 Outcome::ListStarted => {
917 let shape = wip.innermost_shape();
918 match shape.def {
919 Def::Array(_) => {
920 trace!("Array starting for array ({})!", shape.blue());
921 }
924 Def::Slice(_) => {
925 trace!("Array starting for slice ({})!", shape.blue());
926 }
927 Def::List(_) => {
928 trace!("Array starting for list ({})!", shape.blue());
929 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
930 }
931 Def::Scalar(sd) => {
932 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
933 trace!("Empty tuple/scalar, nice");
934 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
935 } else {
936 return Err(self.err(DeserErrorKind::UnsupportedType {
937 got: shape,
938 wanted: "array, list, tuple, or slice",
939 }));
940 }
941 }
942 _ => {
943 if let Type::User(user_ty) = shape.ty {
945 match user_ty {
946 UserType::Enum(_) => {
947 trace!("Array starting for enum ({})!", shape.blue());
948 }
949 UserType::Struct(_) => {
950 trace!("Array starting for tuple struct ({})!", shape.blue());
951 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
952 }
953 _ => {
954 return Err(self.err(DeserErrorKind::UnsupportedType {
955 got: shape,
956 wanted: "array, list, tuple, or slice",
957 }));
958 }
959 }
960 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
961 trace!(
962 "Array starting for tuple ({}) with {} fields!",
963 shape.blue(),
964 tuple_type.fields.len()
965 );
966 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
968 } else {
971 return Err(self.err(DeserErrorKind::UnsupportedType {
972 got: shape,
973 wanted: "array, list, tuple, or slice",
974 }));
975 }
976 }
977 }
978 trace!("Beginning pushback");
979 self.stack.push(Instruction::ListItemOrListClose);
980 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
981 }
982 Outcome::ListEnded => {
983 trace!("List closing");
984 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
985 }
986 Outcome::ObjectStarted => {
987 let shape = wip.innermost_shape();
988 match shape.def {
989 Def::Map(_md) => {
990 trace!("Object starting for map value ({})!", shape.blue());
991 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
992 }
993 _ => {
994 if let Type::User(user_ty) = shape.ty {
996 match user_ty {
997 UserType::Enum(_) => {
998 trace!("Object starting for enum value ({})!", shape.blue());
999 }
1001 UserType::Struct(_) => {
1002 trace!("Object starting for struct value ({})!", shape.blue());
1003 }
1005 _ => {
1006 return Err(self.err(DeserErrorKind::UnsupportedType {
1007 got: shape,
1008 wanted: "map, enum, or struct",
1009 }));
1010 }
1011 }
1012 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
1013 trace!(
1016 "Object starting for tuple ({}) with {} fields - unusual but handling",
1017 shape.blue(),
1018 tuple_type.fields.len()
1019 );
1020 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1022 } else {
1023 return Err(self.err(DeserErrorKind::UnsupportedType {
1024 got: shape,
1025 wanted: "map, enum, struct, or tuple",
1026 }));
1027 }
1028 }
1029 }
1030
1031 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1032 }
1033 Outcome::ObjectEnded => todo!(),
1034 }
1035 Ok(wip)
1036 }
1037
1038 fn object_key_or_object_close<'facet>(
1039 &mut self,
1040 mut wip: Wip<'facet, 'shape>,
1041 outcome: Spanned<Outcome<'input>, C>,
1042 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1043 where
1044 'input: 'facet,
1045 {
1046 match outcome.node {
1047 Outcome::Scalar(Scalar::String(key)) => {
1048 trace!("Parsed object key: {}", key.cyan());
1049
1050 let mut ignore = false;
1051 let mut needs_pop = true;
1052 let mut handled_by_flatten = false;
1053
1054 let shape = wip.innermost_shape();
1055 match shape.ty {
1056 Type::User(UserType::Struct(sd)) => {
1057 if let Some(index) = wip.field_index(&key) {
1059 trace!("It's a struct field");
1060 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1061 } else {
1062 let mut found_in_flatten = false;
1064 for (index, field) in sd.fields.iter().enumerate() {
1065 if field.flags.contains(FieldFlags::FLATTEN) {
1066 trace!("Found flattened field #{}", index);
1067 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1069
1070 if let Some(subfield_index) = wip.field_index(&key) {
1072 trace!("Found key {} in flattened field", key);
1073 wip = wip
1074 .field(subfield_index)
1075 .map_err(|e| self.reflect_err(e))?;
1076 found_in_flatten = true;
1077 handled_by_flatten = true;
1078 break;
1079 } else if let Some((_variant_index, _variant)) =
1080 wip.find_variant(&key)
1081 {
1082 trace!("Found key {} in flattened field", key);
1083 wip = wip
1084 .variant_named(&key)
1085 .map_err(|e| self.reflect_err(e))?;
1086 found_in_flatten = true;
1087 break;
1088 } else {
1089 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1091 }
1092 }
1093 }
1094
1095 if !found_in_flatten {
1096 if wip.shape().has_deny_unknown_fields_attr() {
1097 trace!(
1098 "It's not a struct field AND we're denying unknown fields"
1099 );
1100 return Err(self.err(DeserErrorKind::UnknownField {
1101 field_name: key.to_string(),
1102 shape: wip.shape(),
1103 }));
1104 } else {
1105 trace!(
1106 "It's not a struct field and we're ignoring unknown fields"
1107 );
1108 ignore = true;
1109 }
1110 }
1111 }
1112 }
1113 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
1114 Some((index, variant)) => {
1115 trace!(
1116 "Selecting variant {}::{}",
1117 wip.shape().blue(),
1118 variant.name.yellow(),
1119 );
1120 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
1121
1122 if matches!(variant.data.kind, StructKind::Tuple)
1124 && variant.data.fields.len() == 1
1125 {
1126 trace!(
1127 "Tuple variant {}::{} encountered, pushing field 0",
1128 wip.shape().blue(),
1129 variant.name.yellow()
1130 );
1131 wip = wip.field(0).map_err(|e| self.reflect_err(e))?;
1132 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1133 }
1134
1135 needs_pop = false;
1136 }
1137 None => {
1138 if let Some(_variant_index) = wip.selected_variant() {
1139 trace!(
1140 "Already have a variant selected, treating {} as struct field of {}::{}",
1141 key,
1142 wip.shape().blue(),
1143 wip.selected_variant().unwrap().name.yellow(),
1144 );
1145 if let Some(index) = wip.field_index(&key) {
1147 trace!("Found field {} in selected variant", key.blue());
1148 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1149 } else if wip.shape().has_deny_unknown_fields_attr() {
1150 trace!("Unknown field in variant and denying unknown fields");
1151 return Err(self.err(DeserErrorKind::UnknownField {
1152 field_name: key.to_string(),
1153 shape: wip.shape(),
1154 }));
1155 } else {
1156 trace!(
1157 "Ignoring unknown field '{}' in variant '{}::{}'",
1158 key,
1159 wip.shape(),
1160 wip.selected_variant().unwrap().name
1161 );
1162 ignore = true;
1163 }
1164 } else {
1165 return Err(self.err(DeserErrorKind::NoSuchVariant {
1166 name: key.to_string(),
1167 enum_shape: wip.shape(),
1168 }));
1169 }
1170 }
1171 },
1172 _ => {
1173 if let Def::Map(_) = shape.def {
1175 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
1176 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
1177 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
1178 } else {
1179 return Err(self.err(DeserErrorKind::Unimplemented(
1180 "object key for non-struct/map",
1181 )));
1182 }
1183 }
1184 }
1185
1186 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1187 if ignore {
1188 self.stack.push(Instruction::SkipValue);
1189 } else {
1190 if needs_pop && !handled_by_flatten {
1191 trace!("Pushing Pop insn to stack (ObjectVal)");
1192 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1193 } else if handled_by_flatten {
1194 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1197 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1198 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1199 }
1200 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1201 }
1202 Ok(wip)
1203 }
1204 Outcome::ObjectEnded => {
1205 trace!("Object closing");
1206 Ok(wip)
1207 }
1208 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1209 got: outcome.node.into_owned(),
1210 wanted: "scalar or object close",
1211 })),
1212 }
1213 }
1214
1215 fn list_item_or_list_close<'facet>(
1216 &mut self,
1217 mut wip: Wip<'facet, 'shape>,
1218 outcome: Spanned<Outcome<'input>, C>,
1219 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1220 where
1221 'input: 'facet,
1222 {
1223 match outcome.node {
1224 Outcome::ListEnded => {
1225 trace!("List close");
1226 Ok(wip)
1227 }
1228 _ => {
1229 self.stack.push(Instruction::ListItemOrListClose);
1230 self.stack.push(Instruction::Pop(PopReason::ListVal));
1231
1232 trace!(
1233 "Expecting list item, doing a little push before doing value with outcome {}",
1234 outcome.magenta()
1235 );
1236 trace!("Before push, wip.shape is {}", wip.shape().blue());
1237
1238 let is_tuple = matches!(
1240 wip.innermost_shape().ty,
1241 Type::Sequence(SequenceType::Tuple(_))
1242 );
1243
1244 if is_tuple {
1245 trace!("Handling list item for a tuple type");
1246 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1248 } else {
1249 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1251 }
1252
1253 trace!(" After push, wip.shape is {}", wip.shape().cyan());
1254 wip = self.value(wip, outcome)?;
1255 Ok(wip)
1256 }
1257 }
1258 }
1259}