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 Resegmented(Vec<Subspan>),
80}
81
82impl<'input> From<Scalar<'input>> for Outcome<'input> {
83 fn from(scalar: Scalar<'input>) -> Self {
84 Outcome::Scalar(scalar)
85 }
86}
87
88use core::fmt;
89
90impl fmt::Display for Outcome<'_> {
92 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
93 match self {
94 Outcome::Scalar(scalar) => write!(f, "scalar {}", scalar),
95 Outcome::ListStarted => write!(f, "list start"),
96 Outcome::ListEnded => write!(f, "list end"),
97 Outcome::ObjectStarted => write!(f, "object start"),
98 Outcome::ObjectEnded => write!(f, "object end"),
99 Outcome::Resegmented(_) => write!(f, "resegment"),
100 }
101 }
102}
103
104impl fmt::Display for Scalar<'_> {
106 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107 match self {
108 Scalar::String(s) => write!(f, "string \"{}\"", s),
109 Scalar::U64(val) => write!(f, "u64 {}", val),
110 Scalar::I64(val) => write!(f, "i64 {}", val),
111 Scalar::F64(val) => write!(f, "f64 {}", val),
112 Scalar::Bool(val) => write!(f, "bool {}", val),
113 Scalar::Null => write!(f, "null"),
114 }
115 }
116}
117
118impl Outcome<'_> {
119 fn into_owned(self) -> Outcome<'static> {
120 match self {
121 Outcome::Scalar(scalar) => {
122 let owned_scalar = match scalar {
123 Scalar::String(cow) => Scalar::String(Cow::Owned(cow.into_owned())),
124 Scalar::U64(val) => Scalar::U64(val),
125 Scalar::I64(val) => Scalar::I64(val),
126 Scalar::F64(val) => Scalar::F64(val),
127 Scalar::Bool(val) => Scalar::Bool(val),
128 Scalar::Null => Scalar::Null,
129 };
130 Outcome::Scalar(owned_scalar)
131 }
132 Outcome::ListStarted => Outcome::ListStarted,
133 Outcome::ListEnded => Outcome::ListEnded,
134 Outcome::ObjectStarted => Outcome::ObjectStarted,
135 Outcome::ObjectEnded => Outcome::ObjectEnded,
136 Outcome::Resegmented(subspans) => {
137 let owned_subspans = subspans
138 .into_iter()
139 .map(|s| Subspan {
140 offset: s.offset,
141 len: s.len,
142 meta: s.meta,
143 })
144 .collect();
145 Outcome::Resegmented(owned_subspans)
146 }
147 }
148 }
149}
150
151pub struct NextData<'input, 'facet, 'shape, C = Cooked, I = [u8]>
154where
155 'input: 'facet,
156 I: ?Sized + 'input,
157{
158 start: usize,
160
161 runner: StackRunner<'input, C, I>,
163
164 pub wip: Wip<'facet, 'shape>,
166}
167
168impl<'input, 'facet, 'shape, C, I> NextData<'input, 'facet, 'shape, C, I>
169where
170 'input: 'facet,
171 I: ?Sized + 'input,
172{
173 pub fn input(&self) -> &'input I {
175 self.runner.input
176 }
177
178 pub fn start(&self) -> usize {
180 self.start
181 }
182
183 pub fn substack(&self) -> &Substack<C> {
185 &self.runner.substack
186 }
187}
188
189pub type NextResult<'input, 'facet, 'shape, T, E, C, I = [u8]> =
191 (NextData<'input, 'facet, 'shape, C, I>, Result<T, E>);
192
193pub trait Format {
196 type Input<'input>: ?Sized;
201
202 type SpanType: Debug + SubstackBehavior + 'static;
204
205 fn source(&self) -> &'static str;
207
208 #[allow(clippy::type_complexity)]
210 fn next<'input, 'facet, 'shape>(
211 &mut self,
212 nd: NextData<'input, 'facet, 'shape, Self::SpanType, Self::Input<'input>>,
213 expectation: Expectation,
214 ) -> NextResult<
215 'input,
216 'facet,
217 'shape,
218 Spanned<Outcome<'input>, Self::SpanType>,
219 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
220 Self::SpanType,
221 Self::Input<'input>,
222 >
223 where
224 'shape: 'input;
225
226 #[allow(clippy::type_complexity)]
228 fn skip<'input, 'facet, 'shape>(
229 &mut self,
230 nd: NextData<'input, 'facet, 'shape, Self::SpanType, Self::Input<'input>>,
231 ) -> NextResult<
232 'input,
233 'facet,
234 'shape,
235 Span<Self::SpanType>,
236 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
237 Self::SpanType,
238 Self::Input<'input>,
239 >
240 where
241 'shape: 'input;
242}
243
244pub trait ToCooked<'input, F: Format> {
246 fn to_cooked(self, format: &F, input: &'input F::Input<'input>) -> Span<Cooked>;
248}
249
250impl<'input, F: Format> ToCooked<'input, F> for Span<Cooked> {
251 #[inline]
252 fn to_cooked(self, _format: &F, _input: &'input F::Input<'input>) -> Span<Cooked> {
253 self
254 }
255}
256
257impl<'input, F: Format<SpanType = Raw, Input<'input> = [&'input str]>> ToCooked<'input, F>
258 for Span<Raw>
259{
260 #[inline]
261 fn to_cooked(self, _format: &F, input: &'input [&'input str]) -> Span<Cooked> {
262 let mut start = 0;
264 for arg in input.iter().take(self.start) {
265 start += arg.len() + 1; }
267
268 let len = input[self.start].len();
270
271 Span::<Cooked>::new(start, len)
272 }
273}
274
275#[derive(Debug, Clone, Copy, PartialEq, Eq)]
277pub enum Instruction {
278 Value(ValueReason),
280 SkipValue,
282 Pop(PopReason),
284 ObjectKeyOrObjectClose,
286 ListItemOrListClose,
288 SubstackClose,
290}
291
292#[derive(Debug, Clone, Copy, PartialEq, Eq)]
294pub enum ValueReason {
295 TopLevel,
297 ObjectVal,
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303pub enum PopReason {
304 TopLevel,
306 ObjectVal,
308 ListVal,
310 Some,
312 SmartPointer,
314 Wrapper,
316}
317
318mod deser_impl {
319 use super::*;
320
321 pub fn deserialize<'input, 'facet, 'shape, T, F>(
326 input: &'input F::Input<'input>,
327 format: &mut F,
328 ) -> Result<T, DeserError<'input, 'shape, Cooked>>
329 where
330 T: Facet<'facet>,
331 F: Format + 'shape,
332 F::Input<'input>: InputDebug,
333 F::SpanType: core::fmt::Debug,
334 Span<F::SpanType>: ToCooked<'input, F>,
335 'input: 'facet,
336 'shape: 'input,
337 {
338 let result: Result<T, DeserError<'input, 'shape, Cooked>> = {
340 let source = format.source();
341
342 let wip = match Wip::alloc_shape(T::SHAPE) {
344 Ok(wip) => wip,
345 Err(e) => {
346 let default_span = Span::<F::SpanType>::default();
347 let cooked_span = default_span.to_cooked(format, input);
349 return Err(DeserError::new_reflect(e, input, cooked_span, source));
350 }
351 };
352
353 let heap_value = match deserialize_wip(wip, input, format) {
355 Ok(val) => val,
356 Err(e) => {
357 let cooked_span = e.span.to_cooked(format, input);
358
359 let cooked_error = DeserError {
361 input: e.input,
362 span: cooked_span,
363 kind: e.kind,
364 source_id: e.source_id,
365 };
366
367 return Err(cooked_error);
368 }
369 };
370
371 match heap_value.materialize() {
373 Ok(val) => Ok(val),
374 Err(e) => {
375 let default_span = Span::<F::SpanType>::default();
376 let cooked_span = default_span.to_cooked(format, input);
377 return Err(DeserError::new_reflect(e, input, cooked_span, source));
378 }
379 }
380 };
381
382 match result {
384 Ok(value) => Ok(value),
385 Err(mut error) => {
386 let new_span = error.span.to_cooked(format, input);
387
388 if new_span != error.span {
389 error = DeserError {
390 input: error.input,
391 span: new_span,
392 kind: error.kind,
393 source_id: error.source_id,
394 };
395 }
396
397 Err(error)
398 }
399 }
400 }
401}
402
403pub fn deserialize<'input, 'facet, 'shape, T, F>(
408 input: &'input F::Input<'input>,
409 format: F,
410) -> Result<T, DeserError<'input, 'shape, Cooked>>
411where
412 T: Facet<'facet>,
413 F: Format + 'shape,
414 F::Input<'input>: InputDebug,
415 F::SpanType: core::fmt::Debug,
416 Span<F::SpanType>: ToCooked<'input, F>,
417 'input: 'facet,
418 'shape: 'input,
419{
420 let mut format_copy = format;
421 deser_impl::deserialize(input, &mut format_copy)
422}
423
424pub fn deserialize_wip<'input, 'facet, 'shape, F>(
427 mut wip: Wip<'facet, 'shape>,
428 input: &'input F::Input<'input>,
429 format: &mut F,
430) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape, Cooked>>
431where
432 F: Format + 'shape,
433 F::SpanType: SubstackBehavior,
434 F::Input<'input>: InputDebug,
435 Span<F::SpanType>: ToCooked<'input, F>,
436 'input: 'facet,
437 'shape: 'input,
438{
439 let mut runner = StackRunner {
441 original_input: input,
442 input,
443 stack: vec![
444 Instruction::Pop(PopReason::TopLevel),
445 Instruction::Value(ValueReason::TopLevel),
446 ],
447 substack: Substack::new(),
448 last_span: Span::new(0, 0),
449 format_source: format.source(),
450 };
451
452 macro_rules! next {
453 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
454 let nd = NextData {
455 start: $runner.last_span.end(), runner: $runner,
457 wip: $wip,
458 };
459 let (nd, res) = format.next(nd, $expectation);
460 $runner = nd.runner;
461 $wip = nd.wip;
462 let outcome = res.map_err(|span_kind| {
463 $runner.last_span = span_kind.span;
464 let error = $runner.err(span_kind.node);
465 DeserError {
467 input: error.input,
468 span: error.span.to_cooked(format, input),
469 kind: error.kind,
470 source_id: error.source_id,
471 }
472 })?;
473 if F::SpanType::USES_SUBSTACK {
474 if !$runner.substack.get().is_empty() {
475 trace!("Substack: {}", "carried".cyan());
476 } else {
477 trace!("Substack: {}", "-".red());
478 }
479 }
480 $runner.last_span = outcome.span;
481 if F::SpanType::USES_SUBSTACK {
482 if let Outcome::Resegmented(subspans) = &outcome.node {
483 $runner.substack = subspans.clone().into();
484 }
485 }
486 $wip = $runner.$method($wip, outcome).map_err(|error| {
487 DeserError {
488 input: error.input,
489 span: error.span.to_cooked(format, input),
490 kind: error.kind,
491 source_id: error.source_id,
492 }
493 })?;
494 }};
495 }
496
497 loop {
498 let frame_count = wip.frames_count();
499 debug_assert!(
500 frame_count
501 >= runner
502 .stack
503 .iter()
504 .filter(|f| matches!(f, Instruction::Pop(_)))
505 .count()
506 );
507
508 let insn = match runner.stack.pop() {
509 Some(insn) => insn,
510 None => unreachable!("Instruction stack is empty"),
511 };
512
513 trace!("[{frame_count}] Instruction {:?}", insn.bright_red());
514
515 match insn {
516 Instruction::Pop(reason) => {
517 wip = runner.pop(wip, reason).map_err(|error| {
518 DeserError {
520 input: error.input,
521 span: error.span.to_cooked(format, input),
522 kind: error.kind,
523 source_id: error.source_id,
524 }
525 })?;
526
527 if reason == PopReason::TopLevel {
528 return wip.build().map_err(|e| {
529 let reflect_error = runner.reflect_err(e);
530 DeserError {
532 input: reflect_error.input,
533 span: reflect_error.span.to_cooked(format, input),
534 kind: reflect_error.kind,
535 source_id: reflect_error.source_id,
536 }
537 });
538 } else {
539 wip = wip.pop().map_err(|e| {
540 let reflect_error = runner.reflect_err(e);
541 DeserError {
543 input: reflect_error.input,
544 span: reflect_error.span.to_cooked(format, input),
545 kind: reflect_error.kind,
546 source_id: reflect_error.source_id,
547 }
548 })?;
549 }
550 }
551 Instruction::Value(_why) => {
552 let expectation = match _why {
553 ValueReason::TopLevel => Expectation::Value,
554 ValueReason::ObjectVal => Expectation::ObjectVal,
555 };
556 next!(runner, wip, expectation, value);
557 }
558 Instruction::ObjectKeyOrObjectClose => {
559 next!(
560 runner,
561 wip,
562 Expectation::ObjectKeyOrObjectClose,
563 object_key_or_object_close
564 );
565 }
566 Instruction::ListItemOrListClose => {
567 next!(
568 runner,
569 wip,
570 Expectation::ListItemOrListClose,
571 list_item_or_list_close
572 );
573 }
574 Instruction::SubstackClose => {
575 runner.substack.clear();
576 }
577 Instruction::SkipValue => {
578 let nd = NextData {
580 start: runner.last_span.end(),
581 runner,
582 wip,
583 };
584 let (nd, res) = format.skip(nd);
585 runner = nd.runner;
586 wip = nd.wip;
587 let span = res.map_err(|span_kind| {
589 runner.last_span = span_kind.span;
590 let error = runner.err(span_kind.node);
591 DeserError {
593 input: error.input,
594 span: error.span.to_cooked(format, input),
595 kind: error.kind,
596 source_id: error.source_id,
597 }
598 })?;
599 runner.last_span = span;
601 }
602 }
603 }
604}
605
606#[doc(hidden)]
607pub struct StackRunner<'input, C = Cooked, I: ?Sized + 'input = [u8]> {
612 pub original_input: &'input I,
614
615 pub input: &'input I,
617
618 pub stack: Vec<Instruction>,
620
621 pub substack: Substack<C>,
623
624 pub last_span: Span<C>,
626
627 pub format_source: &'static str,
629}
630
631impl<'input, 'shape, C, I: ?Sized + 'input> StackRunner<'input, C, I>
632where
633 I: InputDebug,
634{
635 fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape, C> {
637 DeserError::new(
638 kind,
639 self.original_input,
640 self.last_span,
641 self.format_source,
642 )
643 }
644
645 fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape, C> {
648 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
649 }
650
651 pub fn pop<'facet>(
652 &mut self,
653 mut wip: Wip<'facet, 'shape>,
654 reason: PopReason,
655 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>> {
656 trace!(
657 "--- STACK has {:?} {}",
658 self.stack.green(),
659 "(POP)".bright_yellow()
660 );
661 trace!("Popping because {:?}", reason.yellow());
662
663 let container_shape = wip.shape();
664 match container_shape.ty {
665 Type::User(UserType::Struct(sd)) => {
666 let mut has_unset = false;
667
668 trace!("Let's check all fields are initialized");
669 for (index, field) in sd.fields.iter().enumerate() {
670 let is_set = wip.is_field_set(index).map_err(|err| {
671 trace!("Error checking field set status: {:?}", err);
672 self.reflect_err(err)
673 })?;
674 if !is_set {
675 if field.flags.contains(FieldFlags::DEFAULT) {
676 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
677 if let Some(default_in_place_fn) = field.vtable.default_fn {
678 wip = wip
679 .put_from_fn(default_in_place_fn)
680 .map_err(|e| self.reflect_err(e))?;
681 trace!(
682 "Field #{} {} @ {} was set to default value (via custom fn)",
683 index.yellow(),
684 field.name.green(),
685 field.offset.blue(),
686 );
687 } else {
688 if !field.shape().is(Characteristic::Default) {
689 return Err(self.reflect_err(
690 ReflectError::DefaultAttrButNoDefaultImpl {
691 shape: field.shape(),
692 },
693 ));
694 }
695 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
696 trace!(
697 "Field #{} {} @ {} was set to default value (via default impl)",
698 index.yellow(),
699 field.name.green(),
700 field.offset.blue(),
701 );
702 }
703 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
704 } else {
705 trace!(
706 "Field #{} {} @ {} is not initialized",
707 index.yellow(),
708 field.name.green(),
709 field.offset.blue(),
710 );
711 has_unset = true;
712 }
713 }
714 }
715
716 if has_unset && container_shape.has_default_attr() {
717 let default_val = Wip::alloc_shape(container_shape)
719 .map_err(|e| self.reflect_err(e))?
720 .put_default()
721 .map_err(|e| self.reflect_err(e))?
722 .build()
723 .map_err(|e| self.reflect_err(e))?;
724 let peek = default_val.peek().into_struct().unwrap();
725
726 for (index, field) in sd.fields.iter().enumerate() {
727 let is_set = wip.is_field_set(index).map_err(|err| {
728 trace!("Error checking field set status: {:?}", err);
729 self.reflect_err(err)
730 })?;
731 if !is_set {
732 let address_of_field_from_default = peek.field(index).unwrap().data();
733 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
734 wip = wip
735 .put_shape(address_of_field_from_default, field.shape())
736 .map_err(|e| self.reflect_err(e))?;
737 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
738 }
739 }
740 }
741 }
742 Type::User(UserType::Enum(ed)) => {
743 trace!("Checking if enum is initialized correctly");
744
745 if let Some(variant) = wip.selected_variant() {
747 trace!("Variant {} is selected", variant.name.blue());
748
749 if !variant.data.fields.is_empty() {
751 let mut has_unset = false;
752
753 for (index, field) in variant.data.fields.iter().enumerate() {
754 let is_set = wip.is_field_set(index).map_err(|err| {
755 trace!("Error checking field set status: {:?}", err);
756 self.reflect_err(err)
757 })?;
758
759 if !is_set {
760 if field.flags.contains(FieldFlags::DEFAULT) {
761 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
762 if let Some(default_in_place_fn) = field.vtable.default_fn {
763 wip = wip
764 .put_from_fn(default_in_place_fn)
765 .map_err(|e| self.reflect_err(e))?;
766 trace!(
767 "Field #{} @ {} in variant {} was set to default value (via custom fn)",
768 index.yellow(),
769 field.offset.blue(),
770 variant.name
771 );
772 } else {
773 if !field.shape().is(Characteristic::Default) {
774 return Err(self.reflect_err(
775 ReflectError::DefaultAttrButNoDefaultImpl {
776 shape: field.shape(),
777 },
778 ));
779 }
780 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
781 trace!(
782 "Field #{} @ {} in variant {} was set to default value (via default impl)",
783 index.yellow(),
784 field.offset.blue(),
785 variant.name
786 );
787 }
788 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
789 } else {
790 trace!(
791 "Field #{} @ {} in variant {} is not initialized",
792 index.yellow(),
793 field.offset.blue(),
794 variant.name
795 );
796 has_unset = true;
797 }
798 }
799 }
800
801 if has_unset && container_shape.has_default_attr() {
802 trace!("Enum has DEFAULT attr but variant has uninitialized fields");
803 let default_val = Wip::alloc_shape(container_shape)
805 .map_err(|e| self.reflect_err(e))?
806 .put_default()
807 .map_err(|e| self.reflect_err(e))?
808 .build()
809 .map_err(|e| self.reflect_err(e))?;
810
811 let peek = default_val.peek();
812 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
813 let default_variant = peek_enum
814 .active_variant()
815 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
816
817 if default_variant == &variant {
818 for (index, field) in variant.data.fields.iter().enumerate() {
820 let is_set = wip.is_field_set(index).map_err(|err| {
821 trace!("Error checking field set status: {:?}", err);
822 self.reflect_err(err)
823 })?;
824 if !is_set {
825 if let Ok(Some(def_field)) = peek_enum.field(index) {
826 wip = wip
827 .field(index)
828 .map_err(|e| self.reflect_err(e))?;
829 wip = wip
830 .put_shape(def_field.data(), field.shape())
831 .map_err(|e| self.reflect_err(e))?;
832 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
833 }
834 }
835 }
836 }
837 }
838 }
839 } else if container_shape.has_default_attr() {
840 trace!("No variant selected but enum has DEFAULT attr; setting to default");
842 let default_val = Wip::alloc_shape(container_shape)
843 .map_err(|e| self.reflect_err(e))?
844 .put_default()
845 .map_err(|e| self.reflect_err(e))?
846 .build()
847 .map_err(|e| self.reflect_err(e))?;
848
849 let peek = default_val.peek();
850 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
851 let default_variant_idx = peek_enum
852 .variant_index()
853 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
854
855 wip = wip
857 .variant(default_variant_idx)
858 .map_err(|e| self.reflect_err(e))?;
859
860 let variant = &ed.variants[default_variant_idx];
862 for (index, field) in variant.data.fields.iter().enumerate() {
863 if let Ok(Some(def_field)) = peek_enum.field(index) {
864 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
865 wip = wip
866 .put_shape(def_field.data(), field.shape())
867 .map_err(|e| self.reflect_err(e))?;
868 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
869 }
870 }
871 }
872 }
873 _ => {
874 trace!(
875 "Thing being popped is not a container I guess (it's a {}, innermost is {})",
876 wip.shape(),
877 wip.innermost_shape()
878 );
879 }
880 }
881 Ok(wip)
882 }
883
884 fn handle_scalar<'facet>(
886 &self,
887 wip: Wip<'facet, 'shape>,
888 scalar: Scalar<'input>,
889 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
890 where
891 'input: 'facet, {
893 match scalar {
894 Scalar::String(cow) => {
895 match wip.innermost_shape().ty {
896 Type::User(UserType::Enum(_)) => {
897 if wip.selected_variant().is_some() {
898 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
900 } else {
901 match wip.find_variant(&cow) {
903 Some((variant_index, _)) => {
904 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
905 }
906 None => Err(self.err(DeserErrorKind::NoSuchVariant {
907 name: cow.to_string(),
908 enum_shape: wip.innermost_shape(),
909 })),
910 }
911 }
912 }
913 Type::Pointer(PointerType::Reference(_))
914 if wip.innermost_shape().is_type::<&str>() =>
915 {
916 match cow {
919 Cow::Borrowed(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
920 Cow::Owned(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
921 }
922 }
923 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
924 }
925 }
926 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
927 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
928 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
929 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
930 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
931 }
932 }
933
934 fn value<'facet>(
936 &mut self,
937 mut wip: Wip<'facet, 'shape>,
938 outcome: Spanned<Outcome<'input>, C>,
939 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
940 where
941 'input: 'facet, {
943 trace!(
944 "--- STACK has {:?} {}",
945 self.stack.green(),
946 "(VALUE)".bright_yellow()
947 );
948
949 let original_shape = wip.shape();
950 trace!("Handling value of type {}", original_shape.blue());
951
952 if matches!(outcome.node, Outcome::Scalar(Scalar::Null)) {
954 return wip.put_default().map_err(|e| self.reflect_err(e));
955 }
956
957 loop {
959 if matches!(wip.shape().def, Def::Option(_)) {
960 trace!(" Starting Some(_) option for {}", wip.shape().blue());
961 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
962 self.stack.push(Instruction::Pop(PopReason::Some));
963 } else if let Def::SmartPointer(inner) = wip.shape().def {
964 if let Some(pointee) = inner.pointee() {
965 trace!(
966 " Starting smart pointer for {} (pointee is {})",
967 wip.shape().blue(),
968 pointee.yellow(),
969 );
970 } else {
971 trace!(
972 " Starting smart pointer for {} (no pointee)",
973 wip.shape().blue()
974 );
975 }
976 wip = wip.push_pointee().map_err(|e| self.reflect_err(e))?;
977 self.stack.push(Instruction::Pop(PopReason::SmartPointer));
978 } else if let Some(inner_fn) = wip.shape().inner {
979 let inner = inner_fn();
980 trace!(
981 " Starting wrapped value for {} (inner is {})",
982 wip.shape().blue(),
983 inner.yellow()
984 );
985 wip = wip.push_inner().map_err(|e| self.reflect_err(e))?;
986 self.stack.push(Instruction::Pop(PopReason::Wrapper));
987 } else {
988 break;
989 }
990 }
991
992 if wip.shape() != original_shape {
993 trace!(
994 "Handling shape {} as innermost {}",
995 original_shape.blue(),
996 wip.shape().yellow()
997 );
998 }
999
1000 match outcome.node {
1001 Outcome::Scalar(s) => {
1002 trace!("Parsed scalar value: {}", s.cyan());
1003 wip = self.handle_scalar(wip, s)?;
1004 }
1005 Outcome::ListStarted => {
1006 let shape = wip.innermost_shape();
1007 match shape.def {
1008 Def::Array(_) => {
1009 trace!("Array starting for array ({})!", shape.blue());
1010 }
1013 Def::Slice(_) => {
1014 trace!("Array starting for slice ({})!", shape.blue());
1015 }
1016 Def::List(_) => {
1017 trace!("Array starting for list ({})!", shape.blue());
1018 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1019 }
1020 Def::Scalar(sd) => {
1021 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
1022 trace!("Empty tuple/scalar, nice");
1023 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1024 } else {
1025 return Err(self.err(DeserErrorKind::UnsupportedType {
1026 got: shape,
1027 wanted: "array, list, tuple, or slice",
1028 }));
1029 }
1030 }
1031 _ => {
1032 if let Type::User(user_ty) = shape.ty {
1034 match user_ty {
1035 UserType::Enum(_) => {
1036 trace!("Array starting for enum ({})!", shape.blue());
1037 }
1038 UserType::Struct(_) => {
1039 trace!("Array starting for tuple struct ({})!", shape.blue());
1040 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1041 }
1042 _ => {
1043 return Err(self.err(DeserErrorKind::UnsupportedType {
1044 got: shape,
1045 wanted: "array, list, tuple, or slice",
1046 }));
1047 }
1048 }
1049 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
1050 trace!(
1051 "Array starting for tuple ({}) with {} fields!",
1052 shape.blue(),
1053 tuple_type.fields.len()
1054 );
1055 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1057 } else {
1060 return Err(self.err(DeserErrorKind::UnsupportedType {
1061 got: shape,
1062 wanted: "array, list, tuple, or slice",
1063 }));
1064 }
1065 }
1066 }
1067 trace!("Beginning pushback");
1068 self.stack.push(Instruction::ListItemOrListClose);
1069 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
1070 }
1071 Outcome::ListEnded => {
1072 trace!("List closing");
1073 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1074 }
1075 Outcome::ObjectStarted => {
1076 let shape = wip.shape();
1077 match shape.def {
1078 Def::Map(_md) => {
1079 trace!("Object starting for map value ({})!", shape.blue());
1080 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1081 }
1082 _ => {
1083 if let Type::User(user_ty) = shape.ty {
1085 match user_ty {
1086 UserType::Enum(_) => {
1087 trace!("Object starting for enum value ({})!", shape.blue());
1088 }
1090 UserType::Struct(_) => {
1091 trace!("Object starting for struct value ({})!", shape.blue());
1092 }
1094 _ => {
1095 return Err(self.err(DeserErrorKind::UnsupportedType {
1096 got: shape,
1097 wanted: "map, enum, or struct",
1098 }));
1099 }
1100 }
1101 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
1102 trace!(
1105 "Object starting for tuple ({}) with {} fields - unusual but handling",
1106 shape.blue(),
1107 tuple_type.fields.len()
1108 );
1109 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1111 } else {
1112 return Err(self.err(DeserErrorKind::UnsupportedType {
1113 got: shape,
1114 wanted: "map, enum, struct, or tuple",
1115 }));
1116 }
1117 }
1118 }
1119
1120 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1121 }
1122 Outcome::Resegmented(subspans) => {
1123 trace!("Resegmented with {} subspans (value)", subspans.len());
1124 }
1131 Outcome::ObjectEnded => todo!(),
1132 }
1133 Ok(wip)
1134 }
1135
1136 fn object_key_or_object_close<'facet>(
1137 &mut self,
1138 mut wip: Wip<'facet, 'shape>,
1139 outcome: Spanned<Outcome<'input>, C>,
1140 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1141 where
1142 'input: 'facet,
1143 {
1144 trace!(
1145 "STACK: {:?} {}",
1146 self.stack.green(),
1147 "(OK/OC)".bright_yellow()
1148 );
1149 trace!("SUBSTACK: {:?}", self.substack.get().bright_green());
1150 match outcome.node {
1151 Outcome::Scalar(Scalar::String(key)) => {
1152 trace!("Parsed object key: {}", key.cyan());
1153
1154 let mut ignore = false;
1155 let mut needs_pop = true;
1156 let mut handled_by_flatten = false;
1157 let has_substack = !self.substack.get().is_empty();
1158
1159 let shape = wip.innermost_shape();
1160 match shape.ty {
1161 Type::User(UserType::Struct(sd)) => {
1162 if let Some(index) = wip.field_index(&key) {
1164 trace!("It's a struct field");
1165 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1166 } else {
1167 trace!(
1168 "Did not find direct field match in innermost shape {}",
1169 shape.blue()
1170 );
1171
1172 let mut found_in_flatten = false;
1174 for (index, field) in sd.fields.iter().enumerate() {
1175 if field.flags.contains(FieldFlags::FLATTEN) {
1176 trace!("Found flattened field #{}", index);
1177 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1179
1180 if let Some(subfield_index) = wip.field_index(&key) {
1182 trace!("Found key {} in flattened field", key);
1183 wip = wip
1184 .field(subfield_index)
1185 .map_err(|e| self.reflect_err(e))?;
1186 found_in_flatten = true;
1187 handled_by_flatten = true;
1188 break;
1189 } else if let Some((_variant_index, _variant)) =
1190 wip.find_variant(&key)
1191 {
1192 trace!("Found key {} in flattened field", key);
1193 wip = wip
1194 .variant_named(&key)
1195 .map_err(|e| self.reflect_err(e))?;
1196 found_in_flatten = true;
1197 break;
1198 } else {
1199 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1201 }
1202 }
1203 }
1204
1205 if !found_in_flatten {
1206 if wip.shape().has_deny_unknown_fields_attr() {
1207 trace!(
1208 "It's not a struct field AND we're denying unknown fields"
1209 );
1210 return Err(self.err(DeserErrorKind::UnknownField {
1211 field_name: key.to_string(),
1212 shape: wip.shape(),
1213 }));
1214 } else {
1215 trace!(
1216 "It's not a struct field and we're ignoring unknown fields"
1217 );
1218 ignore = true;
1219 }
1220 }
1221 }
1222 }
1223 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
1224 Some((index, variant)) => {
1225 trace!(
1226 "Selecting variant {}::{}",
1227 wip.shape().blue(),
1228 variant.name.yellow(),
1229 );
1230 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
1231
1232 if matches!(variant.data.kind, StructKind::Tuple)
1234 && variant.data.fields.len() == 1
1235 {
1236 trace!(
1237 "Tuple variant {}::{} encountered, pushing field 0",
1238 wip.shape().blue(),
1239 variant.name.yellow()
1240 );
1241 wip = wip.field(0).map_err(|e| self.reflect_err(e))?;
1242 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1243 }
1244
1245 needs_pop = false;
1246 }
1247 None => {
1248 if let Some(_variant_index) = wip.selected_variant() {
1249 trace!(
1250 "Already have a variant selected, treating {} as struct field of {}::{}",
1251 key,
1252 wip.shape().blue(),
1253 wip.selected_variant().unwrap().name.yellow(),
1254 );
1255 if let Some(index) = wip.field_index(&key) {
1257 trace!("Found field {} in selected variant", key.blue());
1258 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1259 } else if wip.shape().has_deny_unknown_fields_attr() {
1260 trace!("Unknown field in variant and denying unknown fields");
1261 return Err(self.err(DeserErrorKind::UnknownField {
1262 field_name: key.to_string(),
1263 shape: wip.shape(),
1264 }));
1265 } else {
1266 trace!(
1267 "Ignoring unknown field '{}' in variant '{}::{}'",
1268 key,
1269 wip.shape(),
1270 wip.selected_variant().unwrap().name
1271 );
1272 ignore = true;
1273 }
1274 } else {
1275 return Err(self.err(DeserErrorKind::NoSuchVariant {
1276 name: key.to_string(),
1277 enum_shape: wip.shape(),
1278 }));
1279 }
1280 }
1281 },
1282 _ => {
1283 if let Def::Map(_) = shape.def {
1285 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
1286 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
1287 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
1288 } else {
1289 return Err(self.err(DeserErrorKind::Unimplemented(
1290 "object key for non-struct/map",
1291 )));
1292 }
1293 }
1294 }
1295
1296 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1297 if ignore {
1298 self.stack.push(Instruction::SkipValue);
1299 } else {
1300 if needs_pop && !handled_by_flatten {
1301 trace!("Pushing Pop insn to stack (ObjectVal)");
1302 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1303 if has_substack {
1304 trace!("Pushing SubstackClose insn to stack");
1305 self.stack.push(Instruction::SubstackClose);
1306 }
1307 } else if handled_by_flatten {
1308 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1311 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1312 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1319 }
1320 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1321 }
1322 Ok(wip)
1323 }
1324 Outcome::ObjectEnded => {
1325 trace!("Object closing");
1326 Ok(wip)
1327 }
1328 Outcome::Resegmented(subspans) => {
1329 trace!(
1330 "Resegmented into {} subspans ({:?}) - obj. key/close",
1331 subspans.len(),
1332 subspans
1333 );
1334 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1336 Ok(wip)
1337 }
1338 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1339 got: outcome.node.into_owned(),
1340 wanted: "scalar or object close",
1341 })),
1342 }
1343 }
1344
1345 fn list_item_or_list_close<'facet>(
1346 &mut self,
1347 mut wip: Wip<'facet, 'shape>,
1348 outcome: Spanned<Outcome<'input>, C>,
1349 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1350 where
1351 'input: 'facet,
1352 {
1353 trace!(
1354 "--- STACK has {:?} {}",
1355 self.stack.green(),
1356 "(LI/LC)".bright_yellow()
1357 );
1358 match outcome.node {
1359 Outcome::ListEnded => {
1360 trace!("List close");
1361 Ok(wip)
1362 }
1363 _ => {
1364 self.stack.push(Instruction::ListItemOrListClose);
1365 self.stack.push(Instruction::Pop(PopReason::ListVal));
1366
1367 trace!(
1368 "Expecting list item, doing a little push before doing value with outcome {}",
1369 outcome.magenta()
1370 );
1371 trace!("Before push, wip.shape is {}", wip.shape().blue());
1372
1373 let is_tuple = matches!(wip.shape().ty, Type::Sequence(SequenceType::Tuple(_)));
1375
1376 if is_tuple {
1377 trace!("Handling list item for a tuple type");
1378 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1380 } else {
1381 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1383 }
1384
1385 trace!(" After push, wip.shape is {}", wip.shape().cyan());
1386 wip = self.value(wip, outcome)?;
1387 Ok(wip)
1388 }
1389 }
1390 }
1391}