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};
12
13mod error;
14use alloc::borrow::Cow;
15
16pub use error::*;
17
18mod span;
19use facet_core::{Characteristic, Def, Facet, FieldFlags, ScalarAffinity};
20use owo_colors::OwoColorize;
21pub use span::*;
22
23use facet_reflect::{HeapValue, ReflectError, Wip};
24use log::trace;
25
26#[derive(PartialEq, Debug, Clone)]
27pub enum Scalar<'input> {
32 String(Cow<'input, str>),
34 U64(u64),
36 I64(i64),
38 F64(f64),
40 Bool(bool),
42 Null,
44}
45
46#[derive(PartialEq, Debug, Clone)]
47pub enum Expectation {
49 Value,
51 ObjectKeyOrObjectClose,
53 ObjectVal,
55 ListItemOrListClose,
57}
58
59#[derive(PartialEq, Debug, Clone)]
60pub enum Outcome<'input> {
62 Scalar(Scalar<'input>),
64 ListStarted,
66 ListEnded,
68 ObjectStarted,
70 ObjectEnded,
72}
73
74impl<'input> From<Scalar<'input>> for Outcome<'input> {
75 fn from(scalar: Scalar<'input>) -> Self {
76 Outcome::Scalar(scalar)
77 }
78}
79
80use core::fmt;
81
82impl fmt::Display for Outcome<'_> {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 Outcome::Scalar(scalar) => write!(f, "scalar {}", scalar),
87 Outcome::ListStarted => write!(f, "list start"),
88 Outcome::ListEnded => write!(f, "list end"),
89 Outcome::ObjectStarted => write!(f, "object start"),
90 Outcome::ObjectEnded => write!(f, "object end"),
91 }
92 }
93}
94
95impl fmt::Display for Scalar<'_> {
97 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
98 match self {
99 Scalar::String(s) => write!(f, "string \"{}\"", s),
100 Scalar::U64(val) => write!(f, "u64 {}", val),
101 Scalar::I64(val) => write!(f, "i64 {}", val),
102 Scalar::F64(val) => write!(f, "f64 {}", val),
103 Scalar::Bool(val) => write!(f, "bool {}", val),
104 Scalar::Null => write!(f, "null"),
105 }
106 }
107}
108
109impl Outcome<'_> {
110 fn into_owned(self) -> Outcome<'static> {
111 match self {
112 Outcome::Scalar(scalar) => {
113 let owned_scalar = match scalar {
114 Scalar::String(cow) => Scalar::String(Cow::Owned(cow.into_owned())),
115 Scalar::U64(val) => Scalar::U64(val),
116 Scalar::I64(val) => Scalar::I64(val),
117 Scalar::F64(val) => Scalar::F64(val),
118 Scalar::Bool(val) => Scalar::Bool(val),
119 Scalar::Null => Scalar::Null,
120 };
121 Outcome::Scalar(owned_scalar)
122 }
123 Outcome::ListStarted => Outcome::ListStarted,
124 Outcome::ListEnded => Outcome::ListEnded,
125 Outcome::ObjectStarted => Outcome::ObjectStarted,
126 Outcome::ObjectEnded => Outcome::ObjectEnded,
127 }
128 }
129}
130
131pub struct NextData<'input: 'facet, 'facet> {
134 start: usize,
136
137 runner: StackRunner<'input>,
139
140 pub wip: Wip<'facet>,
142}
143
144impl<'input: 'facet, 'facet> NextData<'input, 'facet> {
145 pub fn input(&self) -> &'input [u8] {
147 self.runner.input
148 }
149
150 pub fn start(&self) -> usize {
152 self.start
153 }
154}
155
156pub type NextResult<'input, 'facet, T, E> = (NextData<'input, 'facet>, Result<T, E>);
158
159pub trait Format {
162 fn next<'input, 'facet>(
164 nd: NextData<'input, 'facet>,
165 expectation: Expectation,
166 ) -> NextResult<'input, 'facet, Spanned<Outcome<'input>>, Spanned<DeserErrorKind>>;
167
168 fn skip<'input, 'facet>(
170 nd: NextData<'input, 'facet>,
171 ) -> NextResult<'input, 'facet, Span, Spanned<DeserErrorKind>>;
172}
173
174#[derive(Debug, Clone, Copy, PartialEq, Eq)]
176pub enum Instruction {
177 Value(ValueReason),
179 SkipValue,
181 Pop(PopReason),
183 ObjectKeyOrObjectClose,
185 ListItemOrListClose,
187}
188
189#[derive(Debug, Clone, Copy, PartialEq, Eq)]
191pub enum ValueReason {
192 TopLevel,
194 ObjectVal,
196}
197
198#[derive(Debug, Clone, Copy, PartialEq, Eq)]
200pub enum PopReason {
201 TopLevel,
203 ObjectVal,
205 ListVal,
207 Some,
209}
210
211pub fn deserialize<'input, 'facet, T, F>(input: &'input [u8]) -> Result<T, DeserError<'input>>
216where
217 T: Facet<'facet>,
218 F: Format,
219 'input: 'facet,
220{
221 let wip = Wip::alloc_shape(T::SHAPE).map_err(|e| DeserError {
222 input: input.into(),
223 span: Span { start: 0, len: 0 },
224 kind: DeserErrorKind::ReflectError(e),
225 })?;
226 deserialize_wip::<F>(wip, input)?
227 .materialize()
228 .map_err(|e| DeserError::new_reflect(e, input, Span { start: 0, len: 0 }))
229}
230
231pub fn deserialize_wip<'input, 'facet, F>(
234 mut wip: Wip<'facet>,
235 input: &'input [u8],
236) -> Result<HeapValue<'facet>, DeserError<'input>>
237where
238 F: Format,
239 'input: 'facet,
240{
241 let mut runner = StackRunner {
243 original_input: input,
244 input,
245 stack: vec![
246 Instruction::Pop(PopReason::TopLevel),
247 Instruction::Value(ValueReason::TopLevel),
248 ],
249 last_span: Span::new(0, 0),
250 };
251
252 macro_rules! next {
253 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
254 let nd = NextData {
255 start: $runner.last_span.end(), runner: $runner,
257 wip: $wip,
258 };
259 let (nd, res) = F::next(nd, $expectation);
260 $runner = nd.runner;
261 $wip = nd.wip;
262 let outcome = res.map_err(|span_kind| {
263 $runner.last_span = span_kind.span;
264 $runner.err(span_kind.node)
265 })?;
266 $runner.last_span = outcome.span;
267 trace!("Got outcome {}", outcome.blue());
268 $wip = $runner.$method($wip, outcome)?;
269 }};
270 }
271
272 loop {
273 let frame_count = wip.frames_count();
274 debug_assert!(
275 frame_count
276 >= runner
277 .stack
278 .iter()
279 .filter(|f| matches!(f, Instruction::Pop(_)))
280 .count()
281 );
282
283 let insn = match runner.stack.pop() {
284 Some(insn) => insn,
285 None => unreachable!("Instruction stack is empty"),
286 };
287
288 trace!("[{frame_count}] Instruction {:?}", insn.yellow());
289
290 match insn {
291 Instruction::Pop(reason) => {
292 wip = runner.pop(wip, reason)?;
293
294 if reason == PopReason::TopLevel {
295 return wip.build().map_err(|e| runner.reflect_err(e));
296 } else {
297 wip = wip.pop().map_err(|e| runner.reflect_err(e))?;
298 }
299 }
300 Instruction::Value(_why) => {
301 let expectation = match _why {
302 ValueReason::TopLevel => Expectation::Value,
303 ValueReason::ObjectVal => Expectation::ObjectVal,
304 };
305 next!(runner, wip, expectation, value);
306 }
307 Instruction::ObjectKeyOrObjectClose => {
308 next!(
309 runner,
310 wip,
311 Expectation::ObjectKeyOrObjectClose,
312 object_key_or_object_close
313 );
314 }
315 Instruction::ListItemOrListClose => {
316 next!(
317 runner,
318 wip,
319 Expectation::ListItemOrListClose,
320 list_item_or_list_close
321 );
322 }
323 Instruction::SkipValue => {
324 let nd = NextData {
326 start: runner.last_span.end(),
327 runner,
328 wip,
329 };
330 let (nd, res) = F::skip(nd);
331 runner = nd.runner;
332 wip = nd.wip;
333 let span = res.map_err(|span_kind| {
335 runner.last_span = span_kind.span;
336 runner.err(span_kind.node)
337 })?;
338 runner.last_span = span;
340 }
341 }
342 }
343}
344
345#[doc(hidden)]
346pub struct StackRunner<'input> {
351 original_input: &'input [u8],
353 pub input: &'input [u8],
355
356 pub stack: Vec<Instruction>,
358 pub last_span: Span,
360}
361
362impl<'input> StackRunner<'input> {
363 fn err(&self, kind: DeserErrorKind) -> DeserError<'input> {
365 DeserError::new(kind, self.original_input, self.last_span)
366 }
367
368 fn reflect_err(&self, err: ReflectError) -> DeserError<'input> {
371 DeserError::new_reflect(err, self.original_input, self.last_span)
372 }
373
374 fn pop<'facet>(
375 &mut self,
376 mut wip: Wip<'facet>,
377 reason: PopReason,
378 ) -> Result<Wip<'facet>, DeserError<'input>> {
379 trace!("Popping because {:?}", reason.yellow());
380
381 let container_shape = wip.shape();
382 match container_shape.def {
383 Def::Struct(sd) => {
384 let mut has_unset = false;
385
386 trace!("Let's check all fields are initialized");
387 for (index, field) in sd.fields.iter().enumerate() {
388 let is_set = wip.is_field_set(index).map_err(|err| {
389 trace!("Error checking field set status: {:?}", err);
390 self.reflect_err(err)
391 })?;
392 if !is_set {
393 if field.flags.contains(FieldFlags::DEFAULT) {
394 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
395 if let Some(default_in_place_fn) = field.vtable.default_fn {
396 wip = wip
397 .put_from_fn(default_in_place_fn)
398 .map_err(|e| self.reflect_err(e))?;
399 trace!(
400 "Field #{} {:?} was set to default value (via custom fn)",
401 index.yellow(),
402 field.blue()
403 );
404 } else {
405 if !field.shape().is(Characteristic::Default) {
406 return Err(self.reflect_err(
407 ReflectError::DefaultAttrButNoDefaultImpl {
408 shape: field.shape(),
409 },
410 ));
411 }
412 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
413 trace!(
414 "Field #{} {:?} was set to default value (via default impl)",
415 index.yellow(),
416 field.blue()
417 );
418 }
419 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
420 } else {
421 trace!(
422 "Field #{} {:?} is not initialized",
423 index.yellow(),
424 field.blue()
425 );
426 has_unset = true;
427 }
428 }
429 }
430
431 if has_unset && container_shape.has_default_attr() {
432 let default_val = Wip::alloc_shape(container_shape)
434 .map_err(|e| self.reflect_err(e))?
435 .put_default()
436 .map_err(|e| self.reflect_err(e))?
437 .build()
438 .map_err(|e| self.reflect_err(e))?;
439 let peek = default_val.peek().into_struct().unwrap();
440
441 for (index, field) in sd.fields.iter().enumerate() {
442 let is_set = wip.is_field_set(index).map_err(|err| {
443 trace!("Error checking field set status: {:?}", err);
444 self.reflect_err(err)
445 })?;
446 if !is_set {
447 let address_of_field_from_default = peek.field(index).unwrap().data();
448 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
449 wip = wip
450 .put_shape(address_of_field_from_default, field.shape())
451 .map_err(|e| self.reflect_err(e))?;
452 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
453 }
454 }
455 }
456 }
457 Def::Enum(_) => {
458 trace!(
459 "TODO: make sure enums are initialized (support container-level and field-level default, etc.)"
460 );
461 }
462 _ => {
463 trace!(
464 "Thing being popped is not a container I guess (it's a {})",
465 wip.shape()
466 );
467 }
468 }
469 Ok(wip)
470 }
471
472 fn handle_scalar<'facet>(
474 &self,
475 wip: Wip<'facet>,
476 scalar: Scalar<'input>,
477 ) -> Result<Wip<'facet>, DeserError<'input>> {
478 match scalar {
479 Scalar::String(cow) => {
480 match wip.innermost_shape().def {
481 Def::Enum(_) => {
482 if wip.selected_variant().is_some() {
483 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
485 } else {
486 match wip.find_variant(&cow) {
488 Some((variant_index, _)) => {
489 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
490 }
491 None => Err(self.err(DeserErrorKind::NoSuchVariant {
492 name: cow.to_string(),
493 enum_shape: wip.innermost_shape(),
494 })),
495 }
496 }
497 }
498 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
499 }
500 }
501 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
502 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
503 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
504 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
505 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
506 }
507 }
508
509 fn value<'facet>(
511 &mut self,
512 mut wip: Wip<'facet>,
513 outcome: Spanned<Outcome<'input>>,
514 ) -> Result<Wip<'facet>, DeserError<'input>> {
515 trace!(
516 "Handling value at wip shape {} (wip innermost shape {})",
517 wip.shape().blue(),
518 wip.innermost_shape().yellow()
519 );
520
521 match outcome.node {
522 Outcome::Scalar(Scalar::Null) => {
523 return wip.put_default().map_err(|e| self.reflect_err(e));
524 }
525 _ => {
526 if matches!(wip.shape().def, Def::Option(_)) {
527 trace!("Starting Some(_) option for {}", wip.shape().blue());
528 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
529 self.stack.push(Instruction::Pop(PopReason::Some));
530 }
531 }
532 }
533
534 match outcome.node {
535 Outcome::Scalar(s) => {
536 wip = self.handle_scalar(wip, s)?;
537 }
538 Outcome::ListStarted => {
539 let shape = wip.innermost_shape();
540 match shape.def {
541 Def::Array(_) => {
542 trace!("Array starting for array ({})!", shape.blue());
543 }
544 Def::Slice(_) => {
545 trace!("Array starting for slice ({})!", shape.blue());
546 }
547 Def::List(_) => {
548 trace!("Array starting for list ({})!", shape.blue());
549 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
550 }
551 Def::Enum(_) => {
552 trace!("Array starting for enum ({})!", shape.blue());
553 }
554 Def::Struct(_) => {
555 trace!("Array starting for tuple ({})!", shape.blue());
556 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
557 }
558 Def::Scalar(sd) => {
559 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
560 trace!("Empty tuple/scalar, nice");
561 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
562 } else {
563 return Err(self.err(DeserErrorKind::UnsupportedType {
564 got: shape,
565 wanted: "array, list, tuple, or slice",
566 }));
567 }
568 }
569 _ => {
570 return Err(self.err(DeserErrorKind::UnsupportedType {
571 got: shape,
572 wanted: "array, list, tuple, or slice",
573 }));
574 }
575 }
576
577 trace!("Beginning pushback");
578 self.stack.push(Instruction::ListItemOrListClose);
579 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
580 }
581 Outcome::ListEnded => {
582 trace!("List closing");
583 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
584 }
585 Outcome::ObjectStarted => {
586 let shape = wip.innermost_shape();
587 match shape.def {
588 Def::Map(_md) => {
589 trace!("Object starting for map value ({})!", shape.blue());
590 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
591 }
592 Def::Enum(_ed) => {
593 trace!("Object starting for enum value ({})!", shape.blue());
594 }
596 Def::Struct(_) => {
597 trace!("Object starting for struct value ({})!", shape.blue());
598 }
600 _ => {
601 return Err(self.err(DeserErrorKind::UnsupportedType {
602 got: shape,
603 wanted: "map, enum, or struct",
604 }));
605 }
606 }
607
608 self.stack.push(Instruction::ObjectKeyOrObjectClose);
609 }
610 Outcome::ObjectEnded => todo!(),
611 }
612 Ok(wip)
613 }
614
615 fn object_key_or_object_close<'facet>(
616 &mut self,
617 mut wip: Wip<'facet>,
618 outcome: Spanned<Outcome<'input>>,
619 ) -> Result<Wip<'facet>, DeserError<'input>>
620 where
621 'input: 'facet,
622 {
623 match outcome.node {
624 Outcome::Scalar(Scalar::String(key)) => {
625 trace!("Parsed object key: {}", key);
626
627 let mut ignore = false;
628 let mut needs_pop = true;
629 let mut handled_by_flatten = false;
630
631 match wip.innermost_shape().def {
632 Def::Struct(sd) => {
633 if let Some(index) = wip.field_index(&key) {
635 trace!("It's a struct field");
636 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
637 } else {
638 let mut found_in_flatten = false;
640 for (index, field) in sd.fields.iter().enumerate() {
641 if field.flags.contains(FieldFlags::FLATTEN) {
642 trace!("Found flattened field #{}", index);
643 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
645
646 if let Some(subfield_index) = wip.field_index(&key) {
648 trace!("Found key {} in flattened field", key);
649 wip = wip
650 .field(subfield_index)
651 .map_err(|e| self.reflect_err(e))?;
652 found_in_flatten = true;
653 handled_by_flatten = true;
654 break;
655 } else if let Some((_variant_index, _variant)) =
656 wip.find_variant(&key)
657 {
658 trace!("Found key {} in flattened field", key);
659 wip = wip
660 .variant_named(&key)
661 .map_err(|e| self.reflect_err(e))?;
662 found_in_flatten = true;
663 break;
664 } else {
665 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
667 }
668 }
669 }
670
671 if !found_in_flatten {
672 if wip.shape().has_deny_unknown_fields_attr() {
673 trace!(
674 "It's not a struct field AND we're denying unknown fields"
675 );
676 return Err(self.err(DeserErrorKind::UnknownField {
677 field_name: key.to_string(),
678 shape: wip.shape(),
679 }));
680 } else {
681 trace!(
682 "It's not a struct field and we're ignoring unknown fields"
683 );
684 ignore = true;
685 }
686 }
687 }
688 }
689 Def::Enum(_ed) => match wip.find_variant(&key) {
690 Some((index, variant)) => {
691 trace!("Variant {} selected", variant.name.blue());
692 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
693 needs_pop = false;
694 }
695 None => {
696 if let Some(_variant_index) = wip.selected_variant() {
697 trace!(
698 "Already have a variant selected, treating key as struct field of variant"
699 );
700 if let Some(index) = wip.field_index(&key) {
702 trace!("Found field {} in selected variant", key.blue());
703 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
704 } else if wip.shape().has_deny_unknown_fields_attr() {
705 trace!("Unknown field in variant and denying unknown fields");
706 return Err(self.err(DeserErrorKind::UnknownField {
707 field_name: key.to_string(),
708 shape: wip.shape(),
709 }));
710 } else {
711 trace!("Ignoring unknown field in variant");
712 ignore = true;
713 }
714 } else {
715 return Err(self.err(DeserErrorKind::NoSuchVariant {
716 name: key.to_string(),
717 enum_shape: wip.shape(),
718 }));
719 }
720 }
721 },
722 Def::Map(_) => {
723 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
724 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
725 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
726 }
727 _ => {
728 return Err(self.err(DeserErrorKind::Unimplemented(
729 "object key for non-struct/map",
730 )));
731 }
732 }
733
734 self.stack.push(Instruction::ObjectKeyOrObjectClose);
735 if ignore {
736 self.stack.push(Instruction::SkipValue);
737 } else {
738 if needs_pop && !handled_by_flatten {
739 trace!("Pushing Pop insn to stack (ObjectVal)");
740 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
741 } else if handled_by_flatten {
742 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
745 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
746 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
747 }
748 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
749 }
750 Ok(wip)
751 }
752 Outcome::ObjectEnded => {
753 trace!("Object closing");
754 Ok(wip)
755 }
756 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
757 got: outcome.node.into_owned(),
758 wanted: "scalar or object close",
759 })),
760 }
761 }
762
763 fn list_item_or_list_close<'facet>(
764 &mut self,
765 mut wip: Wip<'facet>,
766 outcome: Spanned<Outcome<'input>>,
767 ) -> Result<Wip<'facet>, DeserError<'input>>
768 where
769 'input: 'facet,
770 {
771 match outcome.node {
772 Outcome::ListEnded => {
773 trace!("List close");
774 Ok(wip)
775 }
776 _ => {
777 self.stack.push(Instruction::ListItemOrListClose);
778 self.stack.push(Instruction::Pop(PopReason::ListVal));
779
780 trace!(
781 "Expecting list item, doing a little push before doing value with outcome {}",
782 outcome.magenta()
783 );
784 trace!("Before push, wip.shape is {}", wip.shape().blue());
785 wip = wip.push().map_err(|e| self.reflect_err(e))?;
786 trace!(" After push, wip.shape is {}", wip.shape().cyan());
787 wip = self.value(wip, outcome)?;
788 Ok(wip)
789 }
790 }
791 }
792}