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 &mut self,
165 nd: NextData<'input, 'facet>,
166 expectation: Expectation,
167 ) -> NextResult<'input, 'facet, Spanned<Outcome<'input>>, Spanned<DeserErrorKind>>;
168
169 fn skip<'input, 'facet>(
171 &mut self,
172 nd: NextData<'input, 'facet>,
173 ) -> NextResult<'input, 'facet, Span, Spanned<DeserErrorKind>>;
174}
175
176#[derive(Debug, Clone, Copy, PartialEq, Eq)]
178pub enum Instruction {
179 Value(ValueReason),
181 SkipValue,
183 Pop(PopReason),
185 ObjectKeyOrObjectClose,
187 ListItemOrListClose,
189}
190
191#[derive(Debug, Clone, Copy, PartialEq, Eq)]
193pub enum ValueReason {
194 TopLevel,
196 ObjectVal,
198}
199
200#[derive(Debug, Clone, Copy, PartialEq, Eq)]
202pub enum PopReason {
203 TopLevel,
205 ObjectVal,
207 ListVal,
209 Some,
211}
212
213pub fn deserialize<'input, 'facet, T, F>(
218 input: &'input [u8],
219 format: F,
220) -> Result<T, DeserError<'input>>
221where
222 T: Facet<'facet>,
223 F: Format,
224 'input: 'facet,
225{
226 let wip = Wip::alloc_shape(T::SHAPE).map_err(|e| DeserError {
227 input: input.into(),
228 span: Span { start: 0, len: 0 },
229 kind: DeserErrorKind::ReflectError(e),
230 })?;
231 deserialize_wip(wip, input, format)?
232 .materialize()
233 .map_err(|e| DeserError::new_reflect(e, input, Span { start: 0, len: 0 }))
234}
235
236pub fn deserialize_wip<'input, 'facet, F>(
239 mut wip: Wip<'facet>,
240 input: &'input [u8],
241 mut format: F,
242) -> Result<HeapValue<'facet>, DeserError<'input>>
243where
244 F: Format,
245 'input: 'facet,
246{
247 let mut runner = StackRunner {
249 original_input: input,
250 input,
251 stack: vec![
252 Instruction::Pop(PopReason::TopLevel),
253 Instruction::Value(ValueReason::TopLevel),
254 ],
255 last_span: Span::new(0, 0),
256 };
257
258 macro_rules! next {
259 ($runner:ident, $wip:ident, $expectation:expr, $method:ident) => {{
260 let nd = NextData {
261 start: $runner.last_span.end(), runner: $runner,
263 wip: $wip,
264 };
265 let (nd, res) = format.next(nd, $expectation);
266 $runner = nd.runner;
267 $wip = nd.wip;
268 let outcome = res.map_err(|span_kind| {
269 $runner.last_span = span_kind.span;
270 $runner.err(span_kind.node)
271 })?;
272 $runner.last_span = outcome.span;
273 trace!("Got outcome {}", outcome.blue());
274 $wip = $runner.$method($wip, outcome)?;
275 }};
276 }
277
278 loop {
279 let frame_count = wip.frames_count();
280 debug_assert!(
281 frame_count
282 >= runner
283 .stack
284 .iter()
285 .filter(|f| matches!(f, Instruction::Pop(_)))
286 .count()
287 );
288
289 let insn = match runner.stack.pop() {
290 Some(insn) => insn,
291 None => unreachable!("Instruction stack is empty"),
292 };
293
294 trace!("[{frame_count}] Instruction {:?}", insn.yellow());
295
296 match insn {
297 Instruction::Pop(reason) => {
298 wip = runner.pop(wip, reason)?;
299
300 if reason == PopReason::TopLevel {
301 return wip.build().map_err(|e| runner.reflect_err(e));
302 } else {
303 wip = wip.pop().map_err(|e| runner.reflect_err(e))?;
304 }
305 }
306 Instruction::Value(_why) => {
307 let expectation = match _why {
308 ValueReason::TopLevel => Expectation::Value,
309 ValueReason::ObjectVal => Expectation::ObjectVal,
310 };
311 next!(runner, wip, expectation, value);
312 }
313 Instruction::ObjectKeyOrObjectClose => {
314 next!(
315 runner,
316 wip,
317 Expectation::ObjectKeyOrObjectClose,
318 object_key_or_object_close
319 );
320 }
321 Instruction::ListItemOrListClose => {
322 next!(
323 runner,
324 wip,
325 Expectation::ListItemOrListClose,
326 list_item_or_list_close
327 );
328 }
329 Instruction::SkipValue => {
330 let nd = NextData {
332 start: runner.last_span.end(),
333 runner,
334 wip,
335 };
336 let (nd, res) = format.skip(nd);
337 runner = nd.runner;
338 wip = nd.wip;
339 let span = res.map_err(|span_kind| {
341 runner.last_span = span_kind.span;
342 runner.err(span_kind.node)
343 })?;
344 runner.last_span = span;
346 }
347 }
348 }
349}
350
351#[doc(hidden)]
352pub struct StackRunner<'input> {
357 original_input: &'input [u8],
359 pub input: &'input [u8],
361
362 pub stack: Vec<Instruction>,
364 pub last_span: Span,
366}
367
368impl<'input> StackRunner<'input> {
369 fn err(&self, kind: DeserErrorKind) -> DeserError<'input> {
371 DeserError::new(kind, self.original_input, self.last_span)
372 }
373
374 fn reflect_err(&self, err: ReflectError) -> DeserError<'input> {
377 DeserError::new_reflect(err, self.original_input, self.last_span)
378 }
379
380 fn pop<'facet>(
381 &mut self,
382 mut wip: Wip<'facet>,
383 reason: PopReason,
384 ) -> Result<Wip<'facet>, DeserError<'input>> {
385 trace!("Popping because {:?}", reason.yellow());
386
387 let container_shape = wip.shape();
388 match container_shape.def {
389 Def::Struct(sd) => {
390 let mut has_unset = false;
391
392 trace!("Let's check all fields are initialized");
393 for (index, field) in sd.fields.iter().enumerate() {
394 let is_set = wip.is_field_set(index).map_err(|err| {
395 trace!("Error checking field set status: {:?}", err);
396 self.reflect_err(err)
397 })?;
398 if !is_set {
399 if field.flags.contains(FieldFlags::DEFAULT) {
400 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
401 if let Some(default_in_place_fn) = field.vtable.default_fn {
402 wip = wip
403 .put_from_fn(default_in_place_fn)
404 .map_err(|e| self.reflect_err(e))?;
405 trace!(
406 "Field #{} {:?} was set to default value (via custom fn)",
407 index.yellow(),
408 field.blue()
409 );
410 } else {
411 if !field.shape().is(Characteristic::Default) {
412 return Err(self.reflect_err(
413 ReflectError::DefaultAttrButNoDefaultImpl {
414 shape: field.shape(),
415 },
416 ));
417 }
418 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
419 trace!(
420 "Field #{} {:?} was set to default value (via default impl)",
421 index.yellow(),
422 field.blue()
423 );
424 }
425 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
426 } else {
427 trace!(
428 "Field #{} {:?} is not initialized",
429 index.yellow(),
430 field.blue()
431 );
432 has_unset = true;
433 }
434 }
435 }
436
437 if has_unset && container_shape.has_default_attr() {
438 let default_val = Wip::alloc_shape(container_shape)
440 .map_err(|e| self.reflect_err(e))?
441 .put_default()
442 .map_err(|e| self.reflect_err(e))?
443 .build()
444 .map_err(|e| self.reflect_err(e))?;
445 let peek = default_val.peek().into_struct().unwrap();
446
447 for (index, field) in sd.fields.iter().enumerate() {
448 let is_set = wip.is_field_set(index).map_err(|err| {
449 trace!("Error checking field set status: {:?}", err);
450 self.reflect_err(err)
451 })?;
452 if !is_set {
453 let address_of_field_from_default = peek.field(index).unwrap().data();
454 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
455 wip = wip
456 .put_shape(address_of_field_from_default, field.shape())
457 .map_err(|e| self.reflect_err(e))?;
458 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
459 }
460 }
461 }
462 }
463 Def::Enum(_) => {
464 trace!(
465 "TODO: make sure enums are initialized (support container-level and field-level default, etc.)"
466 );
467 }
468 _ => {
469 trace!(
470 "Thing being popped is not a container I guess (it's a {})",
471 wip.shape()
472 );
473 }
474 }
475 Ok(wip)
476 }
477
478 fn handle_scalar<'facet>(
480 &self,
481 wip: Wip<'facet>,
482 scalar: Scalar<'input>,
483 ) -> Result<Wip<'facet>, DeserError<'input>> {
484 match scalar {
485 Scalar::String(cow) => {
486 match wip.innermost_shape().def {
487 Def::Enum(_) => {
488 if wip.selected_variant().is_some() {
489 wip.put(cow.to_string()).map_err(|e| self.reflect_err(e))
491 } else {
492 match wip.find_variant(&cow) {
494 Some((variant_index, _)) => {
495 wip.variant(variant_index).map_err(|e| self.reflect_err(e))
496 }
497 None => Err(self.err(DeserErrorKind::NoSuchVariant {
498 name: cow.to_string(),
499 enum_shape: wip.innermost_shape(),
500 })),
501 }
502 }
503 }
504 _ => wip.put(cow.to_string()).map_err(|e| self.reflect_err(e)),
505 }
506 }
507 Scalar::U64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
508 Scalar::I64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
509 Scalar::F64(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
510 Scalar::Bool(value) => wip.put(value).map_err(|e| self.reflect_err(e)),
511 Scalar::Null => wip.put_default().map_err(|e| self.reflect_err(e)),
512 }
513 }
514
515 fn value<'facet>(
517 &mut self,
518 mut wip: Wip<'facet>,
519 outcome: Spanned<Outcome<'input>>,
520 ) -> Result<Wip<'facet>, DeserError<'input>> {
521 trace!(
522 "Handling value at wip shape {} (wip innermost shape {})",
523 wip.shape().blue(),
524 wip.innermost_shape().yellow()
525 );
526
527 match outcome.node {
528 Outcome::Scalar(Scalar::Null) => {
529 return wip.put_default().map_err(|e| self.reflect_err(e));
530 }
531 _ => {
532 if matches!(wip.shape().def, Def::Option(_)) {
533 trace!("Starting Some(_) option for {}", wip.shape().blue());
534 wip = wip.push_some().map_err(|e| self.reflect_err(e))?;
535 self.stack.push(Instruction::Pop(PopReason::Some));
536 }
537 }
538 }
539
540 match outcome.node {
541 Outcome::Scalar(s) => {
542 wip = self.handle_scalar(wip, s)?;
543 }
544 Outcome::ListStarted => {
545 let shape = wip.innermost_shape();
546 match shape.def {
547 Def::Array(_) => {
548 trace!("Array starting for array ({})!", shape.blue());
549 }
550 Def::Slice(_) => {
551 trace!("Array starting for slice ({})!", shape.blue());
552 }
553 Def::List(_) => {
554 trace!("Array starting for list ({})!", shape.blue());
555 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
556 }
557 Def::Enum(_) => {
558 trace!("Array starting for enum ({})!", shape.blue());
559 }
560 Def::Struct(_) => {
561 trace!("Array starting for tuple ({})!", shape.blue());
562 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
563 }
564 Def::Scalar(sd) => {
565 if matches!(sd.affinity, ScalarAffinity::Empty(_)) {
566 trace!("Empty tuple/scalar, nice");
567 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
568 } else {
569 return Err(self.err(DeserErrorKind::UnsupportedType {
570 got: shape,
571 wanted: "array, list, tuple, or slice",
572 }));
573 }
574 }
575 _ => {
576 return Err(self.err(DeserErrorKind::UnsupportedType {
577 got: shape,
578 wanted: "array, list, tuple, or slice",
579 }));
580 }
581 }
582
583 trace!("Beginning pushback");
584 self.stack.push(Instruction::ListItemOrListClose);
585 wip = wip.begin_pushback().map_err(|e| self.reflect_err(e))?;
586 }
587 Outcome::ListEnded => {
588 trace!("List closing");
589 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
590 }
591 Outcome::ObjectStarted => {
592 let shape = wip.innermost_shape();
593 match shape.def {
594 Def::Map(_md) => {
595 trace!("Object starting for map value ({})!", shape.blue());
596 wip = wip.put_default().map_err(|e| self.reflect_err(e))?;
597 }
598 Def::Enum(_ed) => {
599 trace!("Object starting for enum value ({})!", shape.blue());
600 }
602 Def::Struct(_) => {
603 trace!("Object starting for struct value ({})!", shape.blue());
604 }
606 _ => {
607 return Err(self.err(DeserErrorKind::UnsupportedType {
608 got: shape,
609 wanted: "map, enum, or struct",
610 }));
611 }
612 }
613
614 self.stack.push(Instruction::ObjectKeyOrObjectClose);
615 }
616 Outcome::ObjectEnded => todo!(),
617 }
618 Ok(wip)
619 }
620
621 fn object_key_or_object_close<'facet>(
622 &mut self,
623 mut wip: Wip<'facet>,
624 outcome: Spanned<Outcome<'input>>,
625 ) -> Result<Wip<'facet>, DeserError<'input>>
626 where
627 'input: 'facet,
628 {
629 match outcome.node {
630 Outcome::Scalar(Scalar::String(key)) => {
631 trace!("Parsed object key: {}", key);
632
633 let mut ignore = false;
634 let mut needs_pop = true;
635 let mut handled_by_flatten = false;
636
637 match wip.innermost_shape().def {
638 Def::Struct(sd) => {
639 if let Some(index) = wip.field_index(&key) {
641 trace!("It's a struct field");
642 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
643 } else {
644 let mut found_in_flatten = false;
646 for (index, field) in sd.fields.iter().enumerate() {
647 if field.flags.contains(FieldFlags::FLATTEN) {
648 trace!("Found flattened field #{}", index);
649 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
651
652 if let Some(subfield_index) = wip.field_index(&key) {
654 trace!("Found key {} in flattened field", key);
655 wip = wip
656 .field(subfield_index)
657 .map_err(|e| self.reflect_err(e))?;
658 found_in_flatten = true;
659 handled_by_flatten = true;
660 break;
661 } else if let Some((_variant_index, _variant)) =
662 wip.find_variant(&key)
663 {
664 trace!("Found key {} in flattened field", key);
665 wip = wip
666 .variant_named(&key)
667 .map_err(|e| self.reflect_err(e))?;
668 found_in_flatten = true;
669 break;
670 } else {
671 wip = wip.pop().map_err(|e| self.reflect_err(e))?;
673 }
674 }
675 }
676
677 if !found_in_flatten {
678 if wip.shape().has_deny_unknown_fields_attr() {
679 trace!(
680 "It's not a struct field AND we're denying unknown fields"
681 );
682 return Err(self.err(DeserErrorKind::UnknownField {
683 field_name: key.to_string(),
684 shape: wip.shape(),
685 }));
686 } else {
687 trace!(
688 "It's not a struct field and we're ignoring unknown fields"
689 );
690 ignore = true;
691 }
692 }
693 }
694 }
695 Def::Enum(_ed) => match wip.find_variant(&key) {
696 Some((index, variant)) => {
697 trace!("Variant {} selected", variant.name.blue());
698 wip = wip.variant(index).map_err(|e| self.reflect_err(e))?;
699 needs_pop = false;
700 }
701 None => {
702 if let Some(_variant_index) = wip.selected_variant() {
703 trace!(
704 "Already have a variant selected, treating key as struct field of variant"
705 );
706 if let Some(index) = wip.field_index(&key) {
708 trace!("Found field {} in selected variant", key.blue());
709 wip = wip.field(index).map_err(|e| self.reflect_err(e))?;
710 } else if wip.shape().has_deny_unknown_fields_attr() {
711 trace!("Unknown field in variant and denying unknown fields");
712 return Err(self.err(DeserErrorKind::UnknownField {
713 field_name: key.to_string(),
714 shape: wip.shape(),
715 }));
716 } else {
717 trace!("Ignoring unknown field in variant");
718 ignore = true;
719 }
720 } else {
721 return Err(self.err(DeserErrorKind::NoSuchVariant {
722 name: key.to_string(),
723 enum_shape: wip.shape(),
724 }));
725 }
726 }
727 },
728 Def::Map(_) => {
729 wip = wip.push_map_key().map_err(|e| self.reflect_err(e))?;
730 wip = wip.put(key.to_string()).map_err(|e| self.reflect_err(e))?;
731 wip = wip.push_map_value().map_err(|e| self.reflect_err(e))?;
732 }
733 _ => {
734 return Err(self.err(DeserErrorKind::Unimplemented(
735 "object key for non-struct/map",
736 )));
737 }
738 }
739
740 self.stack.push(Instruction::ObjectKeyOrObjectClose);
741 if ignore {
742 self.stack.push(Instruction::SkipValue);
743 } else {
744 if needs_pop && !handled_by_flatten {
745 trace!("Pushing Pop insn to stack (ObjectVal)");
746 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
747 } else if handled_by_flatten {
748 trace!("Pushing Pop insn to stack (ObjectVal) for flattened field");
751 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
752 self.stack.push(Instruction::Pop(PopReason::ObjectVal));
753 }
754 self.stack.push(Instruction::Value(ValueReason::ObjectVal));
755 }
756 Ok(wip)
757 }
758 Outcome::ObjectEnded => {
759 trace!("Object closing");
760 Ok(wip)
761 }
762 _ => Err(self.err(DeserErrorKind::UnexpectedOutcome {
763 got: outcome.node.into_owned(),
764 wanted: "scalar or object close",
765 })),
766 }
767 }
768
769 fn list_item_or_list_close<'facet>(
770 &mut self,
771 mut wip: Wip<'facet>,
772 outcome: Spanned<Outcome<'input>>,
773 ) -> Result<Wip<'facet>, DeserError<'input>>
774 where
775 'input: 'facet,
776 {
777 match outcome.node {
778 Outcome::ListEnded => {
779 trace!("List close");
780 Ok(wip)
781 }
782 _ => {
783 self.stack.push(Instruction::ListItemOrListClose);
784 self.stack.push(Instruction::Pop(PopReason::ListVal));
785
786 trace!(
787 "Expecting list item, doing a little push before doing value with outcome {}",
788 outcome.magenta()
789 );
790 trace!("Before push, wip.shape is {}", wip.shape().blue());
791 wip = wip.push().map_err(|e| self.reflect_err(e))?;
792 trace!(" After push, wip.shape is {}", wip.shape().cyan());
793 wip = self.value(wip, outcome)?;
794 Ok(wip)
795 }
796 }
797 }
798}