1use alloc::borrow::Cow;
4use alloc::format;
5use alloc::string::{String, ToString};
6use alloc::vec::Vec;
7use core::fmt::{self, Display};
8use core::ptr;
9
10use alloc::collections::{BTreeMap, BTreeSet};
11
12use facet_core::{
13 Characteristic, Def, Facet, KnownPointer, NumericType, PrimitiveType, ScalarType, SequenceType,
14 Shape, ShapeLayout, StructKind, Type, UserType,
15};
16use facet_reflect::{Partial, ReflectError, is_spanned_shape};
17use facet_solver::{FieldInfo, PathSegment, Schema, Solver, VariantsByFormat, specificity_score};
18
19use crate::RawJson;
20use crate::adapter::{AdapterError, AdapterErrorKind, SliceAdapter, SpannedAdapterToken, Token};
21use crate::scanner::ScanErrorKind;
22use facet_reflect::Span;
23
24fn find_similar_field<'a>(unknown: &str, expected: &[&'a str]) -> Option<&'a str> {
27 let mut best_match: Option<(&'a str, f64)> = None;
28
29 for &candidate in expected {
30 let similarity = strsim::jaro_winkler(unknown, candidate);
31 if similarity >= 0.6 && best_match.is_none_or(|(_, best_sim)| similarity > best_sim) {
32 best_match = Some((candidate, similarity));
33 }
34 }
35
36 best_match.map(|(name, _)| name)
37}
38
39#[derive(Debug)]
45pub struct JsonError {
46 pub kind: JsonErrorKind,
48 pub span: Option<Span>,
50 pub source_code: Option<String>,
52}
53
54impl Display for JsonError {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 write!(f, "{}", self.kind)
57 }
58}
59
60impl std::error::Error for JsonError {}
61
62impl miette::Diagnostic for JsonError {
63 fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
64 Some(Box::new(self.kind.code()))
65 }
66
67 fn source_code(&self) -> Option<&dyn miette::SourceCode> {
68 self.source_code
69 .as_ref()
70 .map(|s| s as &dyn miette::SourceCode)
71 }
72
73 fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {
74 if let JsonErrorKind::MissingField {
76 field,
77 object_start,
78 object_end,
79 } = &self.kind
80 {
81 let mut labels = Vec::new();
82 if let Some(start) = object_start {
83 labels.push(miette::LabeledSpan::new(
84 Some("object started here".into()),
85 start.offset,
86 start.len,
87 ));
88 }
89 if let Some(end) = object_end {
90 labels.push(miette::LabeledSpan::new(
91 Some(format!("object ended without field `{field}`")),
92 end.offset,
93 end.len,
94 ));
95 }
96 if labels.is_empty() {
97 return None;
98 }
99 return Some(Box::new(labels.into_iter()));
100 }
101
102 let span = self.span?;
104 Some(Box::new(core::iter::once(miette::LabeledSpan::new(
105 Some(self.kind.label()),
106 span.offset,
107 span.len,
108 ))))
109 }
110}
111
112impl JsonError {
113 pub fn new(kind: JsonErrorKind, span: Span) -> Self {
115 JsonError {
116 kind,
117 span: Some(span),
118 source_code: None,
119 }
120 }
121
122 pub fn without_span(kind: JsonErrorKind) -> Self {
124 JsonError {
125 kind,
126 span: None,
127 source_code: None,
128 }
129 }
130
131 pub fn with_source(mut self, source: &str) -> Self {
133 self.source_code = Some(source.to_string());
134 self
135 }
136}
137
138#[inline(never)]
139#[cold]
140fn attach_source_cold(mut err: JsonError, source: Option<&str>) -> JsonError {
141 if let Some(src) = source {
142 err.source_code = Some(src.to_string());
143 }
144 err
145}
146
147#[derive(Debug)]
149pub enum JsonErrorKind {
150 Scan(ScanErrorKind),
152 ScanWithContext {
154 error: ScanErrorKind,
156 expected_type: &'static str,
158 },
159 UnexpectedToken {
161 got: String,
163 expected: &'static str,
165 },
166 UnexpectedEof {
168 expected: &'static str,
170 },
171 TypeMismatch {
173 expected: &'static str,
175 got: &'static str,
177 },
178 UnknownField {
180 field: String,
182 expected: Vec<&'static str>,
184 suggestion: Option<&'static str>,
186 },
187 MissingField {
189 field: &'static str,
191 object_start: Option<Span>,
193 object_end: Option<Span>,
195 },
196 InvalidValue {
198 message: String,
200 },
201 Reflect(ReflectError),
203 NumberOutOfRange {
205 value: String,
207 target_type: &'static str,
209 },
210 DuplicateKey {
212 key: String,
214 },
215 InvalidUtf8,
217 Solver(String),
219 Io(String),
221}
222
223impl Display for JsonErrorKind {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225 match self {
226 JsonErrorKind::Scan(e) => write!(f, "{e:?}"),
227 JsonErrorKind::ScanWithContext {
228 error,
229 expected_type,
230 } => {
231 write!(f, "{error:?} (while parsing {expected_type})")
232 }
233 JsonErrorKind::UnexpectedToken { got, expected } => {
234 write!(f, "unexpected token: got {got}, expected {expected}")
235 }
236 JsonErrorKind::UnexpectedEof { expected } => {
237 write!(f, "unexpected end of input, expected {expected}")
238 }
239 JsonErrorKind::TypeMismatch { expected, got } => {
240 write!(f, "type mismatch: expected {expected}, got {got}")
241 }
242 JsonErrorKind::UnknownField {
243 field,
244 expected,
245 suggestion,
246 } => {
247 write!(f, "unknown field `{field}`, expected one of: {expected:?}")?;
248 if let Some(suggested) = suggestion {
249 write!(f, " (did you mean `{suggested}`?)")?;
250 }
251 Ok(())
252 }
253 JsonErrorKind::MissingField { field, .. } => {
254 write!(f, "missing required field `{field}`")
255 }
256 JsonErrorKind::InvalidValue { message } => {
257 write!(f, "invalid value: {message}")
258 }
259 JsonErrorKind::Reflect(e) => write!(f, "reflection error: {e}"),
260 JsonErrorKind::NumberOutOfRange { value, target_type } => {
261 write!(f, "number `{value}` out of range for {target_type}")
262 }
263 JsonErrorKind::DuplicateKey { key } => {
264 write!(f, "duplicate key `{key}`")
265 }
266 JsonErrorKind::InvalidUtf8 => write!(f, "invalid UTF-8 sequence"),
267 JsonErrorKind::Solver(msg) => write!(f, "solver error: {msg}"),
268 JsonErrorKind::Io(msg) => write!(f, "I/O error: {msg}"),
269 }
270 }
271}
272
273impl JsonErrorKind {
274 pub fn code(&self) -> &'static str {
276 match self {
277 JsonErrorKind::Scan(_) => "json::scan",
278 JsonErrorKind::ScanWithContext { .. } => "json::scan",
279 JsonErrorKind::UnexpectedToken { .. } => "json::unexpected_token",
280 JsonErrorKind::UnexpectedEof { .. } => "json::unexpected_eof",
281 JsonErrorKind::TypeMismatch { .. } => "json::type_mismatch",
282 JsonErrorKind::UnknownField { .. } => "json::unknown_field",
283 JsonErrorKind::MissingField { .. } => "json::missing_field",
284 JsonErrorKind::InvalidValue { .. } => "json::invalid_value",
285 JsonErrorKind::Reflect(_) => "json::reflect",
286 JsonErrorKind::NumberOutOfRange { .. } => "json::number_out_of_range",
287 JsonErrorKind::DuplicateKey { .. } => "json::duplicate_key",
288 JsonErrorKind::InvalidUtf8 => "json::invalid_utf8",
289 JsonErrorKind::Solver(_) => "json::solver",
290 JsonErrorKind::Io(_) => "json::io",
291 }
292 }
293
294 pub fn label(&self) -> String {
296 match self {
297 JsonErrorKind::Scan(e) => match e {
298 ScanErrorKind::UnexpectedChar(c) => format!("unexpected '{c}'"),
299 ScanErrorKind::UnexpectedEof(ctx) => format!("unexpected end of input {ctx}"),
300 ScanErrorKind::InvalidUtf8 => "invalid UTF-8 here".into(),
301 },
302 JsonErrorKind::ScanWithContext {
303 error,
304 expected_type,
305 } => match error {
306 ScanErrorKind::UnexpectedChar(c) => {
307 format!("unexpected '{c}', expected {expected_type}")
308 }
309 ScanErrorKind::UnexpectedEof(_) => {
310 format!("unexpected end of input, expected {expected_type}")
311 }
312 ScanErrorKind::InvalidUtf8 => "invalid UTF-8 here".into(),
313 },
314 JsonErrorKind::UnexpectedToken { got, expected } => {
315 format!("expected {expected}, got '{got}'")
316 }
317 JsonErrorKind::UnexpectedEof { expected } => format!("expected {expected}"),
318 JsonErrorKind::TypeMismatch { expected, got } => {
319 format!("expected {expected}, got {got}")
320 }
321 JsonErrorKind::UnknownField {
322 field, suggestion, ..
323 } => {
324 if let Some(suggested) = suggestion {
325 format!("unknown field '{field}' - did you mean '{suggested}'?")
326 } else {
327 format!("unknown field '{field}'")
328 }
329 }
330 JsonErrorKind::MissingField { field, .. } => format!("missing field '{field}'"),
331 JsonErrorKind::InvalidValue { .. } => "invalid value".into(),
332 JsonErrorKind::Reflect(_) => "reflection error".into(),
333 JsonErrorKind::NumberOutOfRange { target_type, .. } => {
334 format!("out of range for {target_type}")
335 }
336 JsonErrorKind::DuplicateKey { key } => format!("duplicate key '{key}'"),
337 JsonErrorKind::InvalidUtf8 => "invalid UTF-8".into(),
338 JsonErrorKind::Solver(_) => "solver error".into(),
339 JsonErrorKind::Io(_) => "I/O error".into(),
340 }
341 }
342}
343
344impl From<AdapterError> for JsonError {
345 fn from(err: AdapterError) -> Self {
346 let kind = match err.kind {
347 AdapterErrorKind::Scan(scan_err) => JsonErrorKind::Scan(scan_err),
348 AdapterErrorKind::NeedMore => JsonErrorKind::UnexpectedEof {
349 expected: "more data",
350 },
351 };
352 JsonError {
353 kind,
354 span: Some(err.span),
355 source_code: None,
356 }
357 }
358}
359
360impl From<ReflectError> for JsonError {
361 fn from(err: ReflectError) -> Self {
362 JsonError {
363 kind: JsonErrorKind::Reflect(err),
364 span: None,
365 source_code: None,
366 }
367 }
368}
369
370pub type Result<T> = core::result::Result<T, JsonError>;
372
373use crate::adapter::TokenSource;
378
379pub struct JsonDeserializer<'input, const BORROW: bool, A: TokenSource<'input>> {
389 adapter: A,
390 peeked: Option<SpannedAdapterToken<'input>>,
392}
393
394impl<'input> JsonDeserializer<'input, true, SliceAdapter<'input, true>> {
395 pub fn new(input: &'input [u8]) -> Self {
398 JsonDeserializer {
399 adapter: SliceAdapter::new(input),
400 peeked: None,
401 }
402 }
403}
404
405impl<'input> JsonDeserializer<'input, false, SliceAdapter<'input, false>> {
406 pub fn new_owned(input: &'input [u8]) -> Self {
409 JsonDeserializer {
410 adapter: SliceAdapter::new(input),
411 peeked: None,
412 }
413 }
414}
415
416impl<'input, const BORROW: bool, A: TokenSource<'input>> JsonDeserializer<'input, BORROW, A> {
417 pub fn from_adapter(adapter: A) -> Self {
419 JsonDeserializer {
420 adapter,
421 peeked: None,
422 }
423 }
424
425 fn peek(&mut self) -> Result<&SpannedAdapterToken<'input>> {
427 if self.peeked.is_none() {
428 self.peeked = Some(self.adapter.next_token()?);
429 }
430 Ok(self.peeked.as_ref().unwrap())
431 }
432
433 fn next(&mut self) -> Result<SpannedAdapterToken<'input>> {
435 if let Some(token) = self.peeked.take() {
436 Ok(token)
437 } else {
438 Ok(self.adapter.next_token()?)
439 }
440 }
441
442 fn next_expecting(
444 &mut self,
445 expected_type: &'static str,
446 ) -> Result<SpannedAdapterToken<'input>> {
447 match self.next() {
448 Ok(token) => Ok(token),
449 Err(e) => {
450 if let JsonErrorKind::Scan(scan_err) = e.kind {
452 Err(JsonError {
453 kind: JsonErrorKind::ScanWithContext {
454 error: scan_err,
455 expected_type,
456 },
457 span: e.span,
458 source_code: e.source_code,
459 })
460 } else {
461 Err(e)
462 }
463 }
464 }
465 }
466
467 #[allow(dead_code)]
469 fn expect(&mut self, _expected: &'static str) -> Result<SpannedAdapterToken<'input>> {
470 let token = self.next()?;
471 Ok(token)
473 }
474
475 fn skip_value(&mut self) -> Result<Span> {
477 let token = self.next()?;
478 let start_span = token.span;
479
480 match token.token {
481 Token::ObjectStart => {
482 let mut depth = 1;
484 while depth > 0 {
485 let t = self.next()?;
486 match t.token {
487 Token::ObjectStart => depth += 1,
488 Token::ObjectEnd => depth -= 1,
489 _ => {}
490 }
491 }
492 Ok(start_span)
493 }
494 Token::ArrayStart => {
495 let mut depth = 1;
497 while depth > 0 {
498 let t = self.next()?;
499 match t.token {
500 Token::ArrayStart => depth += 1,
501 Token::ArrayEnd => depth -= 1,
502 _ => {}
503 }
504 }
505 Ok(start_span)
506 }
507 Token::String(_)
508 | Token::F64(_)
509 | Token::I64(_)
510 | Token::U64(_)
511 | Token::U128(_)
512 | Token::I128(_)
513 | Token::True
514 | Token::False
515 | Token::Null => Ok(start_span),
516 _ => Err(JsonError::new(
517 JsonErrorKind::UnexpectedToken {
518 got: format!("{:?}", token.token),
519 expected: "value",
520 },
521 token.span,
522 )),
523 }
524 }
525
526 fn capture_raw_value(&mut self) -> Result<&'input str> {
534 let input = self.adapter.input_bytes().ok_or_else(|| {
536 JsonError::without_span(JsonErrorKind::InvalidValue {
537 message: "RawJson capture is not supported in streaming mode".into(),
538 })
539 })?;
540
541 let token = self.next()?;
542 let start_offset = token.span.offset;
543
544 let end_offset = match token.token {
545 Token::ObjectStart => {
546 let mut depth = 1;
548 let mut last_span = token.span;
549 while depth > 0 {
550 let t = self.next()?;
551 last_span = t.span;
552 match t.token {
553 Token::ObjectStart => depth += 1,
554 Token::ObjectEnd => depth -= 1,
555 _ => {}
556 }
557 }
558 last_span.offset + last_span.len
559 }
560 Token::ArrayStart => {
561 let mut depth = 1;
563 let mut last_span = token.span;
564 while depth > 0 {
565 let t = self.next()?;
566 last_span = t.span;
567 match t.token {
568 Token::ArrayStart => depth += 1,
569 Token::ArrayEnd => depth -= 1,
570 _ => {}
571 }
572 }
573 last_span.offset + last_span.len
574 }
575 Token::String(_)
576 | Token::F64(_)
577 | Token::I64(_)
578 | Token::U64(_)
579 | Token::U128(_)
580 | Token::I128(_)
581 | Token::True
582 | Token::False
583 | Token::Null => token.span.offset + token.span.len,
584 _ => {
585 return Err(JsonError::new(
586 JsonErrorKind::UnexpectedToken {
587 got: format!("{:?}", token.token),
588 expected: "value",
589 },
590 token.span,
591 ));
592 }
593 };
594
595 let raw_bytes = &input[start_offset..end_offset];
597 core::str::from_utf8(raw_bytes).map_err(|e| {
598 JsonError::without_span(JsonErrorKind::InvalidValue {
599 message: format!("invalid UTF-8 in raw JSON: {e}"),
600 })
601 })
602 }
603
604 fn has_flatten_fields(struct_def: &facet_core::StructType) -> bool {
606 struct_def.fields.iter().any(|f| f.is_flattened())
607 }
608
609 pub fn deserialize_into(
611 &mut self,
612 mut wip: Partial<'input, BORROW>,
613 ) -> Result<Partial<'input, BORROW>> {
614 let shape = wip.shape();
615 log::trace!(
616 "deserialize_into: shape={}, def={:?}",
617 shape.type_identifier,
618 std::mem::discriminant(&shape.def)
619 );
620
621 if is_spanned_shape(shape) {
623 return self.deserialize_spanned(wip);
624 }
625
626 if shape == RawJson::SHAPE {
628 let raw = self.capture_raw_value()?;
629 wip = wip.set(RawJson::new(raw))?;
630 return Ok(wip);
631 }
632
633 #[cfg(feature = "alloc")]
635 {
636 let (wip_returned, has_proxy) = wip.begin_custom_deserialization_from_shape()?;
637 wip = wip_returned;
638 if has_proxy {
639 log::trace!(
640 "deserialize_into: using container-level proxy for {}",
641 shape.type_identifier
642 );
643 wip = self.deserialize_into(wip)?;
644 return wip.end().map_err(Into::into);
645 }
646 }
647
648 let is_option = matches!(&shape.def, Def::Option(_));
651 log::trace!("deserialize_into: is_option={is_option}");
652 if is_option {
653 return self.deserialize_option(wip);
654 }
655
656 if shape.builder_shape.is_some() {
659 wip = wip.begin_inner()?;
660 if wip
662 .parent_field()
663 .and_then(|field| field.proxy_convert_in_fn())
664 .is_some()
665 {
666 wip = wip.begin_custom_deserialization()?;
667 wip = self.deserialize_into(wip)?;
668 wip = wip.end()?;
669 } else {
670 wip = self.deserialize_into(wip)?;
671 }
672 wip = wip.end()?;
673 return Ok(wip);
674 }
675
676 if matches!(&shape.def, Def::Pointer(_)) {
678 return self.deserialize_pointer(wip);
679 }
680
681 if shape.inner.is_some()
684 && !matches!(
685 &shape.def,
686 Def::List(_) | Def::Map(_) | Def::Set(_) | Def::Array(_)
687 )
688 {
689 wip = wip.begin_inner()?;
690 wip = self.deserialize_into(wip)?;
691 wip = wip.end()?;
692 return Ok(wip);
693 }
694
695 match &shape.ty {
697 Type::User(UserType::Struct(struct_def)) => {
698 if matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct) {
700 return self.deserialize_tuple(wip);
701 }
702 return self.deserialize_struct(wip);
703 }
704 Type::User(UserType::Enum(_)) => return self.deserialize_enum(wip),
705 _ => {}
706 }
707
708 match &shape.def {
710 Def::Scalar => self.deserialize_scalar(wip),
711 Def::List(_) => self.deserialize_list(wip),
712 Def::Map(_) => self.deserialize_map(wip),
713 Def::Array(_) => self.deserialize_array(wip),
714 Def::Set(_) => self.deserialize_set(wip),
715 Def::DynamicValue(_) => self.deserialize_dynamic_value(wip),
716 _ => Err(JsonError::without_span(JsonErrorKind::InvalidValue {
717 message: format!("unsupported shape def: {:?}", shape.def),
718 })),
719 }
720 }
721
722 fn deserialize_spanned(
728 &mut self,
729 mut wip: Partial<'input, BORROW>,
730 ) -> Result<Partial<'input, BORROW>> {
731 log::trace!("deserialize_spanned");
732
733 let shape = wip.shape();
734
735 let Type::User(UserType::Struct(struct_def)) = &shape.ty else {
737 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
738 message: format!(
739 "expected struct with span metadata, found {}",
740 shape.type_identifier
741 ),
742 }));
743 };
744
745 let span_field = struct_def
746 .fields
747 .iter()
748 .find(|f| f.metadata_kind() == Some("span"))
749 .ok_or_else(|| {
750 JsonError::without_span(JsonErrorKind::InvalidValue {
751 message: format!(
752 "expected struct with span metadata field, found {}",
753 shape.type_identifier
754 ),
755 })
756 })?;
757
758 let value_fields: Vec<_> = struct_def
759 .fields
760 .iter()
761 .filter(|f| !f.is_metadata())
762 .collect();
763
764 let value_span = self.peek()?.span;
766
767 for field in value_fields {
770 wip = wip.begin_field(field.name)?;
771 wip = self.deserialize_into(wip)?;
772 wip = wip.end()?;
773 }
774
775 wip = wip.begin_field(span_field.name)?;
778 wip = wip.set_field("offset", value_span.offset)?;
779 wip = wip.set_field("len", value_span.len)?;
780 wip = wip.end()?;
781
782 Ok(wip)
783 }
784
785 fn deserialize_scalar(
787 &mut self,
788 mut wip: Partial<'input, BORROW>,
789 ) -> Result<Partial<'input, BORROW>> {
790 let expected_type = wip.shape().type_identifier;
791 let token = self.next_expecting(expected_type)?;
792 log::trace!("deserialize_scalar: token={:?}", token.token);
793
794 match token.token {
795 Token::String(s) => {
796 if wip.shape().vtable.has_parse() {
798 wip = wip.parse_from_str(&s)?;
799 } else if wip.shape().type_identifier == "Cow" {
800 wip = wip.set(s)?;
802 } else {
803 wip = wip.set(s.into_owned())?;
804 }
805 }
806 Token::True => {
807 wip = wip.set(true)?;
808 }
809 Token::False => {
810 wip = wip.set(false)?;
811 }
812 Token::Null => {
813 wip = wip.set_default()?;
815 }
816 Token::F64(n) => {
817 wip = self.set_number_f64(wip, n, token.span)?;
818 }
819 Token::I64(n) => {
820 wip = self.set_number_i64(wip, n, token.span)?;
821 }
822 Token::U64(n) => {
823 wip = self.set_number_u64(wip, n, token.span)?;
824 }
825 Token::I128(n) => {
826 wip = self.set_number_i128(wip, n, token.span)?;
827 }
828 Token::U128(n) => {
829 wip = self.set_number_u128(wip, n, token.span)?;
830 }
831 _ => {
832 return Err(JsonError::new(
833 JsonErrorKind::UnexpectedToken {
834 got: format!("{:?}", token.token),
835 expected: "scalar value",
836 },
837 token.span,
838 ));
839 }
840 }
841 Ok(wip)
842 }
843
844 fn deserialize_dynamic_value(
848 &mut self,
849 mut wip: Partial<'input, BORROW>,
850 ) -> Result<Partial<'input, BORROW>> {
851 let token = self.peek()?;
852 log::trace!("deserialize_dynamic_value: token={:?}", token.token);
853
854 match token.token {
855 Token::Null => {
856 self.next()?; wip = wip.set_default()?;
858 }
859 Token::True => {
860 self.next()?;
861 wip = wip.set(true)?;
862 }
863 Token::False => {
864 self.next()?;
865 wip = wip.set(false)?;
866 }
867 Token::I64(n) => {
868 self.next()?;
869 wip = wip.set(n)?;
870 }
871 Token::U64(n) => {
872 self.next()?;
873 if n <= i64::MAX as u64 {
875 wip = wip.set(n as i64)?;
876 } else {
877 wip = wip.set(n)?;
878 }
879 }
880 Token::F64(n) => {
881 self.next()?;
882 wip = wip.set(n)?;
883 }
884 Token::I128(n) => {
885 self.next()?;
886 if let Ok(n) = i64::try_from(n) {
888 wip = wip.set(n)?;
889 } else {
890 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
891 message: format!("i128 value {n} doesn't fit in dynamic value"),
892 }));
893 }
894 }
895 Token::U128(n) => {
896 self.next()?;
897 if let Ok(n) = i64::try_from(n) {
899 wip = wip.set(n)?;
900 } else if let Ok(n) = u64::try_from(n) {
901 wip = wip.set(n)?;
902 } else {
903 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
904 message: format!("u128 value {n} doesn't fit in dynamic value"),
905 }));
906 }
907 }
908 Token::String(ref _s) => {
909 let token = self.next()?;
911 if let Token::String(s) = token.token {
912 wip = wip.set(s.into_owned())?;
913 }
914 }
915 Token::ArrayStart => {
916 self.next()?; wip = wip.begin_list()?;
918
919 loop {
920 let token = self.peek()?;
921 if matches!(token.token, Token::ArrayEnd) {
922 self.next()?;
923 break;
924 }
925
926 wip = wip.begin_list_item()?;
927 wip = self.deserialize_dynamic_value(wip)?;
928 wip = wip.end()?;
929
930 let next = self.peek()?;
931 if matches!(next.token, Token::Comma) {
932 self.next()?;
933 }
934 }
935 }
936 Token::ObjectStart => {
937 self.next()?; wip = wip.begin_map()?; loop {
941 let token = self.peek()?;
942 if matches!(token.token, Token::ObjectEnd) {
943 self.next()?;
944 break;
945 }
946
947 let key_token = self.next()?;
949 let key = match key_token.token {
950 Token::String(s) => s.into_owned(),
951 _ => {
952 return Err(JsonError::new(
953 JsonErrorKind::UnexpectedToken {
954 got: format!("{:?}", key_token.token),
955 expected: "string key",
956 },
957 key_token.span,
958 ));
959 }
960 };
961
962 let colon = self.next()?;
964 if !matches!(colon.token, Token::Colon) {
965 return Err(JsonError::new(
966 JsonErrorKind::UnexpectedToken {
967 got: format!("{:?}", colon.token),
968 expected: "':'",
969 },
970 colon.span,
971 ));
972 }
973
974 wip = wip.begin_object_entry(&key)?;
976 wip = self.deserialize_dynamic_value(wip)?;
977 wip = wip.end()?;
978
979 let next = self.peek()?;
981 if matches!(next.token, Token::Comma) {
982 self.next()?;
983 }
984 }
985 }
986 _ => {
987 return Err(JsonError::new(
988 JsonErrorKind::UnexpectedToken {
989 got: format!("{:?}", token.token),
990 expected: "any JSON value",
991 },
992 token.span,
993 ));
994 }
995 }
996 Ok(wip)
997 }
998
999 fn set_string_value(
1001 &mut self,
1002 mut wip: Partial<'input, BORROW>,
1003 s: Cow<'input, str>,
1004 ) -> Result<Partial<'input, BORROW>> {
1005 let shape = wip.shape();
1006
1007 if let Def::Pointer(ptr_def) = shape.def
1009 && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
1010 && ptr_def
1011 .pointee()
1012 .is_some_and(|p| p.type_identifier == "str")
1013 {
1014 if !BORROW {
1016 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1017 message: "cannot deserialize into &str when borrowing is disabled - use String or Cow<str> instead".into(),
1018 }));
1019 }
1020 match s {
1021 Cow::Borrowed(borrowed) => {
1022 wip = wip.set(borrowed)?;
1023 return Ok(wip);
1024 }
1025 Cow::Owned(_) => {
1026 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1027 message: "cannot borrow &str from JSON string containing escape sequences - use String instead".into(),
1028 }));
1029 }
1030 }
1031 }
1032
1033 if let Def::Pointer(ptr_def) = shape.def
1035 && matches!(ptr_def.known, Some(KnownPointer::Cow))
1036 && ptr_def
1037 .pointee()
1038 .is_some_and(|p| p.type_identifier == "str")
1039 {
1040 wip = wip.set(s)?;
1041 return Ok(wip);
1042 }
1043
1044 wip = wip.set(s.into_owned())?;
1046 Ok(wip)
1047 }
1048
1049 fn set_number_f64(
1051 &mut self,
1052 mut wip: Partial<'input, BORROW>,
1053 n: f64,
1054 span: Span,
1055 ) -> Result<Partial<'input, BORROW>> {
1056 let shape = wip.shape();
1057 let ty = match &shape.ty {
1058 Type::Primitive(PrimitiveType::Numeric(ty)) => ty,
1059 _ => {
1060 return Err(JsonError::new(
1061 JsonErrorKind::TypeMismatch {
1062 expected: shape.type_identifier,
1063 got: "number",
1064 },
1065 span,
1066 ));
1067 }
1068 };
1069
1070 match ty {
1071 NumericType::Float => {
1072 let size = match shape.layout {
1073 ShapeLayout::Sized(layout) => layout.size(),
1074 _ => {
1075 return Err(JsonError::new(
1076 JsonErrorKind::InvalidValue {
1077 message: "unsized float".into(),
1078 },
1079 span,
1080 ));
1081 }
1082 };
1083 match size {
1084 4 => {
1085 wip = wip.set(n as f32)?;
1086 }
1087 8 => {
1088 wip = wip.set(n)?;
1089 }
1090 _ => {
1091 return Err(JsonError::new(
1092 JsonErrorKind::InvalidValue {
1093 message: format!("unexpected float size: {size}"),
1094 },
1095 span,
1096 ));
1097 }
1098 }
1099 }
1100 NumericType::Integer { signed } => {
1101 if n.fract() != 0.0 {
1103 return Err(JsonError::new(
1104 JsonErrorKind::TypeMismatch {
1105 expected: shape.type_identifier,
1106 got: "float with fractional part",
1107 },
1108 span,
1109 ));
1110 }
1111 if *signed {
1112 wip = self.set_number_i64(wip, n as i64, span)?;
1113 } else {
1114 wip = self.set_number_u64(wip, n as u64, span)?;
1115 }
1116 }
1117 }
1118 Ok(wip)
1119 }
1120
1121 fn set_number_i64(
1122 &mut self,
1123 mut wip: Partial<'input, BORROW>,
1124 n: i64,
1125 span: Span,
1126 ) -> Result<Partial<'input, BORROW>> {
1127 let shape = wip.shape();
1128 let size = match shape.layout {
1129 ShapeLayout::Sized(layout) => layout.size(),
1130 _ => {
1131 return Err(JsonError::new(
1132 JsonErrorKind::InvalidValue {
1133 message: "unsized integer".into(),
1134 },
1135 span,
1136 ));
1137 }
1138 };
1139
1140 match &shape.ty {
1142 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: true })) => {
1143 match size {
1144 1 => {
1145 let v = i8::try_from(n).map_err(|_| {
1146 JsonError::new(
1147 JsonErrorKind::NumberOutOfRange {
1148 value: n.to_string(),
1149 target_type: "i8",
1150 },
1151 span,
1152 )
1153 })?;
1154 wip = wip.set(v)?;
1155 }
1156 2 => {
1157 let v = i16::try_from(n).map_err(|_| {
1158 JsonError::new(
1159 JsonErrorKind::NumberOutOfRange {
1160 value: n.to_string(),
1161 target_type: "i16",
1162 },
1163 span,
1164 )
1165 })?;
1166 wip = wip.set(v)?;
1167 }
1168 4 => {
1169 let v = i32::try_from(n).map_err(|_| {
1170 JsonError::new(
1171 JsonErrorKind::NumberOutOfRange {
1172 value: n.to_string(),
1173 target_type: "i32",
1174 },
1175 span,
1176 )
1177 })?;
1178 wip = wip.set(v)?;
1179 }
1180 8 => {
1181 if shape.scalar_type() == Some(ScalarType::ISize) {
1183 let v = isize::try_from(n).map_err(|_| {
1184 JsonError::new(
1185 JsonErrorKind::NumberOutOfRange {
1186 value: n.to_string(),
1187 target_type: "isize",
1188 },
1189 span,
1190 )
1191 })?;
1192 wip = wip.set(v)?;
1193 } else {
1194 wip = wip.set(n)?;
1195 }
1196 }
1197 16 => {
1198 wip = wip.set(n as i128)?;
1199 }
1200 _ => {
1201 if shape.scalar_type() == Some(ScalarType::ISize) {
1203 let v = isize::try_from(n).map_err(|_| {
1204 JsonError::new(
1205 JsonErrorKind::NumberOutOfRange {
1206 value: n.to_string(),
1207 target_type: "isize",
1208 },
1209 span,
1210 )
1211 })?;
1212 wip = wip.set(v)?;
1213 } else {
1214 return Err(JsonError::new(
1215 JsonErrorKind::InvalidValue {
1216 message: format!("unexpected integer size: {size}"),
1217 },
1218 span,
1219 ));
1220 }
1221 }
1222 }
1223 }
1224 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: false })) => {
1225 if n < 0 {
1226 return Err(JsonError::new(
1227 JsonErrorKind::NumberOutOfRange {
1228 value: n.to_string(),
1229 target_type: shape.type_identifier,
1230 },
1231 span,
1232 ));
1233 }
1234 wip = self.set_number_u64(wip, n as u64, span)?;
1235 }
1236 Type::Primitive(PrimitiveType::Numeric(NumericType::Float)) => match size {
1237 4 => {
1238 wip = wip.set(n as f32)?;
1239 }
1240 8 => {
1241 wip = wip.set(n as f64)?;
1242 }
1243 _ => {
1244 return Err(JsonError::new(
1245 JsonErrorKind::InvalidValue {
1246 message: format!("unexpected float size: {size}"),
1247 },
1248 span,
1249 ));
1250 }
1251 },
1252 _ => {
1253 return Err(JsonError::new(
1254 JsonErrorKind::TypeMismatch {
1255 expected: shape.type_identifier,
1256 got: "integer",
1257 },
1258 span,
1259 ));
1260 }
1261 }
1262 Ok(wip)
1263 }
1264
1265 fn set_number_u64(
1266 &mut self,
1267 mut wip: Partial<'input, BORROW>,
1268 n: u64,
1269 span: Span,
1270 ) -> Result<Partial<'input, BORROW>> {
1271 let shape = wip.shape();
1272 let size = match shape.layout {
1273 ShapeLayout::Sized(layout) => layout.size(),
1274 _ => {
1275 return Err(JsonError::new(
1276 JsonErrorKind::InvalidValue {
1277 message: "unsized integer".into(),
1278 },
1279 span,
1280 ));
1281 }
1282 };
1283
1284 match &shape.ty {
1285 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: false })) => {
1286 match size {
1287 1 => {
1288 let v = u8::try_from(n).map_err(|_| {
1289 JsonError::new(
1290 JsonErrorKind::NumberOutOfRange {
1291 value: n.to_string(),
1292 target_type: "u8",
1293 },
1294 span,
1295 )
1296 })?;
1297 wip = wip.set(v)?;
1298 }
1299 2 => {
1300 let v = u16::try_from(n).map_err(|_| {
1301 JsonError::new(
1302 JsonErrorKind::NumberOutOfRange {
1303 value: n.to_string(),
1304 target_type: "u16",
1305 },
1306 span,
1307 )
1308 })?;
1309 wip = wip.set(v)?;
1310 }
1311 4 => {
1312 let v = u32::try_from(n).map_err(|_| {
1313 JsonError::new(
1314 JsonErrorKind::NumberOutOfRange {
1315 value: n.to_string(),
1316 target_type: "u32",
1317 },
1318 span,
1319 )
1320 })?;
1321 wip = wip.set(v)?;
1322 }
1323 8 => {
1324 if shape.scalar_type() == Some(ScalarType::USize) {
1326 let v = usize::try_from(n).map_err(|_| {
1327 JsonError::new(
1328 JsonErrorKind::NumberOutOfRange {
1329 value: n.to_string(),
1330 target_type: "usize",
1331 },
1332 span,
1333 )
1334 })?;
1335 wip = wip.set(v)?;
1336 } else {
1337 wip = wip.set(n)?;
1338 }
1339 }
1340 16 => {
1341 wip = wip.set(n as u128)?;
1342 }
1343 _ => {
1344 if shape.scalar_type() == Some(ScalarType::USize) {
1346 let v = usize::try_from(n).map_err(|_| {
1347 JsonError::new(
1348 JsonErrorKind::NumberOutOfRange {
1349 value: n.to_string(),
1350 target_type: "usize",
1351 },
1352 span,
1353 )
1354 })?;
1355 wip = wip.set(v)?;
1356 } else {
1357 return Err(JsonError::new(
1358 JsonErrorKind::InvalidValue {
1359 message: format!("unexpected integer size: {size}"),
1360 },
1361 span,
1362 ));
1363 }
1364 }
1365 }
1366 }
1367 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: true })) => {
1368 wip = self.set_number_i64(wip, n as i64, span)?;
1370 }
1371 Type::Primitive(PrimitiveType::Numeric(NumericType::Float)) => match size {
1372 4 => {
1373 wip = wip.set(n as f32)?;
1374 }
1375 8 => {
1376 wip = wip.set(n as f64)?;
1377 }
1378 _ => {
1379 return Err(JsonError::new(
1380 JsonErrorKind::InvalidValue {
1381 message: format!("unexpected float size: {size}"),
1382 },
1383 span,
1384 ));
1385 }
1386 },
1387 _ => {
1388 return Err(JsonError::new(
1389 JsonErrorKind::TypeMismatch {
1390 expected: shape.type_identifier,
1391 got: "unsigned integer",
1392 },
1393 span,
1394 ));
1395 }
1396 }
1397 Ok(wip)
1398 }
1399
1400 fn set_number_i128(
1401 &mut self,
1402 mut wip: Partial<'input, BORROW>,
1403 n: i128,
1404 span: Span,
1405 ) -> Result<Partial<'input, BORROW>> {
1406 let shape = wip.shape();
1407 let size = match shape.layout {
1408 ShapeLayout::Sized(layout) => layout.size(),
1409 _ => {
1410 return Err(JsonError::new(
1411 JsonErrorKind::InvalidValue {
1412 message: "unsized integer".into(),
1413 },
1414 span,
1415 ));
1416 }
1417 };
1418
1419 if size == 16 {
1420 wip = wip.set(n)?;
1421 } else {
1422 if let Ok(n64) = i64::try_from(n) {
1424 wip = self.set_number_i64(wip, n64, span)?;
1425 } else {
1426 return Err(JsonError::new(
1427 JsonErrorKind::NumberOutOfRange {
1428 value: n.to_string(),
1429 target_type: shape.type_identifier,
1430 },
1431 span,
1432 ));
1433 }
1434 }
1435 Ok(wip)
1436 }
1437
1438 fn set_number_u128(
1439 &mut self,
1440 mut wip: Partial<'input, BORROW>,
1441 n: u128,
1442 span: Span,
1443 ) -> Result<Partial<'input, BORROW>> {
1444 let shape = wip.shape();
1445 let size = match shape.layout {
1446 ShapeLayout::Sized(layout) => layout.size(),
1447 _ => {
1448 return Err(JsonError::new(
1449 JsonErrorKind::InvalidValue {
1450 message: "unsized integer".into(),
1451 },
1452 span,
1453 ));
1454 }
1455 };
1456
1457 if size == 16 {
1458 wip = wip.set(n)?;
1459 } else {
1460 if let Ok(n64) = u64::try_from(n) {
1462 wip = self.set_number_u64(wip, n64, span)?;
1463 } else {
1464 return Err(JsonError::new(
1465 JsonErrorKind::NumberOutOfRange {
1466 value: n.to_string(),
1467 target_type: shape.type_identifier,
1468 },
1469 span,
1470 ));
1471 }
1472 }
1473 Ok(wip)
1474 }
1475
1476 fn deserialize_struct(
1478 &mut self,
1479 wip: Partial<'input, BORROW>,
1480 ) -> Result<Partial<'input, BORROW>> {
1481 log::trace!("deserialize_struct: {}", wip.shape().type_identifier);
1482
1483 let struct_def = match &wip.shape().ty {
1485 Type::User(UserType::Struct(s)) => s,
1486 _ => {
1487 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1488 message: "expected struct type".into(),
1489 }));
1490 }
1491 };
1492
1493 if Self::has_flatten_fields(struct_def) {
1495 return self.deserialize_struct_with_flatten(wip);
1496 }
1497
1498 self.deserialize_struct_simple(wip)
1500 }
1501
1502 fn deserialize_struct_simple(
1504 &mut self,
1505 mut wip: Partial<'input, BORROW>,
1506 ) -> Result<Partial<'input, BORROW>> {
1507 let open_token = self.next()?;
1509 let object_start_span = match open_token.token {
1510 Token::ObjectStart => open_token.span,
1511 _ => {
1512 return Err(JsonError::new(
1513 JsonErrorKind::UnexpectedToken {
1514 got: format!("{:?}", open_token.token),
1515 expected: "'{'",
1516 },
1517 open_token.span,
1518 ));
1519 }
1520 };
1521
1522 let struct_def = match &wip.shape().ty {
1524 Type::User(UserType::Struct(s)) => s,
1525 _ => {
1526 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1527 message: "expected struct type".into(),
1528 }));
1529 }
1530 };
1531
1532 let num_fields = struct_def.fields.len();
1534 let mut fields_set = alloc::vec![false; num_fields];
1535
1536 #[allow(unused_assignments)]
1538 let mut object_end_span: Option<Span> = None;
1539
1540 let struct_has_default = wip.shape().has_default_attr();
1542 let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
1544
1545 loop {
1547 let token = self.peek()?;
1548 match &token.token {
1549 Token::ObjectEnd => {
1550 let close_token = self.next()?; object_end_span = Some(close_token.span);
1552 break;
1553 }
1554 Token::String(_) => {
1555 let key_token = self.next()?;
1557 let key = match key_token.token {
1558 Token::String(s) => s,
1559 _ => unreachable!(),
1560 };
1561 let _key_span = key_token.span;
1562
1563 let colon = self.next()?;
1565 if !matches!(colon.token, Token::Colon) {
1566 return Err(JsonError::new(
1567 JsonErrorKind::UnexpectedToken {
1568 got: format!("{:?}", colon.token),
1569 expected: "':'",
1570 },
1571 colon.span,
1572 ));
1573 }
1574
1575 let field_info = struct_def
1577 .fields
1578 .iter()
1579 .enumerate()
1580 .find(|(_, f)| f.name == key.as_ref());
1581
1582 if let Some((idx, field)) = field_info {
1583 wip = wip.begin_field(field.name)?;
1584 if field.proxy_convert_in_fn().is_some() {
1586 wip = wip.begin_custom_deserialization()?;
1587 wip = self.deserialize_into(wip)?;
1588 wip = wip.end()?; } else {
1590 wip = self.deserialize_into(wip)?;
1591 }
1592 wip = wip.end()?;
1593 fields_set[idx] = true;
1594 } else {
1595 if deny_unknown_fields {
1597 let expected_fields: Vec<&'static str> =
1598 struct_def.fields.iter().map(|f| f.name).collect();
1599 let suggestion = find_similar_field(&key, &expected_fields);
1600 return Err(JsonError::new(
1601 JsonErrorKind::UnknownField {
1602 field: key.into_owned(),
1603 expected: expected_fields,
1604 suggestion,
1605 },
1606 _key_span,
1607 ));
1608 }
1609 log::trace!("skipping unknown field: {key}");
1610 self.skip_value()?;
1611 }
1612
1613 let next = self.peek()?;
1615 if matches!(next.token, Token::Comma) {
1616 self.next()?; }
1618 }
1619 _ => {
1620 let span = token.span;
1621 return Err(JsonError::new(
1622 JsonErrorKind::UnexpectedToken {
1623 got: format!("{:?}", token.token),
1624 expected: "field name or '}'",
1625 },
1626 span,
1627 ));
1628 }
1629 }
1630 }
1631
1632 for (idx, field) in struct_def.fields.iter().enumerate() {
1634 if fields_set[idx] {
1635 continue; }
1637
1638 let field_has_default = field.has_default();
1642 let field_type_has_default = field.shape().is(Characteristic::Default);
1643 let field_is_option = matches!(field.shape().def, Def::Option(_));
1644
1645 if field_has_default {
1646 wip = wip.set_nth_field_to_default(idx)?;
1648 } else if struct_has_default && field_type_has_default {
1649 wip = wip.set_nth_field_to_default(idx)?;
1651 } else if field_is_option {
1652 wip = wip.begin_field(field.name)?;
1654 wip = wip.set_default()?;
1655 wip = wip.end()?;
1656 } else {
1657 return Err(JsonError {
1659 kind: JsonErrorKind::MissingField {
1660 field: field.name,
1661 object_start: Some(object_start_span),
1662 object_end: object_end_span,
1663 },
1664 span: None, source_code: None,
1666 });
1667 }
1668 }
1669
1670 Ok(wip)
1671 }
1672
1673 fn deserialize_struct_with_flatten(
1679 &mut self,
1680 mut wip: Partial<'input, BORROW>,
1681 ) -> Result<Partial<'input, BORROW>> {
1682 log::trace!(
1683 "deserialize_struct_with_flatten: {wip}",
1684 wip = wip.shape().type_identifier
1685 );
1686
1687 let schema = Schema::build_auto(wip.shape()).map_err(|e| {
1690 JsonError::without_span(JsonErrorKind::Solver(format!(
1691 "failed to build schema: {e}"
1692 )))
1693 })?;
1694
1695 let mut solver = Solver::new(&schema);
1697
1698 let mut field_positions: Vec<(Cow<'input, str>, usize)> = Vec::new();
1700
1701 let token = self.next()?;
1703 match token.token {
1704 Token::ObjectStart => {}
1705 _ => {
1706 return Err(JsonError::new(
1707 JsonErrorKind::UnexpectedToken {
1708 got: format!("{:?}", token.token),
1709 expected: "'{'",
1710 },
1711 token.span,
1712 ));
1713 }
1714 }
1715
1716 loop {
1718 let token = self.peek()?;
1719 match &token.token {
1720 Token::ObjectEnd => {
1721 self.next()?; break;
1723 }
1724 Token::String(_) => {
1725 let key_token = self.next()?;
1727 let key = match &key_token.token {
1728 Token::String(s) => s.clone(),
1729 _ => unreachable!(),
1730 };
1731
1732 let colon = self.next()?;
1734 if !matches!(colon.token, Token::Colon) {
1735 return Err(JsonError::new(
1736 JsonErrorKind::UnexpectedToken {
1737 got: format!("{:?}", colon.token),
1738 expected: "':'",
1739 },
1740 colon.span,
1741 ));
1742 }
1743
1744 let value_start = self.peek()?.span.offset;
1746
1747 let _decision = solver.see_key(key.clone());
1749
1750 field_positions.push((key, value_start));
1751
1752 self.skip_value()?;
1754
1755 let next = self.peek()?;
1757 if matches!(next.token, Token::Comma) {
1758 self.next()?;
1759 }
1760 }
1761 _ => {
1762 let span = token.span;
1763 return Err(JsonError::new(
1764 JsonErrorKind::UnexpectedToken {
1765 got: format!("{:?}", token.token),
1766 expected: "field name or '}'",
1767 },
1768 span,
1769 ));
1770 }
1771 }
1772 }
1773
1774 let seen_keys = solver.seen_keys().clone();
1777 let config_handle = solver
1778 .finish()
1779 .map_err(|e| JsonError::without_span(JsonErrorKind::Solver(format!("{e}"))))?;
1780 let config = config_handle.resolution();
1781
1782 let mut fields_to_process: Vec<_> = field_positions
1786 .iter()
1787 .filter_map(|(key, offset)| config.field(key.as_ref()).map(|info| (info, *offset)))
1788 .collect();
1789
1790 fields_to_process.sort_by(|(a, _), (b, _)| a.path.segments().cmp(b.path.segments()));
1793
1794 let missing_optional_fields: Vec<&FieldInfo> =
1796 config.missing_optional_fields(&seen_keys).collect();
1797
1798 let mut defaults_by_first_segment: BTreeMap<&str, Vec<&FieldInfo>> = BTreeMap::new();
1799 for info in &missing_optional_fields {
1800 if let Some(PathSegment::Field(name)) = info.path.segments().first() {
1801 defaults_by_first_segment
1802 .entry(name)
1803 .or_default()
1804 .push(*info);
1805 }
1806 }
1807
1808 let processed_first_segments: BTreeSet<&str> = fields_to_process
1809 .iter()
1810 .filter_map(|(info, _)| {
1811 if let Some(PathSegment::Field(name)) = info.path.segments().first() {
1812 Some(*name)
1813 } else {
1814 None
1815 }
1816 })
1817 .collect();
1818
1819 let missing_first_segments: BTreeSet<&str> =
1820 defaults_by_first_segment.keys().copied().collect();
1821
1822 for first_field in &missing_first_segments {
1823 if processed_first_segments.contains(first_field) {
1824 continue;
1825 }
1826
1827 wip = wip.begin_field(first_field)?;
1828 if matches!(wip.shape().def, Def::Option(_)) {
1829 wip = wip.set_default()?;
1830 defaults_by_first_segment.remove(first_field);
1831 }
1832 wip = wip.end()?;
1833 }
1834
1835 let mut open_segments: Vec<(&str, bool)> = Vec::new();
1837
1838 for (field_info, offset) in &fields_to_process {
1839 let segments = field_info.path.segments();
1840 let offset = *offset;
1841
1842 let field_segments: Vec<&str> = segments
1844 .iter()
1845 .filter_map(|s| match s {
1846 PathSegment::Field(name) => Some(*name),
1847 PathSegment::Variant(_, _) => None,
1848 })
1849 .collect();
1850
1851 let common_len = open_segments
1853 .iter()
1854 .zip(field_segments.iter())
1855 .take_while(|((name, _), b)| *name == **b)
1856 .count();
1857
1858 while open_segments.len() > common_len {
1860 let (segment_name, is_option) = open_segments.pop().unwrap();
1861 wip = self.apply_defaults_for_segment(
1862 wip,
1863 segment_name,
1864 &mut defaults_by_first_segment,
1865 )?;
1866 if is_option {
1867 wip = wip.end()?; }
1869 wip = wip.end()?; }
1871
1872 for &segment in &field_segments[common_len..] {
1874 wip = wip.begin_field(segment)?;
1875 let is_option = matches!(wip.shape().def, Def::Option(_));
1877 if is_option {
1878 wip = wip.begin_some()?;
1879 }
1880 open_segments.push((segment, is_option));
1881 }
1882
1883 let ends_with_variant = segments
1885 .last()
1886 .is_some_and(|s| matches!(s, PathSegment::Variant(_, _)));
1887
1888 if ends_with_variant
1889 && let Some(PathSegment::Variant(_, variant_name)) = segments.last()
1890 {
1891 wip = wip.select_variant_named(variant_name)?;
1892 }
1893
1894 let sub_adapter = self.adapter.at_offset(offset).ok_or_else(|| {
1898 JsonError::without_span(JsonErrorKind::InvalidValue {
1899 message: "flatten is not supported in streaming mode".into(),
1900 })
1901 })?;
1902 let mut sub = Self::from_adapter(sub_adapter);
1903
1904 if ends_with_variant {
1905 wip = sub.deserialize_variant_struct_content(wip)?;
1906 } else {
1907 if !open_segments.is_empty() {
1910 let (segment_name, is_option) = open_segments.pop().unwrap();
1911 wip = self.apply_defaults_for_segment(
1912 wip,
1913 segment_name,
1914 &mut defaults_by_first_segment,
1915 )?;
1916 wip = sub.deserialize_into(wip)?;
1917 wip = wip.end()?;
1918 if is_option {
1919 wip = wip.end()?; }
1921 } else {
1922 wip = sub.deserialize_into(wip)?;
1923 }
1924 }
1925 }
1926
1927 while let Some((segment_name, is_option)) = open_segments.pop() {
1929 wip =
1930 self.apply_defaults_for_segment(wip, segment_name, &mut defaults_by_first_segment)?;
1931 if is_option {
1932 wip = wip.end()?; }
1934 wip = wip.end()?; }
1936 for infos in defaults_by_first_segment.into_values() {
1937 for info in infos {
1938 wip = self.set_missing_field_default(wip, info, false)?;
1939 }
1940 }
1941
1942 Ok(wip)
1943 }
1944
1945 fn deserialize_enum(
1949 &mut self,
1950 mut wip: Partial<'input, BORROW>,
1951 ) -> Result<Partial<'input, BORROW>> {
1952 log::trace!("deserialize_enum: {}", wip.shape().type_identifier);
1953
1954 if wip.shape().is_untagged() {
1956 return self.deserialize_untagged_enum(wip);
1957 }
1958
1959 let token = self.peek()?;
1960
1961 match &token.token {
1962 Token::String(s) => {
1964 let variant_name = s.clone();
1965 self.next()?; wip = wip.select_variant_named(&variant_name)?;
1968 Ok(wip)
1970 }
1971 Token::ObjectStart => {
1973 self.next()?; let key_token = self.next()?;
1977 let key = match &key_token.token {
1978 Token::String(s) => s.clone(),
1979 Token::ObjectEnd => {
1980 return Err(JsonError::new(
1982 JsonErrorKind::InvalidValue {
1983 message: "empty object cannot represent enum variant".into(),
1984 },
1985 key_token.span,
1986 ));
1987 }
1988 _ => {
1989 return Err(JsonError::new(
1990 JsonErrorKind::UnexpectedToken {
1991 got: format!("{:?}", key_token.token),
1992 expected: "variant name",
1993 },
1994 key_token.span,
1995 ));
1996 }
1997 };
1998
1999 let colon = self.next()?;
2001 if !matches!(colon.token, Token::Colon) {
2002 return Err(JsonError::new(
2003 JsonErrorKind::UnexpectedToken {
2004 got: format!("{:?}", colon.token),
2005 expected: "':'",
2006 },
2007 colon.span,
2008 ));
2009 }
2010
2011 wip = wip.select_variant_named(&key)?;
2013
2014 let variant = wip.selected_variant().ok_or_else(|| {
2016 JsonError::without_span(JsonErrorKind::InvalidValue {
2017 message: "failed to get selected variant".into(),
2018 })
2019 })?;
2020
2021 match variant.data.kind {
2023 StructKind::Unit => {
2024 let tok = self.next()?;
2027 if !matches!(tok.token, Token::Null) {
2028 return Err(JsonError::new(
2029 JsonErrorKind::UnexpectedToken {
2030 got: format!("{:?}", tok.token),
2031 expected: "null for unit variant",
2032 },
2033 tok.span,
2034 ));
2035 }
2036 }
2037 StructKind::TupleStruct | StructKind::Tuple => {
2038 let num_fields = variant.data.fields.len();
2039 if num_fields == 0 {
2040 let tok = self.peek()?;
2042 if matches!(tok.token, Token::Null) {
2043 self.next()?;
2044 }
2045 } else if num_fields == 1 {
2046 let field = &variant.data.fields[0];
2048 wip = wip.begin_nth_field(0)?;
2049 if field.proxy_convert_in_fn().is_some() {
2051 wip = wip.begin_custom_deserialization()?;
2052 wip = self.deserialize_into(wip)?;
2053 wip = wip.end()?; } else {
2055 wip = self.deserialize_into(wip)?;
2056 }
2057 wip = wip.end()?;
2058 } else {
2059 let tok = self.next()?;
2061 if !matches!(tok.token, Token::ArrayStart) {
2062 return Err(JsonError::new(
2063 JsonErrorKind::UnexpectedToken {
2064 got: format!("{:?}", tok.token),
2065 expected: "'[' for tuple variant",
2066 },
2067 tok.span,
2068 ));
2069 }
2070
2071 for i in 0..num_fields {
2072 let field = &variant.data.fields[i];
2073 wip = wip.begin_nth_field(i)?;
2074 if field.proxy_convert_in_fn().is_some() {
2076 wip = wip.begin_custom_deserialization()?;
2077 wip = self.deserialize_into(wip)?;
2078 wip = wip.end()?; } else {
2080 wip = self.deserialize_into(wip)?;
2081 }
2082 wip = wip.end()?;
2083
2084 let next = self.peek()?;
2086 if matches!(next.token, Token::Comma) {
2087 self.next()?;
2088 }
2089 }
2090
2091 let close = self.next()?;
2092 if !matches!(close.token, Token::ArrayEnd) {
2093 return Err(JsonError::new(
2094 JsonErrorKind::UnexpectedToken {
2095 got: format!("{:?}", close.token),
2096 expected: "']'",
2097 },
2098 close.span,
2099 ));
2100 }
2101 }
2102 }
2103 StructKind::Struct => {
2104 wip = self.deserialize_variant_struct_content(wip)?;
2106 }
2107 }
2108
2109 let close = self.next()?;
2111 if !matches!(close.token, Token::ObjectEnd) {
2112 return Err(JsonError::new(
2113 JsonErrorKind::UnexpectedToken {
2114 got: format!("{:?}", close.token),
2115 expected: "'}'",
2116 },
2117 close.span,
2118 ));
2119 }
2120
2121 Ok(wip)
2122 }
2123 _ => {
2124 let span = token.span;
2125 Err(JsonError::new(
2126 JsonErrorKind::UnexpectedToken {
2127 got: format!("{:?}", token.token),
2128 expected: "string or object for enum",
2129 },
2130 span,
2131 ))
2132 }
2133 }
2134 }
2135
2136 fn deserialize_untagged_enum(
2144 &mut self,
2145 mut wip: Partial<'input, BORROW>,
2146 ) -> Result<Partial<'input, BORROW>> {
2147 log::trace!("deserialize_untagged_enum: {}", wip.shape().type_identifier);
2148
2149 let shape = wip.shape();
2150
2151 let schema = Schema::build_auto(shape).map_err(|e| {
2153 JsonError::without_span(JsonErrorKind::Solver(format!(
2154 "failed to build schema: {e}"
2155 )))
2156 })?;
2157
2158 let mut solver = Solver::new(&schema);
2160
2161 let token = self.peek()?;
2163 match &token.token {
2164 Token::ObjectStart => {
2165 let start_offset = token.span.offset;
2167
2168 self.next()?; loop {
2172 let token = self.peek()?;
2173 match &token.token {
2174 Token::ObjectEnd => {
2175 self.next()?;
2176 break;
2177 }
2178 Token::String(_) => {
2179 let key_token = self.next()?;
2180 let key = match &key_token.token {
2181 Token::String(s) => s.clone(),
2182 _ => unreachable!(),
2183 };
2184
2185 let colon = self.next()?;
2186 if !matches!(colon.token, Token::Colon) {
2187 return Err(JsonError::new(
2188 JsonErrorKind::UnexpectedToken {
2189 got: format!("{:?}", colon.token),
2190 expected: "':'",
2191 },
2192 colon.span,
2193 ));
2194 }
2195
2196 let _decision = solver.see_key(key);
2198
2199 self.skip_value()?;
2201
2202 let next = self.peek()?;
2204 if matches!(next.token, Token::Comma) {
2205 self.next()?;
2206 }
2207 }
2208 _ => {
2209 let span = token.span;
2210 return Err(JsonError::new(
2211 JsonErrorKind::UnexpectedToken {
2212 got: format!("{:?}", token.token),
2213 expected: "field name or '}'",
2214 },
2215 span,
2216 ));
2217 }
2218 }
2219 }
2220
2221 let config_handle = solver
2223 .finish()
2224 .map_err(|e| JsonError::without_span(JsonErrorKind::Solver(format!("{e}"))))?;
2225 let config = config_handle.resolution();
2226
2227 let variant_name = config
2229 .variant_selections()
2230 .first()
2231 .map(|vs| vs.variant_name)
2232 .ok_or_else(|| {
2233 JsonError::without_span(JsonErrorKind::InvalidValue {
2234 message: "solver returned resolution with no variant selection".into(),
2235 })
2236 })?;
2237
2238 wip = wip.select_variant_named(variant_name)?;
2240
2241 let rewound_adapter = self.adapter.at_offset(start_offset).ok_or_else(|| {
2244 JsonError::without_span(JsonErrorKind::InvalidValue {
2245 message: "untagged enums not supported in streaming mode".into(),
2246 })
2247 })?;
2248 let mut rewound_deser = Self::from_adapter(rewound_adapter);
2249
2250 wip = rewound_deser.deserialize_variant_struct_content(wip)?;
2252
2253 Ok(wip)
2254 }
2255 Token::ArrayStart => {
2256 self.deserialize_untagged_tuple_variant(wip, shape)
2258 }
2259 Token::Null => {
2260 self.deserialize_untagged_unit_variant(wip, shape)
2262 }
2263 Token::String(_)
2264 | Token::I64(_)
2265 | Token::U64(_)
2266 | Token::I128(_)
2267 | Token::U128(_)
2268 | Token::F64(_)
2269 | Token::True
2270 | Token::False => {
2271 self.deserialize_untagged_scalar_variant(wip, shape)
2273 }
2274 _ => Err(JsonError::new(
2275 JsonErrorKind::InvalidValue {
2276 message: format!("unexpected token {:?} for untagged enum", token.token),
2277 },
2278 token.span,
2279 )),
2280 }
2281 }
2282
2283 fn deserialize_untagged_unit_variant(
2286 &mut self,
2287 mut wip: Partial<'input, BORROW>,
2288 shape: &'static Shape,
2289 ) -> Result<Partial<'input, BORROW>> {
2290 let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2291 JsonError::without_span(JsonErrorKind::InvalidValue {
2292 message: "expected enum shape for untagged deserialization".into(),
2293 })
2294 })?;
2295
2296 if variants_by_format.unit_variants.is_empty() {
2297 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2298 message: format!(
2299 "no unit variants in untagged enum {} for null value",
2300 shape.type_identifier
2301 ),
2302 }));
2303 }
2304
2305 self.next()?;
2307
2308 let variant = variants_by_format.unit_variants[0];
2310 wip = wip.select_variant_named(variant.name)?;
2311
2312 Ok(wip)
2313 }
2314
2315 fn deserialize_untagged_scalar_variant(
2318 &mut self,
2319 mut wip: Partial<'input, BORROW>,
2320 shape: &'static Shape,
2321 ) -> Result<Partial<'input, BORROW>> {
2322 let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2323 JsonError::without_span(JsonErrorKind::InvalidValue {
2324 message: "expected enum shape for untagged deserialization".into(),
2325 })
2326 })?;
2327
2328 let token = self.peek()?.clone();
2330 if let Token::String(ref s) = token.token {
2331 for variant in &variants_by_format.unit_variants {
2333 if variant.name == s.as_ref() {
2334 self.next()?;
2336 wip = wip.select_variant_named(variant.name)?;
2337 return Ok(wip);
2338 }
2339 }
2340 }
2341
2342 if variants_by_format.scalar_variants.is_empty() {
2344 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2345 message: format!(
2346 "no scalar-accepting variants in untagged enum {}",
2347 shape.type_identifier
2348 ),
2349 }));
2350 }
2351
2352 let variant_name = self.select_scalar_variant(&variants_by_format, &token)?;
2354
2355 wip = wip.select_variant_named(variant_name)?;
2356 wip = wip.begin_nth_field(0)?;
2357 wip = self.deserialize_into(wip)?;
2358 wip = wip.end()?;
2359
2360 Ok(wip)
2361 }
2362
2363 fn select_scalar_variant(
2365 &self,
2366 variants: &VariantsByFormat,
2367 token: &SpannedAdapterToken,
2368 ) -> Result<&'static str> {
2369 let mut candidates: Vec<_> = variants.scalar_variants.clone();
2371 candidates.sort_by_key(|(_, inner_shape)| specificity_score(inner_shape));
2372
2373 match &token.token {
2374 Token::True | Token::False => {
2375 for (variant, inner_shape) in &candidates {
2377 if inner_shape.scalar_type() == Some(ScalarType::Bool) {
2378 return Ok(variant.name);
2379 }
2380 }
2381 }
2382 Token::I64(n) => {
2383 let n = *n;
2385 for (variant, inner_shape) in &candidates {
2386 let fits = match inner_shape.scalar_type() {
2387 Some(ScalarType::U8) => n >= 0 && n <= u8::MAX as i64,
2388 Some(ScalarType::U16) => n >= 0 && n <= u16::MAX as i64,
2389 Some(ScalarType::U32) => n >= 0 && n <= u32::MAX as i64,
2390 Some(ScalarType::U64) => n >= 0,
2391 Some(ScalarType::I8) => n >= i8::MIN as i64 && n <= i8::MAX as i64,
2392 Some(ScalarType::I16) => n >= i16::MIN as i64 && n <= i16::MAX as i64,
2393 Some(ScalarType::I32) => n >= i32::MIN as i64 && n <= i32::MAX as i64,
2394 Some(ScalarType::I64) => true,
2395 Some(ScalarType::F32) | Some(ScalarType::F64) => true,
2396 _ => false,
2397 };
2398 if fits {
2399 return Ok(variant.name);
2400 }
2401 }
2402 }
2403 Token::U64(n) => {
2404 let n = *n;
2405 for (variant, inner_shape) in &candidates {
2406 let fits = match inner_shape.scalar_type() {
2407 Some(ScalarType::U8) => n <= u8::MAX as u64,
2408 Some(ScalarType::U16) => n <= u16::MAX as u64,
2409 Some(ScalarType::U32) => n <= u32::MAX as u64,
2410 Some(ScalarType::U64) => true,
2411 Some(ScalarType::I8) => n <= i8::MAX as u64,
2412 Some(ScalarType::I16) => n <= i16::MAX as u64,
2413 Some(ScalarType::I32) => n <= i32::MAX as u64,
2414 Some(ScalarType::I64) => n <= i64::MAX as u64,
2415 Some(ScalarType::F32) | Some(ScalarType::F64) => true,
2416 _ => false,
2417 };
2418 if fits {
2419 return Ok(variant.name);
2420 }
2421 }
2422 }
2423 Token::I128(n) => {
2424 let n = *n;
2425 for (variant, inner_shape) in &candidates {
2426 let fits = match inner_shape.scalar_type() {
2427 Some(ScalarType::I128) => true,
2428 Some(ScalarType::U128) => n >= 0,
2429 _ => false,
2430 };
2431 if fits {
2432 return Ok(variant.name);
2433 }
2434 }
2435 }
2436 Token::U128(n) => {
2437 let n = *n;
2438 for (variant, inner_shape) in &candidates {
2439 let fits = match inner_shape.scalar_type() {
2440 Some(ScalarType::U128) => true,
2441 Some(ScalarType::I128) => n <= i128::MAX as u128,
2442 _ => false,
2443 };
2444 if fits {
2445 return Ok(variant.name);
2446 }
2447 }
2448 }
2449 Token::F64(_) => {
2450 for (variant, inner_shape) in &candidates {
2452 if matches!(
2453 inner_shape.scalar_type(),
2454 Some(ScalarType::F32) | Some(ScalarType::F64)
2455 ) {
2456 return Ok(variant.name);
2457 }
2458 }
2459 }
2460 Token::String(_) => {
2461 for (variant, inner_shape) in &candidates {
2463 if matches!(
2464 inner_shape.scalar_type(),
2465 Some(ScalarType::String) | Some(ScalarType::Str) | Some(ScalarType::CowStr)
2466 ) || inner_shape.scalar_type().is_none()
2467 {
2468 return Ok(variant.name);
2469 }
2470 }
2471 }
2472 _ => {}
2473 }
2474
2475 if let Some((variant, _)) = candidates.first() {
2477 return Ok(variant.name);
2478 }
2479
2480 Err(JsonError::new(
2481 JsonErrorKind::InvalidValue {
2482 message: format!("no matching scalar variant for token {:?}", token.token),
2483 },
2484 token.span,
2485 ))
2486 }
2487
2488 fn deserialize_untagged_tuple_variant(
2490 &mut self,
2491 mut wip: Partial<'input, BORROW>,
2492 shape: &'static Shape,
2493 ) -> Result<Partial<'input, BORROW>> {
2494 let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2495 JsonError::without_span(JsonErrorKind::InvalidValue {
2496 message: "expected enum shape for untagged deserialization".into(),
2497 })
2498 })?;
2499
2500 if variants_by_format.tuple_variants.is_empty() {
2501 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2502 message: format!(
2503 "no tuple variants in untagged enum {} for array value",
2504 shape.type_identifier
2505 ),
2506 }));
2507 }
2508
2509 let start_token = self.peek()?;
2511 let start_offset = start_token.span.offset;
2512
2513 self.next()?; let mut arity = 0;
2516 loop {
2517 let token = self.peek()?;
2518 match &token.token {
2519 Token::ArrayEnd => {
2520 self.next()?;
2521 break;
2522 }
2523 _ => {
2524 arity += 1;
2525 self.skip_value()?;
2526 let next = self.peek()?;
2528 if matches!(next.token, Token::Comma) {
2529 self.next()?;
2530 }
2531 }
2532 }
2533 }
2534
2535 let matching_variants = variants_by_format.tuple_variants_with_arity(arity);
2537 if matching_variants.is_empty() {
2538 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2539 message: format!(
2540 "no tuple variant with arity {} in untagged enum {}",
2541 arity, shape.type_identifier
2542 ),
2543 }));
2544 }
2545
2546 let variant = matching_variants[0];
2548 wip = wip.select_variant_named(variant.name)?;
2549 let is_newtype = variant.data.fields.len() == 1;
2550
2551 let rewound_adapter = self.adapter.at_offset(start_offset).ok_or_else(|| {
2553 JsonError::without_span(JsonErrorKind::InvalidValue {
2554 message: "untagged tuple variants not supported in streaming mode".into(),
2555 })
2556 })?;
2557 let mut rewound_deser = Self::from_adapter(rewound_adapter);
2558
2559 if is_newtype {
2560 wip = wip.begin_nth_field(0)?;
2562 wip = rewound_deser.deserialize_into(wip)?;
2563 wip = wip.end()?;
2564 } else {
2565 rewound_deser.next()?;
2567
2568 for i in 0..arity {
2570 wip = wip.begin_nth_field(i)?;
2571 wip = rewound_deser.deserialize_into(wip)?;
2572 wip = wip.end()?;
2573
2574 let next = rewound_deser.peek()?;
2576 if matches!(next.token, Token::Comma) {
2577 rewound_deser.next()?;
2578 }
2579 }
2580
2581 debug_assert_eq!(
2582 variant.data.fields.len(),
2583 arity,
2584 "tuple variant arity should match array length"
2585 );
2586
2587 rewound_deser.next()?;
2589 }
2590
2591 Ok(wip)
2592 }
2593
2594 fn deserialize_variant_struct_content(
2597 &mut self,
2598 mut wip: Partial<'input, BORROW>,
2599 ) -> Result<Partial<'input, BORROW>> {
2600 let variant = wip.selected_variant().ok_or_else(|| {
2602 JsonError::without_span(JsonErrorKind::InvalidValue {
2603 message: "no variant selected".into(),
2604 })
2605 })?;
2606
2607 let is_struct_variant = variant
2608 .data
2609 .fields
2610 .first()
2611 .map(|f| !f.name.starts_with(|c: char| c.is_ascii_digit()))
2612 .unwrap_or(true);
2613
2614 if is_struct_variant {
2615 self.deserialize_variant_struct_fields(wip, variant.data.fields)
2617 } else if variant.data.fields.len() == 1 {
2618 let field = &variant.data.fields[0];
2620 wip = wip.begin_nth_field(0)?;
2621 if field.proxy_convert_in_fn().is_some() {
2623 wip = wip.begin_custom_deserialization()?;
2624 wip = self.deserialize_into(wip)?;
2625 wip = wip.end()?;
2626 } else {
2627 wip = self.deserialize_into(wip)?;
2628 }
2629 wip = wip.end()?;
2630 Ok(wip)
2631 } else {
2632 self.deserialize_variant_tuple_fields(wip)
2634 }
2635 }
2636
2637 fn deserialize_variant_struct_fields(
2639 &mut self,
2640 mut wip: Partial<'input, BORROW>,
2641 fields: &[facet_core::Field],
2642 ) -> Result<Partial<'input, BORROW>> {
2643 let token = self.next()?;
2644 if !matches!(token.token, Token::ObjectStart) {
2645 return Err(JsonError::new(
2646 JsonErrorKind::UnexpectedToken {
2647 got: format!("{:?}", token.token),
2648 expected: "'{' for struct variant",
2649 },
2650 token.span,
2651 ));
2652 }
2653
2654 loop {
2655 let token = self.peek()?;
2656 if matches!(token.token, Token::ObjectEnd) {
2657 self.next()?;
2658 break;
2659 }
2660
2661 let key_token = self.next()?;
2662 let field_name = match &key_token.token {
2663 Token::String(s) => s.clone(),
2664 _ => {
2665 return Err(JsonError::new(
2666 JsonErrorKind::UnexpectedToken {
2667 got: format!("{:?}", key_token.token),
2668 expected: "field name",
2669 },
2670 key_token.span,
2671 ));
2672 }
2673 };
2674
2675 let colon = self.next()?;
2676 if !matches!(colon.token, Token::Colon) {
2677 return Err(JsonError::new(
2678 JsonErrorKind::UnexpectedToken {
2679 got: format!("{:?}", colon.token),
2680 expected: "':'",
2681 },
2682 colon.span,
2683 ));
2684 }
2685
2686 let field_info = fields.iter().find(|f| f.name == field_name.as_ref());
2688
2689 if let Some(field) = field_info {
2690 wip = wip.begin_field(field.name)?;
2691 if field.proxy_convert_in_fn().is_some() {
2693 wip = wip.begin_custom_deserialization()?;
2694 wip = self.deserialize_into(wip)?;
2695 wip = wip.end()?; } else {
2697 wip = self.deserialize_into(wip)?;
2698 }
2699 wip = wip.end()?;
2700 } else {
2701 self.skip_value()?;
2703 }
2704
2705 let next = self.peek()?;
2706 if matches!(next.token, Token::Comma) {
2707 self.next()?;
2708 }
2709 }
2710
2711 Ok(wip)
2712 }
2713
2714 fn deserialize_variant_tuple_fields(
2716 &mut self,
2717 mut wip: Partial<'input, BORROW>,
2718 ) -> Result<Partial<'input, BORROW>> {
2719 let token = self.next()?;
2720 if !matches!(token.token, Token::ArrayStart) {
2721 return Err(JsonError::new(
2722 JsonErrorKind::UnexpectedToken {
2723 got: format!("{:?}", token.token),
2724 expected: "'[' for tuple variant",
2725 },
2726 token.span,
2727 ));
2728 }
2729
2730 let mut idx = 0;
2731 loop {
2732 let token = self.peek()?;
2733 if matches!(token.token, Token::ArrayEnd) {
2734 self.next()?;
2735 break;
2736 }
2737
2738 let field_name = alloc::format!("{idx}");
2740 wip = wip.begin_field(&field_name)?;
2741 wip = self.deserialize_into(wip)?;
2742 wip = wip.end()?;
2743
2744 idx += 1;
2745 let next = self.peek()?;
2746 if matches!(next.token, Token::Comma) {
2747 self.next()?;
2748 }
2749 }
2750
2751 Ok(wip)
2752 }
2753
2754 fn deserialize_list(
2756 &mut self,
2757 mut wip: Partial<'input, BORROW>,
2758 ) -> Result<Partial<'input, BORROW>> {
2759 log::trace!("deserialize_list");
2760
2761 let token = self.next()?;
2762 if !matches!(token.token, Token::ArrayStart) {
2763 return Err(JsonError::new(
2764 JsonErrorKind::UnexpectedToken {
2765 got: format!("{:?}", token.token),
2766 expected: "'['",
2767 },
2768 token.span,
2769 ));
2770 }
2771
2772 wip = wip.begin_list()?;
2773
2774 loop {
2775 let token = self.peek()?;
2776 if matches!(token.token, Token::ArrayEnd) {
2777 self.next()?;
2778 break;
2779 }
2780
2781 wip = wip.begin_list_item()?;
2782 wip = self.deserialize_into(wip)?;
2783 wip = wip.end()?; let next = self.peek()?;
2786 if matches!(next.token, Token::Comma) {
2787 self.next()?;
2788 }
2789 }
2790
2791 Ok(wip)
2793 }
2794
2795 fn deserialize_map(
2797 &mut self,
2798 mut wip: Partial<'input, BORROW>,
2799 ) -> Result<Partial<'input, BORROW>> {
2800 log::trace!("deserialize_map");
2801
2802 let token = self.next()?;
2803 if !matches!(token.token, Token::ObjectStart) {
2804 return Err(JsonError::new(
2805 JsonErrorKind::UnexpectedToken {
2806 got: format!("{:?}", token.token),
2807 expected: "'{'",
2808 },
2809 token.span,
2810 ));
2811 }
2812
2813 wip = wip.begin_map()?;
2814
2815 loop {
2816 let token = self.peek()?;
2817 if matches!(token.token, Token::ObjectEnd) {
2818 self.next()?;
2819 break;
2820 }
2821
2822 let key_token = self.next()?;
2824 let key = match key_token.token {
2825 Token::String(s) => s,
2826 _ => {
2827 return Err(JsonError::new(
2828 JsonErrorKind::UnexpectedToken {
2829 got: format!("{:?}", key_token.token),
2830 expected: "string key",
2831 },
2832 key_token.span,
2833 ));
2834 }
2835 };
2836
2837 let colon = self.next()?;
2839 if !matches!(colon.token, Token::Colon) {
2840 return Err(JsonError::new(
2841 JsonErrorKind::UnexpectedToken {
2842 got: format!("{:?}", colon.token),
2843 expected: "':'",
2844 },
2845 colon.span,
2846 ));
2847 }
2848
2849 wip = wip.begin_key()?;
2851 let is_pointer = matches!(wip.shape().def, Def::Pointer(_));
2855 if wip.shape().inner.is_some() && !is_pointer {
2856 wip = wip.begin_inner()?;
2857 wip = self.set_string_value(wip, key)?;
2858 wip = wip.end()?;
2859 } else {
2860 wip = self.set_string_value(wip, key)?;
2861 }
2862 wip = wip.end()?;
2863
2864 wip = wip.begin_value()?;
2866 wip = self.deserialize_into(wip)?;
2867 wip = wip.end()?;
2868
2869 let next = self.peek()?;
2871 if matches!(next.token, Token::Comma) {
2872 self.next()?;
2873 }
2874 }
2875
2876 Ok(wip)
2878 }
2879
2880 fn deserialize_option(
2882 &mut self,
2883 mut wip: Partial<'input, BORROW>,
2884 ) -> Result<Partial<'input, BORROW>> {
2885 log::trace!("deserialize_option");
2886
2887 let token = self.peek()?;
2888 if matches!(token.token, Token::Null) {
2889 self.next()?;
2890 wip = wip.set_default()?; } else {
2892 log::trace!("deserialize_option: calling begin_some");
2893 wip = wip.begin_some()?;
2894 log::trace!("deserialize_option: begin_some succeeded, calling deserialize_into");
2895 wip = self.deserialize_into(wip)?;
2896 log::trace!("deserialize_option: deserialize_into succeeded, calling end");
2897 wip = wip.end()?;
2898 log::trace!("deserialize_option: end succeeded");
2899 }
2900 Ok(wip)
2901 }
2902
2903 fn deserialize_pointer(
2905 &mut self,
2906 mut wip: Partial<'input, BORROW>,
2907 ) -> Result<Partial<'input, BORROW>> {
2908 log::trace!("deserialize_pointer");
2909
2910 let (is_slice_pointer, is_reference, is_str_ref, is_cow_str) =
2912 if let Def::Pointer(ptr_def) = wip.shape().def {
2913 let is_slice = if let Some(pointee) = ptr_def.pointee() {
2914 matches!(pointee.ty, Type::Sequence(SequenceType::Slice(_)))
2915 } else {
2916 false
2917 };
2918 let is_ref = matches!(
2919 ptr_def.known,
2920 Some(KnownPointer::SharedReference | KnownPointer::ExclusiveReference)
2921 );
2922 let is_str_ref = matches!(ptr_def.known, Some(KnownPointer::SharedReference))
2924 && ptr_def
2925 .pointee()
2926 .is_some_and(|p| p.type_identifier == "str");
2927 let is_cow_str = matches!(ptr_def.known, Some(KnownPointer::Cow))
2929 && ptr_def
2930 .pointee()
2931 .is_some_and(|p| p.type_identifier == "str");
2932 (is_slice, is_ref, is_str_ref, is_cow_str)
2933 } else {
2934 (false, false, false, false)
2935 };
2936
2937 if is_cow_str {
2940 let token = self.next()?;
2941 match token.token {
2942 Token::String(s) => {
2943 wip = wip.set(s)?;
2945 return Ok(wip);
2946 }
2947 _ => {
2948 return Err(JsonError::new(
2949 JsonErrorKind::UnexpectedToken {
2950 got: format!("{:?}", token.token),
2951 expected: "string",
2952 },
2953 token.span,
2954 ));
2955 }
2956 }
2957 }
2958
2959 if is_str_ref {
2961 if !BORROW {
2963 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2964 message: "cannot deserialize into &str when borrowing is disabled - use String or Cow<str> instead".into(),
2965 }));
2966 }
2967 let token = self.next()?;
2968 match token.token {
2969 Token::String(Cow::Borrowed(s)) => {
2970 wip = wip.set(s)?;
2972 return Ok(wip);
2973 }
2974 Token::String(Cow::Owned(_)) => {
2975 return Err(JsonError::new(
2976 JsonErrorKind::InvalidValue {
2977 message: "cannot borrow &str from JSON string containing escape sequences - use String instead".into(),
2978 },
2979 token.span,
2980 ));
2981 }
2982 _ => {
2983 return Err(JsonError::new(
2984 JsonErrorKind::UnexpectedToken {
2985 got: format!("{:?}", token.token),
2986 expected: "string",
2987 },
2988 token.span,
2989 ));
2990 }
2991 }
2992 }
2993
2994 if is_reference {
2997 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2998 message: format!(
2999 "cannot deserialize into reference type '{wip}' - references require borrowing from existing data",
3000 wip = wip.shape().type_identifier
3001 ),
3002 }));
3003 }
3004
3005 wip = wip.begin_smart_ptr()?;
3010
3011 if is_slice_pointer {
3012 let token = self.next()?;
3014 if !matches!(token.token, Token::ArrayStart) {
3015 return Err(JsonError::new(
3016 JsonErrorKind::UnexpectedToken {
3017 got: format!("{:?}", token.token),
3018 expected: "'['",
3019 },
3020 token.span,
3021 ));
3022 }
3023
3024 let first = self.peek()?;
3026 if matches!(first.token, Token::ArrayEnd) {
3027 self.next()?; wip = wip.end()?;
3029 return Ok(wip);
3030 }
3031
3032 loop {
3034 wip = wip.begin_list_item()?;
3035 wip = self.deserialize_into(wip)?;
3036 wip = wip.end()?;
3037
3038 let next = self.next()?;
3039 match next.token {
3040 Token::Comma => continue,
3041 Token::ArrayEnd => break,
3042 _ => {
3043 return Err(JsonError::new(
3044 JsonErrorKind::UnexpectedToken {
3045 got: format!("{:?}", next.token),
3046 expected: "',' or ']'",
3047 },
3048 next.span,
3049 ));
3050 }
3051 }
3052 }
3053
3054 wip = wip.end()?;
3055 return Ok(wip);
3056 }
3057
3058 wip = self.deserialize_into(wip)?;
3060 wip = wip.end()?;
3061 Ok(wip)
3062 }
3063
3064 fn deserialize_array(
3066 &mut self,
3067 mut wip: Partial<'input, BORROW>,
3068 ) -> Result<Partial<'input, BORROW>> {
3069 log::trace!("deserialize_array");
3070
3071 let token = self.next()?;
3072 if !matches!(token.token, Token::ArrayStart) {
3073 return Err(JsonError::new(
3074 JsonErrorKind::UnexpectedToken {
3075 got: format!("{:?}", token.token),
3076 expected: "'['",
3077 },
3078 token.span,
3079 ));
3080 }
3081
3082 let array_len = match &wip.shape().def {
3084 Def::Array(arr) => arr.n,
3085 _ => {
3086 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
3087 message: "expected array type".into(),
3088 }));
3089 }
3090 };
3091
3092 for i in 0..array_len {
3094 if i > 0 {
3095 let comma = self.next()?;
3096 if !matches!(comma.token, Token::Comma) {
3097 return Err(JsonError::new(
3098 JsonErrorKind::UnexpectedToken {
3099 got: format!("{:?}", comma.token),
3100 expected: "','",
3101 },
3102 comma.span,
3103 ));
3104 }
3105 }
3106
3107 wip = wip.begin_nth_field(i)?;
3108 wip = self.deserialize_into(wip)?;
3109 wip = wip.end()?;
3110 }
3111
3112 let close = self.next()?;
3113 if !matches!(close.token, Token::ArrayEnd) {
3114 if matches!(close.token, Token::Comma) {
3116 return Err(JsonError::new(
3117 JsonErrorKind::InvalidValue {
3118 message: format!(
3119 "Too many elements in array, maximum {array_len} elements"
3120 ),
3121 },
3122 close.span,
3123 ));
3124 }
3125 return Err(JsonError::new(
3126 JsonErrorKind::UnexpectedToken {
3127 got: format!("{:?}", close.token),
3128 expected: "']'",
3129 },
3130 close.span,
3131 ));
3132 }
3133
3134 Ok(wip)
3135 }
3136
3137 fn deserialize_set(
3139 &mut self,
3140 mut wip: Partial<'input, BORROW>,
3141 ) -> Result<Partial<'input, BORROW>> {
3142 log::trace!("deserialize_set");
3143
3144 let token = self.next()?;
3145 if !matches!(token.token, Token::ArrayStart) {
3146 return Err(JsonError::new(
3147 JsonErrorKind::UnexpectedToken {
3148 got: format!("{:?}", token.token),
3149 expected: "'['",
3150 },
3151 token.span,
3152 ));
3153 }
3154
3155 wip = wip.begin_set()?;
3156
3157 loop {
3158 let token = self.peek()?;
3159 if matches!(token.token, Token::ArrayEnd) {
3160 self.next()?;
3161 break;
3162 }
3163
3164 wip = wip.begin_set_item()?;
3165 wip = self.deserialize_into(wip)?;
3166 wip = wip.end()?; let next = self.peek()?;
3169 if matches!(next.token, Token::Comma) {
3170 self.next()?;
3171 }
3172 }
3173
3174 Ok(wip)
3176 }
3177
3178 fn deserialize_tuple(
3180 &mut self,
3181 mut wip: Partial<'input, BORROW>,
3182 ) -> Result<Partial<'input, BORROW>> {
3183 log::trace!("deserialize_tuple");
3184
3185 let token = self.next()?;
3186 if !matches!(token.token, Token::ArrayStart) {
3187 return Err(JsonError::new(
3188 JsonErrorKind::UnexpectedToken {
3189 got: format!("{:?}", token.token),
3190 expected: "'['",
3191 },
3192 token.span,
3193 ));
3194 }
3195
3196 let tuple_len = match &wip.shape().ty {
3198 Type::User(UserType::Struct(struct_def)) => struct_def.fields.len(),
3199 _ => {
3200 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
3201 message: "expected tuple type".into(),
3202 }));
3203 }
3204 };
3205
3206 for i in 0..tuple_len {
3207 if i > 0 {
3208 let comma = self.next()?;
3209 if !matches!(comma.token, Token::Comma) {
3210 return Err(JsonError::new(
3211 JsonErrorKind::UnexpectedToken {
3212 got: format!("{:?}", comma.token),
3213 expected: "','",
3214 },
3215 comma.span,
3216 ));
3217 }
3218 }
3219
3220 wip = wip.begin_nth_field(i)?;
3221 wip = self.deserialize_into(wip)?;
3222 wip = wip.end()?;
3223 }
3224
3225 let close = self.next()?;
3226 if !matches!(close.token, Token::ArrayEnd) {
3227 return Err(JsonError::new(
3228 JsonErrorKind::UnexpectedToken {
3229 got: format!("{:?}", close.token),
3230 expected: "']'",
3231 },
3232 close.span,
3233 ));
3234 }
3235
3236 Ok(wip)
3237 }
3238
3239 fn set_missing_field_default(
3240 &mut self,
3241 mut wip: Partial<'input, BORROW>,
3242 field_info: &FieldInfo,
3243 skip_first_segment: bool,
3244 ) -> Result<Partial<'input, BORROW>> {
3245 log::trace!(
3246 "Initializing missing optional field '{}' via solver path {:?}",
3247 field_info.serialized_name,
3248 field_info.path
3249 );
3250 let segments = field_info.path.segments();
3251 if segments.is_empty() {
3252 return Self::apply_default_for_field(wip, field_info.field);
3253 }
3254
3255 #[allow(unused_mut, unused_variables)]
3256 let mut guards: Vec<PathGuard> = Vec::new();
3257
3258 for (idx, segment) in segments
3259 .iter()
3260 .take(segments.len().saturating_sub(1))
3261 .enumerate()
3262 {
3263 if skip_first_segment && idx == 0 {
3264 continue;
3265 }
3266 match segment {
3267 PathSegment::Field(name) => {
3268 wip = wip.begin_field(name)?;
3269 let is_option = matches!(wip.shape().def, Def::Option(_));
3270 if is_option {
3271 wip = wip.begin_some()?;
3272 }
3273 guards.push(PathGuard::Field {
3274 had_option: is_option,
3275 });
3276 }
3277 PathSegment::Variant(_, variant_name) => {
3278 wip = wip.select_variant_named(variant_name)?;
3279 guards.push(PathGuard::Variant);
3280 }
3281 }
3282 }
3283
3284 wip = Self::apply_default_for_field(wip, field_info.field)?;
3285
3286 while let Some(guard) = guards.pop() {
3287 match guard {
3288 PathGuard::Field { had_option } => {
3289 if had_option {
3290 wip = wip.end()?; }
3292 wip = wip.end()?; }
3294 PathGuard::Variant => {}
3295 }
3296 }
3297
3298 Ok(wip)
3299 }
3300
3301 fn apply_defaults_for_segment(
3302 &mut self,
3303 mut wip: Partial<'input, BORROW>,
3304 segment_name: &str,
3305 defaults_by_first_segment: &mut BTreeMap<&str, Vec<&FieldInfo>>,
3306 ) -> Result<Partial<'input, BORROW>> {
3307 if let Some(entries) = defaults_by_first_segment.remove(segment_name) {
3308 for info in entries {
3309 wip = self.set_missing_field_default(wip, info, true)?;
3310 }
3311 }
3312 Ok(wip)
3313 }
3314
3315 fn apply_default_for_field(
3316 mut wip: Partial<'input, BORROW>,
3317 target_field: &'static facet_core::Field,
3318 ) -> Result<Partial<'input, BORROW>> {
3319 let struct_def = match &wip.shape().ty {
3320 Type::User(UserType::Struct(def)) => def,
3321 _ => {
3322 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
3323 message: format!(
3324 "expected struct while setting default for field '{}'",
3325 target_field.name
3326 ),
3327 }));
3328 }
3329 };
3330
3331 let Some(idx) = struct_def
3332 .fields
3333 .iter()
3334 .position(|field| ptr::eq(field, target_field))
3335 else {
3336 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
3337 message: format!(
3338 "could not find field '{}' while applying default",
3339 target_field.name
3340 ),
3341 }));
3342 };
3343
3344 if target_field.has_default() {
3345 wip = wip.set_nth_field_to_default(idx)?;
3346 } else if matches!(target_field.shape().def, Def::Option(_)) {
3347 wip = wip.begin_nth_field(idx)?;
3349 wip = wip.set_default()?;
3350 wip = wip.end()?;
3351 } else {
3352 wip = wip.set_nth_field_to_default(idx)?;
3354 }
3355
3356 Ok(wip)
3357 }
3358}
3359
3360#[derive(Debug)]
3361enum PathGuard {
3362 Field { had_option: bool },
3363 Variant,
3364}
3365
3366pub fn from_slice<T: Facet<'static>>(input: &[u8]) -> Result<T> {
3383 from_slice_inner(input, None)
3384}
3385
3386pub fn from_str<T: Facet<'static>>(input: &str) -> Result<T> {
3399 let input_bytes = input.as_bytes();
3400
3401 if input_bytes.starts_with(&[0xef, 0xbb, 0xbf]) {
3403 return from_slice_inner(&input_bytes[3..], Some(&input[3..]));
3404 }
3405 from_slice_inner(input_bytes, Some(input))
3406}
3407
3408pub fn from_slice_borrowed<'input, 'facet, T: Facet<'facet>>(input: &'input [u8]) -> Result<T>
3420where
3421 'input: 'facet,
3422{
3423 from_slice_borrowed_inner(input, None)
3424}
3425
3426pub fn from_str_borrowed<'input, 'facet, T: Facet<'facet>>(input: &'input str) -> Result<T>
3438where
3439 'input: 'facet,
3440{
3441 let input_bytes = input.as_bytes();
3442
3443 if input_bytes.starts_with(&[0xef, 0xbb, 0xbf]) {
3445 return from_slice_borrowed_inner(&input_bytes[3..], Some(&input[3..]));
3446 }
3447 from_slice_borrowed_inner(input_bytes, Some(input))
3448}
3449
3450fn from_slice_borrowed_inner<'input, 'facet, T: Facet<'facet>>(
3451 input: &'input [u8],
3452 source: Option<&str>,
3453) -> Result<T>
3454where
3455 'input: 'facet,
3456{
3457 let mut deserializer = JsonDeserializer::new(input);
3458 let wip = Partial::alloc::<T>()?;
3459
3460 let partial = match deserializer.deserialize_into(wip) {
3461 Ok(p) => p,
3462 Err(e) => return Err(attach_source_cold(e, source)),
3463 };
3464
3465 let trailing = deserializer.peek()?;
3467 if !matches!(trailing.token, Token::Eof) {
3468 let mut err = JsonError::new(
3469 JsonErrorKind::UnexpectedToken {
3470 got: format!("{:?}", trailing.token),
3471 expected: "end of input",
3472 },
3473 trailing.span,
3474 );
3475 if let Some(src) = source {
3476 err.source_code = Some(src.to_string());
3477 }
3478 return Err(err);
3479 }
3480
3481 let heap_value = match partial.build() {
3483 Ok(v) => v,
3484 Err(e) => return Err(attach_source_cold(JsonError::from(e), source)),
3485 };
3486
3487 match heap_value.materialize::<T>() {
3488 Ok(v) => Ok(v),
3489 Err(e) => Err(attach_source_cold(JsonError::from(e), source)),
3490 }
3491}
3492
3493fn from_slice_inner<T: Facet<'static>>(input: &[u8], source: Option<&str>) -> Result<T> {
3494 fn inner<'input, T: Facet<'static>>(input: &'input [u8], source: Option<&str>) -> Result<T> {
3508 let mut deserializer = JsonDeserializer::new_owned(input);
3509
3510 #[allow(unsafe_code)]
3517 let wip: Partial<'input, false> = unsafe {
3518 core::mem::transmute::<Partial<'static, false>, Partial<'input, false>>(
3519 Partial::alloc_owned::<T>()?,
3520 )
3521 };
3522
3523 let partial = match deserializer.deserialize_into(wip) {
3524 Ok(p) => p,
3525 Err(e) => return Err(attach_source_cold(e, source)),
3526 };
3527
3528 let trailing = deserializer.peek()?;
3530 if !matches!(trailing.token, Token::Eof) {
3531 let mut err = JsonError::new(
3532 JsonErrorKind::UnexpectedToken {
3533 got: format!("{:?}", trailing.token),
3534 expected: "end of input",
3535 },
3536 trailing.span,
3537 );
3538 if let Some(src) = source {
3539 err.source_code = Some(src.to_string());
3540 }
3541 return Err(err);
3542 }
3543
3544 let heap_value = match partial.build() {
3546 Ok(v) => v,
3547 Err(e) => return Err(attach_source_cold(JsonError::from(e), source)),
3548 };
3549
3550 #[allow(unsafe_code)]
3556 let heap_value: facet_reflect::HeapValue<'static, false> = unsafe {
3557 core::mem::transmute::<
3558 facet_reflect::HeapValue<'input, false>,
3559 facet_reflect::HeapValue<'static, false>,
3560 >(heap_value)
3561 };
3562
3563 match heap_value.materialize::<T>() {
3564 Ok(v) => Ok(v),
3565 Err(e) => Err(attach_source_cold(JsonError::from(e), source)),
3566 }
3567 }
3568
3569 inner::<T>(input, source)
3570}