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#![forbid(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, StructKind, Type, UserType,
24};
25use owo_colors::OwoColorize;
26pub use span::*;
27
28use facet_reflect::{HeapValue, Partial, ReflectError};
29use log::trace;
30
31#[derive(PartialEq, Debug, Clone)]
32pub enum Scalar<'input> {
37 String(Cow<'input, str>),
39 U64(u64),
41 I64(i64),
43 F64(f64),
45 U128(u128),
47 I128(i128),
49 Bool(bool),
51 Null,
53}
54
55#[derive(PartialEq, Debug, Clone)]
56pub enum Expectation {
58 Value,
60 ObjectKeyOrObjectClose,
62 ObjectVal,
64 ListItemOrListClose,
66}
67
68#[derive(PartialEq, Debug, Clone)]
69pub enum Outcome<'input> {
71 Scalar(Scalar<'input>),
73 ListStarted,
75 ListEnded,
77 ObjectStarted,
79 ObjectEnded,
81 Resegmented(Vec<Subspan>),
83}
84
85impl<'input> From<Scalar<'input>> for Outcome<'input> {
86 fn from(scalar: Scalar<'input>) -> Self {
87 Outcome::Scalar(scalar)
88 }
89}
90
91use core::fmt;
92
93impl fmt::Display for Outcome<'_> {
95 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 match self {
97 Outcome::Scalar(scalar) => write!(f, "scalar {}", scalar),
98 Outcome::ListStarted => write!(f, "list start"),
99 Outcome::ListEnded => write!(f, "list end"),
100 Outcome::ObjectStarted => write!(f, "object start"),
101 Outcome::ObjectEnded => write!(f, "object end"),
102 Outcome::Resegmented(_) => write!(f, "resegment"),
103 }
104 }
105}
106
107impl fmt::Display for Scalar<'_> {
109 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
110 match self {
111 Scalar::String(s) => write!(f, "string \"{}\"", s),
112 Scalar::U64(val) => write!(f, "u64 {}", val),
113 Scalar::I64(val) => write!(f, "i64 {}", val),
114 Scalar::F64(val) => write!(f, "f64 {}", val),
115 Scalar::U128(val) => write!(f, "u128 {}", val),
116 Scalar::I128(val) => write!(f, "i128 {}", val),
117 Scalar::Bool(val) => write!(f, "bool {}", val),
118 Scalar::Null => write!(f, "null"),
119 }
120 }
121}
122
123impl Outcome<'_> {
124 fn into_owned(self) -> Outcome<'static> {
125 match self {
126 Outcome::Scalar(scalar) => {
127 let owned_scalar = match scalar {
128 Scalar::String(cow) => Scalar::String(Cow::Owned(cow.into_owned())),
129 Scalar::U64(val) => Scalar::U64(val),
130 Scalar::I64(val) => Scalar::I64(val),
131 Scalar::F64(val) => Scalar::F64(val),
132 Scalar::U128(val) => Scalar::U128(val),
133 Scalar::I128(val) => Scalar::I128(val),
134 Scalar::Bool(val) => Scalar::Bool(val),
135 Scalar::Null => Scalar::Null,
136 };
137 Outcome::Scalar(owned_scalar)
138 }
139 Outcome::ListStarted => Outcome::ListStarted,
140 Outcome::ListEnded => Outcome::ListEnded,
141 Outcome::ObjectStarted => Outcome::ObjectStarted,
142 Outcome::ObjectEnded => Outcome::ObjectEnded,
143 Outcome::Resegmented(subspans) => {
144 let owned_subspans = subspans
145 .into_iter()
146 .map(|s| Subspan {
147 offset: s.offset,
148 len: s.len,
149 meta: s.meta,
150 })
151 .collect();
152 Outcome::Resegmented(owned_subspans)
153 }
154 }
155 }
156}
157
158pub struct NextData<'input, 'facet, 'shape, C = Cooked, I = [u8]>
161where
162 'input: 'facet,
163 I: ?Sized + 'input,
164{
165 start: usize,
167
168 runner: StackRunner<'input, C, I>,
170
171 pub wip: Partial<'facet, 'shape>,
173}
174
175impl<'input, 'facet, 'shape, C, I> NextData<'input, 'facet, 'shape, C, I>
176where
177 'input: 'facet,
178 I: ?Sized + 'input,
179{
180 pub fn input(&self) -> &'input I {
182 self.runner.input
183 }
184
185 pub fn start(&self) -> usize {
187 self.start
188 }
189
190 pub fn substack(&self) -> &Substack<C> {
192 &self.runner.substack
193 }
194}
195
196pub type NextResult<'input, 'facet, 'shape, T, E, C, I = [u8]> =
198 (NextData<'input, 'facet, 'shape, C, I>, Result<T, E>);
199
200pub trait Format {
203 type Input<'input>: ?Sized;
208
209 type SpanType: Debug + SubstackBehavior + 'static;
211
212 fn source(&self) -> &'static str;
214
215 #[allow(clippy::type_complexity)]
217 fn next<'input, 'facet, 'shape>(
218 &mut self,
219 nd: NextData<'input, 'facet, 'shape, Self::SpanType, Self::Input<'input>>,
220 expectation: Expectation,
221 ) -> NextResult<
222 'input,
223 'facet,
224 'shape,
225 Spanned<Outcome<'input>, Self::SpanType>,
226 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
227 Self::SpanType,
228 Self::Input<'input>,
229 >
230 where
231 'shape: 'input;
232
233 #[allow(clippy::type_complexity)]
235 fn skip<'input, 'facet, 'shape>(
236 &mut self,
237 nd: NextData<'input, 'facet, 'shape, Self::SpanType, Self::Input<'input>>,
238 ) -> NextResult<
239 'input,
240 'facet,
241 'shape,
242 Span<Self::SpanType>,
243 Spanned<DeserErrorKind<'shape>, Self::SpanType>,
244 Self::SpanType,
245 Self::Input<'input>,
246 >
247 where
248 'shape: 'input;
249}
250
251pub trait ToCooked<'input, F: Format> {
253 fn to_cooked(self, format: &F, input: &'input F::Input<'input>) -> Span<Cooked>;
255}
256
257impl<'input, F: Format> ToCooked<'input, F> for Span<Cooked> {
258 #[inline]
259 fn to_cooked(self, _format: &F, _input: &'input F::Input<'input>) -> Span<Cooked> {
260 self
261 }
262}
263
264impl<'input, F: Format<SpanType = Raw, Input<'input> = [&'input str]>> ToCooked<'input, F>
265 for Span<Raw>
266{
267 #[inline]
268 fn to_cooked(self, _format: &F, input: &'input [&'input str]) -> Span<Cooked> {
269 if self.start >= input.len() {
270 let mut total_len = 0;
273 for (i, arg) in input.iter().enumerate() {
274 total_len += arg.len();
275 if i < input.len() - 1 {
276 total_len += 1; }
278 }
279 return Span::<Cooked>::new(total_len.saturating_sub(1), 1);
280 }
281
282 let mut start = 0;
284 for arg in input.iter().take(self.start) {
285 start += arg.len() + 1; }
287
288 let len = input[self.start].len();
290
291 Span::<Cooked>::new(start, len)
292 }
293}
294
295#[derive(Debug, Clone, Copy, PartialEq, Eq)]
297pub enum Instruction {
298 Value(ValueReason),
300 SkipValue,
302 Pop(PopReason),
304 ObjectKeyOrObjectClose,
306 ListItemOrListClose,
308 SubstackClose,
310}
311
312#[derive(Debug, Clone, Copy, PartialEq, Eq)]
314pub enum ValueReason {
315 TopLevel,
317 ObjectVal,
319}
320
321#[derive(Debug, Clone, Copy, PartialEq, Eq)]
323pub enum PopReason {
324 TopLevel,
326 ObjectVal,
328 ListVal,
330 Some,
332 SmartPointer,
334 Wrapper,
336}
337
338mod deser_impl {
339 use super::*;
340
341 pub fn deserialize<'input, 'facet, 'shape, T, F>(
346 input: &'input F::Input<'input>,
347 format: &mut F,
348 ) -> Result<T, DeserError<'input, 'shape, Cooked>>
349 where
350 T: Facet<'facet>,
351 F: Format + 'shape,
352 F::Input<'input>: InputDebug,
353 F::SpanType: core::fmt::Debug,
354 Span<F::SpanType>: ToCooked<'input, F>,
355 'input: 'facet,
356 'shape: 'input,
357 {
358 let result: Result<T, DeserError<'input, 'shape, Cooked>> = {
360 let source = format.source();
361
362 let wip = match Partial::alloc_shape(T::SHAPE) {
364 Ok(wip) => wip,
365 Err(e) => {
366 let default_span = Span::<F::SpanType>::default();
367 let cooked_span = default_span.to_cooked(format, input);
369 return Err(DeserError::new_reflect(e, input, cooked_span, source));
370 }
371 };
372
373 let heap_value = match deserialize_wip(wip, input, format) {
375 Ok(val) => val,
376 Err(e) => {
377 let cooked_span = e.span.to_cooked(format, input);
378
379 let cooked_error = DeserError {
381 input: e.input,
382 span: cooked_span,
383 kind: e.kind,
384 source_id: e.source_id,
385 };
386
387 return Err(cooked_error);
388 }
389 };
390
391 match heap_value.materialize() {
393 Ok(val) => Ok(val),
394 Err(e) => {
395 let default_span = Span::<F::SpanType>::default();
396 let cooked_span = default_span.to_cooked(format, input);
397 return Err(DeserError::new_reflect(e, input, cooked_span, source));
398 }
399 }
400 };
401
402 match result {
404 Ok(value) => Ok(value),
405 Err(mut error) => {
406 let new_span = error.span.to_cooked(format, input);
407
408 if new_span != error.span {
409 error = DeserError {
410 input: error.input,
411 span: new_span,
412 kind: error.kind,
413 source_id: error.source_id,
414 };
415 }
416
417 Err(error)
418 }
419 }
420 }
421}
422
423pub fn deserialize<'input, 'facet, 'shape, T, F>(
428 input: &'input F::Input<'input>,
429 format: F,
430) -> Result<T, DeserError<'input, 'shape, Cooked>>
431where
432 T: Facet<'facet>,
433 F: Format + 'shape,
434 F::Input<'input>: InputDebug,
435 F::SpanType: core::fmt::Debug,
436 Span<F::SpanType>: ToCooked<'input, F>,
437 'input: 'facet,
438 'shape: 'input,
439{
440 let mut format_copy = format;
441 deser_impl::deserialize(input, &mut format_copy)
442}
443
444pub fn deserialize_wip<'input, 'facet, 'shape, F>(
447 mut wip: Partial<'facet, 'shape>,
448 input: &'input F::Input<'input>,
449 format: &mut F,
450) -> Result<HeapValue<'facet, 'shape>, DeserError<'input, 'shape, Cooked>>
451where
452 F: Format + 'shape,
453 F::SpanType: SubstackBehavior,
454 F::Input<'input>: InputDebug,
455 Span<F::SpanType>: ToCooked<'input, F>,
456 'input: 'facet,
457 'shape: 'input,
458{
459 let mut runner = StackRunner {
461 original_input: input,
462 input,
463 stack: vec![
464 Instruction::Pop(PopReason::TopLevel),
465 Instruction::Value(ValueReason::TopLevel),
466 ],
467 substack: Substack::new(),
468 last_span: Span::new(0, 0),
469 format_source: format.source(),
470 array_indices: Vec::new(),
471 enum_tuple_field_count: None,
472 enum_tuple_current_field: None,
473 };
474
475 macro_rules! next {
476 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
477 let nd = NextData {
478 start: $runner.last_span.end(), runner: $runner,
480 wip: $wip,
481 };
482 let (nd, res) = format.next(nd, $expectation);
483 $runner = nd.runner;
484 $wip = nd.wip;
485 let outcome = res.map_err(|span_kind| {
486 $runner.last_span = span_kind.span;
487 let error = $runner.err(span_kind.node);
488 DeserError {
490 input: error.input,
491 span: error.span.to_cooked(format, input),
492 kind: error.kind,
493 source_id: error.source_id,
494 }
495 })?;
496 if F::SpanType::USES_SUBSTACK {
497 if !$runner.substack.get().is_empty() {
498 trace!("Substack: {}", "carried".cyan());
499 } else {
500 trace!("Substack: {}", "-".red());
501 }
502 }
503 $runner.last_span = outcome.span;
504 if F::SpanType::USES_SUBSTACK {
505 if let Outcome::Resegmented(subspans) = &outcome.node {
506 $runner.substack = subspans.clone().into();
507 }
508 }
509 $wip = $runner.$method($wip, outcome).map_err(|error| {
510 DeserError {
511 input: error.input,
512 span: error.span.to_cooked(format, input),
513 kind: error.kind,
514 source_id: error.source_id,
515 }
516 })?;
517 }};
518 }
519
520 loop {
521 let insn = match runner.stack.pop() {
525 Some(insn) => insn,
526 None => unreachable!("Instruction stack is empty"),
527 };
528
529 trace!("Instruction {:?}", insn.bright_red());
530
531 match insn {
532 Instruction::Pop(reason) => {
533 wip = runner.pop(wip, reason).map_err(|error| {
534 DeserError {
536 input: error.input,
537 span: error.span.to_cooked(format, input),
538 kind: error.kind,
539 source_id: error.source_id,
540 }
541 })?;
542
543 if reason == PopReason::TopLevel {
544 while wip.frame_count() > 1 {
546 wip.end().map_err(|e| {
547 let reflect_error = runner.reflect_err(e);
548 DeserError {
549 input: reflect_error.input,
550 span: reflect_error.span.to_cooked(format, input),
551 kind: reflect_error.kind,
552 source_id: reflect_error.source_id,
553 }
554 })?;
555 }
556
557 return wip.build().map_err(|e| {
558 let reflect_error = runner.reflect_err(e);
559 DeserError {
561 input: reflect_error.input,
562 span: reflect_error.span.to_cooked(format, input),
563 kind: reflect_error.kind,
564 source_id: reflect_error.source_id,
565 }
566 });
567 } else {
568 wip.end().map_err(|e| {
569 let reflect_error = runner.reflect_err(e);
570 DeserError {
572 input: reflect_error.input,
573 span: reflect_error.span.to_cooked(format, input),
574 kind: reflect_error.kind,
575 source_id: reflect_error.source_id,
576 }
577 })?;
578 }
579 }
580 Instruction::Value(_why) => {
581 let expectation = match _why {
582 ValueReason::TopLevel => Expectation::Value,
583 ValueReason::ObjectVal => Expectation::ObjectVal,
584 };
585 next!(runner, wip, expectation, value);
586 }
587 Instruction::ObjectKeyOrObjectClose => {
588 next!(
589 runner,
590 wip,
591 Expectation::ObjectKeyOrObjectClose,
592 object_key_or_object_close
593 );
594 }
595 Instruction::ListItemOrListClose => {
596 next!(
597 runner,
598 wip,
599 Expectation::ListItemOrListClose,
600 list_item_or_list_close
601 );
602 }
603 Instruction::SubstackClose => {
604 runner.substack.clear();
605 }
606 Instruction::SkipValue => {
607 let nd = NextData {
609 start: runner.last_span.end(),
610 runner,
611 wip,
612 };
613 let (nd, res) = format.skip(nd);
614 runner = nd.runner;
615 wip = nd.wip;
616 let span = res.map_err(|span_kind| {
618 runner.last_span = span_kind.span;
619 let error = runner.err(span_kind.node);
620 DeserError {
622 input: error.input,
623 span: error.span.to_cooked(format, input),
624 kind: error.kind,
625 source_id: error.source_id,
626 }
627 })?;
628 runner.last_span = span;
630 }
631 }
632 }
633}
634
635#[inline]
638fn has_no_fractional_part(value: f64) -> bool {
639 value == (value as i64) as f64
640}
641
642trait NumericConvert: Sized {
644 const TYPE_NAME: &'static str;
645
646 fn to_i8(self) -> Option<i8>;
647 fn to_i16(self) -> Option<i16>;
648 fn to_i32(self) -> Option<i32>;
649 fn to_i64(self) -> Option<i64>;
650 fn to_i128(self) -> Option<i128>;
651 fn to_isize(self) -> Option<isize>;
652
653 fn to_u8(self) -> Option<u8>;
654 fn to_u16(self) -> Option<u16>;
655 fn to_u32(self) -> Option<u32>;
656 fn to_u64(self) -> Option<u64>;
657 fn to_u128(self) -> Option<u128>;
658 fn to_usize(self) -> Option<usize>;
659
660 fn to_f32(self) -> Option<f32>;
661 fn to_f64(self) -> Option<f64>;
662}
663
664impl NumericConvert for u64 {
665 const TYPE_NAME: &'static str = "u64";
666
667 fn to_i8(self) -> Option<i8> {
668 self.try_into().ok()
669 }
670 fn to_i16(self) -> Option<i16> {
671 self.try_into().ok()
672 }
673 fn to_i32(self) -> Option<i32> {
674 self.try_into().ok()
675 }
676 fn to_i64(self) -> Option<i64> {
677 self.try_into().ok()
678 }
679 fn to_i128(self) -> Option<i128> {
680 Some(self as i128)
681 }
682 fn to_isize(self) -> Option<isize> {
683 self.try_into().ok()
684 }
685
686 fn to_u8(self) -> Option<u8> {
687 self.try_into().ok()
688 }
689 fn to_u16(self) -> Option<u16> {
690 self.try_into().ok()
691 }
692 fn to_u32(self) -> Option<u32> {
693 self.try_into().ok()
694 }
695 fn to_u64(self) -> Option<u64> {
696 Some(self)
697 }
698 fn to_u128(self) -> Option<u128> {
699 Some(self as u128)
700 }
701 fn to_usize(self) -> Option<usize> {
702 self.try_into().ok()
703 }
704
705 fn to_f32(self) -> Option<f32> {
706 Some(self as f32)
707 }
708 fn to_f64(self) -> Option<f64> {
709 Some(self as f64)
710 }
711}
712
713impl NumericConvert for i64 {
714 const TYPE_NAME: &'static str = "i64";
715
716 fn to_i8(self) -> Option<i8> {
717 self.try_into().ok()
718 }
719 fn to_i16(self) -> Option<i16> {
720 self.try_into().ok()
721 }
722 fn to_i32(self) -> Option<i32> {
723 self.try_into().ok()
724 }
725 fn to_i64(self) -> Option<i64> {
726 Some(self)
727 }
728 fn to_i128(self) -> Option<i128> {
729 Some(self as i128)
730 }
731 fn to_isize(self) -> Option<isize> {
732 self.try_into().ok()
733 }
734
735 fn to_u8(self) -> Option<u8> {
736 self.try_into().ok()
737 }
738 fn to_u16(self) -> Option<u16> {
739 self.try_into().ok()
740 }
741 fn to_u32(self) -> Option<u32> {
742 self.try_into().ok()
743 }
744 fn to_u64(self) -> Option<u64> {
745 self.try_into().ok()
746 }
747 fn to_u128(self) -> Option<u128> {
748 self.try_into().ok()
749 }
750 fn to_usize(self) -> Option<usize> {
751 self.try_into().ok()
752 }
753
754 fn to_f32(self) -> Option<f32> {
755 Some(self as f32)
756 }
757 fn to_f64(self) -> Option<f64> {
758 Some(self as f64)
759 }
760}
761
762impl NumericConvert for f64 {
763 const TYPE_NAME: &'static str = "f64";
764
765 fn to_i8(self) -> Option<i8> {
766 if has_no_fractional_part(self) && self >= i8::MIN as f64 && self <= i8::MAX as f64 {
767 Some(self as i8)
768 } else {
769 None
770 }
771 }
772 fn to_i16(self) -> Option<i16> {
773 if has_no_fractional_part(self) && self >= i16::MIN as f64 && self <= i16::MAX as f64 {
774 Some(self as i16)
775 } else {
776 None
777 }
778 }
779 fn to_i32(self) -> Option<i32> {
780 if has_no_fractional_part(self) && self >= i32::MIN as f64 && self <= i32::MAX as f64 {
781 Some(self as i32)
782 } else {
783 None
784 }
785 }
786 fn to_i64(self) -> Option<i64> {
787 if has_no_fractional_part(self) && self >= i64::MIN as f64 && self <= i64::MAX as f64 {
788 Some(self as i64)
789 } else {
790 None
791 }
792 }
793 fn to_i128(self) -> Option<i128> {
794 if has_no_fractional_part(self) && self >= i128::MIN as f64 && self <= i128::MAX as f64 {
795 Some(self as i128)
796 } else {
797 None
798 }
799 }
800 fn to_isize(self) -> Option<isize> {
801 if has_no_fractional_part(self) && self >= isize::MIN as f64 && self <= isize::MAX as f64 {
802 Some(self as isize)
803 } else {
804 None
805 }
806 }
807
808 fn to_u8(self) -> Option<u8> {
809 if has_no_fractional_part(self) && self >= 0.0 && self <= u8::MAX as f64 {
810 Some(self as u8)
811 } else {
812 None
813 }
814 }
815 fn to_u16(self) -> Option<u16> {
816 if has_no_fractional_part(self) && self >= 0.0 && self <= u16::MAX as f64 {
817 Some(self as u16)
818 } else {
819 None
820 }
821 }
822 fn to_u32(self) -> Option<u32> {
823 if has_no_fractional_part(self) && self >= 0.0 && self <= u32::MAX as f64 {
824 Some(self as u32)
825 } else {
826 None
827 }
828 }
829 fn to_u64(self) -> Option<u64> {
830 if has_no_fractional_part(self) && self >= 0.0 && self <= u64::MAX as f64 {
831 Some(self as u64)
832 } else {
833 None
834 }
835 }
836 fn to_u128(self) -> Option<u128> {
837 if has_no_fractional_part(self) && self >= 0.0 && self <= u128::MAX as f64 {
838 Some(self as u128)
839 } else {
840 None
841 }
842 }
843 fn to_usize(self) -> Option<usize> {
844 if has_no_fractional_part(self) && self >= 0.0 && self <= usize::MAX as f64 {
845 Some(self as usize)
846 } else {
847 None
848 }
849 }
850
851 fn to_f32(self) -> Option<f32> {
852 Some(self as f32)
853 }
854 fn to_f64(self) -> Option<f64> {
855 Some(self)
856 }
857}
858
859impl NumericConvert for u128 {
860 const TYPE_NAME: &'static str = "u128";
861
862 fn to_i8(self) -> Option<i8> {
863 self.try_into().ok()
864 }
865 fn to_i16(self) -> Option<i16> {
866 self.try_into().ok()
867 }
868 fn to_i32(self) -> Option<i32> {
869 self.try_into().ok()
870 }
871 fn to_i64(self) -> Option<i64> {
872 self.try_into().ok()
873 }
874 fn to_i128(self) -> Option<i128> {
875 Some(self as i128)
876 }
877 fn to_isize(self) -> Option<isize> {
878 self.try_into().ok()
879 }
880
881 fn to_u8(self) -> Option<u8> {
882 self.try_into().ok()
883 }
884 fn to_u16(self) -> Option<u16> {
885 self.try_into().ok()
886 }
887 fn to_u32(self) -> Option<u32> {
888 self.try_into().ok()
889 }
890 fn to_u64(self) -> Option<u64> {
891 self.try_into().ok()
892 }
893 fn to_u128(self) -> Option<u128> {
894 Some(self)
895 }
896 fn to_usize(self) -> Option<usize> {
897 self.try_into().ok()
898 }
899
900 fn to_f32(self) -> Option<f32> {
901 Some(self as f32)
902 }
903 fn to_f64(self) -> Option<f64> {
904 Some(self as f64)
905 }
906}
907
908impl NumericConvert for i128 {
909 const TYPE_NAME: &'static str = "i128";
910
911 fn to_i8(self) -> Option<i8> {
912 self.try_into().ok()
913 }
914 fn to_i16(self) -> Option<i16> {
915 self.try_into().ok()
916 }
917 fn to_i32(self) -> Option<i32> {
918 self.try_into().ok()
919 }
920 fn to_i64(self) -> Option<i64> {
921 self.try_into().ok()
922 }
923 fn to_i128(self) -> Option<i128> {
924 Some(self)
925 }
926 fn to_isize(self) -> Option<isize> {
927 self.try_into().ok()
928 }
929
930 fn to_u8(self) -> Option<u8> {
931 self.try_into().ok()
932 }
933 fn to_u16(self) -> Option<u16> {
934 self.try_into().ok()
935 }
936 fn to_u32(self) -> Option<u32> {
937 self.try_into().ok()
938 }
939 fn to_u64(self) -> Option<u64> {
940 self.try_into().ok()
941 }
942 fn to_u128(self) -> Option<u128> {
943 self.try_into().ok()
944 }
945 fn to_usize(self) -> Option<usize> {
946 self.try_into().ok()
947 }
948
949 fn to_f32(self) -> Option<f32> {
950 Some(self as f32)
951 }
952 fn to_f64(self) -> Option<f64> {
953 Some(self as f64)
954 }
955}
956
957#[doc(hidden)]
958pub struct StackRunner<'input, C = Cooked, I: ?Sized + 'input = [u8]> {
963 pub original_input: &'input I,
965
966 pub input: &'input I,
968
969 pub stack: Vec<Instruction>,
971
972 pub substack: Substack<C>,
974
975 pub last_span: Span<C>,
977
978 pub format_source: &'static str,
980
981 pub array_indices: Vec<usize>,
983
984 pub enum_tuple_field_count: Option<usize>,
986
987 pub enum_tuple_current_field: Option<usize>,
989}
990
991impl<'input, 'shape, C, I: ?Sized + 'input> StackRunner<'input, C, I>
992where
993 I: InputDebug,
994{
995 fn err(&self, kind: DeserErrorKind<'shape>) -> DeserError<'input, 'shape, C> {
997 DeserError::new(
998 kind,
999 self.original_input,
1000 self.last_span,
1001 self.format_source,
1002 )
1003 }
1004
1005 fn reflect_err(&self, err: ReflectError<'shape>) -> DeserError<'input, 'shape, C> {
1008 DeserError::new_reflect(err, self.original_input, self.last_span, self.format_source)
1009 }
1010
1011 pub fn pop<'facet>(
1012 &mut self,
1013 mut wip: Partial<'facet, 'shape>,
1014 reason: PopReason,
1015 ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape, C>> {
1016 trace!(
1017 "--- STACK has {:?} {}",
1018 self.stack.green(),
1019 "(POP)".bright_yellow()
1020 );
1021 trace!("Popping because {:?}", reason.yellow());
1022
1023 let container_shape = wip.shape();
1024 match container_shape.ty {
1025 Type::User(UserType::Struct(sd)) => {
1026 let mut has_unset = false;
1027
1028 trace!("Let's check all fields are initialized");
1029 for (index, field) in sd.fields.iter().enumerate() {
1030 let is_set = wip.is_field_set(index).map_err(|err| {
1031 trace!("Error checking field set status: {:?}", err);
1032 self.reflect_err(err)
1033 })?;
1034 if !is_set {
1035 if field.flags.contains(FieldFlags::DEFAULT) {
1036 wip.begin_nth_field(index)
1037 .map_err(|e| self.reflect_err(e))?;
1038
1039 if let Some(field_default_fn) = field.vtable.default_fn {
1041 wip.set_field_default(field_default_fn)
1042 .map_err(|e| self.reflect_err(e))?;
1043 trace!(
1044 "Field #{} {} @ {} was set to default value (via field default function)",
1045 index.yellow(),
1046 field.name.green(),
1047 field.offset.blue(),
1048 );
1049 } else if field.shape().is(Characteristic::Default) {
1050 wip.set_default().map_err(|e| self.reflect_err(e))?;
1051 trace!(
1052 "Field #{} {} @ {} was set to default value (via type default impl)",
1053 index.yellow(),
1054 field.name.green(),
1055 field.offset.blue(),
1056 );
1057 } else {
1058 return Err(self.reflect_err(
1059 ReflectError::DefaultAttrButNoDefaultImpl {
1060 shape: field.shape(),
1061 },
1062 ));
1063 }
1064 wip.end().map_err(|e| self.reflect_err(e))?;
1065 } else {
1066 trace!(
1067 "Field #{} {} @ {} is not initialized",
1068 index.yellow(),
1069 field.name.green(),
1070 field.offset.blue(),
1071 );
1072 has_unset = true;
1073 }
1074 }
1075 }
1076
1077 if has_unset {
1078 if container_shape.has_default_attr() {
1079 let default_val = Partial::alloc_shape(container_shape)
1081 .map_err(|e| self.reflect_err(e))?
1082 .set_default()
1083 .map_err(|e| self.reflect_err(e))?
1084 .build()
1085 .map_err(|e| self.reflect_err(e))?;
1086 let peek = default_val.peek().into_struct().unwrap();
1087
1088 for (index, field) in sd.fields.iter().enumerate() {
1089 let is_set = wip.is_field_set(index).map_err(|err| {
1090 trace!("Error checking field set status: {:?}", err);
1091 self.reflect_err(err)
1092 })?;
1093 if !is_set {
1094 trace!(
1095 "Field #{} {} @ {} is being set to default value (from default instance)",
1096 index.yellow(),
1097 field.name.green(),
1098 field.offset.blue(),
1099 );
1100 wip.begin_nth_field(index)
1101 .map_err(|e| self.reflect_err(e))?;
1102 let def_field = peek.field(index).unwrap();
1104 wip.set_from_peek(&def_field)
1105 .map_err(|e| self.reflect_err(e))?;
1106 wip.end().map_err(|e| self.reflect_err(e))?;
1107 }
1108 }
1109 } else {
1110 for (index, field) in sd.fields.iter().enumerate() {
1112 let is_set = wip.is_field_set(index).map_err(|err| {
1113 trace!("Error checking field set status: {:?}", err);
1114 self.reflect_err(err)
1115 })?;
1116 if !is_set {
1117 return Err(self.reflect_err(ReflectError::UninitializedField {
1118 shape: container_shape,
1119 field_name: field.name,
1120 }));
1121 }
1122 }
1123 }
1124 }
1125 }
1126 Type::User(UserType::Enum(ed)) => {
1127 trace!("Checking if enum is initialized correctly");
1128
1129 if let Some(variant) = wip.selected_variant() {
1131 trace!("Variant {} is selected", variant.name.blue());
1132
1133 if !variant.data.fields.is_empty() {
1135 let mut has_unset = false;
1136
1137 for (index, field) in variant.data.fields.iter().enumerate() {
1138 let is_set = wip.is_field_set(index).map_err(|err| {
1139 trace!("Error checking field set status: {:?}", err);
1140 self.reflect_err(err)
1141 })?;
1142
1143 if !is_set {
1144 if field.flags.contains(FieldFlags::DEFAULT) {
1145 wip.begin_nth_field(index)
1146 .map_err(|e| self.reflect_err(e))?;
1147
1148 if let Some(field_default_fn) = field.vtable.default_fn {
1150 wip.set_field_default(field_default_fn)
1151 .map_err(|e| self.reflect_err(e))?;
1152 trace!(
1153 "Field #{} @ {} in variant {} was set to default value (via field default function)",
1154 index.yellow(),
1155 field.offset.blue(),
1156 variant.name
1157 );
1158 } else if field.shape().is(Characteristic::Default) {
1159 wip.set_default().map_err(|e| self.reflect_err(e))?;
1160 trace!(
1161 "Field #{} @ {} in variant {} was set to default value (via type default impl)",
1162 index.yellow(),
1163 field.offset.blue(),
1164 variant.name
1165 );
1166 } else {
1167 return Err(self.reflect_err(
1168 ReflectError::DefaultAttrButNoDefaultImpl {
1169 shape: field.shape(),
1170 },
1171 ));
1172 }
1173 wip.end().map_err(|e| self.reflect_err(e))?;
1174 } else {
1175 trace!(
1176 "Field #{} @ {} in variant {} is not initialized",
1177 index.yellow(),
1178 field.offset.blue(),
1179 variant.name
1180 );
1181 has_unset = true;
1182 }
1183 }
1184 }
1185
1186 if has_unset {
1187 if container_shape.has_default_attr() {
1188 trace!(
1189 "Enum has DEFAULT attr but variant has uninitialized fields"
1190 );
1191 let default_val = Partial::alloc_shape(container_shape)
1193 .map_err(|e| self.reflect_err(e))?
1194 .set_default()
1195 .map_err(|e| self.reflect_err(e))?
1196 .build()
1197 .map_err(|e| self.reflect_err(e))?;
1198
1199 let peek = default_val.peek();
1200 let peek_enum =
1201 peek.into_enum().map_err(|e| self.reflect_err(e))?;
1202 let default_variant = peek_enum
1203 .active_variant()
1204 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
1205
1206 if default_variant == &variant {
1207 for (index, _field) in variant.data.fields.iter().enumerate() {
1209 let is_set = wip.is_field_set(index).map_err(|err| {
1210 trace!("Error checking field set status: {:?}", err);
1211 self.reflect_err(err)
1212 })?;
1213 if !is_set {
1214 if let Ok(Some(def_field)) = peek_enum.field(index) {
1215 wip.begin_nth_field(index)
1216 .map_err(|e| self.reflect_err(e))?;
1217 wip.set_from_peek(&def_field)
1218 .map_err(|e| self.reflect_err(e))?;
1219 wip.end().map_err(|e| self.reflect_err(e))?;
1220 }
1221 }
1222 }
1223 }
1224 } else {
1225 for (index, field) in variant.data.fields.iter().enumerate() {
1227 let is_set = wip.is_field_set(index).map_err(|err| {
1228 trace!("Error checking field set status: {:?}", err);
1229 self.reflect_err(err)
1230 })?;
1231 if !is_set {
1232 return Err(self.reflect_err(
1233 ReflectError::UninitializedEnumField {
1234 shape: container_shape,
1235 variant_name: variant.name,
1236 field_name: field.name,
1237 },
1238 ));
1239 }
1240 }
1241 }
1242 }
1243 }
1244 } else if container_shape.has_default_attr() {
1245 trace!("No variant selected but enum has DEFAULT attr; setting to default");
1247 let default_val = Partial::alloc_shape(container_shape)
1248 .map_err(|e| self.reflect_err(e))?
1249 .set_default()
1250 .map_err(|e| self.reflect_err(e))?
1251 .build()
1252 .map_err(|e| self.reflect_err(e))?;
1253
1254 let peek = default_val.peek();
1255 let peek_enum = peek.into_enum().map_err(|e| self.reflect_err(e))?;
1256 let default_variant_idx = peek_enum
1257 .variant_index()
1258 .map_err(|e| self.err(DeserErrorKind::VariantError(e)))?;
1259
1260 wip.select_nth_variant(default_variant_idx)
1262 .map_err(|e| self.reflect_err(e))?;
1263
1264 let variant = &ed.variants[default_variant_idx];
1266 for (index, _field) in variant.data.fields.iter().enumerate() {
1267 if let Ok(Some(def_field)) = peek_enum.field(index) {
1268 wip.begin_nth_field(index)
1269 .map_err(|e| self.reflect_err(e))?;
1270 wip.set_from_peek(&def_field)
1271 .map_err(|e| self.reflect_err(e))?;
1272 wip.end().map_err(|e| self.reflect_err(e))?;
1273 }
1274 }
1275 }
1276 }
1277 _ => {
1278 trace!(
1279 "Thing being popped is not a container I guess (it's a {}, innermost is {})",
1280 wip.shape(),
1281 wip.innermost_shape()
1282 );
1283 }
1284 }
1285 Ok(wip)
1286 }
1287
1288 fn set_numeric_value<'facet, N>(
1291 &self,
1292 wip: &mut Partial<'facet, 'shape>,
1293 value: N,
1294 ) -> Result<(), DeserError<'input, 'shape, C>>
1295 where
1296 'input: 'facet,
1297 N: NumericConvert,
1298 {
1299 let shape = wip.innermost_shape();
1300
1301 if let Def::Scalar(sd) = shape.def {
1303 if let ScalarAffinity::Number(num_affinity) = sd.affinity {
1304 use facet_core::{IntegerSize, NumberBits, Signedness};
1305
1306 macro_rules! convert_and_set {
1308 ($converter:expr, $target_type:expr) => {{
1309 let converted = $converter(value).ok_or_else(|| {
1310 self.err(DeserErrorKind::NumericConversion {
1311 from: N::TYPE_NAME,
1312 to: $target_type,
1313 })
1314 })?;
1315 wip.set(converted).map_err(|e| self.reflect_err(e))?;
1316 }};
1317 }
1318
1319 match num_affinity.bits {
1321 NumberBits::Integer { size, sign } => {
1322 match (size, sign) {
1324 (IntegerSize::Fixed(bits), Signedness::Signed) => match bits {
1325 8 => convert_and_set!(N::to_i8, "i8"),
1326 16 => convert_and_set!(N::to_i16, "i16"),
1327 32 => convert_and_set!(N::to_i32, "i32"),
1328 64 => convert_and_set!(N::to_i64, "i64"),
1329 128 => convert_and_set!(N::to_i128, "i128"),
1330 _ => {
1331 return Err(self.err(DeserErrorKind::NumericConversion {
1332 from: N::TYPE_NAME,
1333 to: "unknown fixed-size signed integer",
1334 }));
1335 }
1336 },
1337 (IntegerSize::Fixed(bits), Signedness::Unsigned) => match bits {
1338 8 => convert_and_set!(N::to_u8, "u8"),
1339 16 => convert_and_set!(N::to_u16, "u16"),
1340 32 => convert_and_set!(N::to_u32, "u32"),
1341 64 => convert_and_set!(N::to_u64, "u64"),
1342 128 => convert_and_set!(N::to_u128, "u128"),
1343 _ => {
1344 return Err(self.err(DeserErrorKind::NumericConversion {
1345 from: N::TYPE_NAME,
1346 to: "unknown fixed-size unsigned integer",
1347 }));
1348 }
1349 },
1350 (IntegerSize::PointerSized, Signedness::Signed) => {
1351 convert_and_set!(N::to_isize, "isize")
1352 }
1353 (IntegerSize::PointerSized, Signedness::Unsigned) => {
1354 convert_and_set!(N::to_usize, "usize")
1355 }
1356 }
1357 }
1358 NumberBits::Float {
1359 sign_bits,
1360 exponent_bits,
1361 mantissa_bits,
1362 ..
1363 } => {
1364 let total_bits = sign_bits + exponent_bits + mantissa_bits;
1366 match total_bits {
1367 32 => convert_and_set!(N::to_f32, "f32"),
1368 64 => convert_and_set!(N::to_f64, "f64"),
1369 _ => {
1370 return Err(self.err(DeserErrorKind::NumericConversion {
1372 from: N::TYPE_NAME,
1373 to: "unknown float size",
1374 }));
1375 }
1376 }
1377 }
1378 _ => {
1379 return Err(self.err(DeserErrorKind::NumericConversion {
1381 from: N::TYPE_NAME,
1382 to: "fixed-point or decimal",
1383 }));
1384 }
1385 }
1386 } else {
1387 return Err(self.err(DeserErrorKind::UnsupportedType {
1389 got: shape,
1390 wanted: "numeric type",
1391 }));
1392 }
1393 } else {
1394 return Err(self.err(DeserErrorKind::UnsupportedType {
1396 got: shape,
1397 wanted: "scalar type",
1398 }));
1399 }
1400
1401 Ok(())
1402 }
1403
1404 fn handle_scalar<'facet>(
1405 &self,
1406 wip: &mut Partial<'facet, 'shape>,
1407 scalar: Scalar<'input>,
1408 ) -> Result<(), DeserError<'input, 'shape, C>>
1409 where
1410 'input: 'facet, {
1412 match scalar {
1413 Scalar::String(cow) => {
1414 match wip.innermost_shape().ty {
1415 Type::User(UserType::Enum(_)) => {
1416 if wip.selected_variant().is_some() {
1417 wip.set(cow).map_err(|e| self.reflect_err(e))?;
1419 } else {
1420 match wip.find_variant(&cow) {
1422 Some((variant_index, _)) => {
1423 wip.select_nth_variant(variant_index)
1424 .map_err(|e| self.reflect_err(e))?;
1425 }
1426 None => {
1427 return Err(self.err(DeserErrorKind::NoSuchVariant {
1428 name: cow.to_string(),
1429 enum_shape: wip.innermost_shape(),
1430 }));
1431 }
1432 }
1433 }
1434 }
1435 Type::Pointer(PointerType::Reference(_))
1436 if wip.innermost_shape().is_type::<&str>() =>
1437 {
1438 match cow {
1441 Cow::Borrowed(s) => wip.set(s).map_err(|e| self.reflect_err(e))?,
1442 Cow::Owned(s) => wip.set(s).map_err(|e| self.reflect_err(e))?,
1443 }; }
1445 _ => {
1446 let shape = wip.innermost_shape();
1448 if let Def::Scalar(scalar_def) = shape.def {
1449 if !matches!(scalar_def.affinity, facet_core::ScalarAffinity::String(_))
1452 {
1453 match wip.parse_from_str(cow.as_ref()) {
1455 Ok(_) => {
1456 }
1458 Err(parse_err) => {
1459 match parse_err {
1462 ReflectError::OperationFailed {
1463 shape: _,
1464 operation,
1465 } if operation.contains("does not support parsing") => {
1466 wip.set(cow.to_string())
1468 .map_err(|e| self.reflect_err(e))?;
1469 }
1470 _ => {
1471 return Err(self.err(DeserErrorKind::ReflectError(
1473 ReflectError::OperationFailed {
1474 shape,
1475 operation: "Failed to parse string value",
1476 }
1477 )));
1478 }
1479 }
1480 }
1481 }
1482 } else {
1483 wip.set(cow.to_string()).map_err(|e| self.reflect_err(e))?;
1485 }
1486 } else {
1487 wip.set(cow.to_string()).map_err(|e| self.reflect_err(e))?;
1489 }
1490 }
1491 }
1492 }
1493 Scalar::U64(value) => {
1494 self.set_numeric_value(wip, value)?;
1495 }
1496 Scalar::I64(value) => {
1497 self.set_numeric_value(wip, value)?;
1498 }
1499 Scalar::F64(value) => {
1500 self.set_numeric_value(wip, value)?;
1501 }
1502 Scalar::U128(value) => {
1503 self.set_numeric_value(wip, value)?;
1504 }
1505 Scalar::I128(value) => {
1506 self.set_numeric_value(wip, value)?;
1507 }
1508 Scalar::Bool(value) => {
1509 wip.set(value).map_err(|e| self.reflect_err(e))?;
1510 }
1511 Scalar::Null => {
1512 wip.set_default().map_err(|e| self.reflect_err(e))?;
1513 }
1514 }
1515 Ok(())
1516 }
1517
1518 fn value<'facet>(
1520 &mut self,
1521 mut wip: Partial<'facet, 'shape>,
1522 outcome: Spanned<Outcome<'input>, C>,
1523 ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape, C>>
1524 where
1525 'input: 'facet, {
1527 trace!(
1528 "--- STACK has {:?} {}",
1529 self.stack.green(),
1530 "(VALUE)".bright_yellow()
1531 );
1532
1533 let original_shape = wip.shape();
1534 trace!("Handling value of type {}", original_shape.blue());
1535
1536 if matches!(outcome.node, Outcome::Scalar(Scalar::Null)) {
1538 wip.set_default().map_err(|e| self.reflect_err(e))?;
1539 return Ok(wip);
1540 }
1541
1542 loop {
1544 if matches!(wip.shape().def, Def::Option(_)) {
1545 trace!(" Starting Some(_) option for {}", wip.shape().blue());
1546 wip.begin_some().map_err(|e| self.reflect_err(e))?;
1547 self.stack.push(Instruction::Pop(PopReason::Some));
1548 } else if let Def::SmartPointer(inner) = wip.shape().def {
1549 if let Some(pointee) = inner.pointee() {
1550 trace!(
1551 " Starting smart pointer for {} (pointee is {})",
1552 wip.shape().blue(),
1553 pointee.yellow(),
1554 );
1555 } else {
1556 trace!(
1557 " Starting smart pointer for {} (no pointee)",
1558 wip.shape().blue()
1559 );
1560 }
1561 wip.begin_smart_ptr().map_err(|e| self.reflect_err(e))?;
1562 self.stack.push(Instruction::Pop(PopReason::SmartPointer));
1563 } else if let Some(inner_fn) = wip.shape().inner {
1564 let inner = inner_fn();
1565 trace!(
1566 " Starting wrapped value for {} (inner is {})",
1567 wip.shape().blue(),
1568 inner.yellow()
1569 );
1570 wip.begin_inner().map_err(|e| self.reflect_err(e))?;
1571 self.stack.push(Instruction::Pop(PopReason::Wrapper));
1572 } else {
1573 break;
1574 }
1575 }
1576
1577 if wip.shape() != original_shape {
1578 trace!(
1579 "Handling shape {} as innermost {}",
1580 original_shape.blue(),
1581 wip.shape().yellow()
1582 );
1583 }
1584
1585 match outcome.node {
1586 Outcome::Scalar(s) => {
1587 trace!("Parsed scalar value: {}", s.cyan());
1588 self.handle_scalar(&mut wip, s)?;
1589 }
1590 Outcome::ListStarted => {
1591 let shape = wip.innermost_shape();
1592
1593 if let Type::User(UserType::Struct(st)) = shape.ty {
1595 if st.kind == StructKind::Tuple {
1596 trace!(
1597 "Array starting for tuple struct ({}) with {} fields!",
1598 shape.blue(),
1599 st.fields.len()
1600 );
1601
1602 trace!("Beginning pushback");
1604 self.stack.push(Instruction::ListItemOrListClose);
1605 return Ok(wip);
1606 }
1607 }
1608
1609 match shape.def {
1610 Def::Array(_) => {
1611 trace!("Array starting for array ({})!", shape.blue());
1612 }
1615 Def::Slice(_) => {
1616 trace!("Array starting for slice ({})!", shape.blue());
1617 }
1618 Def::List(_) => {
1619 trace!("Array starting for list ({})!", shape.blue());
1620 wip.set_default().map_err(|e| self.reflect_err(e))?;
1621 }
1622 _ => {
1623 if let Type::User(user_ty) = shape.ty {
1625 match user_ty {
1626 UserType::Enum(_) => {
1627 trace!("Array starting for enum ({})!", shape.blue());
1628 if let Some(variant) = wip.selected_variant() {
1630 use facet_core::StructKind;
1631 if variant.data.kind == StructKind::Tuple {
1632 self.enum_tuple_field_count =
1635 Some(variant.data.fields.len());
1636 self.enum_tuple_current_field = Some(0);
1637 } else {
1638 return Err(self.err(DeserErrorKind::UnsupportedType {
1639 got: shape,
1640 wanted: "tuple variant for array deserialization",
1641 }));
1642 }
1643 } else {
1644 return Err(self.err(DeserErrorKind::UnsupportedType {
1645 got: shape,
1646 wanted: "enum with variant selected",
1647 }));
1648 }
1649 }
1650 UserType::Struct(_) => {
1651 return Err(self.err(DeserErrorKind::UnsupportedType {
1654 got: shape,
1655 wanted: "array, list, tuple, or slice",
1656 }));
1657 }
1658 _ => {
1659 return Err(self.err(DeserErrorKind::UnsupportedType {
1660 got: shape,
1661 wanted: "array, list, tuple, or slice",
1662 }));
1663 }
1664 }
1665 } else {
1666 return Err(self.err(DeserErrorKind::UnsupportedType {
1667 got: shape,
1668 wanted: "array, list, tuple, or slice",
1669 }));
1670 }
1671 }
1672 }
1673 trace!("Beginning pushback");
1674 self.stack.push(Instruction::ListItemOrListClose);
1675
1676 match shape.def {
1678 Def::List(_) => {
1679 wip.begin_list().map_err(|e| self.reflect_err(e))?;
1680 }
1681 Def::Array(_) => {
1682 self.array_indices.push(0);
1685 }
1686 Def::Slice(_) => {
1687 }
1690 _ => {
1691 }
1693 }
1694 }
1695 Outcome::ListEnded => {
1696 trace!("List closing");
1697 let shape = wip.shape();
1699 if matches!(shape.def, Def::Array(_)) {
1700 self.array_indices.pop();
1701 }
1702 wip.end().map_err(|e| self.reflect_err(e))?;
1703 }
1704 Outcome::ObjectStarted => {
1705 let shape = wip.shape();
1706 match shape.def {
1707 Def::Map(_md) => {
1708 trace!("Object starting for map value ({})!", shape.blue());
1709 wip.begin_map().map_err(|e| self.reflect_err(e))?;
1710 }
1711 _ => {
1712 if let Type::User(user_ty) = shape.ty {
1714 match user_ty {
1715 UserType::Enum(_) => {
1716 trace!("Object starting for enum value ({})!", shape.blue());
1717 }
1719 UserType::Struct(_) => {
1720 trace!("Object starting for struct value ({})!", shape.blue());
1721 }
1723 _ => {
1724 return Err(self.err(DeserErrorKind::UnsupportedType {
1725 got: shape,
1726 wanted: "map, enum, or struct",
1727 }));
1728 }
1729 }
1730 } else if let Type::User(UserType::Struct(struct_type)) = shape.ty {
1731 if struct_type.kind == StructKind::Tuple {
1732 trace!(
1735 "Object starting for tuple ({}) with {} fields - unusual but handling",
1736 shape.blue(),
1737 struct_type.fields.len()
1738 );
1739 }
1741 } else {
1742 return Err(self.err(DeserErrorKind::UnsupportedType {
1743 got: shape,
1744 wanted: "map, enum, struct, or tuple",
1745 }));
1746 }
1747 }
1748 }
1749
1750 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1751 }
1752 Outcome::Resegmented(subspans) => {
1753 trace!("Resegmented with {} subspans (value)", subspans.len());
1754 }
1761 Outcome::ObjectEnded => todo!(),
1762 }
1763 Ok(wip)
1764 }
1765
1766 fn object_key_or_object_close<'facet>(
1767 &mut self,
1768 mut wip: Partial<'facet, 'shape>,
1769 outcome: Spanned<Outcome<'input>, C>,
1770 ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape, C>>
1771 where
1772 'input: 'facet,
1773 {
1774 trace!(
1775 "STACK: {:?} {}",
1776 self.stack.green(),
1777 "(OK/OC)".bright_yellow()
1778 );
1779 trace!("SUBSTACK: {:?}", self.substack.get().bright_green());
1780 match outcome.node {
1781 Outcome::Scalar(Scalar::String(key)) => {
1782 trace!("Parsed object key: {}", key.cyan());
1783
1784 let mut ignore = false;
1785 let mut needs_pop = true;
1786 let mut handled_by_flatten = false;
1787 let has_substack = !self.substack.get().is_empty();
1788
1789 let shape = wip.innermost_shape();
1790 match shape.ty {
1791 Type::User(UserType::Struct(sd)) => {
1792 if let Some(index) = wip.field_index(&key) {
1794 trace!("It's a struct field");
1795 wip.begin_nth_field(index)
1796 .map_err(|e| self.reflect_err(e))?;
1797 } else {
1798 trace!(
1799 "Did not find direct field match in innermost shape {}",
1800 shape.blue()
1801 );
1802
1803 let mut found_in_flatten = false;
1805 for (index, field) in sd.fields.iter().enumerate() {
1806 if field.flags.contains(FieldFlags::FLATTEN) {
1807 trace!("Found flattened field #{}", index);
1808 wip.begin_nth_field(index)
1810 .map_err(|e| self.reflect_err(e))?;
1811
1812 if let Some(subfield_index) = wip.field_index(&key) {
1814 trace!("Found key {} in flattened field", key);
1815 wip.begin_nth_field(subfield_index)
1816 .map_err(|e| self.reflect_err(e))?;
1817 found_in_flatten = true;
1818 handled_by_flatten = true;
1819 break;
1820 } else if let Some((_variant_index, _variant)) =
1821 wip.find_variant(&key)
1822 {
1823 trace!("Found key {} in flattened field", key);
1824 wip.select_variant_named(&key)
1825 .map_err(|e| self.reflect_err(e))?;
1826 found_in_flatten = true;
1827 break;
1828 } else {
1829 wip.end().map_err(|e| self.reflect_err(e))?;
1831 }
1832 }
1833 }
1834
1835 if !found_in_flatten {
1836 if wip.shape().has_deny_unknown_fields_attr() {
1837 trace!(
1838 "It's not a struct field AND we're denying unknown fields"
1839 );
1840 return Err(self.err(DeserErrorKind::UnknownField {
1841 field_name: key.to_string(),
1842 shape: wip.shape(),
1843 }));
1844 } else {
1845 trace!(
1846 "It's not a struct field and we're ignoring unknown fields"
1847 );
1848 ignore = true;
1849 }
1850 }
1851 }
1852 }
1853 Type::User(UserType::Enum(_ed)) => match wip.find_variant(&key) {
1854 Some((index, variant)) => {
1855 trace!(
1856 "Selecting variant {}::{}",
1857 wip.shape().blue(),
1858 variant.name.yellow(),
1859 );
1860 wip.select_nth_variant(index)
1861 .map_err(|e| self.reflect_err(e))?;
1862
1863 if matches!(variant.data.kind, StructKind::Tuple)
1865 && variant.data.fields.len() == 1
1866 {
1867 trace!(
1868 "Tuple variant {}::{} encountered, pushing field 0",
1869 wip.shape().blue(),
1870 variant.name.yellow()
1871 );
1872 wip.begin_nth_field(0).map_err(|e| self.reflect_err(e))?;
1873 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1874 }
1875
1876 needs_pop = false;
1877 }
1878 None => {
1879 if let Some(_variant_index) = wip.selected_variant() {
1880 trace!(
1881 "Already have a variant selected, treating {} as struct field of {}::{}",
1882 key,
1883 wip.shape().blue(),
1884 wip.selected_variant().unwrap().name.yellow(),
1885 );
1886 if let Some(index) = wip.field_index(&key) {
1888 trace!("Found field {} in selected variant", key.blue());
1889 wip.begin_nth_field(index)
1890 .map_err(|e| self.reflect_err(e))?;
1891 } else if wip.shape().has_deny_unknown_fields_attr() {
1892 trace!("Unknown field in variant and denying unknown fields");
1893 return Err(self.err(DeserErrorKind::UnknownField {
1894 field_name: key.to_string(),
1895 shape: wip.shape(),
1896 }));
1897 } else {
1898 trace!(
1899 "Ignoring unknown field '{}' in variant '{}::{}'",
1900 key,
1901 wip.shape(),
1902 wip.selected_variant().unwrap().name
1903 );
1904 ignore = true;
1905 }
1906 } else {
1907 return Err(self.err(DeserErrorKind::NoSuchVariant {
1908 name: key.to_string(),
1909 enum_shape: wip.shape(),
1910 }));
1911 }
1912 }
1913 },
1914 _ => {
1915 if let Def::Map(map_def) = shape.def {
1917 wip.begin_key().map_err(|e| self.reflect_err(e))?;
1918
1919 let key_shape = map_def.k();
1921 if key_shape.inner.is_some() {
1922 wip.begin_inner().map_err(|e| self.reflect_err(e))?;
1926 wip.set(key.to_string()).map_err(|e| self.reflect_err(e))?;
1927 wip.end().map_err(|e| self.reflect_err(e))?; } else {
1929 wip.set(key.to_string()).map_err(|e| self.reflect_err(e))?;
1931 }
1932
1933 wip.end().map_err(|e| self.reflect_err(e))?; wip.begin_value().map_err(|e| self.reflect_err(e))?;
1935 } else {
1936 return Err(self.err(DeserErrorKind::Unimplemented(
1937 "object key for non-struct/map",
1938 )));
1939 }
1940 }
1941 }
1942
1943 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1944 if ignore {
1945 self.stack.push(Instruction::SkipValue);
1946 } else {
1947 if needs_pop && !handled_by_flatten {
1948 trace!("Pushing Pop insn to stack (ObjectVal)");
1949 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1950 if has_substack {
1951 trace!("Pushing SubstackClose insn to stack");
1952 self.stack.push(Instruction::SubstackClose);
1953 }
1954 } else if handled_by_flatten {
1955 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
1958 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
1959 if has_substack {
1960 trace!("Pushing SubstackClose insn to stack");
1961 self.stack.push(Instruction::SubstackClose);
1962 }
1963 }
1964 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
1965 }
1966 Ok(wip)
1967 }
1968 Outcome::ObjectEnded => {
1969 trace!("Object closing");
1970 Ok(wip)
1971 }
1972 Outcome::Resegmented(subspans) => {
1973 trace!(
1974 "Resegmented into {} subspans ({:?}) - obj. key/close",
1975 subspans.len(),
1976 subspans
1977 );
1978 self.stack.push(Instruction::ObjectKeyOrObjectClose);
1980 Ok(wip)
1981 }
1982 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
1983 got: outcome.node.into_owned(),
1984 wanted: "scalar or object close",
1985 })),
1986 }
1987 }
1988
1989 fn list_item_or_list_close<'facet>(
1990 &mut self,
1991 mut wip: Partial<'facet, 'shape>,
1992 outcome: Spanned<Outcome<'input>, C>,
1993 ) -> Result<Partial<'facet, 'shape>, DeserError<'input, 'shape, C>>
1994 where
1995 'input: 'facet,
1996 {
1997 trace!(
1998 "--- STACK has {:?} {}",
1999 self.stack.green(),
2000 "(LI/LC)".bright_yellow()
2001 );
2002 match outcome.node {
2003 Outcome::ListEnded => {
2004 trace!("List close");
2005 let shape = wip.shape();
2007 if matches!(shape.def, Def::Array(_)) {
2008 self.array_indices.pop();
2009 }
2010
2011 if let Type::User(UserType::Enum(_)) = shape.ty {
2013 if self.enum_tuple_field_count.is_some() {
2014 trace!("Enum tuple variant list ended");
2015 self.enum_tuple_field_count = None;
2016 self.enum_tuple_current_field = None;
2017 }
2018 }
2019
2020 if let Type::User(UserType::Struct(st)) = shape.ty {
2022 if st.kind == StructKind::Tuple && st.fields.is_empty() {
2023 trace!("Empty tuple parsed from []");
2024 }
2026 }
2027
2028 Ok(wip)
2030 }
2031 _ => {
2032 self.stack.push(Instruction::ListItemOrListClose);
2033 self.stack.push(Instruction::Pop(PopReason::ListVal));
2034
2035 trace!(
2036 "Expecting list item, doing a little push before doing value with outcome {}",
2037 outcome.magenta()
2038 );
2039 trace!("Before push, wip.shape is {}", wip.shape().blue());
2040
2041 let shape = wip.shape();
2043 match shape.def {
2044 Def::Array(ad) => {
2045 if let Some(current_index) = self.array_indices.last().copied() {
2047 if current_index >= ad.n {
2049 return Err(self.err(DeserErrorKind::ArrayOverflow {
2050 shape,
2051 max_len: ad.n,
2052 }));
2053 }
2054
2055 wip.begin_nth_element(current_index)
2057 .map_err(|e| self.reflect_err(e))?;
2058
2059 if let Some(last) = self.array_indices.last_mut() {
2061 *last += 1;
2062 }
2063 } else {
2064 return Err(self.err(DeserErrorKind::Unimplemented(
2066 "Array index tracking not initialized",
2067 )));
2068 }
2069 }
2070 Def::List(_) => {
2071 wip.begin_list_item().map_err(|e| self.reflect_err(e))?;
2072 }
2073 _ => {
2074 if let Type::User(UserType::Enum(_)) = shape.ty {
2076 if let (Some(field_count), Some(current_field)) =
2077 (self.enum_tuple_field_count, self.enum_tuple_current_field)
2078 {
2079 if current_field >= field_count {
2080 return Err(self.err(DeserErrorKind::ArrayOverflow {
2082 shape,
2083 max_len: field_count,
2084 }));
2085 }
2086
2087 wip.begin_nth_enum_field(current_field)
2089 .map_err(|e| self.reflect_err(e))?;
2090
2091 self.enum_tuple_current_field = Some(current_field + 1);
2093 } else {
2094 return Err(self.err(DeserErrorKind::UnsupportedType {
2095 got: shape,
2096 wanted: "enum with tuple variant selected",
2097 }));
2098 }
2099 }
2100 else if let Type::User(UserType::Struct(struct_type)) = shape.ty {
2102 if struct_type.kind == StructKind::Tuple {
2103 let mut field_index = None;
2106 for i in 0..struct_type.fields.len() {
2107 if !wip.is_field_set(i).map_err(|e| self.reflect_err(e))? {
2108 field_index = Some(i);
2109 break;
2110 }
2111 }
2112
2113 if let Some(idx) = field_index {
2114 wip.begin_nth_field(idx).map_err(|e| self.reflect_err(e))?;
2115 } else {
2116 return Err(self.err(DeserErrorKind::ArrayOverflow {
2118 shape,
2119 max_len: struct_type.fields.len(),
2120 }));
2121 }
2122 } else {
2123 return Err(self.err(DeserErrorKind::UnsupportedType {
2125 got: shape,
2126 wanted: "array, list, or tuple",
2127 }));
2128 }
2129 } else {
2130 return Err(self.err(DeserErrorKind::UnsupportedType {
2132 got: shape,
2133 wanted: "array, list, or tuple",
2134 }));
2135 }
2136 }
2137 }
2138
2139 trace!(" After push, wip.shape is {}", wip.shape().cyan());
2140
2141 if matches!(outcome.node, Outcome::ListStarted) {
2144 if let Type::User(UserType::Struct(st)) = wip.shape().ty {
2145 if st.kind == StructKind::Tuple && st.fields.is_empty() {
2146 trace!(
2147 "Empty tuple field with list start - initializing empty tuple and expecting immediate close"
2148 );
2149 wip.set_default().map_err(|e| self.reflect_err(e))?;
2151 }
2153 }
2154 }
2155
2156 wip = self.value(wip, outcome)?;
2157 Ok(wip)
2158 }
2159 }
2160 }
2161}