1use std::borrow::Cow;
2use std::cell::Cell;
3
4use ::serde::de::DeserializeSeed;
5use ::serde::de::EnumAccess;
6use ::serde::de::IntoDeserializer;
7use ::serde::de::MapAccess;
8use ::serde::de::SeqAccess;
9use ::serde::de::VariantAccess;
10use ::serde::de::Visitor;
11use ::serde::forward_to_deserialize_any;
12
13use super::ParseOptions;
14use super::common::Range;
15use super::errors::ParseError;
16use super::errors::ParseErrorKind;
17use super::tokens::Token;
18use crate::parser::JsoncParser;
19
20pub fn parse_to_serde_value<T: ::serde::de::DeserializeOwned>(
62 text: &str,
63 parse_options: &ParseOptions,
64) -> Result<T, ParseError> {
65 let mut parser = JsoncParser::new(text, parse_options);
66
67 let token = parser.scan()?;
68 match token {
69 Some(token) => parser.put_back(token),
70 None => parser.put_back(Token::Null),
71 }
72
73 let value = T::deserialize(&mut parser)?;
74 if parser.scan()?.is_some() {
75 return Err(
76 parser
77 .scanner
78 .create_error_for_current_token(ParseErrorKind::MultipleRootJsonValues),
79 );
80 }
81 Ok(value)
82}
83
84impl ::serde::de::Error for ParseError {
85 fn custom<T: std::fmt::Display>(msg: T) -> Self {
86 ParseError::custom_err(msg.to_string())
87 }
88}
89
90impl<'de> ::serde::Deserializer<'de> for &mut JsoncParser<'de> {
91 type Error = ParseError;
92
93 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
94 match self.scan()? {
95 None => Err(ParseError::custom_err("unexpected end of input".to_string())),
96 Some(token) => deserialize_token(self, token, visitor),
97 }
98 }
99
100 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
101 match self.scan()? {
102 Some(Token::Null) => visitor.visit_none(),
103 Some(token) => {
104 self.put_back(token);
105 visitor.visit_some(self)
106 }
107 None => visitor.visit_none(),
108 }
109 }
110
111 fn deserialize_enum<V: Visitor<'de>>(
112 self,
113 _name: &'static str,
114 _variants: &'static [&'static str],
115 visitor: V,
116 ) -> Result<V::Value, Self::Error> {
117 let token = self.scan()?;
118 let token_range = Range::new(self.scanner.token_start(), self.scanner.token_end());
119 let text = self.text;
120 let result = match token {
121 Some(Token::String(s)) => {
122 let variant: String = s.into_owned();
123 visitor.visit_enum(variant.into_deserializer())
124 }
125 Some(Token::OpenBrace) => {
126 let key = match self.scan()? {
128 Some(Token::String(s)) => s.into_owned(),
129 _ => {
130 return Err(ParseError::new(
131 token_range,
132 ParseErrorKind::Custom("expected a string key for enum variant".to_string()),
133 text,
134 ));
135 }
136 };
137
138 self.scan_object_colon()?;
140
141 let result = visitor.visit_enum(ObjectEnumAccess {
142 parser: self,
143 variant: key,
144 });
145 result.and_then(|v| {
146 match self.scan()? {
148 Some(Token::CloseBrace) => Ok(v),
149 _ => Err(
150 self
151 .scanner
152 .create_error_for_current_token(ParseErrorKind::UnterminatedObject),
153 ),
154 }
155 })
156 }
157 _ => {
158 return Err(ParseError::new(
159 token_range,
160 ParseErrorKind::Custom("expected a string or object for enum".to_string()),
161 text,
162 ));
163 }
164 };
165 result.map_err(|e| e.with_position(token_range, text))
166 }
167
168 fn deserialize_newtype_struct<V: Visitor<'de>>(
169 self,
170 _name: &'static str,
171 visitor: V,
172 ) -> Result<V::Value, Self::Error> {
173 visitor.visit_newtype_struct(self)
174 }
175
176 forward_to_deserialize_any! {
177 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64
178 char str string bytes byte_buf unit unit_struct
179 seq tuple tuple_struct map struct identifier ignored_any
180 }
181}
182
183fn deserialize_token<'de, V: Visitor<'de>>(
184 parser: &mut JsoncParser<'de>,
185 token: Token<'de>,
186 visitor: V,
187) -> Result<V::Value, ParseError> {
188 let token_range = Range::new(parser.scanner.token_start(), parser.scanner.token_end());
189 let text = parser.text;
190 let result = match token {
191 Token::Null => visitor.visit_unit(),
192 Token::Boolean(b) => visitor.visit_bool(b),
193 Token::Number(n) => visit_number(n, visitor),
194 Token::String(s) => match s {
195 Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
196 Cow::Owned(o) => visitor.visit_string(o),
197 },
198 Token::OpenBracket => {
199 parser.enter_container()?;
200 let finished = Cell::new(false);
201 let result = visitor.visit_seq(ScannerSeqAccess {
202 parser,
203 first: true,
204 finished: &finished,
205 });
206 if result.is_ok() && !finished.get() {
207 if let Err(e) = drain_array(parser) {
208 parser.exit_container();
209 return Err(e);
210 }
211 }
212 parser.exit_container();
213 result
214 }
215 Token::OpenBrace => {
216 parser.enter_container()?;
217 let result = visitor.visit_map(ScannerMapAccess { parser, first: true });
218 parser.exit_container();
219 result
220 }
221 other => return Err(parser.unexpected_token_error(&other)),
222 };
223 result.map_err(|e| e.with_position(token_range, text))
224}
225
226fn visit_number<'de, V: Visitor<'de>>(raw: &str, visitor: V) -> Result<V::Value, ParseError> {
229 let trimmed = raw.trim_start_matches(['-', '+']);
231 if trimmed.len() > 2 && (trimmed.starts_with("0x") || trimmed.starts_with("0X")) {
232 let hex_part = &trimmed[2..];
233 match i64::from_str_radix(hex_part, 16) {
234 Ok(val) => {
235 let val = if raw.starts_with('-') { -val } else { val };
236 return visitor.visit_i64(val);
237 }
238 Err(_) => return visitor.visit_str(raw),
239 }
240 }
241
242 let num_str = raw.trim_start_matches('+');
244
245 if let Ok(v) = num_str.parse::<i64>() {
246 return visitor.visit_i64(v);
247 }
248 if let Ok(v) = num_str.parse::<u64>() {
249 return visitor.visit_u64(v);
250 }
251 if let Ok(v) = num_str.parse::<f64>() {
252 return visitor.visit_f64(v);
253 }
254
255 visitor.visit_str(raw)
257}
258
259fn drain_array(parser: &mut JsoncParser) -> Result<(), ParseError> {
264 loop {
265 match parser.scan_array_comma()? {
266 Some(Token::CloseBracket) => return Ok(()),
267 Some(token) => {
268 parser.put_back(token);
269 <::serde::de::IgnoredAny as ::serde::Deserialize>::deserialize(&mut *parser)?;
270 }
271 None => {
272 return Err(
273 parser
274 .scanner
275 .create_error_for_current_token(ParseErrorKind::UnterminatedArray),
276 );
277 }
278 }
279 }
280}
281
282struct ScannerSeqAccess<'a, 'b> {
283 parser: &'b mut JsoncParser<'a>,
284 first: bool,
285 finished: &'b Cell<bool>,
286}
287
288impl<'de, 'b> SeqAccess<'de> for ScannerSeqAccess<'de, 'b> {
289 type Error = ParseError;
290
291 fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> {
292 let token = if self.first {
293 self.first = false;
294 self.parser.scan()?
295 } else {
296 self.parser.scan_array_comma()?
297 };
298
299 match token {
300 Some(Token::CloseBracket) => {
301 self.finished.set(true);
302 Ok(None)
303 }
304 Some(token) => {
305 self.parser.put_back(token);
306 seed.deserialize(&mut *self.parser).map(Some)
307 }
308 None => Err(
309 self
310 .parser
311 .scanner
312 .create_error_for_current_token(ParseErrorKind::UnterminatedArray),
313 ),
314 }
315 }
316}
317
318struct ScannerMapAccess<'a, 'b> {
321 parser: &'b mut JsoncParser<'a>,
322 first: bool,
323}
324
325impl<'de, 'b> MapAccess<'de> for ScannerMapAccess<'de, 'b> {
326 type Error = ParseError;
327
328 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> {
329 let key = self.parser.scan_object_entry(self.first)?;
330 self.first = false;
331
332 match key {
333 None => Ok(None),
334 Some(key) => {
335 seed
338 .deserialize(<Cow<'de, str> as IntoDeserializer<Self::Error>>::into_deserializer(
339 key.into_cow(),
340 ))
341 .map(Some)
342 }
343 }
344 }
345
346 fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value, Self::Error> {
347 self.parser.scan_object_colon()?;
348 seed.deserialize(&mut *self.parser)
349 }
350}
351
352struct ObjectEnumAccess<'a, 'b> {
355 parser: &'b mut JsoncParser<'a>,
356 variant: String,
357}
358
359impl<'de, 'b> EnumAccess<'de> for ObjectEnumAccess<'de, 'b> {
360 type Error = ParseError;
361 type Variant = ObjectVariantAccess<'de, 'b>;
362
363 fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> {
364 let variant = seed.deserialize(<String as IntoDeserializer<Self::Error>>::into_deserializer(
365 self.variant,
366 ))?;
367 Ok((variant, ObjectVariantAccess { parser: self.parser }))
368 }
369}
370
371struct ObjectVariantAccess<'a, 'b> {
372 parser: &'b mut JsoncParser<'a>,
373}
374
375impl<'de, 'b> VariantAccess<'de> for ObjectVariantAccess<'de, 'b> {
376 type Error = ParseError;
377
378 fn unit_variant(self) -> Result<(), Self::Error> {
379 ::serde::Deserialize::deserialize(&mut *self.parser)
380 }
381
382 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value, Self::Error> {
383 seed.deserialize(&mut *self.parser)
384 }
385
386 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> {
387 match self.parser.scan()? {
388 Some(Token::OpenBracket) => {
389 self.parser.enter_container()?;
390 let finished = Cell::new(false);
391 let result = visitor.visit_seq(ScannerSeqAccess {
392 parser: self.parser,
393 first: true,
394 finished: &finished,
395 });
396 if result.is_ok() && !finished.get() {
397 if let Err(e) = drain_array(self.parser) {
398 self.parser.exit_container();
399 return Err(e);
400 }
401 }
402 self.parser.exit_container();
403 result
404 }
405 _ => Err(ParseError::custom_err(
406 "expected an array for tuple variant".to_string(),
407 )),
408 }
409 }
410
411 fn struct_variant<V: Visitor<'de>>(
412 self,
413 _fields: &'static [&'static str],
414 visitor: V,
415 ) -> Result<V::Value, Self::Error> {
416 match self.parser.scan()? {
417 Some(Token::OpenBrace) => {
418 self.parser.enter_container()?;
419 let result = visitor.visit_map(ScannerMapAccess {
420 parser: self.parser,
421 first: true,
422 });
423 self.parser.exit_container();
424 result
425 }
426 _ => Err(ParseError::custom_err(
427 "expected an object for struct variant".to_string(),
428 )),
429 }
430 }
431}
432
433#[cfg(test)]
434mod tests {
435 use pretty_assertions::assert_eq;
436 use serde_json::Value as SerdeValue;
437 use std::str::FromStr;
438
439 use super::*;
440
441 #[test]
442 fn it_should_error_when_has_error() {
443 assert_has_error(
444 "[][]",
445 "Text cannot contain more than one JSON value on line 1 column 3",
446 );
447 }
448
449 fn assert_has_error(text: &str, message: &str) {
450 let result = parse_to_serde_value::<SerdeValue>(text, &Default::default());
451 match result {
452 Ok(_) => panic!("Expected error, but did not find one."),
453 Err(err) => assert_eq!(err.to_string(), message),
454 }
455 }
456
457 #[test]
458 fn it_should_parse_to_serde_value() {
459 let result = parse_to_serde_value::<SerdeValue>(
460 r#"{ "a": { "a1": 5 }, "b": [0.3e+025], "c": "c1", "d": true, "e": false, "f": null }"#,
461 &Default::default(),
462 )
463 .unwrap();
464
465 let mut expected_value = serde_json::map::Map::new();
466 expected_value.insert("a".to_string(), {
467 let mut inner_obj = serde_json::map::Map::new();
468 inner_obj.insert(
469 "a1".to_string(),
470 SerdeValue::Number(serde_json::Number::from_str("5").unwrap()),
471 );
472 SerdeValue::Object(inner_obj)
473 });
474 expected_value.insert("b".to_string(), {
475 let mut inner_array = Vec::new();
476 inner_array.push(SerdeValue::Number(serde_json::Number::from_str("0.3e+025").unwrap()));
477 SerdeValue::Array(inner_array)
478 });
479 expected_value.insert("c".to_string(), SerdeValue::String("c1".to_string()));
480 expected_value.insert("d".to_string(), SerdeValue::Bool(true));
481 expected_value.insert("e".to_string(), SerdeValue::Bool(false));
482 expected_value.insert("f".to_string(), SerdeValue::Null);
483
484 assert_eq!(result, SerdeValue::Object(expected_value));
485 }
486
487 #[test]
488 fn it_should_parse_hexadecimal_numbers_to_decimal() {
489 let result = parse_to_serde_value::<SerdeValue>(
490 r#"{
491 "hex1": 0x7DF,
492 "hex2": 0xFF,
493 "hex3": 0x10
494 }"#,
495 &Default::default(),
496 )
497 .unwrap();
498
499 let mut expected_value = serde_json::map::Map::new();
500 expected_value.insert("hex1".to_string(), SerdeValue::Number(serde_json::Number::from(2015)));
501 expected_value.insert("hex2".to_string(), SerdeValue::Number(serde_json::Number::from(255)));
502 expected_value.insert("hex3".to_string(), SerdeValue::Number(serde_json::Number::from(16)));
503
504 assert_eq!(result, SerdeValue::Object(expected_value));
505 }
506
507 #[test]
508 fn it_should_parse_unary_plus_numbers() {
509 let result = parse_to_serde_value::<SerdeValue>(
510 r#"{
511 "pos1": +42,
512 "pos2": +0.5,
513 "pos3": +1e10
514 }"#,
515 &Default::default(),
516 )
517 .unwrap();
518
519 let mut expected_value = serde_json::map::Map::new();
520 expected_value.insert("pos1".to_string(), SerdeValue::Number(serde_json::Number::from(42)));
521 expected_value.insert(
522 "pos2".to_string(),
523 SerdeValue::Number(serde_json::Number::from_str("0.5").unwrap()),
524 );
525 expected_value.insert(
526 "pos3".to_string(),
527 SerdeValue::Number(serde_json::Number::from_str("1e10").unwrap()),
528 );
529
530 assert_eq!(result, SerdeValue::Object(expected_value));
531 }
532
533 #[test]
534 fn it_should_deserialize_to_struct() {
535 #[derive(::serde::Deserialize, Debug, PartialEq)]
536 #[serde(crate = "::serde")]
537 struct Config {
538 name: String,
539 value: u32,
540 enabled: bool,
541 }
542
543 let result: Config = parse_to_serde_value(
544 r#"{ "name": "test", "value": 42, "enabled": true }"#,
545 &Default::default(),
546 )
547 .unwrap();
548
549 assert_eq!(
550 result,
551 Config {
552 name: "test".to_string(),
553 value: 42,
554 enabled: true,
555 }
556 );
557 }
558
559 #[test]
560 fn it_should_report_position_on_type_error() {
561 #[derive(::serde::Deserialize, Debug)]
562 #[serde(crate = "::serde")]
563 #[allow(dead_code)]
564 struct Config {
565 name: String,
566 }
567
568 let text = r#"{
569 "name": true
570}"#;
571 let err = parse_to_serde_value::<Config>(text, &Default::default()).unwrap_err();
572 assert_eq!(err.line_display(), 2);
574 assert_eq!(err.column_display(), 11);
575 assert!(err.to_string().contains("invalid type"), "got: {}", err);
576 }
577
578 #[test]
579 fn it_should_deserialize_option_fields() {
580 #[derive(::serde::Deserialize, Debug, PartialEq)]
581 #[serde(crate = "::serde")]
582 struct Config {
583 a: Option<u32>,
584 b: Option<u32>,
585 }
586
587 let result: Config = parse_to_serde_value(r#"{ "a": 5, "b": null }"#, &Default::default()).unwrap();
588
589 assert_eq!(result, Config { a: Some(5), b: None });
590 }
591
592 #[test]
593 fn it_should_deserialize_enum() {
594 #[derive(::serde::Deserialize, Debug, PartialEq)]
595 #[serde(crate = "::serde")]
596 enum Color {
597 Red,
598 Green,
599 Blue,
600 }
601
602 #[derive(::serde::Deserialize, Debug, PartialEq)]
603 #[serde(crate = "::serde")]
604 struct Config {
605 color: Color,
606 }
607
608 let result: Config = parse_to_serde_value(r#"{ "color": "Red" }"#, &Default::default()).unwrap();
609
610 assert_eq!(result, Config { color: Color::Red });
611 }
612
613 #[test]
614 fn it_should_deserialize_complex_enum() {
615 #[derive(::serde::Deserialize, Debug, PartialEq)]
616 #[serde(crate = "::serde")]
617 enum Shape {
618 Circle(f64),
619 Rectangle { width: f64, height: f64 },
620 }
621
622 let result: Shape = parse_to_serde_value(r#"{ "Circle": 5.0 }"#, &Default::default()).unwrap();
623 assert_eq!(result, Shape::Circle(5.0));
624
625 let result: Shape = parse_to_serde_value(
626 r#"{ "Rectangle": { "width": 3.0, "height": 4.0 } }"#,
627 &Default::default(),
628 )
629 .unwrap();
630 assert_eq!(
631 result,
632 Shape::Rectangle {
633 width: 3.0,
634 height: 4.0
635 }
636 );
637 }
638
639 #[test]
640 fn it_should_return_null_for_empty_input() {
641 let result = parse_to_serde_value::<SerdeValue>("", &Default::default()).unwrap();
642 assert_eq!(result, SerdeValue::Null);
643 }
644
645 #[test]
646 fn it_should_return_none_for_empty_input_with_option() {
647 let result: Option<SerdeValue> = parse_to_serde_value("", &Default::default()).unwrap();
648 assert_eq!(result, None);
649 }
650
651 #[test]
652 fn it_should_return_some_for_non_empty_input_with_option() {
653 let result: Option<SerdeValue> = parse_to_serde_value(r#"{ "a": 1 }"#, &Default::default()).unwrap();
654 assert!(result.is_some());
655 }
656
657 #[test]
658 fn it_should_return_none_for_empty_input_with_option_struct() {
659 #[derive(::serde::Deserialize, Debug, PartialEq)]
660 #[serde(crate = "::serde")]
661 struct Config {
662 value: u32,
663 }
664
665 let result: Option<Config> = parse_to_serde_value("", &Default::default()).unwrap();
666 assert_eq!(result, None);
667
668 let result: Option<Config> = parse_to_serde_value(" \n ", &Default::default()).unwrap();
669 assert_eq!(result, None);
670 }
671
672 #[test]
673 fn it_should_deserialize_tuples() {
674 let result: (u8,) = parse_to_serde_value("[1]", &Default::default()).unwrap();
676 assert_eq!(result, (1,));
677
678 let result: (u8, String) = parse_to_serde_value(r#"[1, "hello"]"#, &Default::default()).unwrap();
680 assert_eq!(result, (1, "hello".to_string()));
681
682 #[derive(::serde::Deserialize, Debug, PartialEq)]
684 #[serde(crate = "::serde")]
685 struct Config {
686 version: (u8, u8, u8),
687 }
688 let result: Config = parse_to_serde_value(r#"{ "version": [0, 3, 0] }"#, &Default::default()).unwrap();
689 assert_eq!(result, Config { version: (0, 3, 0) });
690
691 let result: (u8, u8, u8, u8, u8, u8) = parse_to_serde_value("[1, 2, 3, 4, 5, 6]", &Default::default()).unwrap();
693 assert_eq!(result, (1, 2, 3, 4, 5, 6));
694
695 let result: (u8, u8, u8, u8, u8, u8, u8, u8, u8) =
697 parse_to_serde_value("[1, 2, 3, 4, 5, 6, 7, 8, 9]", &Default::default()).unwrap();
698 assert_eq!(result, (1, 2, 3, 4, 5, 6, 7, 8, 9));
699
700 let result: (u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8) =
702 parse_to_serde_value("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]", &Default::default()).unwrap();
703 assert_eq!(result, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
704 }
705
706 #[test]
707 fn it_should_handle_comments_in_jsonc() {
708 #[derive(::serde::Deserialize, Debug, PartialEq)]
709 #[serde(crate = "::serde")]
710 struct Config {
711 value: u32,
712 }
713
714 let result: Config = parse_to_serde_value(
715 r#"{
716 // this is a comment
717 "value": 42 /* inline comment */
718 }"#,
719 &Default::default(),
720 )
721 .unwrap();
722
723 assert_eq!(result, Config { value: 42 });
724 }
725}