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_unary_plus_numbers() {
528 let result = parse_to_serde_value::<SerdeValue>(
529 r#"{
530 "pos1": +42,
531 "pos2": +0.5,
532 "pos3": +1e10
533 }"#,
534 &Default::default(),
535 )
536 .unwrap();
537
538 let mut expected_value = serde_json::map::Map::new();
539 expected_value.insert("pos1".to_string(), SerdeValue::Number(serde_json::Number::from(42)));
540 expected_value.insert(
541 "pos2".to_string(),
542 SerdeValue::Number(serde_json::Number::from_str("0.5").unwrap()),
543 );
544 expected_value.insert(
545 "pos3".to_string(),
546 SerdeValue::Number(serde_json::Number::from_str("1e10").unwrap()),
547 );
548
549 assert_eq!(result, SerdeValue::Object(expected_value));
550 }
551
552 #[test]
553 fn it_should_error_when_number_is_out_of_f64_range() {
554 assert_has_error(r#"{ "amount": 1e400 }"#, "Number is out of range on line 1 column 13");
555 assert_has_error("[-1e400]", "Number is out of range on line 1 column 2");
556 assert_has_error("1.7976931348623159e308", "Number is out of range on line 1 column 1");
557
558 let err = parse_to_serde_value::<f64>("1e400", &Default::default()).unwrap_err();
560 assert_eq!(err.to_string(), "Number is out of range on line 1 column 1");
561
562 #[derive(::serde::Deserialize, Debug, PartialEq)]
564 #[serde(crate = "::serde")]
565 struct Amount {
566 amount: u32,
567 }
568 let err = parse_to_serde_value::<Amount>(r#"{ "amount": 1, "other": 1e400 }"#, &Default::default()).unwrap_err();
569 assert_eq!(err.to_string(), "Number is out of range on line 1 column 25");
570
571 let result = parse_to_serde_value::<f64>("1e-400", &Default::default()).unwrap();
573 assert_eq!(result, 0.0);
574 let result = parse_to_serde_value::<f64>("-1e-400", &Default::default()).unwrap();
575 assert_eq!(result, -0.0);
576 assert!(result.is_sign_negative());
577
578 let result = parse_to_serde_value::<f64>("1.7976931348623157e308", &Default::default()).unwrap();
580 assert_eq!(result, f64::MAX);
581 }
582
583 #[test]
584 fn it_should_error_when_hexadecimal_number_is_out_of_range() {
585 assert_has_error(
586 r#"{ "value": 0xFFFFFFFFFFFFFFFFFF }"#,
587 "Number is out of range on line 1 column 12",
588 );
589 assert_has_error("-0x8000000000000001", "Number is out of range on line 1 column 1");
590
591 let result = parse_to_serde_value::<u64>("0x8000000000000000", &Default::default()).unwrap();
593 assert_eq!(result, 9223372036854775808);
594
595 let result = parse_to_serde_value::<i64>("-0x8000000000000000", &Default::default()).unwrap();
597 assert_eq!(result, i64::MIN);
598 }
599
600 #[test]
601 fn it_should_deserialize_to_struct() {
602 #[derive(::serde::Deserialize, Debug, PartialEq)]
603 #[serde(crate = "::serde")]
604 struct Config {
605 name: String,
606 value: u32,
607 enabled: bool,
608 }
609
610 let result: Config = parse_to_serde_value(
611 r#"{ "name": "test", "value": 42, "enabled": true }"#,
612 &Default::default(),
613 )
614 .unwrap();
615
616 assert_eq!(
617 result,
618 Config {
619 name: "test".to_string(),
620 value: 42,
621 enabled: true,
622 }
623 );
624 }
625
626 #[test]
627 fn it_should_report_position_on_type_error() {
628 #[derive(::serde::Deserialize, Debug)]
629 #[serde(crate = "::serde")]
630 #[allow(dead_code)]
631 struct Config {
632 name: String,
633 }
634
635 let text = r#"{
636 "name": true
637}"#;
638 let err = parse_to_serde_value::<Config>(text, &Default::default()).unwrap_err();
639 assert_eq!(err.line_display(), 2);
641 assert_eq!(err.column_display(), 11);
642 assert!(err.to_string().contains("invalid type"), "got: {}", err);
643 }
644
645 #[test]
646 fn it_should_deserialize_option_fields() {
647 #[derive(::serde::Deserialize, Debug, PartialEq)]
648 #[serde(crate = "::serde")]
649 struct Config {
650 a: Option<u32>,
651 b: Option<u32>,
652 }
653
654 let result: Config = parse_to_serde_value(r#"{ "a": 5, "b": null }"#, &Default::default()).unwrap();
655
656 assert_eq!(result, Config { a: Some(5), b: None });
657 }
658
659 #[test]
660 fn it_should_deserialize_enum() {
661 #[derive(::serde::Deserialize, Debug, PartialEq)]
662 #[serde(crate = "::serde")]
663 enum Color {
664 Red,
665 Green,
666 Blue,
667 }
668
669 #[derive(::serde::Deserialize, Debug, PartialEq)]
670 #[serde(crate = "::serde")]
671 struct Config {
672 color: Color,
673 }
674
675 let result: Config = parse_to_serde_value(r#"{ "color": "Red" }"#, &Default::default()).unwrap();
676
677 assert_eq!(result, Config { color: Color::Red });
678 }
679
680 #[test]
681 fn it_should_deserialize_complex_enum() {
682 #[derive(::serde::Deserialize, Debug, PartialEq)]
683 #[serde(crate = "::serde")]
684 enum Shape {
685 Circle(f64),
686 Rectangle { width: f64, height: f64 },
687 }
688
689 let result: Shape = parse_to_serde_value(r#"{ "Circle": 5.0 }"#, &Default::default()).unwrap();
690 assert_eq!(result, Shape::Circle(5.0));
691
692 let result: Shape = parse_to_serde_value(
693 r#"{ "Rectangle": { "width": 3.0, "height": 4.0 } }"#,
694 &Default::default(),
695 )
696 .unwrap();
697 assert_eq!(
698 result,
699 Shape::Rectangle {
700 width: 3.0,
701 height: 4.0
702 }
703 );
704 }
705
706 #[test]
707 fn it_should_return_null_for_empty_input() {
708 let result = parse_to_serde_value::<SerdeValue>("", &Default::default()).unwrap();
709 assert_eq!(result, SerdeValue::Null);
710 }
711
712 #[test]
713 fn it_should_return_none_for_empty_input_with_option() {
714 let result: Option<SerdeValue> = parse_to_serde_value("", &Default::default()).unwrap();
715 assert_eq!(result, None);
716 }
717
718 #[test]
719 fn it_should_return_some_for_non_empty_input_with_option() {
720 let result: Option<SerdeValue> = parse_to_serde_value(r#"{ "a": 1 }"#, &Default::default()).unwrap();
721 assert!(result.is_some());
722 }
723
724 #[test]
725 fn it_should_return_none_for_empty_input_with_option_struct() {
726 #[derive(::serde::Deserialize, Debug, PartialEq)]
727 #[serde(crate = "::serde")]
728 struct Config {
729 value: u32,
730 }
731
732 let result: Option<Config> = parse_to_serde_value("", &Default::default()).unwrap();
733 assert_eq!(result, None);
734
735 let result: Option<Config> = parse_to_serde_value(" \n ", &Default::default()).unwrap();
736 assert_eq!(result, None);
737 }
738
739 #[test]
740 fn it_should_deserialize_tuples() {
741 let result: (u8,) = parse_to_serde_value("[1]", &Default::default()).unwrap();
743 assert_eq!(result, (1,));
744
745 let result: (u8, String) = parse_to_serde_value(r#"[1, "hello"]"#, &Default::default()).unwrap();
747 assert_eq!(result, (1, "hello".to_string()));
748
749 #[derive(::serde::Deserialize, Debug, PartialEq)]
751 #[serde(crate = "::serde")]
752 struct Config {
753 version: (u8, u8, u8),
754 }
755 let result: Config = parse_to_serde_value(r#"{ "version": [0, 3, 0] }"#, &Default::default()).unwrap();
756 assert_eq!(result, Config { version: (0, 3, 0) });
757
758 let result: (u8, u8, u8, u8, u8, u8) = parse_to_serde_value("[1, 2, 3, 4, 5, 6]", &Default::default()).unwrap();
760 assert_eq!(result, (1, 2, 3, 4, 5, 6));
761
762 let result: (u8, u8, u8, u8, u8, u8, u8, u8, u8) =
764 parse_to_serde_value("[1, 2, 3, 4, 5, 6, 7, 8, 9]", &Default::default()).unwrap();
765 assert_eq!(result, (1, 2, 3, 4, 5, 6, 7, 8, 9));
766
767 let result: (u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8) =
769 parse_to_serde_value("[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]", &Default::default()).unwrap();
770 assert_eq!(result, (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12));
771 }
772
773 #[test]
774 fn it_should_handle_comments_in_jsonc() {
775 #[derive(::serde::Deserialize, Debug, PartialEq)]
776 #[serde(crate = "::serde")]
777 struct Config {
778 value: u32,
779 }
780
781 let result: Config = parse_to_serde_value(
782 r#"{
783 // this is a comment
784 "value": 42 /* inline comment */
785 }"#,
786 &Default::default(),
787 )
788 .unwrap();
789
790 assert_eq!(result, Config { value: 42 });
791 }
792
793 #[test]
794 fn missing_comma_between_array_elements() {
795 let result = parse_to_serde_value::<SerdeValue>("[1 2]", &Default::default()).unwrap();
796 assert_eq!(result, serde_json::json!([1, 2]));
797
798 assert_has_strict_error("[1 2]", "Expected comma on line 1 column 3");
800 assert_has_strict_error("[01]", "Expected comma on line 1 column 3");
801 assert_has_strict_error(r#"["a" "b"]"#, "Expected comma on line 1 column 5");
802 assert_has_strict_error("[true false]", "Expected comma on line 1 column 6");
803 assert_has_strict_error("[null null]", "Expected comma on line 1 column 6");
804 assert_has_strict_error("[[1] [2]]", "Expected comma on line 1 column 5");
805 assert_has_strict_error(r#"[{"a":1} {"b":2}]"#, "Expected comma on line 1 column 9");
806
807 for text in ["[]", "[1,2]", "[1 , 2]", "[[1],[2]]", r#"[{"a":1},{"b":2}]"#] {
808 parse_to_serde_value_strict::<SerdeValue>(text).unwrap();
809 }
810 }
811
812 #[test]
813 fn missing_comma_between_array_elements_when_draining() {
814 assert_has_strict_drain_error::<(u32,)>("[1 2]", "Expected comma on line 1 column 3");
817 assert_has_strict_drain_error::<(u32, SerdeValue)>(r#"[1, {"a":2} 3]"#, "Expected comma on line 1 column 12");
819 }
820
821 #[test]
822 fn missing_comma_with_comment_between_array_elements() {
823 let result = parse_to_serde_value::<SerdeValue>(
826 r#"[
827 1 // comment here
828 2
829]"#,
830 &ParseOptions {
831 allow_comments: true,
832 allow_missing_commas: false,
833 ..Default::default()
834 },
835 );
836 match result {
837 Ok(_) => panic!("Expected error, but did not find one."),
838 Err(err) => assert_eq!(err.to_string(), "Expected comma on line 2 column 4"),
839 }
840 }
841
842 #[track_caller]
843 fn assert_has_strict_error(text: &str, message: &str) {
844 match parse_to_serde_value_strict::<SerdeValue>(text) {
845 Ok(_) => panic!("Expected error, but did not find one."),
846 Err(err) => assert_eq!(err.to_string(), message),
847 }
848 }
849
850 #[track_caller]
851 fn assert_has_strict_drain_error<T: ::serde::de::DeserializeOwned>(text: &str, message: &str) {
852 match parse_to_serde_value_strict::<T>(text) {
853 Ok(_) => panic!("Expected error, but did not find one."),
854 Err(err) => assert_eq!(err.to_string(), message),
855 }
856 }
857
858 fn parse_to_serde_value_strict<T: ::serde::de::DeserializeOwned>(text: &str) -> Result<T, ParseError> {
859 parse_to_serde_value(
860 text,
861 &ParseOptions {
862 allow_comments: false,
863 allow_loose_object_property_names: false,
864 allow_trailing_commas: false,
865 allow_missing_commas: false,
866 allow_single_quoted_strings: false,
867 allow_hexadecimal_numbers: false,
868 allow_unary_plus_numbers: false,
869 },
870 )
871 }
872}