1use alloc::borrow::Cow;
4use alloc::format;
5use alloc::string::{String, ToString};
6use alloc::vec::Vec;
7use core::fmt::{self, Display};
8
9use alloc::collections::BTreeSet;
10
11use facet_core::{
12 Characteristic, Def, Facet, KnownPointer, NumericType, PrimitiveType, ScalarType, SequenceType,
13 Shape, ShapeLayout, StructKind, Type, UserType,
14};
15use facet_reflect::{Partial, ReflectError, is_spanned_shape};
16use facet_solver::{PathSegment, Schema, Solver, VariantsByFormat, specificity_score};
17
18use crate::RawJson;
19use crate::adapter::{AdapterError, AdapterErrorKind, SliceAdapter, SpannedAdapterToken, Token};
20use crate::scanner::ScanErrorKind;
21use facet_reflect::Span;
22
23fn find_similar_field<'a>(unknown: &str, expected: &[&'a str]) -> Option<&'a str> {
26 let mut best_match: Option<(&'a str, f64)> = None;
27
28 for &candidate in expected {
29 let similarity = strsim::jaro_winkler(unknown, candidate);
30 if similarity >= 0.6 && best_match.is_none_or(|(_, best_sim)| similarity > best_sim) {
31 best_match = Some((candidate, similarity));
32 }
33 }
34
35 best_match.map(|(name, _)| name)
36}
37
38#[derive(Debug)]
44pub struct JsonError {
45 pub kind: JsonErrorKind,
47 pub span: Option<Span>,
49 pub source_code: Option<String>,
51}
52
53impl Display for JsonError {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(f, "{}", self.kind)
56 }
57}
58
59impl std::error::Error for JsonError {}
60
61impl miette::Diagnostic for JsonError {
62 fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
63 Some(Box::new(self.kind.code()))
64 }
65
66 fn source_code(&self) -> Option<&dyn miette::SourceCode> {
67 self.source_code
68 .as_ref()
69 .map(|s| s as &dyn miette::SourceCode)
70 }
71
72 fn labels(&self) -> Option<Box<dyn Iterator<Item = miette::LabeledSpan> + '_>> {
73 if let JsonErrorKind::MissingField {
75 field,
76 object_start,
77 object_end,
78 } = &self.kind
79 {
80 let mut labels = Vec::new();
81 if let Some(start) = object_start {
82 labels.push(miette::LabeledSpan::new(
83 Some("object started here".into()),
84 start.offset,
85 start.len,
86 ));
87 }
88 if let Some(end) = object_end {
89 labels.push(miette::LabeledSpan::new(
90 Some(format!("object ended without field `{field}`")),
91 end.offset,
92 end.len,
93 ));
94 }
95 if labels.is_empty() {
96 return None;
97 }
98 return Some(Box::new(labels.into_iter()));
99 }
100
101 let span = self.span?;
103 Some(Box::new(core::iter::once(miette::LabeledSpan::new(
104 Some(self.kind.label()),
105 span.offset,
106 span.len,
107 ))))
108 }
109}
110
111impl JsonError {
112 pub fn new(kind: JsonErrorKind, span: Span) -> Self {
114 JsonError {
115 kind,
116 span: Some(span),
117 source_code: None,
118 }
119 }
120
121 pub fn without_span(kind: JsonErrorKind) -> Self {
123 JsonError {
124 kind,
125 span: None,
126 source_code: None,
127 }
128 }
129
130 pub fn with_source(mut self, source: &str) -> Self {
132 self.source_code = Some(source.to_string());
133 self
134 }
135}
136
137#[inline(never)]
138#[cold]
139fn attach_source_cold(mut err: JsonError, source: Option<&str>) -> JsonError {
140 if let Some(src) = source {
141 err.source_code = Some(src.to_string());
142 }
143 err
144}
145
146#[derive(Debug)]
148pub enum JsonErrorKind {
149 Scan(ScanErrorKind),
151 ScanWithContext {
153 error: ScanErrorKind,
155 expected_type: &'static str,
157 },
158 UnexpectedToken {
160 got: String,
162 expected: &'static str,
164 },
165 UnexpectedEof {
167 expected: &'static str,
169 },
170 TypeMismatch {
172 expected: &'static str,
174 got: &'static str,
176 },
177 UnknownField {
179 field: String,
181 expected: Vec<&'static str>,
183 suggestion: Option<&'static str>,
185 },
186 MissingField {
188 field: &'static str,
190 object_start: Option<Span>,
192 object_end: Option<Span>,
194 },
195 InvalidValue {
197 message: String,
199 },
200 Reflect(ReflectError),
202 NumberOutOfRange {
204 value: String,
206 target_type: &'static str,
208 },
209 DuplicateKey {
211 key: String,
213 },
214 InvalidUtf8,
216 Solver(String),
218 Io(String),
220}
221
222impl Display for JsonErrorKind {
223 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
224 match self {
225 JsonErrorKind::Scan(e) => write!(f, "{e:?}"),
226 JsonErrorKind::ScanWithContext {
227 error,
228 expected_type,
229 } => {
230 write!(f, "{error:?} (while parsing {expected_type})")
231 }
232 JsonErrorKind::UnexpectedToken { got, expected } => {
233 write!(f, "unexpected token: got {got}, expected {expected}")
234 }
235 JsonErrorKind::UnexpectedEof { expected } => {
236 write!(f, "unexpected end of input, expected {expected}")
237 }
238 JsonErrorKind::TypeMismatch { expected, got } => {
239 write!(f, "type mismatch: expected {expected}, got {got}")
240 }
241 JsonErrorKind::UnknownField {
242 field,
243 expected,
244 suggestion,
245 } => {
246 write!(f, "unknown field `{field}`, expected one of: {expected:?}")?;
247 if let Some(suggested) = suggestion {
248 write!(f, " (did you mean `{suggested}`?)")?;
249 }
250 Ok(())
251 }
252 JsonErrorKind::MissingField { field, .. } => {
253 write!(f, "missing required field `{field}`")
254 }
255 JsonErrorKind::InvalidValue { message } => {
256 write!(f, "invalid value: {message}")
257 }
258 JsonErrorKind::Reflect(e) => write!(f, "reflection error: {e}"),
259 JsonErrorKind::NumberOutOfRange { value, target_type } => {
260 write!(f, "number `{value}` out of range for {target_type}")
261 }
262 JsonErrorKind::DuplicateKey { key } => {
263 write!(f, "duplicate key `{key}`")
264 }
265 JsonErrorKind::InvalidUtf8 => write!(f, "invalid UTF-8 sequence"),
266 JsonErrorKind::Solver(msg) => write!(f, "solver error: {msg}"),
267 JsonErrorKind::Io(msg) => write!(f, "I/O error: {msg}"),
268 }
269 }
270}
271
272impl JsonErrorKind {
273 pub fn code(&self) -> &'static str {
275 match self {
276 JsonErrorKind::Scan(_) => "json::scan",
277 JsonErrorKind::ScanWithContext { .. } => "json::scan",
278 JsonErrorKind::UnexpectedToken { .. } => "json::unexpected_token",
279 JsonErrorKind::UnexpectedEof { .. } => "json::unexpected_eof",
280 JsonErrorKind::TypeMismatch { .. } => "json::type_mismatch",
281 JsonErrorKind::UnknownField { .. } => "json::unknown_field",
282 JsonErrorKind::MissingField { .. } => "json::missing_field",
283 JsonErrorKind::InvalidValue { .. } => "json::invalid_value",
284 JsonErrorKind::Reflect(_) => "json::reflect",
285 JsonErrorKind::NumberOutOfRange { .. } => "json::number_out_of_range",
286 JsonErrorKind::DuplicateKey { .. } => "json::duplicate_key",
287 JsonErrorKind::InvalidUtf8 => "json::invalid_utf8",
288 JsonErrorKind::Solver(_) => "json::solver",
289 JsonErrorKind::Io(_) => "json::io",
290 }
291 }
292
293 pub fn label(&self) -> String {
295 match self {
296 JsonErrorKind::Scan(e) => match e {
297 ScanErrorKind::UnexpectedChar(c) => format!("unexpected '{c}'"),
298 ScanErrorKind::UnexpectedEof(ctx) => format!("unexpected end of input {ctx}"),
299 ScanErrorKind::InvalidUtf8 => "invalid UTF-8 here".into(),
300 },
301 JsonErrorKind::ScanWithContext {
302 error,
303 expected_type,
304 } => match error {
305 ScanErrorKind::UnexpectedChar(c) => {
306 format!("unexpected '{c}', expected {expected_type}")
307 }
308 ScanErrorKind::UnexpectedEof(_) => {
309 format!("unexpected end of input, expected {expected_type}")
310 }
311 ScanErrorKind::InvalidUtf8 => "invalid UTF-8 here".into(),
312 },
313 JsonErrorKind::UnexpectedToken { got, expected } => {
314 format!("expected {expected}, got '{got}'")
315 }
316 JsonErrorKind::UnexpectedEof { expected } => format!("expected {expected}"),
317 JsonErrorKind::TypeMismatch { expected, got } => {
318 format!("expected {expected}, got {got}")
319 }
320 JsonErrorKind::UnknownField {
321 field, suggestion, ..
322 } => {
323 if let Some(suggested) = suggestion {
324 format!("unknown field '{field}' - did you mean '{suggested}'?")
325 } else {
326 format!("unknown field '{field}'")
327 }
328 }
329 JsonErrorKind::MissingField { field, .. } => format!("missing field '{field}'"),
330 JsonErrorKind::InvalidValue { .. } => "invalid value".into(),
331 JsonErrorKind::Reflect(_) => "reflection error".into(),
332 JsonErrorKind::NumberOutOfRange { target_type, .. } => {
333 format!("out of range for {target_type}")
334 }
335 JsonErrorKind::DuplicateKey { key } => format!("duplicate key '{key}'"),
336 JsonErrorKind::InvalidUtf8 => "invalid UTF-8".into(),
337 JsonErrorKind::Solver(_) => "solver error".into(),
338 JsonErrorKind::Io(_) => "I/O error".into(),
339 }
340 }
341}
342
343impl From<AdapterError> for JsonError {
344 fn from(err: AdapterError) -> Self {
345 let kind = match err.kind {
346 AdapterErrorKind::Scan(scan_err) => JsonErrorKind::Scan(scan_err),
347 AdapterErrorKind::NeedMore => JsonErrorKind::UnexpectedEof {
348 expected: "more data",
349 },
350 };
351 JsonError {
352 kind,
353 span: Some(err.span),
354 source_code: None,
355 }
356 }
357}
358
359impl From<ReflectError> for JsonError {
360 fn from(err: ReflectError) -> Self {
361 JsonError {
362 kind: JsonErrorKind::Reflect(err),
363 span: None,
364 source_code: None,
365 }
366 }
367}
368
369pub type Result<T> = core::result::Result<T, JsonError>;
371
372use crate::adapter::TokenSource;
377
378pub struct JsonDeserializer<'input, const BORROW: bool, A: TokenSource<'input>> {
388 adapter: A,
389 peeked: Option<SpannedAdapterToken<'input>>,
391}
392
393impl<'input> JsonDeserializer<'input, true, SliceAdapter<'input, true>> {
394 pub fn new(input: &'input [u8]) -> Self {
397 JsonDeserializer {
398 adapter: SliceAdapter::new(input),
399 peeked: None,
400 }
401 }
402}
403
404impl<'input> JsonDeserializer<'input, false, SliceAdapter<'input, false>> {
405 pub fn new_owned(input: &'input [u8]) -> Self {
408 JsonDeserializer {
409 adapter: SliceAdapter::new(input),
410 peeked: None,
411 }
412 }
413}
414
415impl<'input, const BORROW: bool, A: TokenSource<'input>> JsonDeserializer<'input, BORROW, A> {
416 pub fn from_adapter(adapter: A) -> Self {
418 JsonDeserializer {
419 adapter,
420 peeked: None,
421 }
422 }
423
424 fn peek(&mut self) -> Result<&SpannedAdapterToken<'input>> {
426 if self.peeked.is_none() {
427 self.peeked = Some(self.adapter.next_token()?);
428 }
429 Ok(self.peeked.as_ref().unwrap())
430 }
431
432 fn next(&mut self) -> Result<SpannedAdapterToken<'input>> {
434 if let Some(token) = self.peeked.take() {
435 Ok(token)
436 } else {
437 Ok(self.adapter.next_token()?)
438 }
439 }
440
441 fn next_expecting(
443 &mut self,
444 expected_type: &'static str,
445 ) -> Result<SpannedAdapterToken<'input>> {
446 match self.next() {
447 Ok(token) => Ok(token),
448 Err(e) => {
449 if let JsonErrorKind::Scan(scan_err) = e.kind {
451 Err(JsonError {
452 kind: JsonErrorKind::ScanWithContext {
453 error: scan_err,
454 expected_type,
455 },
456 span: e.span,
457 source_code: e.source_code,
458 })
459 } else {
460 Err(e)
461 }
462 }
463 }
464 }
465
466 #[allow(dead_code)]
468 fn expect(&mut self, _expected: &'static str) -> Result<SpannedAdapterToken<'input>> {
469 let token = self.next()?;
470 Ok(token)
472 }
473
474 fn skip_value(&mut self) -> Result<Span> {
476 let token = self.next()?;
477 let start_span = token.span;
478
479 match token.token {
480 Token::ObjectStart => {
481 let mut depth = 1;
483 while depth > 0 {
484 let t = self.next()?;
485 match t.token {
486 Token::ObjectStart => depth += 1,
487 Token::ObjectEnd => depth -= 1,
488 _ => {}
489 }
490 }
491 Ok(start_span)
492 }
493 Token::ArrayStart => {
494 let mut depth = 1;
496 while depth > 0 {
497 let t = self.next()?;
498 match t.token {
499 Token::ArrayStart => depth += 1,
500 Token::ArrayEnd => depth -= 1,
501 _ => {}
502 }
503 }
504 Ok(start_span)
505 }
506 Token::String(_)
507 | Token::F64(_)
508 | Token::I64(_)
509 | Token::U64(_)
510 | Token::U128(_)
511 | Token::I128(_)
512 | Token::True
513 | Token::False
514 | Token::Null => Ok(start_span),
515 _ => Err(JsonError::new(
516 JsonErrorKind::UnexpectedToken {
517 got: format!("{:?}", token.token),
518 expected: "value",
519 },
520 token.span,
521 )),
522 }
523 }
524
525 fn capture_raw_value(&mut self) -> Result<&'input str> {
533 let input = self.adapter.input_bytes().ok_or_else(|| {
535 JsonError::without_span(JsonErrorKind::InvalidValue {
536 message: "RawJson capture is not supported in streaming mode".into(),
537 })
538 })?;
539
540 let token = self.next()?;
541 let start_offset = token.span.offset;
542
543 let end_offset = match token.token {
544 Token::ObjectStart => {
545 let mut depth = 1;
547 let mut last_span = token.span;
548 while depth > 0 {
549 let t = self.next()?;
550 last_span = t.span;
551 match t.token {
552 Token::ObjectStart => depth += 1,
553 Token::ObjectEnd => depth -= 1,
554 _ => {}
555 }
556 }
557 last_span.offset + last_span.len
558 }
559 Token::ArrayStart => {
560 let mut depth = 1;
562 let mut last_span = token.span;
563 while depth > 0 {
564 let t = self.next()?;
565 last_span = t.span;
566 match t.token {
567 Token::ArrayStart => depth += 1,
568 Token::ArrayEnd => depth -= 1,
569 _ => {}
570 }
571 }
572 last_span.offset + last_span.len
573 }
574 Token::String(_)
575 | Token::F64(_)
576 | Token::I64(_)
577 | Token::U64(_)
578 | Token::U128(_)
579 | Token::I128(_)
580 | Token::True
581 | Token::False
582 | Token::Null => token.span.offset + token.span.len,
583 _ => {
584 return Err(JsonError::new(
585 JsonErrorKind::UnexpectedToken {
586 got: format!("{:?}", token.token),
587 expected: "value",
588 },
589 token.span,
590 ));
591 }
592 };
593
594 let raw_bytes = &input[start_offset..end_offset];
596 core::str::from_utf8(raw_bytes).map_err(|e| {
597 JsonError::without_span(JsonErrorKind::InvalidValue {
598 message: format!("invalid UTF-8 in raw JSON: {e}"),
599 })
600 })
601 }
602
603 fn has_flatten_fields(struct_def: &facet_core::StructType) -> bool {
605 struct_def.fields.iter().any(|f| f.is_flattened())
606 }
607
608 pub fn deserialize_into(
610 &mut self,
611 mut wip: Partial<'input, BORROW>,
612 ) -> Result<Partial<'input, BORROW>> {
613 let shape = wip.shape();
614 log::trace!(
615 "deserialize_into: shape={}, def={:?}",
616 shape.type_identifier,
617 std::mem::discriminant(&shape.def)
618 );
619
620 if is_spanned_shape(shape) {
622 return self.deserialize_spanned(wip);
623 }
624
625 if shape == RawJson::SHAPE {
627 let raw = self.capture_raw_value()?;
628 wip = wip.set(RawJson::new(raw))?;
629 return Ok(wip);
630 }
631
632 #[cfg(feature = "alloc")]
634 {
635 let (wip_returned, has_proxy) = wip.begin_custom_deserialization_from_shape()?;
636 wip = wip_returned;
637 if has_proxy {
638 log::trace!(
639 "deserialize_into: using container-level proxy for {}",
640 shape.type_identifier
641 );
642 wip = self.deserialize_into(wip)?;
643 return wip.end().map_err(Into::into);
644 }
645 }
646
647 let is_option = matches!(&shape.def, Def::Option(_));
650 log::trace!("deserialize_into: is_option={is_option}");
651 if is_option {
652 return self.deserialize_option(wip);
653 }
654
655 if matches!(&shape.def, Def::Pointer(_)) {
658 return self.deserialize_pointer(wip);
659 }
660
661 if shape.inner.is_some() {
664 wip = wip.begin_inner()?;
665 if wip
667 .parent_field()
668 .and_then(|field| field.proxy_convert_in_fn())
669 .is_some()
670 {
671 wip = wip.begin_custom_deserialization()?;
672 wip = self.deserialize_into(wip)?;
673 wip = wip.end()?;
674 } else {
675 wip = self.deserialize_into(wip)?;
676 }
677 wip = wip.end()?;
678 return Ok(wip);
679 }
680
681 match &shape.ty {
683 Type::User(UserType::Struct(struct_def)) => {
684 if matches!(struct_def.kind, StructKind::Tuple | StructKind::TupleStruct) {
686 return self.deserialize_tuple(wip);
687 }
688 return self.deserialize_struct(wip);
689 }
690 Type::User(UserType::Enum(_)) => return self.deserialize_enum(wip),
691 _ => {}
692 }
693
694 match &shape.def {
696 Def::Scalar => self.deserialize_scalar(wip),
697 Def::List(_) => self.deserialize_list(wip),
698 Def::Map(_) => self.deserialize_map(wip),
699 Def::Array(_) => self.deserialize_array(wip),
700 Def::Set(_) => self.deserialize_set(wip),
701 Def::DynamicValue(_) => self.deserialize_dynamic_value(wip),
702 other => Err(JsonError::without_span(JsonErrorKind::InvalidValue {
703 message: format!("unsupported shape def: {other:?}"),
704 })),
705 }
706 }
707
708 fn deserialize_spanned(
714 &mut self,
715 mut wip: Partial<'input, BORROW>,
716 ) -> Result<Partial<'input, BORROW>> {
717 log::trace!("deserialize_spanned");
718
719 let shape = wip.shape();
720
721 let Type::User(UserType::Struct(struct_def)) = &shape.ty else {
723 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
724 message: format!(
725 "expected struct with span metadata, found {}",
726 shape.type_identifier
727 ),
728 }));
729 };
730
731 let span_field = struct_def
732 .fields
733 .iter()
734 .find(|f| f.metadata_kind() == Some("span"))
735 .ok_or_else(|| {
736 JsonError::without_span(JsonErrorKind::InvalidValue {
737 message: format!(
738 "expected struct with span metadata field, found {}",
739 shape.type_identifier
740 ),
741 })
742 })?;
743
744 let value_fields: Vec<_> = struct_def
745 .fields
746 .iter()
747 .filter(|f| !f.is_metadata())
748 .collect();
749
750 let value_span = self.peek()?.span;
752
753 for field in value_fields {
756 wip = wip.begin_field(field.name)?;
757 wip = self.deserialize_into(wip)?;
758 wip = wip.end()?;
759 }
760
761 wip = wip.begin_field(span_field.name)?;
764 wip = wip.set_field("offset", value_span.offset)?;
765 wip = wip.set_field("len", value_span.len)?;
766 wip = wip.end()?;
767
768 Ok(wip)
769 }
770
771 fn deserialize_scalar(
773 &mut self,
774 mut wip: Partial<'input, BORROW>,
775 ) -> Result<Partial<'input, BORROW>> {
776 let expected_type = wip.shape().type_identifier;
777 let token = self.next_expecting(expected_type)?;
778 log::trace!("deserialize_scalar: token={:?}", token.token);
779
780 match token.token {
781 Token::String(s) => {
782 if wip.shape().vtable.has_parse() {
784 wip = wip.parse_from_str(&s)?;
785 } else if wip.shape().type_identifier == "Cow" {
786 wip = wip.set(s)?;
788 } else {
789 wip = wip.set(s.into_owned())?;
790 }
791 }
792 Token::True => {
793 wip = wip.set(true)?;
794 }
795 Token::False => {
796 wip = wip.set(false)?;
797 }
798 Token::Null => {
799 wip = wip.set_default()?;
801 }
802 Token::F64(n) => {
803 wip = self.set_number_f64(wip, n, token.span)?;
804 }
805 Token::I64(n) => {
806 wip = self.set_number_i64(wip, n, token.span)?;
807 }
808 Token::U64(n) => {
809 wip = self.set_number_u64(wip, n, token.span)?;
810 }
811 Token::I128(n) => {
812 wip = self.set_number_i128(wip, n, token.span)?;
813 }
814 Token::U128(n) => {
815 wip = self.set_number_u128(wip, n, token.span)?;
816 }
817 _ => {
818 return Err(JsonError::new(
819 JsonErrorKind::UnexpectedToken {
820 got: format!("{:?}", token.token),
821 expected: "scalar value",
822 },
823 token.span,
824 ));
825 }
826 }
827 Ok(wip)
828 }
829
830 fn deserialize_dynamic_value(
834 &mut self,
835 mut wip: Partial<'input, BORROW>,
836 ) -> Result<Partial<'input, BORROW>> {
837 let token = self.peek()?;
838 log::trace!("deserialize_dynamic_value: token={:?}", token.token);
839
840 match token.token {
841 Token::Null => {
842 self.next()?; wip = wip.set_default()?;
844 }
845 Token::True => {
846 self.next()?;
847 wip = wip.set(true)?;
848 }
849 Token::False => {
850 self.next()?;
851 wip = wip.set(false)?;
852 }
853 Token::I64(n) => {
854 self.next()?;
855 wip = wip.set(n)?;
856 }
857 Token::U64(n) => {
858 self.next()?;
859 if n <= i64::MAX as u64 {
861 wip = wip.set(n as i64)?;
862 } else {
863 wip = wip.set(n)?;
864 }
865 }
866 Token::F64(n) => {
867 self.next()?;
868 wip = wip.set(n)?;
869 }
870 Token::I128(n) => {
871 self.next()?;
872 if let Ok(n) = i64::try_from(n) {
874 wip = wip.set(n)?;
875 } else {
876 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
877 message: format!("i128 value {n} doesn't fit in dynamic value"),
878 }));
879 }
880 }
881 Token::U128(n) => {
882 self.next()?;
883 if let Ok(n) = i64::try_from(n) {
885 wip = wip.set(n)?;
886 } else if let Ok(n) = u64::try_from(n) {
887 wip = wip.set(n)?;
888 } else {
889 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
890 message: format!("u128 value {n} doesn't fit in dynamic value"),
891 }));
892 }
893 }
894 Token::String(ref _s) => {
895 let token = self.next()?;
897 if let Token::String(s) = token.token {
898 wip = wip.set(s.into_owned())?;
899 }
900 }
901 Token::ArrayStart => {
902 self.next()?; wip = wip.begin_list()?;
904
905 loop {
906 let token = self.peek()?;
907 if matches!(token.token, Token::ArrayEnd) {
908 self.next()?;
909 break;
910 }
911
912 wip = wip.begin_list_item()?;
913 wip = self.deserialize_dynamic_value(wip)?;
914 wip = wip.end()?;
915
916 let next = self.peek()?;
917 if matches!(next.token, Token::Comma) {
918 self.next()?;
919 }
920 }
921 }
922 Token::ObjectStart => {
923 self.next()?; wip = wip.begin_map()?; loop {
927 let token = self.peek()?;
928 if matches!(token.token, Token::ObjectEnd) {
929 self.next()?;
930 break;
931 }
932
933 let key_token = self.next()?;
935 let key = match key_token.token {
936 Token::String(s) => s.into_owned(),
937 _ => {
938 return Err(JsonError::new(
939 JsonErrorKind::UnexpectedToken {
940 got: format!("{:?}", key_token.token),
941 expected: "string key",
942 },
943 key_token.span,
944 ));
945 }
946 };
947
948 let colon = self.next()?;
950 if !matches!(colon.token, Token::Colon) {
951 return Err(JsonError::new(
952 JsonErrorKind::UnexpectedToken {
953 got: format!("{:?}", colon.token),
954 expected: "':'",
955 },
956 colon.span,
957 ));
958 }
959
960 wip = wip.begin_object_entry(&key)?;
962 wip = self.deserialize_dynamic_value(wip)?;
963 wip = wip.end()?;
964
965 let next = self.peek()?;
967 if matches!(next.token, Token::Comma) {
968 self.next()?;
969 }
970 }
971 }
972 _ => {
973 return Err(JsonError::new(
974 JsonErrorKind::UnexpectedToken {
975 got: format!("{:?}", token.token),
976 expected: "any JSON value",
977 },
978 token.span,
979 ));
980 }
981 }
982 Ok(wip)
983 }
984
985 fn set_string_value(
987 &mut self,
988 mut wip: Partial<'input, BORROW>,
989 s: Cow<'input, str>,
990 ) -> Result<Partial<'input, BORROW>> {
991 let shape = wip.shape();
992
993 if let Def::Pointer(ptr_def) = shape.def
995 && matches!(ptr_def.known, Some(KnownPointer::SharedReference))
996 && ptr_def
997 .pointee()
998 .is_some_and(|p| p.type_identifier == "str")
999 {
1000 if !BORROW {
1002 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1003 message: "cannot deserialize into &str when borrowing is disabled - use String or Cow<str> instead".into(),
1004 }));
1005 }
1006 match s {
1007 Cow::Borrowed(borrowed) => {
1008 wip = wip.set(borrowed)?;
1009 return Ok(wip);
1010 }
1011 Cow::Owned(_) => {
1012 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1013 message: "cannot borrow &str from JSON string containing escape sequences - use String instead".into(),
1014 }));
1015 }
1016 }
1017 }
1018
1019 if let Def::Pointer(ptr_def) = shape.def
1021 && matches!(ptr_def.known, Some(KnownPointer::Cow))
1022 && ptr_def
1023 .pointee()
1024 .is_some_and(|p| p.type_identifier == "str")
1025 {
1026 wip = wip.set(s)?;
1027 return Ok(wip);
1028 }
1029
1030 wip = wip.set(s.into_owned())?;
1032 Ok(wip)
1033 }
1034
1035 fn set_number_f64(
1037 &mut self,
1038 mut wip: Partial<'input, BORROW>,
1039 n: f64,
1040 span: Span,
1041 ) -> Result<Partial<'input, BORROW>> {
1042 let shape = wip.shape();
1043 let ty = match &shape.ty {
1044 Type::Primitive(PrimitiveType::Numeric(ty)) => ty,
1045 _ => {
1046 return Err(JsonError::new(
1047 JsonErrorKind::TypeMismatch {
1048 expected: shape.type_identifier,
1049 got: "number",
1050 },
1051 span,
1052 ));
1053 }
1054 };
1055
1056 match ty {
1057 NumericType::Float => {
1058 let size = match shape.layout {
1059 ShapeLayout::Sized(layout) => layout.size(),
1060 _ => {
1061 return Err(JsonError::new(
1062 JsonErrorKind::InvalidValue {
1063 message: "unsized float".into(),
1064 },
1065 span,
1066 ));
1067 }
1068 };
1069 match size {
1070 4 => {
1071 wip = wip.set(n as f32)?;
1072 }
1073 8 => {
1074 wip = wip.set(n)?;
1075 }
1076 _ => {
1077 return Err(JsonError::new(
1078 JsonErrorKind::InvalidValue {
1079 message: format!("unexpected float size: {size}"),
1080 },
1081 span,
1082 ));
1083 }
1084 }
1085 }
1086 NumericType::Integer { signed } => {
1087 if n.fract() != 0.0 {
1089 return Err(JsonError::new(
1090 JsonErrorKind::TypeMismatch {
1091 expected: shape.type_identifier,
1092 got: "float with fractional part",
1093 },
1094 span,
1095 ));
1096 }
1097 if *signed {
1098 wip = self.set_number_i64(wip, n as i64, span)?;
1099 } else {
1100 wip = self.set_number_u64(wip, n as u64, span)?;
1101 }
1102 }
1103 }
1104 Ok(wip)
1105 }
1106
1107 fn set_number_i64(
1108 &mut self,
1109 mut wip: Partial<'input, BORROW>,
1110 n: i64,
1111 span: Span,
1112 ) -> Result<Partial<'input, BORROW>> {
1113 let shape = wip.shape();
1114 let size = match shape.layout {
1115 ShapeLayout::Sized(layout) => layout.size(),
1116 _ => {
1117 return Err(JsonError::new(
1118 JsonErrorKind::InvalidValue {
1119 message: "unsized integer".into(),
1120 },
1121 span,
1122 ));
1123 }
1124 };
1125
1126 match &shape.ty {
1128 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: true })) => {
1129 match size {
1130 1 => {
1131 let v = i8::try_from(n).map_err(|_| {
1132 JsonError::new(
1133 JsonErrorKind::NumberOutOfRange {
1134 value: n.to_string(),
1135 target_type: "i8",
1136 },
1137 span,
1138 )
1139 })?;
1140 wip = wip.set(v)?;
1141 }
1142 2 => {
1143 let v = i16::try_from(n).map_err(|_| {
1144 JsonError::new(
1145 JsonErrorKind::NumberOutOfRange {
1146 value: n.to_string(),
1147 target_type: "i16",
1148 },
1149 span,
1150 )
1151 })?;
1152 wip = wip.set(v)?;
1153 }
1154 4 => {
1155 let v = i32::try_from(n).map_err(|_| {
1156 JsonError::new(
1157 JsonErrorKind::NumberOutOfRange {
1158 value: n.to_string(),
1159 target_type: "i32",
1160 },
1161 span,
1162 )
1163 })?;
1164 wip = wip.set(v)?;
1165 }
1166 8 => {
1167 if shape.scalar_type() == Some(ScalarType::ISize) {
1169 let v = isize::try_from(n).map_err(|_| {
1170 JsonError::new(
1171 JsonErrorKind::NumberOutOfRange {
1172 value: n.to_string(),
1173 target_type: "isize",
1174 },
1175 span,
1176 )
1177 })?;
1178 wip = wip.set(v)?;
1179 } else {
1180 wip = wip.set(n)?;
1181 }
1182 }
1183 16 => {
1184 wip = wip.set(n as i128)?;
1185 }
1186 _ => {
1187 if shape.scalar_type() == Some(ScalarType::ISize) {
1189 let v = isize::try_from(n).map_err(|_| {
1190 JsonError::new(
1191 JsonErrorKind::NumberOutOfRange {
1192 value: n.to_string(),
1193 target_type: "isize",
1194 },
1195 span,
1196 )
1197 })?;
1198 wip = wip.set(v)?;
1199 } else {
1200 return Err(JsonError::new(
1201 JsonErrorKind::InvalidValue {
1202 message: format!("unexpected integer size: {size}"),
1203 },
1204 span,
1205 ));
1206 }
1207 }
1208 }
1209 }
1210 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: false })) => {
1211 if n < 0 {
1212 return Err(JsonError::new(
1213 JsonErrorKind::NumberOutOfRange {
1214 value: n.to_string(),
1215 target_type: shape.type_identifier,
1216 },
1217 span,
1218 ));
1219 }
1220 wip = self.set_number_u64(wip, n as u64, span)?;
1221 }
1222 Type::Primitive(PrimitiveType::Numeric(NumericType::Float)) => match size {
1223 4 => {
1224 wip = wip.set(n as f32)?;
1225 }
1226 8 => {
1227 wip = wip.set(n as f64)?;
1228 }
1229 _ => {
1230 return Err(JsonError::new(
1231 JsonErrorKind::InvalidValue {
1232 message: format!("unexpected float size: {size}"),
1233 },
1234 span,
1235 ));
1236 }
1237 },
1238 _ => {
1239 return Err(JsonError::new(
1240 JsonErrorKind::TypeMismatch {
1241 expected: shape.type_identifier,
1242 got: "integer",
1243 },
1244 span,
1245 ));
1246 }
1247 }
1248 Ok(wip)
1249 }
1250
1251 fn set_number_u64(
1252 &mut self,
1253 mut wip: Partial<'input, BORROW>,
1254 n: u64,
1255 span: Span,
1256 ) -> Result<Partial<'input, BORROW>> {
1257 let shape = wip.shape();
1258 let size = match shape.layout {
1259 ShapeLayout::Sized(layout) => layout.size(),
1260 _ => {
1261 return Err(JsonError::new(
1262 JsonErrorKind::InvalidValue {
1263 message: "unsized integer".into(),
1264 },
1265 span,
1266 ));
1267 }
1268 };
1269
1270 match &shape.ty {
1271 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: false })) => {
1272 match size {
1273 1 => {
1274 let v = u8::try_from(n).map_err(|_| {
1275 JsonError::new(
1276 JsonErrorKind::NumberOutOfRange {
1277 value: n.to_string(),
1278 target_type: "u8",
1279 },
1280 span,
1281 )
1282 })?;
1283 wip = wip.set(v)?;
1284 }
1285 2 => {
1286 let v = u16::try_from(n).map_err(|_| {
1287 JsonError::new(
1288 JsonErrorKind::NumberOutOfRange {
1289 value: n.to_string(),
1290 target_type: "u16",
1291 },
1292 span,
1293 )
1294 })?;
1295 wip = wip.set(v)?;
1296 }
1297 4 => {
1298 let v = u32::try_from(n).map_err(|_| {
1299 JsonError::new(
1300 JsonErrorKind::NumberOutOfRange {
1301 value: n.to_string(),
1302 target_type: "u32",
1303 },
1304 span,
1305 )
1306 })?;
1307 wip = wip.set(v)?;
1308 }
1309 8 => {
1310 if shape.scalar_type() == Some(ScalarType::USize) {
1312 let v = usize::try_from(n).map_err(|_| {
1313 JsonError::new(
1314 JsonErrorKind::NumberOutOfRange {
1315 value: n.to_string(),
1316 target_type: "usize",
1317 },
1318 span,
1319 )
1320 })?;
1321 wip = wip.set(v)?;
1322 } else {
1323 wip = wip.set(n)?;
1324 }
1325 }
1326 16 => {
1327 wip = wip.set(n as u128)?;
1328 }
1329 _ => {
1330 if shape.scalar_type() == Some(ScalarType::USize) {
1332 let v = usize::try_from(n).map_err(|_| {
1333 JsonError::new(
1334 JsonErrorKind::NumberOutOfRange {
1335 value: n.to_string(),
1336 target_type: "usize",
1337 },
1338 span,
1339 )
1340 })?;
1341 wip = wip.set(v)?;
1342 } else {
1343 return Err(JsonError::new(
1344 JsonErrorKind::InvalidValue {
1345 message: format!("unexpected integer size: {size}"),
1346 },
1347 span,
1348 ));
1349 }
1350 }
1351 }
1352 }
1353 Type::Primitive(PrimitiveType::Numeric(NumericType::Integer { signed: true })) => {
1354 wip = self.set_number_i64(wip, n as i64, span)?;
1356 }
1357 Type::Primitive(PrimitiveType::Numeric(NumericType::Float)) => match size {
1358 4 => {
1359 wip = wip.set(n as f32)?;
1360 }
1361 8 => {
1362 wip = wip.set(n as f64)?;
1363 }
1364 _ => {
1365 return Err(JsonError::new(
1366 JsonErrorKind::InvalidValue {
1367 message: format!("unexpected float size: {size}"),
1368 },
1369 span,
1370 ));
1371 }
1372 },
1373 _ => {
1374 return Err(JsonError::new(
1375 JsonErrorKind::TypeMismatch {
1376 expected: shape.type_identifier,
1377 got: "unsigned integer",
1378 },
1379 span,
1380 ));
1381 }
1382 }
1383 Ok(wip)
1384 }
1385
1386 fn set_number_i128(
1387 &mut self,
1388 mut wip: Partial<'input, BORROW>,
1389 n: i128,
1390 span: Span,
1391 ) -> Result<Partial<'input, BORROW>> {
1392 let shape = wip.shape();
1393 let size = match shape.layout {
1394 ShapeLayout::Sized(layout) => layout.size(),
1395 _ => {
1396 return Err(JsonError::new(
1397 JsonErrorKind::InvalidValue {
1398 message: "unsized integer".into(),
1399 },
1400 span,
1401 ));
1402 }
1403 };
1404
1405 if size == 16 {
1406 wip = wip.set(n)?;
1407 } else {
1408 if let Ok(n64) = i64::try_from(n) {
1410 wip = self.set_number_i64(wip, n64, span)?;
1411 } else {
1412 return Err(JsonError::new(
1413 JsonErrorKind::NumberOutOfRange {
1414 value: n.to_string(),
1415 target_type: shape.type_identifier,
1416 },
1417 span,
1418 ));
1419 }
1420 }
1421 Ok(wip)
1422 }
1423
1424 fn set_number_u128(
1425 &mut self,
1426 mut wip: Partial<'input, BORROW>,
1427 n: u128,
1428 span: Span,
1429 ) -> Result<Partial<'input, BORROW>> {
1430 let shape = wip.shape();
1431 let size = match shape.layout {
1432 ShapeLayout::Sized(layout) => layout.size(),
1433 _ => {
1434 return Err(JsonError::new(
1435 JsonErrorKind::InvalidValue {
1436 message: "unsized integer".into(),
1437 },
1438 span,
1439 ));
1440 }
1441 };
1442
1443 if size == 16 {
1444 wip = wip.set(n)?;
1445 } else {
1446 if let Ok(n64) = u64::try_from(n) {
1448 wip = self.set_number_u64(wip, n64, span)?;
1449 } else {
1450 return Err(JsonError::new(
1451 JsonErrorKind::NumberOutOfRange {
1452 value: n.to_string(),
1453 target_type: shape.type_identifier,
1454 },
1455 span,
1456 ));
1457 }
1458 }
1459 Ok(wip)
1460 }
1461
1462 fn deserialize_struct(
1464 &mut self,
1465 wip: Partial<'input, BORROW>,
1466 ) -> Result<Partial<'input, BORROW>> {
1467 log::trace!("deserialize_struct: {}", wip.shape().type_identifier);
1468
1469 let struct_def = match &wip.shape().ty {
1471 Type::User(UserType::Struct(s)) => s,
1472 _ => {
1473 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1474 message: "expected struct type".into(),
1475 }));
1476 }
1477 };
1478
1479 if Self::has_flatten_fields(struct_def) {
1481 return self.deserialize_struct_with_flatten(wip);
1482 }
1483
1484 self.deserialize_struct_simple(wip)
1486 }
1487
1488 fn deserialize_struct_simple(
1490 &mut self,
1491 mut wip: Partial<'input, BORROW>,
1492 ) -> Result<Partial<'input, BORROW>> {
1493 let open_token = self.next()?;
1495 let object_start_span = match open_token.token {
1496 Token::ObjectStart => open_token.span,
1497 _ => {
1498 return Err(JsonError::new(
1499 JsonErrorKind::UnexpectedToken {
1500 got: format!("{:?}", open_token.token),
1501 expected: "'{'",
1502 },
1503 open_token.span,
1504 ));
1505 }
1506 };
1507
1508 let struct_def = match &wip.shape().ty {
1510 Type::User(UserType::Struct(s)) => s,
1511 _ => {
1512 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
1513 message: "expected struct type".into(),
1514 }));
1515 }
1516 };
1517
1518 let num_fields = struct_def.fields.len();
1520 let mut fields_set = alloc::vec![false; num_fields];
1521
1522 #[allow(unused_assignments)]
1524 let mut object_end_span: Option<Span> = None;
1525
1526 let struct_has_default = wip.shape().has_default_attr();
1528 let deny_unknown_fields = wip.shape().has_deny_unknown_fields_attr();
1530
1531 loop {
1533 let token = self.peek()?;
1534 match &token.token {
1535 Token::ObjectEnd => {
1536 let close_token = self.next()?; object_end_span = Some(close_token.span);
1538 break;
1539 }
1540 Token::String(_) => {
1541 let key_token = self.next()?;
1543 let key = match key_token.token {
1544 Token::String(s) => s,
1545 _ => unreachable!(),
1546 };
1547 let _key_span = key_token.span;
1548
1549 let colon = self.next()?;
1551 if !matches!(colon.token, Token::Colon) {
1552 return Err(JsonError::new(
1553 JsonErrorKind::UnexpectedToken {
1554 got: format!("{:?}", colon.token),
1555 expected: "':'",
1556 },
1557 colon.span,
1558 ));
1559 }
1560
1561 let field_info = struct_def
1563 .fields
1564 .iter()
1565 .enumerate()
1566 .find(|(_, f)| f.name == key.as_ref());
1567
1568 if let Some((idx, field)) = field_info {
1569 wip = wip.begin_field(field.name)?;
1570 if field.proxy_convert_in_fn().is_some() {
1572 wip = wip.begin_custom_deserialization()?;
1573 wip = self.deserialize_into(wip)?;
1574 wip = wip.end()?; } else {
1576 wip = self.deserialize_into(wip)?;
1577 }
1578 wip = wip.end()?;
1579 fields_set[idx] = true;
1580 } else {
1581 if deny_unknown_fields {
1583 let expected_fields: Vec<&'static str> =
1584 struct_def.fields.iter().map(|f| f.name).collect();
1585 let suggestion = find_similar_field(&key, &expected_fields);
1586 return Err(JsonError::new(
1587 JsonErrorKind::UnknownField {
1588 field: key.into_owned(),
1589 expected: expected_fields,
1590 suggestion,
1591 },
1592 _key_span,
1593 ));
1594 }
1595 log::trace!("skipping unknown field: {key}");
1596 self.skip_value()?;
1597 }
1598
1599 let next = self.peek()?;
1601 if matches!(next.token, Token::Comma) {
1602 self.next()?; }
1604 }
1605 _ => {
1606 let span = token.span;
1607 return Err(JsonError::new(
1608 JsonErrorKind::UnexpectedToken {
1609 got: format!("{:?}", token.token),
1610 expected: "field name or '}'",
1611 },
1612 span,
1613 ));
1614 }
1615 }
1616 }
1617
1618 for (idx, field) in struct_def.fields.iter().enumerate() {
1620 if fields_set[idx] {
1621 continue; }
1623
1624 let field_has_default = field.has_default();
1628 let field_type_has_default = field.shape().is(Characteristic::Default);
1629 let field_is_option = matches!(field.shape().def, Def::Option(_));
1630
1631 if field_has_default {
1632 wip = wip.set_nth_field_to_default(idx)?;
1634 } else if struct_has_default && field_type_has_default {
1635 wip = wip.set_nth_field_to_default(idx)?;
1637 } else if field_is_option {
1638 wip = wip.begin_field(field.name)?;
1640 wip = wip.set_default()?;
1641 wip = wip.end()?;
1642 } else {
1643 return Err(JsonError {
1645 kind: JsonErrorKind::MissingField {
1646 field: field.name,
1647 object_start: Some(object_start_span),
1648 object_end: object_end_span,
1649 },
1650 span: None, source_code: None,
1652 });
1653 }
1654 }
1655
1656 Ok(wip)
1657 }
1658
1659 fn deserialize_struct_with_flatten(
1665 &mut self,
1666 mut wip: Partial<'input, BORROW>,
1667 ) -> Result<Partial<'input, BORROW>> {
1668 log::trace!(
1669 "deserialize_struct_with_flatten: {wip}",
1670 wip = wip.shape().type_identifier
1671 );
1672
1673 let schema = Schema::build_auto(wip.shape()).map_err(|e| {
1676 JsonError::without_span(JsonErrorKind::Solver(format!(
1677 "failed to build schema: {e}"
1678 )))
1679 })?;
1680
1681 let mut solver = Solver::new(&schema);
1683
1684 let mut field_positions: Vec<(Cow<'input, str>, usize)> = Vec::new();
1686
1687 let token = self.next()?;
1689 match token.token {
1690 Token::ObjectStart => {}
1691 _ => {
1692 return Err(JsonError::new(
1693 JsonErrorKind::UnexpectedToken {
1694 got: format!("{:?}", token.token),
1695 expected: "'{'",
1696 },
1697 token.span,
1698 ));
1699 }
1700 }
1701
1702 loop {
1704 let token = self.peek()?;
1705 match &token.token {
1706 Token::ObjectEnd => {
1707 self.next()?; break;
1709 }
1710 Token::String(_) => {
1711 let key_token = self.next()?;
1713 let key = match &key_token.token {
1714 Token::String(s) => s.clone(),
1715 _ => unreachable!(),
1716 };
1717
1718 let colon = self.next()?;
1720 if !matches!(colon.token, Token::Colon) {
1721 return Err(JsonError::new(
1722 JsonErrorKind::UnexpectedToken {
1723 got: format!("{:?}", colon.token),
1724 expected: "':'",
1725 },
1726 colon.span,
1727 ));
1728 }
1729
1730 let value_start = self.peek()?.span.offset;
1732
1733 let _decision = solver.see_key(key.clone());
1735
1736 field_positions.push((key, value_start));
1737
1738 self.skip_value()?;
1740
1741 let next = self.peek()?;
1743 if matches!(next.token, Token::Comma) {
1744 self.next()?;
1745 }
1746 }
1747 _ => {
1748 let span = token.span;
1749 return Err(JsonError::new(
1750 JsonErrorKind::UnexpectedToken {
1751 got: format!("{:?}", token.token),
1752 expected: "field name or '}'",
1753 },
1754 span,
1755 ));
1756 }
1757 }
1758 }
1759
1760 let seen_keys = solver.seen_keys().clone();
1763 let config = solver
1764 .finish()
1765 .map_err(|e| JsonError::without_span(JsonErrorKind::Solver(format!("{e}"))))?;
1766
1767 let mut fields_to_process: Vec<_> = field_positions
1771 .iter()
1772 .filter_map(|(key, offset)| config.field(key.as_ref()).map(|info| (info, *offset)))
1773 .collect();
1774
1775 fields_to_process.sort_by(|(a, _), (b, _)| a.path.segments().cmp(b.path.segments()));
1778
1779 let mut open_segments: Vec<(&str, bool)> = Vec::new();
1781
1782 for (field_info, offset) in &fields_to_process {
1783 let segments = field_info.path.segments();
1784 let offset = *offset;
1785
1786 let field_segments: Vec<&str> = segments
1788 .iter()
1789 .filter_map(|s| match s {
1790 PathSegment::Field(name) => Some(*name),
1791 PathSegment::Variant(_, _) => None,
1792 })
1793 .collect();
1794
1795 let common_len = open_segments
1797 .iter()
1798 .zip(field_segments.iter())
1799 .take_while(|((name, _), b)| *name == **b)
1800 .count();
1801
1802 while open_segments.len() > common_len {
1804 let (_, is_option) = open_segments.pop().unwrap();
1805 if is_option {
1806 wip = wip.end()?; }
1808 wip = wip.end()?; }
1810
1811 for &segment in &field_segments[common_len..] {
1813 wip = wip.begin_field(segment)?;
1814 let is_option = matches!(wip.shape().def, Def::Option(_));
1816 if is_option {
1817 wip = wip.begin_some()?;
1818 }
1819 open_segments.push((segment, is_option));
1820 }
1821
1822 let ends_with_variant = segments
1824 .last()
1825 .is_some_and(|s| matches!(s, PathSegment::Variant(_, _)));
1826
1827 if ends_with_variant
1828 && let Some(PathSegment::Variant(_, variant_name)) = segments.last()
1829 {
1830 wip = wip.select_variant_named(variant_name)?;
1831 }
1832
1833 let sub_adapter = self.adapter.at_offset(offset).ok_or_else(|| {
1837 JsonError::without_span(JsonErrorKind::InvalidValue {
1838 message: "flatten is not supported in streaming mode".into(),
1839 })
1840 })?;
1841 let mut sub = Self::from_adapter(sub_adapter);
1842
1843 if ends_with_variant {
1844 wip = sub.deserialize_variant_struct_content(wip)?;
1845 } else {
1846 if !open_segments.is_empty() {
1849 let (_, is_option) = open_segments.pop().unwrap();
1850 wip = sub.deserialize_into(wip)?;
1851 wip = wip.end()?;
1852 if is_option {
1853 wip = wip.end()?; }
1855 } else {
1856 wip = sub.deserialize_into(wip)?;
1857 }
1858 }
1859 }
1860
1861 while let Some((_, is_option)) = open_segments.pop() {
1863 if is_option {
1864 wip = wip.end()?; }
1866 wip = wip.end()?; }
1868
1869 let processed_first_segments: BTreeSet<&str> = fields_to_process
1874 .iter()
1875 .filter_map(|(info, _)| {
1876 if let Some(PathSegment::Field(name)) = info.path.segments().first() {
1877 Some(*name)
1878 } else {
1879 None
1880 }
1881 })
1882 .collect();
1883
1884 let missing_first_segments: BTreeSet<&str> = config
1886 .missing_optional_fields(&seen_keys)
1887 .filter_map(|info| {
1888 if let Some(PathSegment::Field(name)) = info.path.segments().first() {
1889 Some(*name)
1890 } else {
1891 None
1892 }
1893 })
1894 .collect();
1895
1896 for first_field in missing_first_segments {
1898 if processed_first_segments.contains(first_field) {
1899 continue;
1901 }
1902
1903 log::trace!("setting default for flattened Option field: {first_field}");
1904
1905 wip = wip.begin_field(first_field)?;
1906 if matches!(wip.shape().def, Def::Option(_)) {
1907 wip = wip.set_default()?;
1909 }
1910 wip = wip.end()?;
1911 }
1912
1913 Ok(wip)
1914 }
1915
1916 fn deserialize_enum(
1920 &mut self,
1921 mut wip: Partial<'input, BORROW>,
1922 ) -> Result<Partial<'input, BORROW>> {
1923 log::trace!("deserialize_enum: {}", wip.shape().type_identifier);
1924
1925 if wip.shape().is_untagged() {
1927 return self.deserialize_untagged_enum(wip);
1928 }
1929
1930 let token = self.peek()?;
1931
1932 match &token.token {
1933 Token::String(s) => {
1935 let variant_name = s.clone();
1936 self.next()?; wip = wip.select_variant_named(&variant_name)?;
1939 Ok(wip)
1941 }
1942 Token::ObjectStart => {
1944 self.next()?; let key_token = self.next()?;
1948 let key = match &key_token.token {
1949 Token::String(s) => s.clone(),
1950 Token::ObjectEnd => {
1951 return Err(JsonError::new(
1953 JsonErrorKind::InvalidValue {
1954 message: "empty object cannot represent enum variant".into(),
1955 },
1956 key_token.span,
1957 ));
1958 }
1959 _ => {
1960 return Err(JsonError::new(
1961 JsonErrorKind::UnexpectedToken {
1962 got: format!("{:?}", key_token.token),
1963 expected: "variant name",
1964 },
1965 key_token.span,
1966 ));
1967 }
1968 };
1969
1970 let colon = self.next()?;
1972 if !matches!(colon.token, Token::Colon) {
1973 return Err(JsonError::new(
1974 JsonErrorKind::UnexpectedToken {
1975 got: format!("{:?}", colon.token),
1976 expected: "':'",
1977 },
1978 colon.span,
1979 ));
1980 }
1981
1982 wip = wip.select_variant_named(&key)?;
1984
1985 let variant = wip.selected_variant().ok_or_else(|| {
1987 JsonError::without_span(JsonErrorKind::InvalidValue {
1988 message: "failed to get selected variant".into(),
1989 })
1990 })?;
1991
1992 match variant.data.kind {
1994 StructKind::Unit => {
1995 let tok = self.next()?;
1998 if !matches!(tok.token, Token::Null) {
1999 return Err(JsonError::new(
2000 JsonErrorKind::UnexpectedToken {
2001 got: format!("{:?}", tok.token),
2002 expected: "null for unit variant",
2003 },
2004 tok.span,
2005 ));
2006 }
2007 }
2008 StructKind::TupleStruct | StructKind::Tuple => {
2009 let num_fields = variant.data.fields.len();
2010 if num_fields == 0 {
2011 let tok = self.peek()?;
2013 if matches!(tok.token, Token::Null) {
2014 self.next()?;
2015 }
2016 } else if num_fields == 1 {
2017 let field = &variant.data.fields[0];
2019 wip = wip.begin_nth_field(0)?;
2020 if field.proxy_convert_in_fn().is_some() {
2022 wip = wip.begin_custom_deserialization()?;
2023 wip = self.deserialize_into(wip)?;
2024 wip = wip.end()?; } else {
2026 wip = self.deserialize_into(wip)?;
2027 }
2028 wip = wip.end()?;
2029 } else {
2030 let tok = self.next()?;
2032 if !matches!(tok.token, Token::ArrayStart) {
2033 return Err(JsonError::new(
2034 JsonErrorKind::UnexpectedToken {
2035 got: format!("{:?}", tok.token),
2036 expected: "'[' for tuple variant",
2037 },
2038 tok.span,
2039 ));
2040 }
2041
2042 for i in 0..num_fields {
2043 let field = &variant.data.fields[i];
2044 wip = wip.begin_nth_field(i)?;
2045 if field.proxy_convert_in_fn().is_some() {
2047 wip = wip.begin_custom_deserialization()?;
2048 wip = self.deserialize_into(wip)?;
2049 wip = wip.end()?; } else {
2051 wip = self.deserialize_into(wip)?;
2052 }
2053 wip = wip.end()?;
2054
2055 let next = self.peek()?;
2057 if matches!(next.token, Token::Comma) {
2058 self.next()?;
2059 }
2060 }
2061
2062 let close = self.next()?;
2063 if !matches!(close.token, Token::ArrayEnd) {
2064 return Err(JsonError::new(
2065 JsonErrorKind::UnexpectedToken {
2066 got: format!("{:?}", close.token),
2067 expected: "']'",
2068 },
2069 close.span,
2070 ));
2071 }
2072 }
2073 }
2074 StructKind::Struct => {
2075 wip = self.deserialize_variant_struct_content(wip)?;
2077 }
2078 }
2079
2080 let close = self.next()?;
2082 if !matches!(close.token, Token::ObjectEnd) {
2083 return Err(JsonError::new(
2084 JsonErrorKind::UnexpectedToken {
2085 got: format!("{:?}", close.token),
2086 expected: "'}'",
2087 },
2088 close.span,
2089 ));
2090 }
2091
2092 Ok(wip)
2093 }
2094 _ => {
2095 let span = token.span;
2096 Err(JsonError::new(
2097 JsonErrorKind::UnexpectedToken {
2098 got: format!("{:?}", token.token),
2099 expected: "string or object for enum",
2100 },
2101 span,
2102 ))
2103 }
2104 }
2105 }
2106
2107 fn deserialize_untagged_enum(
2115 &mut self,
2116 mut wip: Partial<'input, BORROW>,
2117 ) -> Result<Partial<'input, BORROW>> {
2118 log::trace!("deserialize_untagged_enum: {}", wip.shape().type_identifier);
2119
2120 let shape = wip.shape();
2121
2122 let schema = Schema::build_auto(shape).map_err(|e| {
2124 JsonError::without_span(JsonErrorKind::Solver(format!(
2125 "failed to build schema: {e}"
2126 )))
2127 })?;
2128
2129 let mut solver = Solver::new(&schema);
2131
2132 let token = self.peek()?;
2134 match &token.token {
2135 Token::ObjectStart => {
2136 let start_offset = token.span.offset;
2138
2139 self.next()?; loop {
2143 let token = self.peek()?;
2144 match &token.token {
2145 Token::ObjectEnd => {
2146 self.next()?;
2147 break;
2148 }
2149 Token::String(_) => {
2150 let key_token = self.next()?;
2151 let key = match &key_token.token {
2152 Token::String(s) => s.clone(),
2153 _ => unreachable!(),
2154 };
2155
2156 let colon = self.next()?;
2157 if !matches!(colon.token, Token::Colon) {
2158 return Err(JsonError::new(
2159 JsonErrorKind::UnexpectedToken {
2160 got: format!("{:?}", colon.token),
2161 expected: "':'",
2162 },
2163 colon.span,
2164 ));
2165 }
2166
2167 let _decision = solver.see_key(key);
2169
2170 self.skip_value()?;
2172
2173 let next = self.peek()?;
2175 if matches!(next.token, Token::Comma) {
2176 self.next()?;
2177 }
2178 }
2179 _ => {
2180 let span = token.span;
2181 return Err(JsonError::new(
2182 JsonErrorKind::UnexpectedToken {
2183 got: format!("{:?}", token.token),
2184 expected: "field name or '}'",
2185 },
2186 span,
2187 ));
2188 }
2189 }
2190 }
2191
2192 let config = solver
2194 .finish()
2195 .map_err(|e| JsonError::without_span(JsonErrorKind::Solver(format!("{e}"))))?;
2196
2197 let variant_name = config
2199 .variant_selections()
2200 .first()
2201 .map(|vs| vs.variant_name)
2202 .ok_or_else(|| {
2203 JsonError::without_span(JsonErrorKind::InvalidValue {
2204 message: "solver returned resolution with no variant selection".into(),
2205 })
2206 })?;
2207
2208 wip = wip.select_variant_named(variant_name)?;
2210
2211 let rewound_adapter = self.adapter.at_offset(start_offset).ok_or_else(|| {
2214 JsonError::without_span(JsonErrorKind::InvalidValue {
2215 message: "untagged enums not supported in streaming mode".into(),
2216 })
2217 })?;
2218 let mut rewound_deser = Self::from_adapter(rewound_adapter);
2219
2220 wip = rewound_deser.deserialize_variant_struct_content(wip)?;
2222
2223 Ok(wip)
2224 }
2225 Token::ArrayStart => {
2226 self.deserialize_untagged_tuple_variant(wip, shape)
2228 }
2229 Token::Null => {
2230 self.deserialize_untagged_unit_variant(wip, shape)
2232 }
2233 Token::String(_)
2234 | Token::I64(_)
2235 | Token::U64(_)
2236 | Token::I128(_)
2237 | Token::U128(_)
2238 | Token::F64(_)
2239 | Token::True
2240 | Token::False => {
2241 self.deserialize_untagged_scalar_variant(wip, shape)
2243 }
2244 _ => Err(JsonError::new(
2245 JsonErrorKind::InvalidValue {
2246 message: format!("unexpected token {:?} for untagged enum", token.token),
2247 },
2248 token.span,
2249 )),
2250 }
2251 }
2252
2253 fn deserialize_untagged_unit_variant(
2256 &mut self,
2257 mut wip: Partial<'input, BORROW>,
2258 shape: &'static Shape,
2259 ) -> Result<Partial<'input, BORROW>> {
2260 let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2261 JsonError::without_span(JsonErrorKind::InvalidValue {
2262 message: "expected enum shape for untagged deserialization".into(),
2263 })
2264 })?;
2265
2266 if variants_by_format.unit_variants.is_empty() {
2267 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2268 message: format!(
2269 "no unit variants in untagged enum {} for null value",
2270 shape.type_identifier
2271 ),
2272 }));
2273 }
2274
2275 self.next()?;
2277
2278 let variant = variants_by_format.unit_variants[0];
2280 wip = wip.select_variant_named(variant.name)?;
2281
2282 Ok(wip)
2283 }
2284
2285 fn deserialize_untagged_scalar_variant(
2288 &mut self,
2289 mut wip: Partial<'input, BORROW>,
2290 shape: &'static Shape,
2291 ) -> Result<Partial<'input, BORROW>> {
2292 let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2293 JsonError::without_span(JsonErrorKind::InvalidValue {
2294 message: "expected enum shape for untagged deserialization".into(),
2295 })
2296 })?;
2297
2298 let token = self.peek()?.clone();
2300 if let Token::String(ref s) = token.token {
2301 for variant in &variants_by_format.unit_variants {
2303 if variant.name == s.as_ref() {
2304 self.next()?;
2306 wip = wip.select_variant_named(variant.name)?;
2307 return Ok(wip);
2308 }
2309 }
2310 }
2311
2312 if variants_by_format.scalar_variants.is_empty() {
2314 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2315 message: format!(
2316 "no scalar-accepting variants in untagged enum {}",
2317 shape.type_identifier
2318 ),
2319 }));
2320 }
2321
2322 let variant_name = self.select_scalar_variant(&variants_by_format, &token)?;
2324
2325 wip = wip.select_variant_named(variant_name)?;
2326 wip = wip.begin_nth_field(0)?;
2327 wip = self.deserialize_into(wip)?;
2328 wip = wip.end()?;
2329
2330 Ok(wip)
2331 }
2332
2333 fn select_scalar_variant(
2335 &self,
2336 variants: &VariantsByFormat,
2337 token: &SpannedAdapterToken,
2338 ) -> Result<&'static str> {
2339 let mut candidates: Vec<_> = variants.scalar_variants.clone();
2341 candidates.sort_by_key(|(_, inner_shape)| specificity_score(inner_shape));
2342
2343 match &token.token {
2344 Token::True | Token::False => {
2345 for (variant, inner_shape) in &candidates {
2347 if inner_shape.scalar_type() == Some(ScalarType::Bool) {
2348 return Ok(variant.name);
2349 }
2350 }
2351 }
2352 Token::I64(n) => {
2353 let n = *n;
2355 for (variant, inner_shape) in &candidates {
2356 let fits = match inner_shape.scalar_type() {
2357 Some(ScalarType::U8) => n >= 0 && n <= u8::MAX as i64,
2358 Some(ScalarType::U16) => n >= 0 && n <= u16::MAX as i64,
2359 Some(ScalarType::U32) => n >= 0 && n <= u32::MAX as i64,
2360 Some(ScalarType::U64) => n >= 0,
2361 Some(ScalarType::I8) => n >= i8::MIN as i64 && n <= i8::MAX as i64,
2362 Some(ScalarType::I16) => n >= i16::MIN as i64 && n <= i16::MAX as i64,
2363 Some(ScalarType::I32) => n >= i32::MIN as i64 && n <= i32::MAX as i64,
2364 Some(ScalarType::I64) => true,
2365 Some(ScalarType::F32) | Some(ScalarType::F64) => true,
2366 _ => false,
2367 };
2368 if fits {
2369 return Ok(variant.name);
2370 }
2371 }
2372 }
2373 Token::U64(n) => {
2374 let n = *n;
2375 for (variant, inner_shape) in &candidates {
2376 let fits = match inner_shape.scalar_type() {
2377 Some(ScalarType::U8) => n <= u8::MAX as u64,
2378 Some(ScalarType::U16) => n <= u16::MAX as u64,
2379 Some(ScalarType::U32) => n <= u32::MAX as u64,
2380 Some(ScalarType::U64) => true,
2381 Some(ScalarType::I8) => n <= i8::MAX as u64,
2382 Some(ScalarType::I16) => n <= i16::MAX as u64,
2383 Some(ScalarType::I32) => n <= i32::MAX as u64,
2384 Some(ScalarType::I64) => n <= i64::MAX as u64,
2385 Some(ScalarType::F32) | Some(ScalarType::F64) => true,
2386 _ => false,
2387 };
2388 if fits {
2389 return Ok(variant.name);
2390 }
2391 }
2392 }
2393 Token::I128(n) => {
2394 let n = *n;
2395 for (variant, inner_shape) in &candidates {
2396 let fits = match inner_shape.scalar_type() {
2397 Some(ScalarType::I128) => true,
2398 Some(ScalarType::U128) => n >= 0,
2399 _ => false,
2400 };
2401 if fits {
2402 return Ok(variant.name);
2403 }
2404 }
2405 }
2406 Token::U128(n) => {
2407 let n = *n;
2408 for (variant, inner_shape) in &candidates {
2409 let fits = match inner_shape.scalar_type() {
2410 Some(ScalarType::U128) => true,
2411 Some(ScalarType::I128) => n <= i128::MAX as u128,
2412 _ => false,
2413 };
2414 if fits {
2415 return Ok(variant.name);
2416 }
2417 }
2418 }
2419 Token::F64(_) => {
2420 for (variant, inner_shape) in &candidates {
2422 if matches!(
2423 inner_shape.scalar_type(),
2424 Some(ScalarType::F32) | Some(ScalarType::F64)
2425 ) {
2426 return Ok(variant.name);
2427 }
2428 }
2429 }
2430 Token::String(_) => {
2431 for (variant, inner_shape) in &candidates {
2433 if matches!(
2434 inner_shape.scalar_type(),
2435 Some(ScalarType::String) | Some(ScalarType::Str) | Some(ScalarType::CowStr)
2436 ) || inner_shape.scalar_type().is_none()
2437 {
2438 return Ok(variant.name);
2439 }
2440 }
2441 }
2442 _ => {}
2443 }
2444
2445 if let Some((variant, _)) = candidates.first() {
2447 return Ok(variant.name);
2448 }
2449
2450 Err(JsonError::new(
2451 JsonErrorKind::InvalidValue {
2452 message: format!("no matching scalar variant for token {:?}", token.token),
2453 },
2454 token.span,
2455 ))
2456 }
2457
2458 fn deserialize_untagged_tuple_variant(
2460 &mut self,
2461 mut wip: Partial<'input, BORROW>,
2462 shape: &'static Shape,
2463 ) -> Result<Partial<'input, BORROW>> {
2464 let variants_by_format = VariantsByFormat::from_shape(shape).ok_or_else(|| {
2465 JsonError::without_span(JsonErrorKind::InvalidValue {
2466 message: "expected enum shape for untagged deserialization".into(),
2467 })
2468 })?;
2469
2470 if variants_by_format.tuple_variants.is_empty() {
2471 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2472 message: format!(
2473 "no tuple variants in untagged enum {} for array value",
2474 shape.type_identifier
2475 ),
2476 }));
2477 }
2478
2479 let start_token = self.peek()?;
2481 let start_offset = start_token.span.offset;
2482
2483 self.next()?; let mut arity = 0;
2486 loop {
2487 let token = self.peek()?;
2488 match &token.token {
2489 Token::ArrayEnd => {
2490 self.next()?;
2491 break;
2492 }
2493 _ => {
2494 arity += 1;
2495 self.skip_value()?;
2496 let next = self.peek()?;
2498 if matches!(next.token, Token::Comma) {
2499 self.next()?;
2500 }
2501 }
2502 }
2503 }
2504
2505 let matching_variants = variants_by_format.tuple_variants_with_arity(arity);
2507 if matching_variants.is_empty() {
2508 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2509 message: format!(
2510 "no tuple variant with arity {} in untagged enum {}",
2511 arity, shape.type_identifier
2512 ),
2513 }));
2514 }
2515
2516 let variant = matching_variants[0];
2518 wip = wip.select_variant_named(variant.name)?;
2519 let is_newtype = variant.data.fields.len() == 1;
2520
2521 let rewound_adapter = self.adapter.at_offset(start_offset).ok_or_else(|| {
2523 JsonError::without_span(JsonErrorKind::InvalidValue {
2524 message: "untagged tuple variants not supported in streaming mode".into(),
2525 })
2526 })?;
2527 let mut rewound_deser = Self::from_adapter(rewound_adapter);
2528
2529 if is_newtype {
2530 wip = wip.begin_nth_field(0)?;
2532 wip = rewound_deser.deserialize_into(wip)?;
2533 wip = wip.end()?;
2534 } else {
2535 rewound_deser.next()?;
2537
2538 for i in 0..arity {
2540 wip = wip.begin_nth_field(i)?;
2541 wip = rewound_deser.deserialize_into(wip)?;
2542 wip = wip.end()?;
2543
2544 let next = rewound_deser.peek()?;
2546 if matches!(next.token, Token::Comma) {
2547 rewound_deser.next()?;
2548 }
2549 }
2550
2551 debug_assert_eq!(
2552 variant.data.fields.len(),
2553 arity,
2554 "tuple variant arity should match array length"
2555 );
2556
2557 rewound_deser.next()?;
2559 }
2560
2561 Ok(wip)
2562 }
2563
2564 fn deserialize_variant_struct_content(
2567 &mut self,
2568 mut wip: Partial<'input, BORROW>,
2569 ) -> Result<Partial<'input, BORROW>> {
2570 let variant = wip.selected_variant().ok_or_else(|| {
2572 JsonError::without_span(JsonErrorKind::InvalidValue {
2573 message: "no variant selected".into(),
2574 })
2575 })?;
2576
2577 let is_struct_variant = variant
2578 .data
2579 .fields
2580 .first()
2581 .map(|f| !f.name.starts_with(|c: char| c.is_ascii_digit()))
2582 .unwrap_or(true);
2583
2584 if is_struct_variant {
2585 self.deserialize_variant_struct_fields(wip, variant.data.fields)
2587 } else if variant.data.fields.len() == 1 {
2588 let field = &variant.data.fields[0];
2590 wip = wip.begin_nth_field(0)?;
2591 if field.proxy_convert_in_fn().is_some() {
2593 wip = wip.begin_custom_deserialization()?;
2594 wip = self.deserialize_into(wip)?;
2595 wip = wip.end()?;
2596 } else {
2597 wip = self.deserialize_into(wip)?;
2598 }
2599 wip = wip.end()?;
2600 Ok(wip)
2601 } else {
2602 self.deserialize_variant_tuple_fields(wip)
2604 }
2605 }
2606
2607 fn deserialize_variant_struct_fields(
2609 &mut self,
2610 mut wip: Partial<'input, BORROW>,
2611 fields: &[facet_core::Field],
2612 ) -> Result<Partial<'input, BORROW>> {
2613 let token = self.next()?;
2614 if !matches!(token.token, Token::ObjectStart) {
2615 return Err(JsonError::new(
2616 JsonErrorKind::UnexpectedToken {
2617 got: format!("{:?}", token.token),
2618 expected: "'{' for struct variant",
2619 },
2620 token.span,
2621 ));
2622 }
2623
2624 loop {
2625 let token = self.peek()?;
2626 if matches!(token.token, Token::ObjectEnd) {
2627 self.next()?;
2628 break;
2629 }
2630
2631 let key_token = self.next()?;
2632 let field_name = match &key_token.token {
2633 Token::String(s) => s.clone(),
2634 _ => {
2635 return Err(JsonError::new(
2636 JsonErrorKind::UnexpectedToken {
2637 got: format!("{:?}", key_token.token),
2638 expected: "field name",
2639 },
2640 key_token.span,
2641 ));
2642 }
2643 };
2644
2645 let colon = self.next()?;
2646 if !matches!(colon.token, Token::Colon) {
2647 return Err(JsonError::new(
2648 JsonErrorKind::UnexpectedToken {
2649 got: format!("{:?}", colon.token),
2650 expected: "':'",
2651 },
2652 colon.span,
2653 ));
2654 }
2655
2656 let field_info = fields.iter().find(|f| f.name == field_name.as_ref());
2658
2659 if let Some(field) = field_info {
2660 wip = wip.begin_field(field.name)?;
2661 if field.proxy_convert_in_fn().is_some() {
2663 wip = wip.begin_custom_deserialization()?;
2664 wip = self.deserialize_into(wip)?;
2665 wip = wip.end()?; } else {
2667 wip = self.deserialize_into(wip)?;
2668 }
2669 wip = wip.end()?;
2670 } else {
2671 self.skip_value()?;
2673 }
2674
2675 let next = self.peek()?;
2676 if matches!(next.token, Token::Comma) {
2677 self.next()?;
2678 }
2679 }
2680
2681 Ok(wip)
2682 }
2683
2684 fn deserialize_variant_tuple_fields(
2686 &mut self,
2687 mut wip: Partial<'input, BORROW>,
2688 ) -> Result<Partial<'input, BORROW>> {
2689 let token = self.next()?;
2690 if !matches!(token.token, Token::ArrayStart) {
2691 return Err(JsonError::new(
2692 JsonErrorKind::UnexpectedToken {
2693 got: format!("{:?}", token.token),
2694 expected: "'[' for tuple variant",
2695 },
2696 token.span,
2697 ));
2698 }
2699
2700 let mut idx = 0;
2701 loop {
2702 let token = self.peek()?;
2703 if matches!(token.token, Token::ArrayEnd) {
2704 self.next()?;
2705 break;
2706 }
2707
2708 let field_name = alloc::format!("{idx}");
2710 wip = wip.begin_field(&field_name)?;
2711 wip = self.deserialize_into(wip)?;
2712 wip = wip.end()?;
2713
2714 idx += 1;
2715 let next = self.peek()?;
2716 if matches!(next.token, Token::Comma) {
2717 self.next()?;
2718 }
2719 }
2720
2721 Ok(wip)
2722 }
2723
2724 fn deserialize_list(
2726 &mut self,
2727 mut wip: Partial<'input, BORROW>,
2728 ) -> Result<Partial<'input, BORROW>> {
2729 log::trace!("deserialize_list");
2730
2731 let token = self.next()?;
2732 if !matches!(token.token, Token::ArrayStart) {
2733 return Err(JsonError::new(
2734 JsonErrorKind::UnexpectedToken {
2735 got: format!("{:?}", token.token),
2736 expected: "'['",
2737 },
2738 token.span,
2739 ));
2740 }
2741
2742 wip = wip.begin_list()?;
2743
2744 loop {
2745 let token = self.peek()?;
2746 if matches!(token.token, Token::ArrayEnd) {
2747 self.next()?;
2748 break;
2749 }
2750
2751 wip = wip.begin_list_item()?;
2752 wip = self.deserialize_into(wip)?;
2753 wip = wip.end()?; let next = self.peek()?;
2756 if matches!(next.token, Token::Comma) {
2757 self.next()?;
2758 }
2759 }
2760
2761 Ok(wip)
2763 }
2764
2765 fn deserialize_map(
2767 &mut self,
2768 mut wip: Partial<'input, BORROW>,
2769 ) -> Result<Partial<'input, BORROW>> {
2770 log::trace!("deserialize_map");
2771
2772 let token = self.next()?;
2773 if !matches!(token.token, Token::ObjectStart) {
2774 return Err(JsonError::new(
2775 JsonErrorKind::UnexpectedToken {
2776 got: format!("{:?}", token.token),
2777 expected: "'{'",
2778 },
2779 token.span,
2780 ));
2781 }
2782
2783 wip = wip.begin_map()?;
2784
2785 loop {
2786 let token = self.peek()?;
2787 if matches!(token.token, Token::ObjectEnd) {
2788 self.next()?;
2789 break;
2790 }
2791
2792 let key_token = self.next()?;
2794 let key = match key_token.token {
2795 Token::String(s) => s,
2796 _ => {
2797 return Err(JsonError::new(
2798 JsonErrorKind::UnexpectedToken {
2799 got: format!("{:?}", key_token.token),
2800 expected: "string key",
2801 },
2802 key_token.span,
2803 ));
2804 }
2805 };
2806
2807 let colon = self.next()?;
2809 if !matches!(colon.token, Token::Colon) {
2810 return Err(JsonError::new(
2811 JsonErrorKind::UnexpectedToken {
2812 got: format!("{:?}", colon.token),
2813 expected: "':'",
2814 },
2815 colon.span,
2816 ));
2817 }
2818
2819 wip = wip.begin_key()?;
2821 let is_pointer = matches!(wip.shape().def, Def::Pointer(_));
2825 if wip.shape().inner.is_some() && !is_pointer {
2826 wip = wip.begin_inner()?;
2827 wip = self.set_string_value(wip, key)?;
2828 wip = wip.end()?;
2829 } else {
2830 wip = self.set_string_value(wip, key)?;
2831 }
2832 wip = wip.end()?;
2833
2834 wip = wip.begin_value()?;
2836 wip = self.deserialize_into(wip)?;
2837 wip = wip.end()?;
2838
2839 let next = self.peek()?;
2841 if matches!(next.token, Token::Comma) {
2842 self.next()?;
2843 }
2844 }
2845
2846 Ok(wip)
2848 }
2849
2850 fn deserialize_option(
2852 &mut self,
2853 mut wip: Partial<'input, BORROW>,
2854 ) -> Result<Partial<'input, BORROW>> {
2855 log::trace!("deserialize_option");
2856
2857 let token = self.peek()?;
2858 if matches!(token.token, Token::Null) {
2859 self.next()?;
2860 wip = wip.set_default()?; } else {
2862 log::trace!("deserialize_option: calling begin_some");
2863 wip = wip.begin_some()?;
2864 log::trace!("deserialize_option: begin_some succeeded, calling deserialize_into");
2865 wip = self.deserialize_into(wip)?;
2866 log::trace!("deserialize_option: deserialize_into succeeded, calling end");
2867 wip = wip.end()?;
2868 log::trace!("deserialize_option: end succeeded");
2869 }
2870 Ok(wip)
2871 }
2872
2873 fn deserialize_pointer(
2875 &mut self,
2876 mut wip: Partial<'input, BORROW>,
2877 ) -> Result<Partial<'input, BORROW>> {
2878 log::trace!("deserialize_pointer");
2879
2880 let (is_slice_pointer, is_reference, is_str_ref, is_cow_str) =
2882 if let Def::Pointer(ptr_def) = wip.shape().def {
2883 let is_slice = if let Some(pointee) = ptr_def.pointee() {
2884 matches!(pointee.ty, Type::Sequence(SequenceType::Slice(_)))
2885 } else {
2886 false
2887 };
2888 let is_ref = matches!(
2889 ptr_def.known,
2890 Some(KnownPointer::SharedReference | KnownPointer::ExclusiveReference)
2891 );
2892 let is_str_ref = matches!(ptr_def.known, Some(KnownPointer::SharedReference))
2894 && ptr_def
2895 .pointee()
2896 .is_some_and(|p| p.type_identifier == "str");
2897 let is_cow_str = matches!(ptr_def.known, Some(KnownPointer::Cow))
2899 && ptr_def
2900 .pointee()
2901 .is_some_and(|p| p.type_identifier == "str");
2902 (is_slice, is_ref, is_str_ref, is_cow_str)
2903 } else {
2904 (false, false, false, false)
2905 };
2906
2907 if is_cow_str {
2910 let token = self.next()?;
2911 match token.token {
2912 Token::String(s) => {
2913 wip = wip.set(s)?;
2915 return Ok(wip);
2916 }
2917 _ => {
2918 return Err(JsonError::new(
2919 JsonErrorKind::UnexpectedToken {
2920 got: format!("{:?}", token.token),
2921 expected: "string",
2922 },
2923 token.span,
2924 ));
2925 }
2926 }
2927 }
2928
2929 if is_str_ref {
2931 if !BORROW {
2933 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2934 message: "cannot deserialize into &str when borrowing is disabled - use String or Cow<str> instead".into(),
2935 }));
2936 }
2937 let token = self.next()?;
2938 match token.token {
2939 Token::String(Cow::Borrowed(s)) => {
2940 wip = wip.set(s)?;
2942 return Ok(wip);
2943 }
2944 Token::String(Cow::Owned(_)) => {
2945 return Err(JsonError::new(
2946 JsonErrorKind::InvalidValue {
2947 message: "cannot borrow &str from JSON string containing escape sequences - use String instead".into(),
2948 },
2949 token.span,
2950 ));
2951 }
2952 _ => {
2953 return Err(JsonError::new(
2954 JsonErrorKind::UnexpectedToken {
2955 got: format!("{:?}", token.token),
2956 expected: "string",
2957 },
2958 token.span,
2959 ));
2960 }
2961 }
2962 }
2963
2964 if is_reference {
2967 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
2968 message: format!(
2969 "cannot deserialize into reference type '{wip}' - references require borrowing from existing data",
2970 wip = wip.shape().type_identifier
2971 ),
2972 }));
2973 }
2974
2975 wip = wip.begin_smart_ptr()?;
2980
2981 if is_slice_pointer {
2982 let token = self.next()?;
2984 if !matches!(token.token, Token::ArrayStart) {
2985 return Err(JsonError::new(
2986 JsonErrorKind::UnexpectedToken {
2987 got: format!("{:?}", token.token),
2988 expected: "'['",
2989 },
2990 token.span,
2991 ));
2992 }
2993
2994 let first = self.peek()?;
2996 if matches!(first.token, Token::ArrayEnd) {
2997 self.next()?; wip = wip.end()?;
2999 return Ok(wip);
3000 }
3001
3002 loop {
3004 wip = wip.begin_list_item()?;
3005 wip = self.deserialize_into(wip)?;
3006 wip = wip.end()?;
3007
3008 let next = self.next()?;
3009 match next.token {
3010 Token::Comma => continue,
3011 Token::ArrayEnd => break,
3012 _ => {
3013 return Err(JsonError::new(
3014 JsonErrorKind::UnexpectedToken {
3015 got: format!("{:?}", next.token),
3016 expected: "',' or ']'",
3017 },
3018 next.span,
3019 ));
3020 }
3021 }
3022 }
3023
3024 wip = wip.end()?;
3025 return Ok(wip);
3026 }
3027
3028 wip = self.deserialize_into(wip)?;
3030 wip = wip.end()?;
3031 Ok(wip)
3032 }
3033
3034 fn deserialize_array(
3036 &mut self,
3037 mut wip: Partial<'input, BORROW>,
3038 ) -> Result<Partial<'input, BORROW>> {
3039 log::trace!("deserialize_array");
3040
3041 let token = self.next()?;
3042 if !matches!(token.token, Token::ArrayStart) {
3043 return Err(JsonError::new(
3044 JsonErrorKind::UnexpectedToken {
3045 got: format!("{:?}", token.token),
3046 expected: "'['",
3047 },
3048 token.span,
3049 ));
3050 }
3051
3052 let array_len = match &wip.shape().def {
3054 Def::Array(arr) => arr.n,
3055 _ => {
3056 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
3057 message: "expected array type".into(),
3058 }));
3059 }
3060 };
3061
3062 for i in 0..array_len {
3064 if i > 0 {
3065 let comma = self.next()?;
3066 if !matches!(comma.token, Token::Comma) {
3067 return Err(JsonError::new(
3068 JsonErrorKind::UnexpectedToken {
3069 got: format!("{:?}", comma.token),
3070 expected: "','",
3071 },
3072 comma.span,
3073 ));
3074 }
3075 }
3076
3077 wip = wip.begin_nth_field(i)?;
3078 wip = self.deserialize_into(wip)?;
3079 wip = wip.end()?;
3080 }
3081
3082 let close = self.next()?;
3083 if !matches!(close.token, Token::ArrayEnd) {
3084 if matches!(close.token, Token::Comma) {
3086 return Err(JsonError::new(
3087 JsonErrorKind::InvalidValue {
3088 message: format!(
3089 "Too many elements in array, maximum {array_len} elements"
3090 ),
3091 },
3092 close.span,
3093 ));
3094 }
3095 return Err(JsonError::new(
3096 JsonErrorKind::UnexpectedToken {
3097 got: format!("{:?}", close.token),
3098 expected: "']'",
3099 },
3100 close.span,
3101 ));
3102 }
3103
3104 Ok(wip)
3105 }
3106
3107 fn deserialize_set(
3109 &mut self,
3110 mut wip: Partial<'input, BORROW>,
3111 ) -> Result<Partial<'input, BORROW>> {
3112 log::trace!("deserialize_set");
3113
3114 let token = self.next()?;
3115 if !matches!(token.token, Token::ArrayStart) {
3116 return Err(JsonError::new(
3117 JsonErrorKind::UnexpectedToken {
3118 got: format!("{:?}", token.token),
3119 expected: "'['",
3120 },
3121 token.span,
3122 ));
3123 }
3124
3125 wip = wip.begin_set()?;
3126
3127 loop {
3128 let token = self.peek()?;
3129 if matches!(token.token, Token::ArrayEnd) {
3130 self.next()?;
3131 break;
3132 }
3133
3134 wip = wip.begin_set_item()?;
3135 wip = self.deserialize_into(wip)?;
3136 wip = wip.end()?; let next = self.peek()?;
3139 if matches!(next.token, Token::Comma) {
3140 self.next()?;
3141 }
3142 }
3143
3144 Ok(wip)
3146 }
3147
3148 fn deserialize_tuple(
3150 &mut self,
3151 mut wip: Partial<'input, BORROW>,
3152 ) -> Result<Partial<'input, BORROW>> {
3153 log::trace!("deserialize_tuple");
3154
3155 let token = self.next()?;
3156 if !matches!(token.token, Token::ArrayStart) {
3157 return Err(JsonError::new(
3158 JsonErrorKind::UnexpectedToken {
3159 got: format!("{:?}", token.token),
3160 expected: "'['",
3161 },
3162 token.span,
3163 ));
3164 }
3165
3166 let tuple_len = match &wip.shape().ty {
3168 Type::User(UserType::Struct(struct_def)) => struct_def.fields.len(),
3169 _ => {
3170 return Err(JsonError::without_span(JsonErrorKind::InvalidValue {
3171 message: "expected tuple type".into(),
3172 }));
3173 }
3174 };
3175
3176 for i in 0..tuple_len {
3177 if i > 0 {
3178 let comma = self.next()?;
3179 if !matches!(comma.token, Token::Comma) {
3180 return Err(JsonError::new(
3181 JsonErrorKind::UnexpectedToken {
3182 got: format!("{:?}", comma.token),
3183 expected: "','",
3184 },
3185 comma.span,
3186 ));
3187 }
3188 }
3189
3190 wip = wip.begin_nth_field(i)?;
3191 wip = self.deserialize_into(wip)?;
3192 wip = wip.end()?;
3193 }
3194
3195 let close = self.next()?;
3196 if !matches!(close.token, Token::ArrayEnd) {
3197 return Err(JsonError::new(
3198 JsonErrorKind::UnexpectedToken {
3199 got: format!("{:?}", close.token),
3200 expected: "']'",
3201 },
3202 close.span,
3203 ));
3204 }
3205
3206 Ok(wip)
3207 }
3208}
3209
3210pub fn from_slice<T: Facet<'static>>(input: &[u8]) -> Result<T> {
3227 from_slice_inner(input, None)
3228}
3229
3230pub fn from_str<T: Facet<'static>>(input: &str) -> Result<T> {
3243 let input_bytes = input.as_bytes();
3244
3245 if input_bytes.starts_with(&[0xef, 0xbb, 0xbf]) {
3247 return from_slice_inner(&input_bytes[3..], Some(&input[3..]));
3248 }
3249 from_slice_inner(input_bytes, Some(input))
3250}
3251
3252pub fn from_slice_borrowed<'input, 'facet, T: Facet<'facet>>(input: &'input [u8]) -> Result<T>
3264where
3265 'input: 'facet,
3266{
3267 from_slice_borrowed_inner(input, None)
3268}
3269
3270pub fn from_str_borrowed<'input, 'facet, T: Facet<'facet>>(input: &'input str) -> Result<T>
3282where
3283 'input: 'facet,
3284{
3285 let input_bytes = input.as_bytes();
3286
3287 if input_bytes.starts_with(&[0xef, 0xbb, 0xbf]) {
3289 return from_slice_borrowed_inner(&input_bytes[3..], Some(&input[3..]));
3290 }
3291 from_slice_borrowed_inner(input_bytes, Some(input))
3292}
3293
3294fn from_slice_borrowed_inner<'input, 'facet, T: Facet<'facet>>(
3295 input: &'input [u8],
3296 source: Option<&str>,
3297) -> Result<T>
3298where
3299 'input: 'facet,
3300{
3301 let mut deserializer = JsonDeserializer::new(input);
3302 let wip = Partial::alloc::<T>()?;
3303
3304 let partial = match deserializer.deserialize_into(wip) {
3305 Ok(p) => p,
3306 Err(e) => return Err(attach_source_cold(e, source)),
3307 };
3308
3309 let trailing = deserializer.peek()?;
3311 if !matches!(trailing.token, Token::Eof) {
3312 let mut err = JsonError::new(
3313 JsonErrorKind::UnexpectedToken {
3314 got: format!("{:?}", trailing.token),
3315 expected: "end of input",
3316 },
3317 trailing.span,
3318 );
3319 if let Some(src) = source {
3320 err.source_code = Some(src.to_string());
3321 }
3322 return Err(err);
3323 }
3324
3325 let heap_value = match partial.build() {
3327 Ok(v) => v,
3328 Err(e) => return Err(attach_source_cold(JsonError::from(e), source)),
3329 };
3330
3331 match heap_value.materialize::<T>() {
3332 Ok(v) => Ok(v),
3333 Err(e) => Err(attach_source_cold(JsonError::from(e), source)),
3334 }
3335}
3336
3337fn from_slice_inner<T: Facet<'static>>(input: &[u8], source: Option<&str>) -> Result<T> {
3338 fn inner<'input, T: Facet<'static>>(input: &'input [u8], source: Option<&str>) -> Result<T> {
3352 let mut deserializer = JsonDeserializer::new_owned(input);
3353
3354 #[allow(unsafe_code)]
3361 let wip: Partial<'input, false> = unsafe {
3362 core::mem::transmute::<Partial<'static, false>, Partial<'input, false>>(
3363 Partial::alloc_owned::<T>()?,
3364 )
3365 };
3366
3367 let partial = match deserializer.deserialize_into(wip) {
3368 Ok(p) => p,
3369 Err(e) => return Err(attach_source_cold(e, source)),
3370 };
3371
3372 let trailing = deserializer.peek()?;
3374 if !matches!(trailing.token, Token::Eof) {
3375 let mut err = JsonError::new(
3376 JsonErrorKind::UnexpectedToken {
3377 got: format!("{:?}", trailing.token),
3378 expected: "end of input",
3379 },
3380 trailing.span,
3381 );
3382 if let Some(src) = source {
3383 err.source_code = Some(src.to_string());
3384 }
3385 return Err(err);
3386 }
3387
3388 let heap_value = match partial.build() {
3390 Ok(v) => v,
3391 Err(e) => return Err(attach_source_cold(JsonError::from(e), source)),
3392 };
3393
3394 #[allow(unsafe_code)]
3400 let heap_value: facet_reflect::HeapValue<'static, false> = unsafe {
3401 core::mem::transmute::<
3402 facet_reflect::HeapValue<'input, false>,
3403 facet_reflect::HeapValue<'static, false>,
3404 >(heap_value)
3405 };
3406
3407 match heap_value.materialize::<T>() {
3408 Ok(v) => Ok(v),
3409 Err(e) => Err(attach_source_cold(JsonError::from(e), source)),
3410 }
3411 }
3412
3413 inner::<T>(input, source)
3414}