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 if self.start >= input.len() {
263 let mut total_len = 0;
266 for (i, arg) in input.iter().enumerate() {
267 total_len += arg.len();
268 if i < input.len() - 1 {
269 total_len += 1; }
271 }
272 return Span::<Cooked>::new(total_len.saturating_sub(1), 1);
273 }
274
275 let mut start = 0;
277 for arg in input.iter().take(self.start) {
278 start += arg.len() + 1; }
280
281 let len = input[self.start].len();
283
284 Span::<Cooked>::new(start, len)
285 }
286}
287
288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
290pub enum Instruction {
291 Value(ValueReason),
293 SkipValue,
295 Pop(PopReason),
297 ObjectKeyOrObjectClose,
299 ListItemOrListClose,
301 SubstackClose,
303}
304
305#[derive(Debug, Clone, Copy, PartialEq, Eq)]
307pub enum ValueReason {
308 TopLevel,
310 ObjectVal,
312}
313
314#[derive(Debug, Clone, Copy, PartialEq, Eq)]
316pub enum PopReason {
317 TopLevel,
319 ObjectVal,
321 ListVal,
323 Some,
325 SmartPointer,
327 Wrapper,
329}
330
331mod deser_impl {
332 use super::*;
333
334 pub fn deserialize<'input, 'facet, 'shape, T, F>(
339 input: &'input F::Input<'input>,
340 format: &mut F,
341 ) -> Result<T, DeserError<'input, 'shape, Cooked>>
342 where
343 T: Facet<'facet>,
344 F: Format + 'shape,
345 F::Input<'input>: InputDebug,
346 F::SpanType: core::fmt::Debug,
347 Span<F::SpanType>: ToCooked<'input, F>,
348 'input: 'facet,
349 'shape: 'input,
350 {
351 let result: Result<T, DeserError<'input, 'shape, Cooked>> = {
353 let source = format.source();
354
355 let wip = match Wip::alloc_shape(T::SHAPE) {
357 Ok(wip) => wip,
358 Err(e) => {
359 let default_span = Span::<F::SpanType>::default();
360 let cooked_span = default_span.to_cooked(format, input);
362 return Err(DeserError::new_reflect(e, input, cooked_span, source));
363 }
364 };
365
366 let heap_value = match deserialize_wip(wip, input, format) {
368 Ok(val) => val,
369 Err(e) => {
370 let cooked_span = e.span.to_cooked(format, input);
371
372 let cooked_error = DeserError {
374 input: e.input,
375 span: cooked_span,
376 kind: e.kind,
377 source_id: e.source_id,
378 };
379
380 return Err(cooked_error);
381 }
382 };
383
384 match heap_value.materialize() {
386 Ok(val) => Ok(val),
387 Err(e) => {
388 let default_span = Span::<F::SpanType>::default();
389 let cooked_span = default_span.to_cooked(format, input);
390 return Err(DeserError::new_reflect(e, input, cooked_span, source));
391 }
392 }
393 };
394
395 match result {
397 Ok(value) => Ok(value),
398 Err(mut error) => {
399 let new_span = error.span.to_cooked(format, input);
400
401 if new_span != error.span {
402 error = DeserError {
403 input: error.input,
404 span: new_span,
405 kind: error.kind,
406 source_id: error.source_id,
407 };
408 }
409
410 Err(error)
411 }
412 }
413 }
414}
415
416pub fn deserialize<'input, 'facet, 'shape, T, F>(
421 input: &'input F::Input<'input>,
422 format: F,
423) -> Result<T, DeserError<'input, 'shape, Cooked>>
424where
425 T: Facet<'facet>,
426 F: Format + 'shape,
427 F::Input<'input>: InputDebug,
428 F::SpanType: core::fmt::Debug,
429 Span<F::SpanType>: ToCooked<'input, F>,
430 'input: 'facet,
431 'shape: 'input,
432{
433 let mut format_copy = format;
434 deser_impl::deserialize(input, &mut format_copy)
435}
436
437pub fn deserialize_wip<'input, 'facet, 'shape, F>(
440 mut wip: Wip<'facet, 'shape>,
441 input: &'input F::Input<'input>,
442 format: &mut F,
443) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape, Cooked>>
444where
445 F: Format + 'shape,
446 F::SpanType: SubstackBehavior,
447 F::Input<'input>: InputDebug,
448 Span<F::SpanType>: ToCooked<'input, F>,
449 'input: 'facet,
450 'shape: 'input,
451{
452 let mut runner = StackRunner {
454 original_input: input,
455 input,
456 stack: vec![
457 Instruction::Pop(PopReason::TopLevel),
458 Instruction::Value(ValueReason::TopLevel),
459 ],
460 substack: Substack::new(),
461 last_span: Span::new(0, 0),
462 format_source: format.source(),
463 };
464
465 macro_rules! next {
466 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
467 let nd = NextData {
468 start: $runner.last_span.end(), runner: $runner,
470 wip: $wip,
471 };
472 let (nd, res) = format.next(nd, $expectation);
473 $runner = nd.runner;
474 $wip = nd.wip;
475 let outcome = res.map_err(|span_kind| {
476 $runner.last_span = span_kind.span;
477 let error = $runner.err(span_kind.node);
478 DeserError {
480 input: error.input,
481 span: error.span.to_cooked(format, input),
482 kind: error.kind,
483 source_id: error.source_id,
484 }
485 })?;
486 if F::SpanType::USES_SUBSTACK {
487 if !$runner.substack.get().is_empty() {
488 trace!("Substack: {}", "carried".cyan());
489 } else {
490 trace!("Substack: {}", "-".red());
491 }
492 }
493 $runner.last_span = outcome.span;
494 if F::SpanType::USES_SUBSTACK {
495 if let Outcome::Resegmented(subspans) = &outcome.node {
496 $runner.substack = subspans.clone().into();
497 }
498 }
499 $wip = $runner.$method($wip, outcome).map_err(|error| {
500 DeserError {
501 input: error.input,
502 span: error.span.to_cooked(format, input),
503 kind: error.kind,
504 source_id: error.source_id,
505 }
506 })?;
507 }};
508 }
509
510 loop {
511 let frame_count = wip.frames_count();
512 debug_assert!(
513 frame_count
514 >= runner
515 .stack
516 .iter()
517 .filter(|f| matches!(f, Instruction::Pop(_)))
518 .count()
519 );
520
521 let insn = match runner.stack.pop() {
522 Some(insn) => insn,
523 None => unreachable!("Instruction stack is empty"),
524 };
525
526 trace!("[{frame_count}] Instruction {:?}", insn.bright_red());
527
528 match insn {
529 Instruction::Pop(reason) => {
530 wip = runner.pop(wip, reason).map_err(|error| {
531 DeserError {
533 input: error.input,
534 span: error.span.to_cooked(format, input),
535 kind: error.kind,
536 source_id: error.source_id,
537 }
538 })?;
539
540 if reason == PopReason::TopLevel {
541 return wip.build().map_err(|e| {
542 let reflect_error = runner.reflect_err(e);
543 DeserError {
545 input: reflect_error.input,
546 span: reflect_error.span.to_cooked(format, input),
547 kind: reflect_error.kind,
548 source_id: reflect_error.source_id,
549 }
550 });
551 } else {
552 wip = wip.pop().map_err(|e| {
553 let reflect_error = runner.reflect_err(e);
554 DeserError {
556 input: reflect_error.input,
557 span: reflect_error.span.to_cooked(format, input),
558 kind: reflect_error.kind,
559 source_id: reflect_error.source_id,
560 }
561 })?;
562 }
563 }
564 Instruction::Value(_why) => {
565 let expectation = match _why {
566 ValueReason::TopLevel => Expectation::Value,
567 ValueReason::ObjectVal => Expectation::ObjectVal,
568 };
569 next!(runner, wip, expectation, value);
570 }
571 Instruction::ObjectKeyOrObjectClose => {
572 next!(
573 runner,
574 wip,
575 Expectation::ObjectKeyOrObjectClose,
576 object_key_or_object_close
577 );
578 }
579 Instruction::ListItemOrListClose => {
580 next!(
581 runner,
582 wip,
583 Expectation::ListItemOrListClose,
584 list_item_or_list_close
585 );
586 }
587 Instruction::SubstackClose => {
588 runner.substack.clear();
589 }
590 Instruction::SkipValue => {
591 let nd = NextData {
593 start: runner.last_span.end(),
594 runner,
595 wip,
596 };
597 let (nd, res) = format.skip(nd);
598 runner = nd.runner;
599 wip = nd.wip;
600 let span = res.map_err(|span_kind| {
602 runner.last_span = span_kind.span;
603 let error = runner.err(span_kind.node);
604 DeserError {
606 input: error.input,
607 span: error.span.to_cooked(format, input),
608 kind: error.kind,
609 source_id: error.source_id,
610 }
611 })?;
612 runner.last_span = span;
614 }
615 }
616 }
617}
618
619#[doc(hidden)]
620pub struct StackRunner<'input, C = Cooked, I: ?Sized + 'input = [u8]> {
625 pub original_input: &'input I,
627
628 pub input: &'input I,
630
631 pub stack: Vec<Instruction>,
633
634 pub substack: Substack<C>,
636
637 pub last_span: Span<C>,
639
640 pub format_source: &'static str,
642}
643
644impl<'input, 'shape, C, I: ?Sized + 'input> StackRunner<'input, C, I>
645where
646 I: InputDebug,
647{
648 fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape, C> {
650 DeserError::new(
651 kind,
652 self.original_input,
653 self.last_span,
654 self.format_source,
655 )
656 }
657
658 fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape, C> {
661 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
662 }
663
664 pub fn pop<'facet>(
665 &mut self,
666 mut wip: Wip<'facet, 'shape>,
667 reason: PopReason,
668 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>> {
669 trace!(
670 "--- STACK has {:?} {}",
671 self.stack.green(),
672 "(POP)".bright_yellow()
673 );
674 trace!("Popping because {:?}", reason.yellow());
675
676 let container_shape = wip.shape();
677 match container_shape.ty {
678 Type::User(UserType::Struct(sd)) => {
679 let mut has_unset = false;
680
681 trace!("Let's check all fields are initialized");
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 if field.flags.contains(FieldFlags::DEFAULT) {
689 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
690 if let Some(default_in_place_fn) = field.vtable.default_fn {
691 wip = wip
692 .put_from_fn(default_in_place_fn)
693 .map_err(|e| self.reflect_err(e))?;
694 trace!(
695 "Field #{} {} @ {} was set to default value (via custom fn)",
696 index.yellow(),
697 field.name.green(),
698 field.offset.blue(),
699 );
700 } else {
701 if !field.shape().is(Characteristic::Default) {
702 return Err(self.reflect_err(
703 ReflectError::DefaultAttrButNoDefaultImpl {
704 shape: field.shape(),
705 },
706 ));
707 }
708 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
709 trace!(
710 "Field #{} {} @ {} was set to default value (via default impl)",
711 index.yellow(),
712 field.name.green(),
713 field.offset.blue(),
714 );
715 }
716 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
717 } else {
718 trace!(
719 "Field #{} {} @ {} is not initialized",
720 index.yellow(),
721 field.name.green(),
722 field.offset.blue(),
723 );
724 has_unset = true;
725 }
726 }
727 }
728
729 if has_unset && container_shape.has_default_attr() {
730 let default_val = Wip::alloc_shape(container_shape)
732 .map_err(|e| self.reflect_err(e))?
733 .put_default()
734 .map_err(|e| self.reflect_err(e))?
735 .build()
736 .map_err(|e| self.reflect_err(e))?;
737 let peek = default_val.peek().into_struct().unwrap();
738
739 for (index, field) in sd.fields.iter().enumerate() {
740 let is_set = wip.is_field_set(index).map_err(|err| {
741 trace!("Error checking field set status: {:?}", err);
742 self.reflect_err(err)
743 })?;
744 if !is_set {
745 let address_of_field_from_default = peek.field(index).unwrap().data();
746 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
747 wip = wip
748 .put_shape(address_of_field_from_default, field.shape())
749 .map_err(|e| self.reflect_err(e))?;
750 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
751 }
752 }
753 }
754 }
755 Type::User(UserType::Enum(ed)) => {
756 trace!("Checking if enum is initialized correctly");
757
758 if let Some(variant) = wip.selected_variant() {
760 trace!("Variant {} is selected", variant.name.blue());
761
762 if !variant.data.fields.is_empty() {
764 let mut has_unset = false;
765
766 for (index, field) in variant.data.fields.iter().enumerate() {
767 let is_set = wip.is_field_set(index).map_err(|err| {
768 trace!("Error checking field set status: {:?}", err);
769 self.reflect_err(err)
770 })?;
771
772 if !is_set {
773 if field.flags.contains(FieldFlags::DEFAULT) {
774 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
775 if let Some(default_in_place_fn) = field.vtable.default_fn {
776 wip = wip
777 .put_from_fn(default_in_place_fn)
778 .map_err(|e| self.reflect_err(e))?;
779 trace!(
780 "Field #{} @ {} in variant {} was set to default value (via custom fn)",
781 index.yellow(),
782 field.offset.blue(),
783 variant.name
784 );
785 } else {
786 if !field.shape().is(Characteristic::Default) {
787 return Err(self.reflect_err(
788 ReflectError::DefaultAttrButNoDefaultImpl {
789 shape: field.shape(),
790 },
791 ));
792 }
793 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
794 trace!(
795 "Field #{} @ {} in variant {} was set to default value (via default impl)",
796 index.yellow(),
797 field.offset.blue(),
798 variant.name
799 );
800 }
801 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
802 } else {
803 trace!(
804 "Field #{} @ {} in variant {} is not initialized",
805 index.yellow(),
806 field.offset.blue(),
807 variant.name
808 );
809 has_unset = true;
810 }
811 }
812 }
813
814 if has_unset && container_shape.has_default_attr() {
815 trace!("Enum has DEFAULT attr but variant has uninitialized fields");
816 let default_val = Wip::alloc_shape(container_shape)
818 .map_err(|e| self.reflect_err(e))?
819 .put_default()
820 .map_err(|e| self.reflect_err(e))?
821 .build()
822 .map_err(|e| self.reflect_err(e))?;
823
824 let peek = default_val.peek();
825 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
826 let default_variant = peek_enum
827 .active_variant()
828 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
829
830 if default_variant == &variant {
831 for (index, field) in variant.data.fields.iter().enumerate() {
833 let is_set = wip.is_field_set(index).map_err(|err| {
834 trace!("Error checking field set status: {:?}", err);
835 self.reflect_err(err)
836 })?;
837 if !is_set {
838 if let Ok(Some(def_field)) = peek_enum.field(index) {
839 wip = wip
840 .field(index)
841 .map_err(|e| self.reflect_err(e))?;
842 wip = wip
843 .put_shape(def_field.data(), field.shape())
844 .map_err(|e| self.reflect_err(e))?;
845 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
846 }
847 }
848 }
849 }
850 }
851 }
852 } else if container_shape.has_default_attr() {
853 trace!("No variant selected but enum has DEFAULT attr; setting to default");
855 let default_val = Wip::alloc_shape(container_shape)
856 .map_err(|e| self.reflect_err(e))?
857 .put_default()
858 .map_err(|e| self.reflect_err(e))?
859 .build()
860 .map_err(|e| self.reflect_err(e))?;
861
862 let peek = default_val.peek();
863 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
864 let default_variant_idx = peek_enum
865 .variant_index()
866 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
867
868 wip = wip
870 .variant(default_variant_idx)
871 .map_err(|e| self.reflect_err(e))?;
872
873 let variant = &ed.variants[default_variant_idx];
875 for (index, field) in variant.data.fields.iter().enumerate() {
876 if let Ok(Some(def_field)) = peek_enum.field(index) {
877 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
878 wip = wip
879 .put_shape(def_field.data(), field.shape())
880 .map_err(|e| self.reflect_err(e))?;
881 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
882 }
883 }
884 }
885 }
886 _ => {
887 trace!(
888 "Thing being popped is not a container I guess (it's a {}, innermost is {})",
889 wip.shape(),
890 wip.innermost_shape()
891 );
892 }
893 }
894 Ok(wip)
895 }
896
897 fn handle_scalar<'facet>(
899 &self,
900 wip: Wip<'facet, 'shape>,
901 scalar: Scalar<'input>,
902 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
903 where
904 'input: 'facet, {
906 match scalar {
907 Scalar::String(cow) => {
908 match wip.innermost_shape().ty {
909 Type::User(UserType::Enum(_)) => {
910 if wip.selected_variant().is_some() {
911 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
913 } else {
914 match wip.find_variant(&cow) {
916 Some((variant_index, _)) => {
917 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
918 }
919 None => Err(self.err(DeserErrorKind::NoSuchVariant {
920 name: cow.to_string(),
921 enum_shape: wip.innermost_shape(),
922 })),
923 }
924 }
925 }
926 Type::Pointer(PointerType::Reference(_))
927 if wip.innermost_shape().is_type::<&str>() =>
928 {
929 match cow {
932 Cow::Borrowed(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
933 Cow::Owned(s) => wip.put(s).map_err(|e| self.reflect_err(e)),
934 }
935 }
936 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
937 }
938 }
939 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
940 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
941 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
942 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
943 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
944 }
945 }
946
947 fn value<'facet>(
949 &mut self,
950 mut wip: Wip<'facet, 'shape>,
951 outcome: Spanned<Outcome<'input>, C>,
952 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
953 where
954 'input: 'facet, {
956 trace!(
957 "--- STACK has {:?} {}",
958 self.stack.green(),
959 "(VALUE)".bright_yellow()
960 );
961
962 let original_shape = wip.shape();
963 trace!("Handling value of type {}", original_shape.blue());
964
965 if matches!(outcome.node, Outcome::Scalar(Scalar::Null)) {
967 return wip.put_default().map_err(|e| self.reflect_err(e));
968 }
969
970 loop {
972 if matches!(wip.shape().def, Def::Option(_)) {
973 trace!(" Starting Some(_) option for {}", wip.shape().blue());
974 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
975 self.stack.push(Instruction::Pop(PopReason::Some));
976 } else if let Def::SmartPointer(inner) = wip.shape().def {
977 if let Some(pointee) = inner.pointee() {
978 trace!(
979 " Starting smart pointer for {} (pointee is {})",
980 wip.shape().blue(),
981 pointee.yellow(),
982 );
983 } else {
984 trace!(
985 " Starting smart pointer for {} (no pointee)",
986 wip.shape().blue()
987 );
988 }
989 wip = wip.push_pointee().map_err(|e| self.reflect_err(e))?;
990 self.stack.push(Instruction::Pop(PopReason::SmartPointer));
991 } else if let Some(inner_fn) = wip.shape().inner {
992 let inner = inner_fn();
993 trace!(
994 " Starting wrapped value for {} (inner is {})",
995 wip.shape().blue(),
996 inner.yellow()
997 );
998 wip = wip.push_inner().map_err(|e| self.reflect_err(e))?;
999 self.stack.push(Instruction::Pop(PopReason::Wrapper));
1000 } else {
1001 break;
1002 }
1003 }
1004
1005 if wip.shape() != original_shape {
1006 trace!(
1007 "Handling shape {} as innermost {}",
1008 original_shape.blue(),
1009 wip.shape().yellow()
1010 );
1011 }
1012
1013 match outcome.node {
1014 Outcome::Scalar(s) => {
1015 trace!("Parsed scalar value: {}", s.cyan());
1016 wip = self.handle_scalar(wip, s)?;
1017 }
1018 Outcome::ListStarted => {
1019 let shape = wip.innermost_shape();
1020 match shape.def {
1021 Def::Array(_) => {
1022 trace!("Array starting for array ({})!", shape.blue());
1023 }
1026 Def::Slice(_) => {
1027 trace!("Array starting for slice ({})!", shape.blue());
1028 }
1029 Def::List(_) => {
1030 trace!("Array starting for list ({})!", shape.blue());
1031 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1032 }
1033 Def::Scalar(sd) => {
1034 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
1035 trace!("Empty tuple/scalar, nice");
1036 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: "array, list, tuple, or slice",
1041 }));
1042 }
1043 }
1044 _ => {
1045 if let Type::User(user_ty) = shape.ty {
1047 match user_ty {
1048 UserType::Enum(_) => {
1049 trace!("Array starting for enum ({})!", shape.blue());
1050 }
1051 UserType::Struct(_) => {
1052 trace!("Array starting for tuple struct ({})!", shape.blue());
1053 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1054 }
1055 _ => {
1056 return Err(self.err(DeserErrorKind::UnsupportedType {
1057 got: shape,
1058 wanted: "array, list, tuple, or slice",
1059 }));
1060 }
1061 }
1062 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
1063 trace!(
1064 "Array starting for tuple ({}) with {} fields!",
1065 shape.blue(),
1066 tuple_type.fields.len()
1067 );
1068 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1070 } else {
1073 return Err(self.err(DeserErrorKind::UnsupportedType {
1074 got: shape,
1075 wanted: "array, list, tuple, or slice",
1076 }));
1077 }
1078 }
1079 }
1080 trace!("Beginning pushback");
1081 self.stack.push(Instruction::ListItemOrListClose);
1082 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
1083 }
1084 Outcome::ListEnded => {
1085 trace!("List closing");
1086 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1087 }
1088 Outcome::ObjectStarted => {
1089 let shape = wip.shape();
1090 match shape.def {
1091 Def::Map(_md) => {
1092 trace!("Object starting for map value ({})!", shape.blue());
1093 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1094 }
1095 _ => {
1096 if let Type::User(user_ty) = shape.ty {
1098 match user_ty {
1099 UserType::Enum(_) => {
1100 trace!("Object starting for enum value ({})!", shape.blue());
1101 }
1103 UserType::Struct(_) => {
1104 trace!("Object starting for struct value ({})!", shape.blue());
1105 }
1107 _ => {
1108 return Err(self.err(DeserErrorKind::UnsupportedType {
1109 got: shape,
1110 wanted: "map, enum, or struct",
1111 }));
1112 }
1113 }
1114 } else if let Type::Sequence(SequenceType::Tuple(tuple_type)) = shape.ty {
1115 trace!(
1118 "Object starting for tuple ({}) with {} fields - unusual but handling",
1119 shape.blue(),
1120 tuple_type.fields.len()
1121 );
1122 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
1124 } else {
1125 return Err(self.err(DeserErrorKind::UnsupportedType {
1126 got: shape,
1127 wanted: "map, enum, struct, or tuple",
1128 }));
1129 }
1130 }
1131 }
1132
1133 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1134 }
1135 Outcome::Resegmented(subspans) => {
1136 trace!("Resegmented with {} subspans (value)", subspans.len());
1137 }
1144 Outcome::ObjectEnded => todo!(),
1145 }
1146 Ok(wip)
1147 }
1148
1149 fn object_key_or_object_close<'facet>(
1150 &mut self,
1151 mut wip: Wip<'facet, 'shape>,
1152 outcome: Spanned<Outcome<'input>, C>,
1153 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1154 where
1155 'input: 'facet,
1156 {
1157 trace!(
1158 "STACK: {:?} {}",
1159 self.stack.green(),
1160 "(OK/OC)".bright_yellow()
1161 );
1162 trace!("SUBSTACK: {:?}", self.substack.get().bright_green());
1163 match outcome.node {
1164 Outcome::Scalar(Scalar::String(key)) => {
1165 trace!("Parsed object key: {}", key.cyan());
1166
1167 let mut ignore = false;
1168 let mut needs_pop = true;
1169 let mut handled_by_flatten = false;
1170 let has_substack = !self.substack.get().is_empty();
1171
1172 let shape = wip.innermost_shape();
1173 match shape.ty {
1174 Type::User(UserType::Struct(sd)) => {
1175 if let Some(index) = wip.field_index(&key) {
1177 trace!("It's a struct field");
1178 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1179 } else {
1180 trace!(
1181 "Did not find direct field match in innermost shape {}",
1182 shape.blue()
1183 );
1184
1185 let mut found_in_flatten = false;
1187 for (index, field) in sd.fields.iter().enumerate() {
1188 if field.flags.contains(FieldFlags::FLATTEN) {
1189 trace!("Found flattened field #{}", index);
1190 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1192
1193 if let Some(subfield_index) = wip.field_index(&key) {
1195 trace!("Found key {} in flattened field", key);
1196 wip = wip
1197 .field(subfield_index)
1198 .map_err(|e| self.reflect_err(e))?;
1199 found_in_flatten = true;
1200 handled_by_flatten = true;
1201 break;
1202 } else if let Some((_variant_index, _variant)) =
1203 wip.find_variant(&key)
1204 {
1205 trace!("Found key {} in flattened field", key);
1206 wip = wip
1207 .variant_named(&key)
1208 .map_err(|e| self.reflect_err(e))?;
1209 found_in_flatten = true;
1210 break;
1211 } else {
1212 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
1214 }
1215 }
1216 }
1217
1218 if !found_in_flatten {
1219 if wip.shape().has_deny_unknown_fields_attr() {
1220 trace!(
1221 "It's not a struct field AND we're denying unknown fields"
1222 );
1223 return Err(self.err(DeserErrorKind::UnknownField {
1224 field_name: key.to_string(),
1225 shape: wip.shape(),
1226 }));
1227 } else {
1228 trace!(
1229 "It's not a struct field and we're ignoring unknown fields"
1230 );
1231 ignore = true;
1232 }
1233 }
1234 }
1235 }
1236 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
1237 Some((index, variant)) => {
1238 trace!(
1239 "Selecting variant {}::{}",
1240 wip.shape().blue(),
1241 variant.name.yellow(),
1242 );
1243 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
1244
1245 if matches!(variant.data.kind, StructKind::Tuple)
1247 && variant.data.fields.len() == 1
1248 {
1249 trace!(
1250 "Tuple variant {}::{} encountered, pushing field 0",
1251 wip.shape().blue(),
1252 variant.name.yellow()
1253 );
1254 wip = wip.field(0).map_err(|e| self.reflect_err(e))?;
1255 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1256 }
1257
1258 needs_pop = false;
1259 }
1260 None => {
1261 if let Some(_variant_index) = wip.selected_variant() {
1262 trace!(
1263 "Already have a variant selected, treating {} as struct field of {}::{}",
1264 key,
1265 wip.shape().blue(),
1266 wip.selected_variant().unwrap().name.yellow(),
1267 );
1268 if let Some(index) = wip.field_index(&key) {
1270 trace!("Found field {} in selected variant", key.blue());
1271 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
1272 } else if wip.shape().has_deny_unknown_fields_attr() {
1273 trace!("Unknown field in variant and denying unknown fields");
1274 return Err(self.err(DeserErrorKind::UnknownField {
1275 field_name: key.to_string(),
1276 shape: wip.shape(),
1277 }));
1278 } else {
1279 trace!(
1280 "Ignoring unknown field '{}' in variant '{}::{}'",
1281 key,
1282 wip.shape(),
1283 wip.selected_variant().unwrap().name
1284 );
1285 ignore = true;
1286 }
1287 } else {
1288 return Err(self.err(DeserErrorKind::NoSuchVariant {
1289 name: key.to_string(),
1290 enum_shape: wip.shape(),
1291 }));
1292 }
1293 }
1294 },
1295 _ => {
1296 if let Def::Map(_) = shape.def {
1298 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
1299 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
1300 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
1301 } else {
1302 return Err(self.err(DeserErrorKind::Unimplemented(
1303 "object key for non-struct/map",
1304 )));
1305 }
1306 }
1307 }
1308
1309 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1310 if ignore {
1311 self.stack.push(Instruction::SkipValue);
1312 } else {
1313 if needs_pop && !handled_by_flatten {
1314 trace!("Pushing Pop insn to stack (ObjectVal)");
1315 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1316 if has_substack {
1317 trace!("Pushing SubstackClose insn to stack");
1318 self.stack.push(Instruction::SubstackClose);
1319 }
1320 } else if handled_by_flatten {
1321 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1324 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1325 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1332 }
1333 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1334 }
1335 Ok(wip)
1336 }
1337 Outcome::ObjectEnded => {
1338 trace!("Object closing");
1339 Ok(wip)
1340 }
1341 Outcome::Resegmented(subspans) => {
1342 trace!(
1343 "Resegmented into {} subspans ({:?}) - obj. key/close",
1344 subspans.len(),
1345 subspans
1346 );
1347 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1349 Ok(wip)
1350 }
1351 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1352 got: outcome.node.into_owned(),
1353 wanted: "scalar or object close",
1354 })),
1355 }
1356 }
1357
1358 fn list_item_or_list_close<'facet>(
1359 &mut self,
1360 mut wip: Wip<'facet, 'shape>,
1361 outcome: Spanned<Outcome<'input>, C>,
1362 ) -> Result<Wip<'facet, 'shape>, DeserError<'input, 'shape, C>>
1363 where
1364 'input: 'facet,
1365 {
1366 trace!(
1367 "--- STACK has {:?} {}",
1368 self.stack.green(),
1369 "(LI/LC)".bright_yellow()
1370 );
1371 match outcome.node {
1372 Outcome::ListEnded => {
1373 trace!("List close");
1374 Ok(wip)
1375 }
1376 _ => {
1377 self.stack.push(Instruction::ListItemOrListClose);
1378 self.stack.push(Instruction::Pop(PopReason::ListVal));
1379
1380 trace!(
1381 "Expecting list item, doing a little push before doing value with outcome {}",
1382 outcome.magenta()
1383 );
1384 trace!("Before push, wip.shape is {}", wip.shape().blue());
1385
1386 let is_tuple = matches!(wip.shape().ty, Type::Sequence(SequenceType::Tuple(_)));
1388
1389 if is_tuple {
1390 trace!("Handling list item for a tuple type");
1391 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1393 } else {
1394 wip = wip.push().map_err(|e| self.reflect_err(e))?;
1396 }
1397
1398 trace!(" After push, wip.shape is {}", wip.shape().cyan());
1399 wip = self.value(wip, outcome)?;
1400 Ok(wip)
1401 }
1402 }
1403 }
1404}