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 let negative = raw.starts_with('-');
234 if let Ok(val) = i64::from_str_radix(hex_part, 16) {
235 return visitor.visit_i64(if negative { -val } else { val });
236 }
237 return match i128::from_str_radix(hex_part, 16) {
240 Ok(val) => {
241 let val = if negative { -val } else { val };
242 if let Ok(val) = i64::try_from(val) {
243 visitor.visit_i64(val)
244 } else if let Ok(val) = u64::try_from(val) {
245 visitor.visit_u64(val)
246 } else {
247 Err(number_out_of_range_error())
248 }
249 }
250 Err(_) => Err(number_out_of_range_error()),
251 };
252 }
253
254 let num_str = raw.trim_start_matches('+');
256
257 if let Ok(v) = num_str.parse::<i64>() {
258 return visitor.visit_i64(v);
259 }
260 if let Ok(v) = num_str.parse::<u64>() {
261 return visitor.visit_u64(v);
262 }
263 match num_str.parse::<f64>() {
264 Ok(v) if v.is_finite() => visitor.visit_f64(v),
265 _ => Err(number_out_of_range_error()),
268 }
269}
270
271fn number_out_of_range_error() -> ParseError {
275 ParseError::custom_err("Number is out of range".to_string())
276}
277
278fn drain_array(parser: &mut JsoncParser) -> Result<(), ParseError> {
283 loop {
284 match parser.scan_array_comma()? {
285 Some(Token::CloseBracket) => return Ok(()),
286 Some(token) => {
287 parser.put_back(token);
288 <::serde::de::IgnoredAny as ::serde::Deserialize>::deserialize(&mut *parser)?;
289 }
290 None => {
291 return Err(
292 parser
293 .scanner
294 .create_error_for_current_token(ParseErrorKind::UnterminatedArray),
295 );
296 }
297 }
298 }
299}
300
301struct ScannerSeqAccess<'a, 'b> {
302 parser: &'b mut JsoncParser<'a>,
303 first: bool,
304 finished: &'b Cell<bool>,
305}
306
307impl<'de, 'b> SeqAccess<'de> for ScannerSeqAccess<'de, 'b> {
308 type Error = ParseError;
309
310 fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> {
311 let token = if self.first {
312 self.first = false;
313 self.parser.scan()?
314 } else {
315 self.parser.scan_array_comma()?
316 };
317
318 match token {
319 Some(Token::CloseBracket) => {
320 self.finished.set(true);
321 Ok(None)
322 }
323 Some(token) => {
324 self.parser.put_back(token);
325 seed.deserialize(&mut *self.parser).map(Some)
326 }
327 None => Err(
328 self
329 .parser
330 .scanner
331 .create_error_for_current_token(ParseErrorKind::UnterminatedArray),
332 ),
333 }
334 }
335}
336
337struct ScannerMapAccess<'a, 'b> {
340 parser: &'b mut JsoncParser<'a>,
341 first: bool,
342}
343
344impl<'de, 'b> MapAccess<'de> for ScannerMapAccess<'de, 'b> {
345 type Error = ParseError;
346
347 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> {
348 let key = self.parser.scan_object_entry(self.first)?;
349 self.first = false;
350
351 match key {
352 None => Ok(None),
353 Some(key) => {
354 seed
357 .deserialize(<Cow<'de, str> as IntoDeserializer<Self::Error>>::into_deserializer(
358 key.into_cow(),
359 ))
360 .map(Some)
361 }
362 }
363 }
364
365 fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value, Self::Error> {
366 self.parser.scan_object_colon()?;
367 seed.deserialize(&mut *self.parser)
368 }
369}
370
371struct ObjectEnumAccess<'a, 'b> {
374 parser: &'b mut JsoncParser<'a>,
375 variant: String,
376}
377
378impl<'de, 'b> EnumAccess<'de> for ObjectEnumAccess<'de, 'b> {
379 type Error = ParseError;
380 type Variant = ObjectVariantAccess<'de, 'b>;
381
382 fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error> {
383 let variant = seed.deserialize(<String as IntoDeserializer<Self::Error>>::into_deserializer(
384 self.variant,
385 ))?;
386 Ok((variant, ObjectVariantAccess { parser: self.parser }))
387 }
388}
389
390struct ObjectVariantAccess<'a, 'b> {
391 parser: &'b mut JsoncParser<'a>,
392}
393
394impl<'de, 'b> VariantAccess<'de> for ObjectVariantAccess<'de, 'b> {
395 type Error = ParseError;
396
397 fn unit_variant(self) -> Result<(), Self::Error> {
398 ::serde::Deserialize::deserialize(&mut *self.parser)
399 }
400
401 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value, Self::Error> {
402 seed.deserialize(&mut *self.parser)
403 }
404
405 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error> {
406 match self.parser.scan()? {
407 Some(Token::OpenBracket) => {
408 self.parser.enter_container()?;
409 let finished = Cell::new(false);
410 let result = visitor.visit_seq(ScannerSeqAccess {
411 parser: self.parser,
412 first: true,
413 finished: &finished,
414 });
415 if result.is_ok() && !finished.get() {
416 if let Err(e) = drain_array(self.parser) {
417 self.parser.exit_container();
418 return Err(e);
419 }
420 }
421 self.parser.exit_container();
422 result
423 }
424 _ => Err(ParseError::custom_err(
425 "expected an array for tuple variant".to_string(),
426 )),
427 }
428 }
429
430 fn struct_variant<V: Visitor<'de>>(
431 self,
432 _fields: &'static [&'static str],
433 visitor: V,
434 ) -> Result<V::Value, Self::Error> {
435 match self.parser.scan()? {
436 Some(Token::OpenBrace) => {
437 self.parser.enter_container()?;
438 let result = visitor.visit_map(ScannerMapAccess {
439 parser: self.parser,
440 first: true,
441 });
442 self.parser.exit_container();
443 result
444 }
445 _ => Err(ParseError::custom_err(
446 "expected an object for struct variant".to_string(),
447 )),
448 }
449 }
450}
451
452#[cfg(test)]
453mod tests {
454 use pretty_assertions::assert_eq;
455 use serde_json::Value as SerdeValue;
456 use std::str::FromStr;
457
458 use super::*;
459
460 #[test]
461 fn it_should_error_when_has_error() {
462 assert_has_error(
463 "[][]",
464 "Text cannot contain more than one JSON value on line 1 column 3",
465 );
466 }
467
468 fn assert_has_error(text: &str, message: &str) {
469 let result = parse_to_serde_value::<SerdeValue>(text, &Default::default());
470 match result {
471 Ok(_) => panic!("Expected error, but did not find one."),
472 Err(err) => assert_eq!(err.to_string(), message),
473 }
474 }
475
476 #[test]
477 fn it_should_parse_to_serde_value() {
478 let result = parse_to_serde_value::<SerdeValue>(
479 r#"{ "a": { "a1": 5 }, "b": [0.3e+025], "c": "c1", "d": true, "e": false, "f": null }"#,
480 &Default::default(),
481 )
482 .unwrap();
483
484 let mut expected_value = serde_json::map::Map::new();
485 expected_value.insert("a".to_string(), {
486 let mut inner_obj = serde_json::map::Map::new();
487 inner_obj.insert(
488 "a1".to_string(),
489 SerdeValue::Number(serde_json::Number::from_str("5").unwrap()),
490 );
491 SerdeValue::Object(inner_obj)
492 });
493 expected_value.insert("b".to_string(), {
494 let mut inner_array = Vec::new();
495 inner_array.push(SerdeValue::Number(serde_json::Number::from_str("0.3e+025").unwrap()));
496 SerdeValue::Array(inner_array)
497 });
498 expected_value.insert("c".to_string(), SerdeValue::String("c1".to_string()));
499 expected_value.insert("d".to_string(), SerdeValue::Bool(true));
500 expected_value.insert("e".to_string(), SerdeValue::Bool(false));
501 expected_value.insert("f".to_string(), SerdeValue::Null);
502
503 assert_eq!(result, SerdeValue::Object(expected_value));
504 }
505
506 #[test]
507 fn it_should_parse_hexadecimal_numbers_to_decimal() {
508 let result = parse_to_serde_value::<SerdeValue>(
509 r#"{
510 "hex1": 0x7DF,
511 "hex2": 0xFF,
512 "hex3": 0x10
513 }"#,
514 &Default::default(),
515 )
516 .unwrap();
517
518 let mut expected_value = serde_json::map::Map::new();
519 expected_value.insert("hex1".to_string(), SerdeValue::Number(serde_json::Number::from(2015)));
520 expected_value.insert("hex2".to_string(), SerdeValue::Number(serde_json::Number::from(255)));
521 expected_value.insert("hex3".to_string(), SerdeValue::Number(serde_json::Number::from(16)));
522
523 assert_eq!(result, SerdeValue::Object(expected_value));
524 }
525
526 #[test]
527 fn it_should_parse_keywords_as_loose_property_names() {
528 let result = parse_to_serde_value::<SerdeValue>(r#"{ true: 1, false: 2 null: 3 }"#, &Default::default()).unwrap();
529 assert_eq!(result, serde_json::json!({ "true": 1, "false": 2, "null": 3 }));
530 assert_has_strict_error(
531 r#"{ null: 1 }"#,
532 "Expected string for object property on line 1 column 3",
533 );
534 assert_has_strict_error(r#"{ "a": 1 true: 2 }"#, "Expected comma on line 1 column 9");
535 }
536
537 #[test]
538 fn it_should_parse_unary_plus_numbers() {
539 let result = parse_to_serde_value::<SerdeValue>(
540 r#"{
541 "pos1": +42,
542 "pos2": +0.5,
543 "pos3": +1e10
544 }"#,
545 &Default::default(),
546 )
547 .unwrap();
548
549 let mut expected_value = serde_json::map::Map::new();
550 expected_value.insert("pos1".to_string(), SerdeValue::Number(serde_json::Number::from(42)));
551 expected_value.insert(
552 "pos2".to_string(),
553 SerdeValue::Number(serde_json::Number::from_str("0.5").unwrap()),
554 );
555 expected_value.insert(
556 "pos3".to_string(),
557 SerdeValue::Number(serde_json::Number::from_str("1e10").unwrap()),
558 );
559
560 assert_eq!(result, SerdeValue::Object(expected_value));
561 }
562
563 #[test]
564 fn it_should_parse_bare_decimal_point_numbers() {
565 let result = parse_to_serde_value::<SerdeValue>(r#"[.5, -.5, 5., 5.e3]"#, &Default::default()).unwrap();
566 assert_eq!(result, serde_json::json!([0.5, -0.5, 5.0, 5000.0]));
567 assert!(result[2].is_f64());
568 }
569
570 #[test]
571 fn it_should_error_for_non_finite_numbers() {
572 assert_has_error(r#"{ "a": Infinity }"#, "Number is out of range on line 1 column 8");
574 assert_has_error("[-Infinity]", "Number is out of range on line 1 column 2");
575 assert_has_error("NaN", "Number is out of range on line 1 column 1");
576 let value = parse_to_serde_value::<f64>("-Infinity", &Default::default());
577 assert!(value.is_err());
578 }
579
580 #[test]
581 fn it_should_error_when_number_is_out_of_f64_range() {
582 assert_has_error(r#"{ "amount": 1e400 }"#, "Number is out of range on line 1 column 13");
583 assert_has_error("[-1e400]", "Number is out of range on line 1 column 2");
584 assert_has_error("1.7976931348623159e308", "Number is out of range on line 1 column 1");
585
586 let err = parse_to_serde_value::<f64>("1e400", &Default::default()).unwrap_err();
588 assert_eq!(err.to_string(), "Number is out of range on line 1 column 1");
589
590 #[derive(::serde::Deserialize, Debug, PartialEq)]
592 #[serde(crate = "::serde")]
593 struct Amount {
594 amount: u32,
595 }
596 let err = parse_to_serde_value::<Amount>(r#"{ "amount": 1, "other": 1e400 }"#, &Default::default()).unwrap_err();
597 assert_eq!(err.to_string(), "Number is out of range on line 1 column 25");
598
599 let result = parse_to_serde_value::<f64>("1e-400", &Default::default()).unwrap();
601 assert_eq!(result, 0.0);
602 let result = parse_to_serde_value::<f64>("-1e-400", &Default::default()).unwrap();
603 assert_eq!(result, -0.0);
604 assert!(result.is_sign_negative());
605
606 let result = parse_to_serde_value::<f64>("1.7976931348623157e308", &Default::default()).unwrap();
608 assert_eq!(result, f64::MAX);
609 }
610
611 #[test]
612 fn it_should_error_when_hexadecimal_number_is_out_of_range() {
613 assert_has_error(
614 r#"{ "value": 0xFFFFFFFFFFFFFFFFFF }"#,
615 "Number is out of range on line 1 column 12",
616 );
617 assert_has_error("-0x8000000000000001", "Number is out of range on line 1 column 1");
618
619 let result = parse_to_serde_value::<u64>("0x8000000000000000", &Default::default()).unwrap();
621 assert_eq!(result, 9223372036854775808);
622
623 let result = parse_to_serde_value::<i64>("-0x8000000000000000", &Default::default()).unwrap();
625 assert_eq!(result, i64::MIN);
626 }
627
628 #[test]
629 fn it_should_deserialize_to_struct() {
630 #[derive(::serde::Deserialize, Debug, PartialEq)]
631 #[serde(crate = "::serde")]
632 struct Config {
633 name: String,
634 value: u32,
635 enabled: bool,
636 }
637
638 let result: Config = parse_to_serde_value(
639 r#"{ "name": "test", "value": 42, "enabled": true }"#,
640 &Default::default(),
641 )
642 .unwrap();
643
644 assert_eq!(
645 result,
646 Config {
647 name: "test".to_string(),
648 value: 42,
649 enabled: true,
650 }
651 );
652 }
653
654 #[test]
655 fn it_should_report_position_on_type_error() {
656 #[derive(::serde::Deserialize, Debug)]
657 #[serde(crate = "::serde")]
658 #[allow(dead_code)]
659 struct Config {
660 name: String,
661 }
662
663 let text = r#"{
664 "name": true
665}"#;
666 let err = parse_to_serde_value::<Config>(text, &Default::default()).unwrap_err();
667 assert_eq!(err.line_display(), 2);
669 assert_eq!(err.column_display(), 11);
670 assert!(err.to_string().contains("invalid type"), "got: {}", err);
671 }
672
673 #[test]
674 fn it_should_deserialize_option_fields() {
675 #[derive(::serde::Deserialize, Debug, PartialEq)]
676 #[serde(crate = "::serde")]
677 struct Config {
678 a: Option<u32>,
679 b: Option<u32>,
680 }
681
682 let result: Config = parse_to_serde_value(r#"{ "a": 5, "b": null }"#, &Default::default()).unwrap();
683
684 assert_eq!(result, Config { a: Some(5), b: None });
685 }
686
687 #[test]
688 fn it_should_deserialize_enum() {
689 #[derive(::serde::Deserialize, Debug, PartialEq)]
690 #[serde(crate = "::serde")]
691 enum Color {
692 Red,
693 Green,
694 Blue,
695 }
696
697 #[derive(::serde::Deserialize, Debug, PartialEq)]
698 #[serde(crate = "::serde")]
699 struct Config {
700 color: Color,
701 }
702
703 let result: Config = parse_to_serde_value(r#"{ "color": "Red" }"#, &Default::default()).unwrap();
704
705 assert_eq!(result, Config { color: Color::Red });
706 }
707
708 #[test]
709 fn it_should_deserialize_complex_enum() {
710 #[derive(::serde::Deserialize, Debug, PartialEq)]
711 #[serde(crate = "::serde")]
712 enum Shape {
713 Circle(f64),
714 Rectangle { width: f64, height: f64 },
715 }
716
717 let result: Shape = parse_to_serde_value(r#"{ "Circle": 5.0 }"#, &Default::default()).unwrap();
718 assert_eq!(result, Shape::Circle(5.0));
719
720 let result: Shape = parse_to_serde_value(
721 r#"{ "Rectangle": { "width": 3.0, "height": 4.0 } }"#,
722 &Default::default(),
723 )
724 .unwrap();
725 assert_eq!(
726 result,
727 Shape::Rectangle {
728 width: 3.0,
729 height: 4.0
730 }
731 );
732 }
733
734 #[test]
735 fn it_should_return_null_for_empty_input() {
736 let result = parse_to_serde_value::<SerdeValue>("", &Default::default()).unwrap();
737 assert_eq!(result, SerdeValue::Null);
738 }
739
740 #[test]
741 fn it_should_return_none_for_empty_input_with_option() {
742 let result: Option<SerdeValue> = parse_to_serde_value("", &Default::default()).unwrap();
743 assert_eq!(result, None);
744 }
745
746 #[test]
747 fn it_should_return_some_for_non_empty_input_with_option() {
748 let result: Option<SerdeValue> = parse_to_serde_value(r#"{ "a": 1 }"#, &Default::default()).unwrap();
749 assert!(result.is_some());
750 }
751
752 #[test]
753 fn it_should_return_none_for_empty_input_with_option_struct() {
754 #[derive(::serde::Deserialize, Debug, PartialEq)]
755 #[serde(crate = "::serde")]
756 struct Config {
757 value: u32,
758 }
759
760 let result: Option<Config> = parse_to_serde_value("", &Default::default()).unwrap();
761 assert_eq!(result, None);
762
763 let result: Option<Config> = parse_to_serde_value(" \n ", &Default::default()).unwrap();
764 assert_eq!(result, None);
765 }
766
767 #[test]
768 fn it_should_deserialize_tuples() {
769 let result: (u8,) = parse_to_serde_value("[1]", &Default::default()).unwrap();
771 assert_eq!(result, (1,));
772
773 let result: (u8, String) = parse_to_serde_value(r#"[1, "hello"]"#, &Default::default()).unwrap();
775 assert_eq!(result, (1, "hello".to_string()));
776
777 #[derive(::serde::Deserialize, Debug, PartialEq)]
779 #[serde(crate = "::serde")]
780 struct Config {
781 version: (u8, u8, u8),
782 }
783 let result: Config = parse_to_serde_value(r#"{ "version": [0, 3, 0] }"#, &Default::default()).unwrap();
784 assert_eq!(result, Config { version: (0, 3, 0) });
785
786 let result: (u8, u8, u8, u8, u8, u8) = parse_to_serde_value("[1, 2, 3, 4, 5, 6]", &Default::default()).unwrap();
788 assert_eq!(result, (1, 2, 3, 4, 5, 6));
789
790 let result: (u8, u8, u8, u8, u8, u8, u8, u8, u8) =
792 parse_to_serde_value("[1, 2, 3, 4, 5, 6, 7, 8, 9]", &Default::default()).unwrap();
793 assert_eq!(result, (1, 2, 3, 4, 5, 6, 7, 8, 9));
794
795 let result: (u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8) =
797 parse_to_serde_value("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]", &Default::default()).unwrap();
798 assert_eq!(result, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
799 }
800
801 #[test]
802 fn it_should_handle_comments_in_jsonc() {
803 #[derive(::serde::Deserialize, Debug, PartialEq)]
804 #[serde(crate = "::serde")]
805 struct Config {
806 value: u32,
807 }
808
809 let result: Config = parse_to_serde_value(
810 r#"{
811 // this is a comment
812 "value": 42 /* inline comment */
813 }"#,
814 &Default::default(),
815 )
816 .unwrap();
817
818 assert_eq!(result, Config { value: 42 });
819 }
820
821 #[test]
822 fn missing_comma_between_array_elements() {
823 let result = parse_to_serde_value::<SerdeValue>("[1 2]", &Default::default()).unwrap();
824 assert_eq!(result, serde_json::json!([1, 2]));
825
826 assert_has_strict_error("[1 2]", "Expected comma on line 1 column 3");
828 assert_has_strict_error("[01]", "Expected comma on line 1 column 3");
829 assert_has_strict_error(r#"["a" "b"]"#, "Expected comma on line 1 column 5");
830 assert_has_strict_error("[true false]", "Expected comma on line 1 column 6");
831 assert_has_strict_error("[null null]", "Expected comma on line 1 column 6");
832 assert_has_strict_error("[[1] [2]]", "Expected comma on line 1 column 5");
833 assert_has_strict_error(r#"[{"a":1} {"b":2}]"#, "Expected comma on line 1 column 9");
834
835 for text in ["[]", "[1,2]", "[1 , 2]", "[[1],[2]]", r#"[{"a":1},{"b":2}]"#] {
836 parse_to_serde_value_strict::<SerdeValue>(text).unwrap();
837 }
838 }
839
840 #[test]
841 fn missing_comma_between_array_elements_when_draining() {
842 assert_has_strict_drain_error::<(u32,)>("[1 2]", "Expected comma on line 1 column 3");
845 assert_has_strict_drain_error::<(u32, SerdeValue)>(r#"[1, {"a":2} 3]"#, "Expected comma on line 1 column 12");
847 }
848
849 #[test]
850 fn missing_comma_with_comment_between_array_elements() {
851 let result = parse_to_serde_value::<SerdeValue>(
854 r#"[
855 1 // comment here
856 2
857]"#,
858 &ParseOptions {
859 allow_comments: true,
860 allow_missing_commas: false,
861 ..Default::default()
862 },
863 );
864 match result {
865 Ok(_) => panic!("Expected error, but did not find one."),
866 Err(err) => assert_eq!(err.to_string(), "Expected comma on line 2 column 4"),
867 }
868 }
869
870 #[track_caller]
871 fn assert_has_strict_error(text: &str, message: &str) {
872 match parse_to_serde_value_strict::<SerdeValue>(text) {
873 Ok(_) => panic!("Expected error, but did not find one."),
874 Err(err) => assert_eq!(err.to_string(), message),
875 }
876 }
877
878 #[track_caller]
879 fn assert_has_strict_drain_error<T: ::serde::de::DeserializeOwned>(text: &str, message: &str) {
880 match parse_to_serde_value_strict::<T>(text) {
881 Ok(_) => panic!("Expected error, but did not find one."),
882 Err(err) => assert_eq!(err.to_string(), message),
883 }
884 }
885
886 fn parse_to_serde_value_strict<T: ::serde::de::DeserializeOwned>(text: &str) -> Result<T, ParseError> {
887 parse_to_serde_value(
888 text,
889 &ParseOptions {
890 allow_comments: false,
891 allow_loose_object_property_names: false,
892 allow_trailing_commas: false,
893 allow_missing_commas: false,
894 allow_single_quoted_strings: false,
895 allow_hexadecimal_numbers: false,
896 allow_unary_plus_numbers: false,
897 allow_bare_decimal_point_numbers: false,
898 allow_non_finite_numbers: false,
899 allow_extended_string_escapes: false,
900 },
901 )
902 }
903}