1use std::cell::Cell;
4
5use serde::Deserialize;
6use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor};
7
8use crate::error::{Error, ErrorKind, Result};
9
10thread_local! {
11 static IS_LIST_CONTEXT: Cell<Option<bool>> = const { Cell::new(None) };
17}
18
19pub(crate) fn take_list_context() -> Option<bool> {
22 IS_LIST_CONTEXT.with(|c| c.take())
23}
24
25pub(crate) fn set_list_context(is_list: bool) {
27 IS_LIST_CONTEXT.with(|c| c.set(Some(is_list)));
28}
29
30pub(crate) fn clear_list_context() {
34 IS_LIST_CONTEXT.with(|c| c.set(None));
35}
36
37pub(crate) fn strip_trivia(mut s: &str) -> &str {
45 loop {
46 s = s.trim_start();
47 if s.starts_with('#') || s.starts_with("//") {
48 match s.find('\n') {
49 Some(pos) => s = &s[pos + 1..],
50 None => return "",
51 }
52 } else if s.starts_with("/*") {
53 match s.find("*/") {
54 Some(pos) => s = &s[pos + 2..],
55 None => return s,
56 }
57 } else {
58 return s;
59 }
60 }
61}
62
63fn is_name_char(c: char) -> bool {
66 c.is_ascii_alphanumeric() || matches!(c, '-' | '_' | '*')
67}
68
69pub struct Deserializer<'de> {
71 input: &'de str,
72 at_root: bool,
76}
77
78impl<'de> Deserializer<'de> {
79 #[allow(clippy::should_implement_trait)]
83 pub fn from_str(input: &'de str) -> Self {
84 Deserializer {
85 input,
86 at_root: true,
87 }
88 }
89
90 pub fn end(&mut self) -> Result<()> {
97 self.skip_whitespace();
98 if self.input.is_empty() {
99 Ok(())
100 } else {
101 Err(ErrorKind::TrailingCharacters.into())
102 }
103 }
104
105 fn peek_char(&self) -> Result<char> {
107 self.input.chars().next().ok_or_else(|| ErrorKind::Eof.into())
108 }
109
110 fn next_char(&mut self) -> Result<char> {
112 let ch = self.peek_char()?;
113 self.input = &self.input[ch.len_utf8()..];
114 Ok(ch)
115 }
116
117 fn skip_whitespace(&mut self) {
119 self.input = strip_trivia(self.input);
120 }
121
122 fn is_implicit_group_start(&self) -> bool {
127 let input = self.input;
128
129 let mut len = 0;
131 for (idx, ch) in input.char_indices() {
132 if idx == 0 {
133 if ch.is_ascii_alphabetic() || ch == '*' {
134 len = ch.len_utf8();
135 } else {
136 return false;
137 }
138 } else if is_name_char(ch) {
139 len = idx + ch.len_utf8();
140 } else {
141 break;
142 }
143 }
144
145 if len == 0 {
146 return false;
147 }
148
149 let rest = strip_trivia(&input[len..]);
151
152 matches!(rest.chars().next(), Some('=' | ':'))
154 }
155
156 fn parse_bool(&mut self) -> Result<bool> {
158 self.skip_whitespace();
159 if self
162 .input
163 .get(..4)
164 .is_some_and(|s| s.eq_ignore_ascii_case("true"))
165 && !self.input[4..].chars().next().is_some_and(is_name_char)
166 {
167 self.input = &self.input[4..];
168 Ok(true)
169 } else if self
170 .input
171 .get(..5)
172 .is_some_and(|s| s.eq_ignore_ascii_case("false"))
173 && !self.input[5..].chars().next().is_some_and(is_name_char)
174 {
175 self.input = &self.input[5..];
176 Ok(false)
177 } else {
178 Err(ErrorKind::ExpectedBoolean.into())
179 }
180 }
181
182 fn parse_identifier(&mut self) -> Result<&'de str> {
185 self.skip_whitespace();
186 let start = self.input;
187 let mut len = 0;
188
189 for (idx, ch) in self.input.char_indices() {
190 if idx == 0 {
191 if ch.is_ascii_alphabetic() || ch == '*' {
192 len = ch.len_utf8();
193 } else {
194 break;
195 }
196 } else if is_name_char(ch) {
197 len = idx + ch.len_utf8();
198 } else {
199 break;
200 }
201 }
202
203 if len == 0 {
204 if self.input.starts_with("/*") {
207 return Err(ErrorKind::UnterminatedComment.into());
208 }
209 return Err(ErrorKind::ExpectedIdentifier.into());
210 }
211
212 let ident = &start[..len];
213 self.input = &self.input[len..];
214 Ok(ident)
215 }
216
217 fn parse_single_string(&mut self) -> Result<String> {
219 if self.next_char()? != '"' {
220 return Err(ErrorKind::ExpectedString.into());
221 }
222
223 let mut result = String::new();
224 let mut escape = false;
225
226 loop {
227 if self.input.is_empty() {
228 return Err(ErrorKind::Eof.into());
229 }
230
231 let ch = self.next_char()?;
232
233 if escape {
234 match ch {
235 '"' => result.push('"'),
236 '\\' => result.push('\\'),
237 'n' => result.push('\n'),
238 'r' => result.push('\r'),
239 't' => result.push('\t'),
240 'f' => result.push('\x0C'),
241 'b' => result.push('\x08'),
242 'v' => result.push('\x0B'),
243 'a' => result.push('\x07'),
244 'x' => {
245 let hex = self.input.get(..2).ok_or(ErrorKind::InvalidEscape)?;
249 if let Ok(byte) = u8::from_str_radix(hex, 16) {
250 result.push(byte as char);
251 self.input = &self.input[2..];
252 } else {
253 return Err(ErrorKind::InvalidEscape.into());
254 }
255 }
256 _ => return Err(ErrorKind::InvalidEscape.into()),
257 }
258 escape = false;
259 } else if ch == '\\' {
260 escape = true;
261 } else if ch == '"' {
262 break;
263 } else {
264 result.push(ch);
265 }
266 }
267
268 Ok(result)
269 }
270
271 fn parse_borrowed_string(&mut self) -> Result<Option<&'de str>> {
276 let original = self.input;
277 if !original.starts_with('"') {
278 return Err(ErrorKind::ExpectedString.into());
279 }
280 let bytes = original.as_bytes();
281 let mut i = 1;
282 while i < bytes.len() {
283 match bytes[i] {
284 b'\\' => return Ok(None),
286 b'"' => {
287 if strip_trivia(&original[i + 1..]).starts_with('"') {
289 return Ok(None);
290 }
291 let inner = &original[1..i];
292 self.input = &original[i + 1..];
293 return Ok(Some(inner));
294 }
295 _ => i += 1,
296 }
297 }
298 Err(ErrorKind::Eof.into())
299 }
300
301 fn parse_string(&mut self) -> Result<String> {
304 self.skip_whitespace();
305 let mut result = self.parse_single_string()?;
306
307 loop {
309 self.skip_whitespace();
310 if self.input.starts_with('"') {
311 result.push_str(&self.parse_single_string()?);
312 } else {
313 break;
314 }
315 }
316
317 Ok(result)
318 }
319
320 fn parse_number(&mut self) -> Result<Number> {
329 self.skip_whitespace();
330 let s = self.input;
331 let bytes = s.as_bytes();
332 let mut i = 0;
333
334 #[derive(PartialEq, Clone, Copy)]
335 enum Base {
336 Dec,
337 Hex,
338 Bin,
339 Oct,
340 }
341
342 let has_sign = matches!(bytes.first(), Some(b'+' | b'-'));
344 if has_sign {
345 i += 1;
346 }
347
348 let mut base = Base::Dec;
349 if !has_sign && bytes.len() > i + 1 && bytes[i] == b'0' {
350 match bytes[i + 1] {
351 b'x' | b'X' => {
352 base = Base::Hex;
353 i += 2;
354 }
355 b'b' | b'B' => {
356 base = Base::Bin;
357 i += 2;
358 }
359 b'o' | b'O' | b'q' | b'Q' => {
360 base = Base::Oct;
361 i += 2;
362 }
363 _ => {}
364 }
365 }
366
367 let digits_start = i;
368 let mut digit_count = 0usize;
369 let mut is_float = false;
370
371 if base == Base::Dec {
372 while i < bytes.len() && bytes[i].is_ascii_digit() {
373 i += 1;
374 digit_count += 1;
375 }
376 if i < bytes.len() && bytes[i] == b'.' {
378 is_float = true;
379 i += 1;
380 while i < bytes.len() && bytes[i].is_ascii_digit() {
381 i += 1;
382 digit_count += 1;
383 }
384 }
385 if i < bytes.len() && (bytes[i] == b'e' || bytes[i] == b'E') {
387 let mut j = i + 1;
388 if j < bytes.len() && (bytes[j] == b'+' || bytes[j] == b'-') {
389 j += 1;
390 }
391 let exp_digits_start = j;
392 while j < bytes.len() && bytes[j].is_ascii_digit() {
393 j += 1;
394 }
395 if j > exp_digits_start {
396 is_float = true;
397 i = j;
398 }
399 }
400 } else {
401 while i < bytes.len()
402 && match base {
403 Base::Hex => bytes[i].is_ascii_hexdigit(),
404 Base::Bin => matches!(bytes[i], b'0' | b'1'),
405 Base::Oct => matches!(bytes[i], b'0'..=b'7'),
406 Base::Dec => unreachable!(),
407 }
408 {
409 i += 1;
410 digit_count += 1;
411 }
412 }
413
414 if digit_count == 0 {
415 return Err(ErrorKind::ExpectedInteger.into());
416 }
417
418 let max_digits = match base {
422 Base::Dec => usize::MAX, Base::Hex => 16,
424 Base::Bin => 64,
425 Base::Oct => 21,
426 };
427 if digit_count > max_digits {
428 return Err(ErrorKind::InvalidNumber.into());
429 }
430
431 let digits_end = i;
432
433 let mut is_long = false;
435 if !is_float && i < bytes.len() && bytes[i] == b'L' {
436 is_long = true;
437 i += 1;
438 if i < bytes.len() && bytes[i] == b'L' {
439 i += 1;
440 }
441 }
442
443 let num_str = &s[..i];
444 self.input = &s[i..];
445
446 if is_float {
447 let val = num_str.parse::<f64>().map_err(|_| ErrorKind::InvalidNumber)?;
448 return Ok(Number::Float(val));
449 }
450
451 let digits = &s[digits_start..digits_end];
452 let (radix, promote_digits) = match base {
453 Base::Dec => (10, usize::MAX),
454 Base::Hex => (16, 8),
455 Base::Bin => (2, 32),
456 Base::Oct => (8, 10),
457 };
458
459 if base == Base::Dec {
460 let signed = &s[..digits_end];
461 if is_long {
462 let val = signed.parse::<i64>().map_err(|_| ErrorKind::InvalidNumber)?;
463 Ok(Number::I64(val))
464 } else {
465 match signed.parse::<i32>() {
467 Ok(val) => Ok(Number::I32(val)),
468 Err(_) => {
469 let val = signed.parse::<i64>().map_err(|_| ErrorKind::InvalidNumber)?;
470 Ok(Number::I64(val))
471 }
472 }
473 }
474 } else {
475 let val = i64::from_str_radix(digits, radix).map_err(|_| ErrorKind::InvalidNumber)?;
476 if is_long || digit_count > promote_digits {
477 Ok(Number::I64(val))
478 } else {
479 Ok(Number::I32(val as i32))
482 }
483 }
484 }
485}
486
487pub fn from_str<'a, T>(s: &'a str) -> Result<T>
495where
496 T: Deserialize<'a>,
497{
498 let mut deserializer = Deserializer::from_str(s);
499 let result = T::deserialize(&mut deserializer).and_then(|t| {
500 deserializer.end()?;
501 Ok(t)
502 });
503 clear_list_context();
504 result.map_err(|e| {
505 let (line, column) = locate(s, deserializer.input);
506 e.with_location(line, column)
507 })
508}
509
510pub fn from_reader<R, T>(mut reader: R) -> Result<T>
522where
523 R: std::io::Read,
524 T: de::DeserializeOwned,
525{
526 let mut s = String::new();
527 reader
528 .read_to_string(&mut s)
529 .map_err(|e| ErrorKind::Io(e.to_string()))?;
530 from_str(&s)
531}
532
533fn locate(original: &str, remaining: &str) -> (usize, usize) {
536 let consumed = original.len().saturating_sub(remaining.len());
537 let consumed_text = &original[..consumed.min(original.len())];
538 let line = consumed_text.matches('\n').count() + 1;
539 let column = consumed_text
540 .rsplit('\n')
541 .next()
542 .map(|l| l.chars().count())
543 .unwrap_or(0)
544 + 1;
545 (line, column)
546}
547
548#[derive(Debug, Clone)]
549enum Number {
550 I32(i32),
551 I64(i64),
552 Float(f64),
553}
554
555macro_rules! deserialize_integer {
557 ($method:ident, $visit:ident, $ty:ty) => {
558 fn $method<V>(self, visitor: V) -> Result<V::Value>
559 where
560 V: Visitor<'de>,
561 {
562 match self.parse_number()? {
563 Number::I32(v) => {
564 visitor.$visit(<$ty>::try_from(v).map_err(|_| ErrorKind::IntegerOutOfRange)?)
565 }
566 Number::I64(v) => {
567 visitor.$visit(<$ty>::try_from(v).map_err(|_| ErrorKind::IntegerOutOfRange)?)
568 }
569 Number::Float(_) => Err(ErrorKind::ExpectedInteger.into()),
570 }
571 }
572 };
573}
574
575impl<'de> de::Deserializer<'de> for &mut Deserializer<'de> {
576 type Error = Error;
577
578 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
579 where
580 V: Visitor<'de>,
581 {
582 self.skip_whitespace();
583 if self.input.is_empty() {
586 return visitor.visit_map(ImplicitGroupAccess::new(self));
587 }
588 match self.peek_char()? {
589 't' | 'T' | 'f' | 'F' => {
590 if self.is_implicit_group_start() {
593 visitor.visit_map(ImplicitGroupAccess::new(self))
594 } else {
595 self.deserialize_bool(visitor)
596 }
597 }
598 '"' => self.deserialize_string(visitor),
599 '[' => self.deserialize_seq(visitor),
600 '(' => self.deserialize_seq(visitor), '{' => self.deserialize_map(visitor),
602 '-' | '+' | '0'..='9' | '.' => {
603 let num = self.parse_number()?;
605 match num {
606 Number::I32(v) => visitor.visit_i32(v),
607 Number::I64(v) => visitor.visit_i64(v),
608 Number::Float(v) => visitor.visit_f64(v),
609 }
610 }
611 c if c.is_ascii_alphabetic() || c == '*' => {
612 visitor.visit_map(ImplicitGroupAccess::new(self))
614 }
615 '/' if self.input.starts_with("/*") => Err(ErrorKind::UnterminatedComment.into()),
616 _ => Err(ErrorKind::Syntax.into()),
617 }
618 }
619
620 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
621 where
622 V: Visitor<'de>,
623 {
624 visitor.visit_bool(self.parse_bool()?)
625 }
626
627 deserialize_integer!(deserialize_i8, visit_i8, i8);
634 deserialize_integer!(deserialize_i16, visit_i16, i16);
635 deserialize_integer!(deserialize_i32, visit_i32, i32);
636 deserialize_integer!(deserialize_i64, visit_i64, i64);
637 deserialize_integer!(deserialize_u8, visit_u8, u8);
638 deserialize_integer!(deserialize_u16, visit_u16, u16);
639 deserialize_integer!(deserialize_u32, visit_u32, u32);
640 deserialize_integer!(deserialize_u64, visit_u64, u64);
641
642 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
643 where
644 V: Visitor<'de>,
645 {
646 let num = self.parse_number()?;
647 match num {
648 Number::I32(v) => visitor.visit_f32(v as f32),
649 Number::I64(v) => visitor.visit_f32(v as f32),
650 Number::Float(v) => {
651 let f = v as f32;
652 if f.is_infinite() && v.is_finite() {
654 return Err(ErrorKind::FloatOutOfRange.into());
655 }
656 visitor.visit_f32(f)
657 }
658 }
659 }
660
661 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
662 where
663 V: Visitor<'de>,
664 {
665 let num = self.parse_number()?;
666 match num {
667 Number::I32(v) => visitor.visit_f64(v as f64),
668 Number::I64(v) => visitor.visit_f64(v as f64),
669 Number::Float(v) => visitor.visit_f64(v),
670 }
671 }
672
673 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
674 where
675 V: Visitor<'de>,
676 {
677 let s = self.parse_string()?;
678 let mut chars = s.chars();
679 let ch = chars.next().ok_or(ErrorKind::ExpectedString)?;
680 if chars.next().is_some() {
681 return Err(ErrorKind::ExpectedString.into());
682 }
683 visitor.visit_char(ch)
684 }
685
686 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
687 where
688 V: Visitor<'de>,
689 {
690 self.skip_whitespace();
696 match self.parse_borrowed_string()? {
697 Some(s) => visitor.visit_borrowed_str(s),
698 None => visitor.visit_string(self.parse_string()?),
699 }
700 }
701
702 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
703 where
704 V: Visitor<'de>,
705 {
706 self.deserialize_str(visitor)
707 }
708
709 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
710 where
711 V: Visitor<'de>,
712 {
713 self.deserialize_seq(visitor)
714 }
715
716 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
717 where
718 V: Visitor<'de>,
719 {
720 self.deserialize_seq(visitor)
721 }
722
723 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
724 where
725 V: Visitor<'de>,
726 {
727 visitor.visit_some(self)
728 }
729
730 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
731 where
732 V: Visitor<'de>,
733 {
734 visitor.visit_unit()
735 }
736
737 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
738 where
739 V: Visitor<'de>,
740 {
741 self.deserialize_unit(visitor)
742 }
743
744 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
745 where
746 V: Visitor<'de>,
747 {
748 visitor.visit_newtype_struct(self)
749 }
750
751 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
752 where
753 V: Visitor<'de>,
754 {
755 self.skip_whitespace();
756 let ch = self.peek_char()?;
757
758 if ch == '[' {
759 self.next_char()?;
760 set_list_context(false);
761 let value = visitor.visit_seq(ArrayAccess::new(self, ']', false))?;
762 self.skip_whitespace();
763 if self.next_char()? == ']' {
764 Ok(value)
765 } else {
766 Err(ErrorKind::ExpectedArrayEnd.into())
767 }
768 } else if ch == '(' {
769 self.next_char()?;
770 set_list_context(true);
771 let value = visitor.visit_seq(ArrayAccess::new(self, ')', true))?;
772 self.skip_whitespace();
773 if self.next_char()? == ')' {
774 Ok(value)
775 } else {
776 Err(ErrorKind::ExpectedListEnd.into())
777 }
778 } else {
779 Err(ErrorKind::ExpectedArray.into())
780 }
781 }
782
783 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
784 where
785 V: Visitor<'de>,
786 {
787 self.deserialize_seq(visitor)
788 }
789
790 fn deserialize_tuple_struct<V>(
791 self,
792 _name: &'static str,
793 _len: usize,
794 visitor: V,
795 ) -> Result<V::Value>
796 where
797 V: Visitor<'de>,
798 {
799 self.deserialize_seq(visitor)
800 }
801
802 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
803 where
804 V: Visitor<'de>,
805 {
806 self.skip_whitespace();
807 if self.input.starts_with('{') {
811 if self.at_root {
812 return Err(ErrorKind::TopLevelBraces.into());
813 }
814 self.next_char()?;
815 let value = visitor.visit_map(GroupAccess::new(self))?;
816 self.skip_whitespace();
817 if self.next_char()? == '}' {
818 Ok(value)
819 } else {
820 Err(ErrorKind::ExpectedGroupEnd.into())
821 }
822 } else {
823 visitor.visit_map(ImplicitGroupAccess::new(self))
824 }
825 }
826
827 fn deserialize_struct<V>(
828 self,
829 _name: &'static str,
830 _fields: &'static [&'static str],
831 visitor: V,
832 ) -> Result<V::Value>
833 where
834 V: Visitor<'de>,
835 {
836 self.deserialize_map(visitor)
837 }
838
839 fn deserialize_enum<V>(
840 self,
841 _name: &'static str,
842 _variants: &'static [&'static str],
843 visitor: V,
844 ) -> Result<V::Value>
845 where
846 V: Visitor<'de>,
847 {
848 self.skip_whitespace();
849 match self.peek_char()? {
850 '"' => visitor.visit_enum(self.parse_string()?.into_deserializer()),
852 '{' => {
857 self.next_char()?;
858 self.at_root = false;
859 let value = visitor.visit_enum(EnumGroupAccess { de: &mut *self })?;
860 self.skip_whitespace();
861 if matches!(self.peek_char(), Ok(';' | ',')) {
862 self.next_char()?;
863 self.skip_whitespace();
864 }
865 if self.next_char()? == '}' {
866 Ok(value)
867 } else {
868 Err(ErrorKind::ExpectedGroupEnd.into())
869 }
870 }
871 _ => Err(ErrorKind::ExpectedString.into()),
872 }
873 }
874
875 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
876 where
877 V: Visitor<'de>,
878 {
879 visitor.visit_str(self.parse_identifier()?)
880 }
881
882 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
883 where
884 V: Visitor<'de>,
885 {
886 self.deserialize_any(visitor)
887 }
888}
889
890struct MapKeyDeserializer<'a, 'de: 'a> {
893 de: &'a mut Deserializer<'de>,
894}
895
896impl<'de> de::Deserializer<'de> for MapKeyDeserializer<'_, 'de> {
897 type Error = Error;
898
899 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
900 where
901 V: Visitor<'de>,
902 {
903 visitor.visit_borrowed_str(self.de.parse_identifier()?)
904 }
905
906 serde::forward_to_deserialize_any! {
907 bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string
908 bytes byte_buf option unit unit_struct newtype_struct seq tuple
909 tuple_struct map struct enum identifier ignored_any
910 }
911}
912
913struct EnumGroupAccess<'a, 'de: 'a> {
915 de: &'a mut Deserializer<'de>,
916}
917
918impl<'de, 'a> de::EnumAccess<'de> for EnumGroupAccess<'a, 'de> {
919 type Error = Error;
920 type Variant = VariantGroupAccess<'a, 'de>;
921
922 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
923 where
924 V: DeserializeSeed<'de>,
925 {
926 let variant = self.de.parse_identifier()?;
927 let variant_de: de::value::StrDeserializer<'de, Error> = variant.into_deserializer();
928 let value = seed.deserialize(variant_de)?;
929 self.de.skip_whitespace();
930 let ch = self.de.next_char()?;
931 if ch != '=' && ch != ':' {
932 return Err(ErrorKind::ExpectedEquals.into());
933 }
934 Ok((value, VariantGroupAccess { de: self.de }))
935 }
936}
937
938struct VariantGroupAccess<'a, 'de: 'a> {
939 de: &'a mut Deserializer<'de>,
940}
941
942impl<'de> de::VariantAccess<'de> for VariantGroupAccess<'_, 'de> {
943 type Error = Error;
944
945 fn unit_variant(self) -> Result<()> {
946 Err(ErrorKind::ExpectedString.into())
948 }
949
950 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
951 where
952 T: DeserializeSeed<'de>,
953 {
954 seed.deserialize(&mut *self.de)
955 }
956
957 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
958 where
959 V: Visitor<'de>,
960 {
961 de::Deserializer::deserialize_seq(&mut *self.de, visitor)
962 }
963
964 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
965 where
966 V: Visitor<'de>,
967 {
968 de::Deserializer::deserialize_map(&mut *self.de, visitor)
969 }
970}
971
972struct ArrayAccess<'a, 'de: 'a> {
973 de: &'a mut Deserializer<'de>,
974 first: bool,
975 end_char: char,
976 is_list: bool,
977}
978
979impl<'a, 'de> ArrayAccess<'a, 'de> {
980 fn new(de: &'a mut Deserializer<'de>, end_char: char, is_list: bool) -> Self {
981 ArrayAccess {
982 de,
983 first: true,
984 end_char,
985 is_list,
986 }
987 }
988}
989
990impl<'de, 'a> SeqAccess<'de> for ArrayAccess<'a, 'de> {
991 type Error = Error;
992
993 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
994 where
995 T: DeserializeSeed<'de>,
996 {
997 self.de.skip_whitespace();
998
999 if self.de.peek_char()? == self.end_char {
1001 return Ok(None);
1002 }
1003
1004 if !self.first {
1006 if self.de.peek_char()? == ',' {
1007 self.de.next_char()?;
1008 self.de.skip_whitespace();
1009 if self.de.peek_char()? == self.end_char {
1011 return Ok(None);
1012 }
1013 } else {
1014 return Err(ErrorKind::ExpectedArrayComma.into());
1015 }
1016 }
1017 self.first = false;
1018
1019 if !self.is_list && matches!(self.de.peek_char()?, '{' | '[' | '(') {
1023 return Err(ErrorKind::ArrayElementNotScalar.into());
1024 }
1025
1026 self.de.at_root = false;
1027 seed.deserialize(&mut *self.de).map(Some)
1028 }
1029}
1030
1031struct GroupAccess<'a, 'de: 'a> {
1032 de: &'a mut Deserializer<'de>,
1033 first: bool,
1034}
1035
1036impl<'a, 'de> GroupAccess<'a, 'de> {
1037 fn new(de: &'a mut Deserializer<'de>) -> Self {
1038 GroupAccess { de, first: true }
1039 }
1040}
1041
1042struct ImplicitGroupAccess<'a, 'de: 'a> {
1043 de: &'a mut Deserializer<'de>,
1044 first: bool,
1045}
1046
1047impl<'a, 'de> ImplicitGroupAccess<'a, 'de> {
1048 fn new(de: &'a mut Deserializer<'de>) -> Self {
1049 ImplicitGroupAccess { de, first: true }
1050 }
1051}
1052
1053impl<'de, 'a> MapAccess<'de> for GroupAccess<'a, 'de> {
1054 type Error = Error;
1055
1056 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
1057 where
1058 K: DeserializeSeed<'de>,
1059 {
1060 self.de.skip_whitespace();
1061
1062 if self.de.peek_char()? == '}' {
1064 return Ok(None);
1065 }
1066
1067 if !self.first {
1069 let ch = self.de.peek_char()?;
1070 if ch == ';' || ch == ',' {
1071 self.de.next_char()?;
1072 self.de.skip_whitespace();
1073 if self.de.peek_char()? == '}' {
1075 return Ok(None);
1076 }
1077 }
1078 }
1080 self.first = false;
1081
1082 seed.deserialize(MapKeyDeserializer { de: &mut *self.de })
1083 .map(Some)
1084 }
1085
1086 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
1087 where
1088 V: DeserializeSeed<'de>,
1089 {
1090 self.de.skip_whitespace();
1091
1092 let ch = self.de.next_char()?;
1094 if ch != '=' && ch != ':' {
1095 return Err(ErrorKind::ExpectedEquals.into());
1096 }
1097
1098 self.de.at_root = false;
1099 seed.deserialize(&mut *self.de)
1100 }
1101}
1102
1103impl<'de, 'a> MapAccess<'de> for ImplicitGroupAccess<'a, 'de> {
1104 type Error = Error;
1105
1106 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
1107 where
1108 K: DeserializeSeed<'de>,
1109 {
1110 self.de.skip_whitespace();
1111
1112 if self.de.input.is_empty() {
1114 return Ok(None);
1115 }
1116
1117 if !self.first {
1119 let ch = self.de.peek_char()?;
1120 if ch == ';' || ch == ',' {
1121 self.de.next_char()?;
1122 self.de.skip_whitespace();
1123 if self.de.input.is_empty() {
1125 return Ok(None);
1126 }
1127 }
1128 }
1130 self.first = false;
1131
1132 seed.deserialize(MapKeyDeserializer { de: &mut *self.de })
1133 .map(Some)
1134 }
1135
1136 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
1137 where
1138 V: DeserializeSeed<'de>,
1139 {
1140 self.de.skip_whitespace();
1141
1142 let ch = self.de.next_char()?;
1144 if ch != '=' && ch != ':' {
1145 return Err(ErrorKind::ExpectedEquals.into());
1146 }
1147
1148 self.de.at_root = false;
1149 seed.deserialize(&mut *self.de)
1150 }
1151}
1152
1153#[cfg(test)]
1154mod tests {
1155 use super::*;
1156 use serde::Deserialize;
1157
1158 #[test]
1159 fn test_deserialize_primitives() {
1160 assert_eq!(from_str::<u32>("42").unwrap(), 42);
1161 assert_eq!(from_str::<i64>("42L").unwrap(), 42);
1162 assert_eq!(from_str::<f64>("2.25").unwrap(), 2.25);
1163 assert!(from_str::<bool>("true").unwrap());
1164 assert_eq!(from_str::<String>("\"hello\"").unwrap(), "hello");
1165 }
1166
1167 #[test]
1168 fn test_deserialize_array() {
1169 let arr: Vec<i32> = from_str("[1, 2, 3]").unwrap();
1170 assert_eq!(arr, vec![1, 2, 3]);
1171 }
1172
1173 #[test]
1174 fn test_deserialize_struct() {
1175 #[derive(Debug, Deserialize, PartialEq)]
1176 struct Test {
1177 a: i32,
1178 b: String,
1179 }
1180
1181 let input = r#"a = 42; b = "hello";"#;
1182 let result: Test = from_str(input).unwrap();
1183 assert_eq!(
1184 result,
1185 Test {
1186 a: 42,
1187 b: "hello".to_string()
1188 }
1189 );
1190 }
1191
1192 #[test]
1193 fn test_deserialize_with_comments() {
1194 let input = r#"
1195 # This is a comment
1196 // Another comment
1197 a = 42; /* inline comment */
1198 b = "hello";
1199 "#;
1200
1201 #[derive(Debug, Deserialize, PartialEq)]
1202 struct Test {
1203 a: i32,
1204 b: String,
1205 }
1206
1207 let result: Test = from_str(input).unwrap();
1208 assert_eq!(
1209 result,
1210 Test {
1211 a: 42,
1212 b: "hello".to_string()
1213 }
1214 );
1215 }
1216
1217 #[test]
1218 fn test_case_insensitive_booleans() {
1219 assert!(from_str::<bool>("true").unwrap());
1220 assert!(from_str::<bool>("True").unwrap());
1221 assert!(from_str::<bool>("TRUE").unwrap());
1222 assert!(!from_str::<bool>("false").unwrap());
1223 assert!(!from_str::<bool>("False").unwrap());
1224 assert!(!from_str::<bool>("FALSE").unwrap());
1225 assert!(!from_str::<bool>("FaLsE").unwrap());
1226 }
1227
1228 #[test]
1229 fn test_bool_word_boundary() {
1230 assert!(from_str::<bool>("trueblah").is_err());
1232 assert!(from_str::<bool>("falsehood").is_err());
1233 }
1234
1235 #[test]
1236 fn test_adjacent_string_concatenation() {
1237 let result: String = from_str(r#""hello" " world""#).unwrap();
1238 assert_eq!(result, "hello world");
1239
1240 let result: String = from_str(r#""a" "b" "c""#).unwrap();
1241 assert_eq!(result, "abc");
1242 }
1243
1244 #[test]
1245 fn test_integer_auto_promotion() {
1246 let val: i64 = from_str("3000000000").unwrap();
1248 assert_eq!(val, 3_000_000_000i64);
1249 }
1250
1251 #[test]
1252 fn test_hex_binary_octal() {
1253 assert_eq!(from_str::<i32>("0xFF").unwrap(), 255);
1254 assert_eq!(from_str::<i32>("0b1010").unwrap(), 10);
1255 assert_eq!(from_str::<i32>("0o17").unwrap(), 15);
1256 assert_eq!(from_str::<i32>("0q17").unwrap(), 15);
1257 }
1258
1259 #[test]
1260 fn test_hex_auto_promotion_by_digit_count() {
1261 let val: i64 = from_str("0x1FFFFFFFF").unwrap();
1263 assert_eq!(val, 0x1FFFFFFFFi64);
1264 }
1265
1266 #[test]
1267 fn test_float_leading_dot() {
1268 let val: f64 = from_str(".5").unwrap();
1269 assert_eq!(val, 0.5);
1270 }
1271
1272 #[test]
1273 fn test_list_deserialization() {
1274 let arr: Vec<i32> = from_str("(1, 2, 3)").unwrap();
1275 assert_eq!(arr, vec![1, 2, 3]);
1276 }
1277
1278 #[test]
1279 fn test_implicit_group_as_value() {
1280 use crate::Value;
1281
1282 let raw_string = r#"
1283 title = "My HTTP server";
1284 listen_ports = [ 80, 443 ];
1285 misc = {
1286 owner = "Chuck Norris";
1287 location = "CA";
1288 contact = {
1289 phone = "415-256-9999";
1290 emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
1291 };
1292 };"#;
1293
1294 let parsed_value: Value = from_str(raw_string).expect("Failed to parse value");
1295 assert_eq!(parsed_value["title"], "My HTTP server");
1296 assert_eq!(parsed_value["listen_ports"][0], 80);
1297 assert_eq!(parsed_value["listen_ports"][1], 443);
1298 assert_eq!(parsed_value["misc"]["owner"], "Chuck Norris");
1299 assert_eq!(parsed_value["misc"]["contact"]["phone"], "415-256-9999");
1300 }
1301
1302 #[test]
1303 fn test_implicit_group_bool_key() {
1304 use crate::Value;
1306
1307 let input = r#"flag = true; total = 100;"#;
1308 let v: Value = from_str(input).expect("Failed to parse");
1309 assert_eq!(v["flag"], true);
1310 assert_eq!(v["total"], 100);
1311 }
1312
1313 #[test]
1314 fn test_standalone_bool_still_works() {
1315 assert!(from_str::<bool>("true").unwrap());
1317 assert!(!from_str::<bool>("false").unwrap());
1318
1319 use crate::Value;
1320 let v: Value = from_str("true").unwrap();
1321 assert_eq!(v, Value::Bool(true));
1322
1323 let v: Value = from_str("false").unwrap();
1324 assert_eq!(v, Value::Bool(false));
1325 }
1326
1327 #[test]
1328 fn test_optional_semicolons() {
1329 #[derive(Debug, Deserialize, PartialEq)]
1330 struct Test {
1331 a: i32,
1332 b: i32,
1333 c: i32,
1334 }
1335
1336 let result: Test = from_str(r#"a = 1; b = 2; c = 3;"#).unwrap();
1338 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1339
1340 let result: Test = from_str("a = 1\n b = 2\n c = 3").unwrap();
1342 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1343
1344 let result: Test = from_str("a = 1; b = 2\n c = 3").unwrap();
1346 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1347
1348 let result: Test = from_str(r#"a = 1; b = 2; c = 3;"#).unwrap();
1350 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1351 }
1352
1353 #[test]
1354 fn test_commas_as_setting_separators() {
1355 #[derive(Debug, Deserialize, PartialEq)]
1356 struct Test {
1357 a: i32,
1358 b: i32,
1359 c: i32,
1360 }
1361
1362 let result: Test = from_str(r#"a = 1, b = 2, c = 3"#).unwrap();
1364 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1365
1366 let result: Test = from_str(r#"a = 1, b = 2, c = 3,"#).unwrap();
1368 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1369 }
1370
1371 #[test]
1372 fn test_optional_separators_in_implicit_group() {
1373 use crate::Value;
1374
1375 let v: Value = from_str("a = 1\nb = 2\nc = 3").unwrap();
1377 assert_eq!(v["a"], 1);
1378 assert_eq!(v["b"], 2);
1379 assert_eq!(v["c"], 3);
1380
1381 let v: Value = from_str("a = 1; b = 2; c = 3;").unwrap();
1383 assert_eq!(v["a"], 1);
1384 assert_eq!(v["b"], 2);
1385 assert_eq!(v["c"], 3);
1386 }
1387
1388 #[test]
1389 fn test_auto_promotion_i64_via_value() {
1390 use crate::Value;
1391
1392 let v: Value = from_str("42").unwrap();
1394 assert!(v.is_i32());
1395 assert_eq!(v, Value::Integer(42));
1396
1397 let v: Value = from_str("3000000000").unwrap();
1399 assert!(v.is_i64());
1400 assert_eq!(v.as_i64(), Some(3_000_000_000i64));
1401
1402 let v: Value = from_str("42L").unwrap();
1404 assert!(v.is_i64());
1405 assert_eq!(v.as_i64(), Some(42i64));
1406
1407 let v: Value = from_str("-3000000000").unwrap();
1409 assert!(v.is_i64());
1410 assert_eq!(v.as_i64(), Some(-3_000_000_000i64));
1411
1412 let v: Value = from_str("2147483647").unwrap();
1414 assert!(v.is_i32());
1415
1416 let v: Value = from_str("2147483648").unwrap();
1418 assert!(v.is_i64());
1419 }
1420
1421 #[test]
1422 fn test_negative_numbers() {
1423 assert_eq!(from_str::<i32>("-42").unwrap(), -42);
1425 assert_eq!(from_str::<i32>("-1").unwrap(), -1);
1426
1427 assert_eq!(from_str::<i64>("-42L").unwrap(), -42);
1429
1430 assert_eq!(from_str::<f64>("-2.25").unwrap(), -2.25);
1432 assert_eq!(from_str::<f64>("-0.5").unwrap(), -0.5);
1433
1434 #[derive(Debug, Deserialize, PartialEq)]
1436 struct Coords {
1437 x: i32,
1438 y: i32,
1439 z: f64,
1440 }
1441
1442 let result: Coords = from_str(r#"x = -10; y = -20; z = -1.5;"#).unwrap();
1443 assert_eq!(
1444 result,
1445 Coords {
1446 x: -10,
1447 y: -20,
1448 z: -1.5,
1449 }
1450 );
1451
1452 use crate::Value;
1454 let v: Value = from_str("-42").unwrap();
1455 assert_eq!(v, Value::Integer(-42));
1456
1457 let v: Value = from_str("-2.25").unwrap();
1458 assert_eq!(v, Value::Float(-2.25));
1459 }
1460
1461 #[test]
1462 fn test_identifier_must_start_with_letter_or_asterisk() {
1463 #[derive(Debug, Deserialize)]
1464 #[allow(dead_code)]
1465 struct Test {
1466 a: i32,
1467 }
1468 let _: Test = from_str(r#"a = 1;"#).unwrap();
1470
1471 assert!(from_str::<Test>(r#"1a = 1;"#).is_err());
1473 }
1474
1475 #[test]
1476 fn test_float_signed_exponent() {
1477 assert_eq!(from_str::<f64>("1e+5").unwrap(), 1e5);
1479 assert_eq!(from_str::<f64>("1e-5").unwrap(), 1e-5);
1480 assert_eq!(from_str::<f64>("3.1e-2").unwrap(), 3.1e-2);
1481 assert_eq!(from_str::<f64>("-2.5E+3").unwrap(), -2.5e3);
1482 assert_eq!(from_str::<f64>("1e5").unwrap(), 1e5);
1483
1484 use crate::Value;
1485 let v: Value = from_str("avogadro = 6.02e+23;").unwrap();
1486 assert_eq!(v["avogadro"], 6.02e23);
1487
1488 assert!(from_str::<f64>("1e").is_err());
1490 assert!(from_str::<f64>("1e+").is_err());
1491 }
1492
1493 #[test]
1494 fn test_ll_suffix() {
1495 assert_eq!(from_str::<i64>("42LL").unwrap(), 42);
1497 assert_eq!(from_str::<i64>("-42LL").unwrap(), -42);
1498 assert_eq!(from_str::<i64>("0xFFLL").unwrap(), 255);
1499 assert_eq!(from_str::<i64>("0b1010LL").unwrap(), 10);
1500 assert_eq!(from_str::<i64>("0o17LL").unwrap(), 15);
1501
1502 use crate::Value;
1503 let v: Value = from_str("42LL").unwrap();
1504 assert!(v.is_i64());
1505 }
1506
1507 #[test]
1508 fn test_multibyte_input_does_not_panic() {
1509 use crate::Value;
1511 assert!(from_str::<Value>("tr€").is_err());
1512 assert!(from_str::<bool>("tr€").is_err());
1513 assert!(from_str::<bool>("fals€").is_err());
1514 assert!(from_str::<String>("\"\\x€\"").is_err());
1515 }
1516
1517 #[test]
1518 fn test_integer_range_checked() {
1519 assert!(matches!(from_str::<u8>("300"), Err(e) if *e.kind() == ErrorKind::IntegerOutOfRange));
1522 assert!(matches!(from_str::<u32>("-1"), Err(e) if *e.kind() == ErrorKind::IntegerOutOfRange));
1523 assert!(matches!(
1524 from_str::<i8>("128"),
1525 Err(e) if *e.kind() == ErrorKind::IntegerOutOfRange
1526 ));
1527 assert!(matches!(
1528 from_str::<i32>("3000000000"),
1529 Err(e) if *e.kind() == ErrorKind::IntegerOutOfRange
1530 ));
1531
1532 assert_eq!(from_str::<u8>("255").unwrap(), 255);
1534 assert_eq!(from_str::<i32>("100L").unwrap(), 100);
1535 assert_eq!(from_str::<i8>("-128").unwrap(), -128);
1536 }
1537
1538 #[test]
1539 fn test_float_not_coerced_to_integer() {
1540 assert!(from_str::<i8>("3.9").is_err());
1542 assert!(from_str::<i64>("1.0").is_err());
1543 assert_eq!(from_str::<f64>("42").unwrap(), 42.0);
1545 }
1546
1547 #[test]
1548 fn test_unquoted_string_values_rejected() {
1549 assert!(from_str::<String>("foo").is_err());
1552
1553 #[derive(Debug, Deserialize)]
1554 #[allow(dead_code)]
1555 struct S {
1556 name: String,
1557 }
1558 assert!(from_str::<S>("name = foo;").is_err());
1559 assert!(from_str::<S>("name = \"foo\";").is_ok());
1560 }
1561
1562 #[test]
1563 fn test_empty_configuration() {
1564 use crate::Value;
1566 let v: Value = from_str("").unwrap();
1567 assert_eq!(v, Value::Group(crate::Map::new()));
1568
1569 let v: Value = from_str(" # just a comment\n").unwrap();
1570 assert_eq!(v, Value::Group(crate::Map::new()));
1571
1572 #[derive(Debug, Deserialize, PartialEq)]
1573 struct AllOptional {
1574 a: Option<i32>,
1575 }
1576 assert_eq!(from_str::<AllOptional>("").unwrap(), AllOptional { a: None });
1577 }
1578
1579 #[test]
1580 fn test_map_from_implicit_group() {
1581 use indexmap::IndexMap;
1582 let m: IndexMap<String, i32> = from_str("a = 1; b = 2;").unwrap();
1583 assert_eq!(m["a"], 1);
1584 assert_eq!(m["b"], 2);
1585
1586 let m: IndexMap<String, i32> = from_str("").unwrap();
1587 assert!(m.is_empty());
1588 }
1589
1590 #[test]
1591 fn test_top_level_braces_rejected() {
1592 use crate::Value;
1595 use indexmap::IndexMap;
1596
1597 assert!(matches!(
1598 from_str::<Value>("{ a = 1; }"),
1599 Err(e) if *e.kind() == ErrorKind::TopLevelBraces
1600 ));
1601 assert!(matches!(
1602 from_str::<IndexMap<String, i32>>("{ a = 1; }"),
1603 Err(e) if *e.kind() == ErrorKind::TopLevelBraces
1604 ));
1605
1606 #[derive(Debug, Deserialize)]
1607 #[allow(dead_code)]
1608 struct S {
1609 a: i32,
1610 }
1611 assert!(matches!(
1612 from_str::<S>("{ a = 1; }"),
1613 Err(e) if *e.kind() == ErrorKind::TopLevelBraces
1614 ));
1615
1616 let v: Value = from_str("g = { a = 1; }; l = ({ b = 2; });").unwrap();
1618 assert_eq!(v["g.a"], 1);
1619 assert_eq!(v["l.[0].b"], 2);
1620 }
1621
1622 #[test]
1623 fn test_arrays_are_scalar_only() {
1624 use crate::Value;
1625 assert!(matches!(
1627 from_str::<Value>("x = [{ a = 1; }];"),
1628 Err(e) if *e.kind() == ErrorKind::ArrayElementNotScalar
1629 ));
1630 assert!(matches!(
1631 from_str::<Value>("x = [[1, 2]];"),
1632 Err(e) if *e.kind() == ErrorKind::ArrayElementNotScalar
1633 ));
1634 assert!(matches!(
1635 from_str::<Value>("x = [(1, 2)];"),
1636 Err(e) if *e.kind() == ErrorKind::ArrayElementNotScalar
1637 ));
1638 assert!(from_str::<Value>("x = ({ a = 1; }, [1, 2], (3));").is_ok());
1640 }
1641
1642 #[test]
1643 fn test_array_elements_same_type() {
1644 use crate::Value;
1645 assert!(from_str::<Value>("x = [1, \"a\"];").is_err());
1646 assert!(from_str::<Value>("x = [true, 1];").is_err());
1647 assert!(from_str::<Value>("x = [1, 5000000000];").is_ok());
1649 assert!(from_str::<Value>("x = (1, \"a\");").is_ok());
1651 }
1652
1653 #[test]
1654 fn test_duplicate_setting_names_rejected() {
1655 use crate::Value;
1656 assert!(from_str::<Value>("a = 1; a = 2;").is_err());
1659 assert!(from_str::<Value>("g = { x = 1; x = 2; };").is_err());
1660 }
1661
1662 #[test]
1663 fn test_enum_round_trip() {
1664 use crate::to_string;
1665
1666 #[derive(Debug, Deserialize, serde::Serialize, PartialEq)]
1667 enum E {
1668 Unit,
1669 Newtype(i32),
1670 Tuple(i32, bool),
1671 Struct { x: i32 },
1672 }
1673
1674 for e in [
1675 E::Unit,
1676 E::Newtype(5),
1677 E::Tuple(7, true),
1678 E::Struct { x: 9 },
1679 ] {
1680 let s = to_string(&e).unwrap();
1681 let back: E = from_str(&s).unwrap();
1682 assert_eq!(back, e, "round-trip failed for {s:?}");
1683 }
1684
1685 assert_eq!(from_str::<E>("\"Unit\"").unwrap(), E::Unit);
1687 assert_eq!(from_str::<E>("{ Newtype = 5; }").unwrap(), E::Newtype(5));
1688 assert_eq!(
1689 from_str::<E>("{ Tuple = (7, true); }").unwrap(),
1690 E::Tuple(7, true)
1691 );
1692 assert_eq!(
1693 from_str::<E>("{ Struct = { x = 9; }; }").unwrap(),
1694 E::Struct { x: 9 }
1695 );
1696 assert_eq!(from_str::<E>("{ Newtype: 5 }").unwrap(), E::Newtype(5));
1698 }
1699
1700 #[test]
1701 fn test_identifier_is_ascii_only() {
1702 use crate::Value;
1703 assert!(from_str::<Value>("café = 1;").is_err());
1705 assert!(from_str::<Value>("*wild-card_2* = 1;").is_ok());
1706 }
1707
1708 #[test]
1709 fn test_comment_between_identifier_and_equals() {
1710 use crate::Value;
1711 let v: Value = from_str("total /* count */ = 3;").unwrap();
1713 assert_eq!(v["total"], 3);
1714 }
1715
1716 #[test]
1717 fn test_string_concatenation_with_comments() {
1718 let s: String =
1720 from_str("\"The quick\" /* comment */ \" brown fox \" // another comment\n\"jumped\"")
1721 .unwrap();
1722 assert_eq!(s, "The quick brown fox jumped");
1723 }
1724
1725 #[test]
1726 fn test_parse_errors_carry_line_and_column() {
1727 use crate::Value;
1728 let err = from_str::<Value>("a = 1;\nb = 2;\nc = @;\n").unwrap_err();
1729 assert_eq!(err.line(), Some(3));
1730 assert!(err.column().is_some());
1731 let msg = err.to_string();
1732 assert!(msg.contains("line 3"), "message was: {msg}");
1733
1734 let err = crate::to_string(&f64::NAN).unwrap_err();
1736 assert_eq!(err.line(), None);
1737 }
1738
1739 #[test]
1740 fn test_deserializer_end() {
1741 let mut de = Deserializer::from_str("42 # trailing comment");
1742 let v: i32 = serde::Deserialize::deserialize(&mut de).unwrap();
1743 assert_eq!(v, 42);
1744 assert!(de.end().is_ok());
1745
1746 let mut de = Deserializer::from_str("42 garbage");
1747 let _: i32 = serde::Deserialize::deserialize(&mut de).unwrap();
1748 assert!(matches!(
1749 de.end().unwrap_err().kind(),
1750 ErrorKind::TrailingCharacters
1751 ));
1752 }
1753
1754 #[test]
1755 fn test_f32_out_of_range_errors() {
1756 assert!(matches!(
1757 from_str::<f32>("1e300").unwrap_err().kind(),
1758 ErrorKind::FloatOutOfRange
1759 ));
1760 assert_eq!(from_str::<f32>("2.5").unwrap(), 2.5);
1761 assert!(from_str::<f32>("5000000000L").is_ok());
1763 }
1764
1765 use crate::Value;
1771
1772 fn parses(input: &str) -> Value {
1773 from_str::<Value>(input)
1774 .unwrap_or_else(|e| panic!("expected {input:?} to parse, got: {e}"))
1775 }
1776
1777 fn rejects(input: &str) {
1778 assert!(
1779 from_str::<Value>(input).is_err(),
1780 "expected {input:?} to be rejected"
1781 );
1782 }
1783
1784 #[test]
1785 fn appendix_b_configuration() {
1786 assert_eq!(parses(""), Value::Group(crate::Map::new()));
1788 parses("a = 1;");
1789 parses("a = 1; b = 2;");
1790 rejects("{ a = 1; }");
1792 }
1795
1796 #[test]
1797 fn appendix_b_setting() {
1798 parses("a = 1;"); parses("a : 1;"); parses("a = 1,"); parses("a = 1"); parses("a = 1 b = 2"); parses("a = 1, b = 2; c = 3");
1805 rejects("a 1;"); rejects("a = ;"); rejects("= 1;"); }
1809
1810 #[test]
1811 fn appendix_b_name() {
1812 parses("a = 1;");
1814 parses("A = 1;");
1815 parses("* = 1;");
1816 parses("*a-b_c9* = 1;");
1817 rejects("1a = 1;"); rejects("_a = 1;"); rejects("-a = 1;"); rejects("café = 1;"); }
1822
1823 #[test]
1824 fn appendix_b_group() {
1825 let v = parses("g = { a = 1; b = 2; };");
1827 assert_eq!(v["g.a"], 1);
1828 let v = parses("g = { };");
1829 assert_eq!(v["g"], Value::Group(crate::Map::new()));
1830 rejects("g = { ; };"); rejects("g = { a = 1; ;");
1832 }
1833
1834 #[test]
1835 fn appendix_b_array() {
1836 parses("x = [];");
1838 parses("x = [1];");
1839 parses("x = [1, 2, 3];");
1840 parses("x = [1, 2,];"); parses("x = [-1, +2];"); parses("x = [\"a\" \"b\", \"c\"];"); rejects("x = [,];"); rejects("x = [1,, 2];"); rejects("x = [{ a = 1; }];"); rejects("x = [[1]];"); rejects("x = [(1)];"); }
1849
1850 #[test]
1851 fn appendix_b_list() {
1852 parses("x = ();");
1854 parses("x = (1, \"two\", true, 4.5);");
1855 parses("x = (1, 2,);"); parses("x = (( \"abc\", 123, true ), 1.234, ( ));"); parses("x = ({ a = 1; }, [1, 2]);"); rejects("x = (,);");
1859 }
1860
1861 #[test]
1862 fn appendix_b_boolean() {
1863 for t in ["true", "True", "TRUE", "tRuE"] {
1865 assert_eq!(parses(&format!("b = {t};"))["b"], true);
1866 }
1867 for f in ["false", "False", "FALSE", "fAlSe"] {
1868 assert_eq!(parses(&format!("b = {f};"))["b"], false);
1869 }
1870 rejects("b = truex;"); rejects("b = yes;");
1872 }
1873
1874 #[test]
1875 fn appendix_b_integers() {
1876 assert_eq!(parses("i = 0;")["i"], 0);
1878 assert_eq!(parses("i = +42;")["i"], 42);
1879 assert_eq!(parses("i = -42;")["i"], -42);
1880 assert_eq!(parses("i = 007;")["i"], 7); assert!(parses("i = 42L;")["i"].is_i64());
1882 assert!(parses("i = 42LL;")["i"].is_i64());
1883 assert!(parses("i = -42LL;")["i"].is_i64());
1884 }
1885
1886 #[test]
1887 fn appendix_b_radix_integers() {
1888 assert_eq!(parses("i = 0b1010;")["i"], 10);
1892 assert_eq!(parses("i = 0B1;")["i"], 1);
1893 assert_eq!(parses("i = 0o17;")["i"], 15);
1894 assert_eq!(parses("i = 0O17;")["i"], 15);
1895 assert_eq!(parses("i = 0q17;")["i"], 15);
1896 assert_eq!(parses("i = 0Q17;")["i"], 15);
1897 assert_eq!(parses("i = 0xff;")["i"], 255);
1898 assert_eq!(parses("i = 0XFF;")["i"], 255);
1899 assert!(parses("i = 0xffLL;")["i"].is_i64());
1900
1901 rejects("i = -0x10;");
1903 rejects("i = +0b1;");
1904 rejects("i = 0o8;");
1906 rejects("i = 0b2;");
1907 rejects("i = 0x;");
1908
1909 parses(&format!("i = 0b{};", "0".repeat(64)));
1912 rejects(&format!("i = 0b{};", "0".repeat(65)));
1913 parses(&format!("i = 0x{};", "0".repeat(16)));
1914 rejects(&format!("i = 0x{};", "0".repeat(17)));
1915 parses(&format!("i = 0o{};", "0".repeat(21)));
1916 rejects(&format!("i = 0o{};", "0".repeat(22)));
1917 }
1918
1919 #[test]
1920 fn appendix_b_float_exponent_case_insensitive() {
1921 assert_eq!(from_str::<f64>("1E5").unwrap(), 1e5);
1923 assert_eq!(from_str::<f64>("1E+5").unwrap(), 1e5);
1924 assert_eq!(from_str::<f64>("1E-5").unwrap(), 1e-5);
1925 assert_eq!(from_str::<f64>("2.5E3").unwrap(), 2500.0);
1926 assert_eq!(from_str::<f64>(".5E-2").unwrap(), 0.005);
1927 assert_eq!(from_str::<f64>("5.E3").unwrap(), 5000.0);
1928 assert_eq!(from_str::<f64>("-2.5E+3").unwrap(), -2500.0);
1929 assert_eq!(
1931 from_str::<f64>("1E5").unwrap(),
1932 from_str::<f64>("1e5").unwrap()
1933 );
1934 }
1935
1936 #[test]
1937 fn test_zero_copy_borrowed_strings() {
1938 #[derive(Debug, Deserialize, PartialEq)]
1939 struct S<'a> {
1940 name: &'a str,
1941 owned: String,
1942 }
1943
1944 let input = r#"name = "zero copy"; owned = "also fine";"#;
1946 let s: S = from_str(input).unwrap();
1947 assert_eq!(s.name, "zero copy");
1948 assert_eq!(s.owned, "also fine");
1949
1950 assert!(from_str::<S>(r#"name = "no\tborrow"; owned = "x";"#).is_err());
1953 #[derive(Debug, Deserialize)]
1954 struct Owned {
1955 owned: String,
1956 }
1957 let o: Owned = from_str(r#"owned = "has\ttab";"#).unwrap();
1958 assert_eq!(o.owned, "has\ttab");
1959
1960 let o: Owned = from_str(r#"owned = "a" "b";"#).unwrap();
1962 assert_eq!(o.owned, "ab");
1963 }
1964
1965 #[test]
1966 fn appendix_b_float() {
1967 assert_eq!(parses("f = 1.5;")["f"], 1.5);
1970 assert_eq!(parses("f = .5;")["f"], 0.5);
1971 assert_eq!(parses("f = 5.;")["f"], 5.0);
1972 assert_eq!(parses("f = 5.e3;")["f"], 5000.0);
1973 assert_eq!(parses("f = 1e5;")["f"], 1e5);
1974 assert_eq!(parses("f = 1e+5;")["f"], 1e5);
1975 assert_eq!(parses("f = 1.25e-2;")["f"], 1.25e-2);
1976 assert_eq!(parses("f = -2.5E+3;")["f"], -2.5e3);
1977 rejects("f = 1e;");
1979 rejects("f = 1e+;");
1980 rejects("f = .;");
1983 rejects("f = 1.5L;");
1985 }
1986
1987 #[test]
1988 fn section_2_10_comments() {
1989 let v = parses("# script\n// c++\n/* c */ a = /* mid */ 1; # end");
1991 assert_eq!(v["a"], 1);
1992
1993 assert_eq!(parses("a = /* spans\nseveral\nlines */ 1;")["a"], 1);
1995
1996 let v = parses("a = 1; /* outer /* inner */ b = 2;");
1998 assert_eq!(v["b"], 2);
1999
2000 let v = parses(r#"s = "has # and // and /* inside";"#);
2003 assert_eq!(v["s"], "has # and // and /* inside");
2004
2005 assert_eq!(parses("a = 1; # no newline")["a"], 1);
2007 assert_eq!(parses("a = 1; // no newline")["a"], 1);
2008
2009 assert!(matches!(
2012 from_str::<Value>("a = 1; /* never closed").unwrap_err().kind(),
2013 ErrorKind::UnterminatedComment
2014 ));
2015 assert!(matches!(
2016 from_str::<Value>("/* only").unwrap_err().kind(),
2017 ErrorKind::UnterminatedComment
2018 ));
2019 #[derive(Debug, Deserialize)]
2020 #[allow(dead_code)]
2021 struct S {
2022 a: i32,
2023 }
2024 assert!(from_str::<S>("a = /* open 1;").is_err());
2025
2026 assert_eq!(parses("/* nothing */"), Value::Group(crate::Map::new()));
2028 }
2029
2030 #[test]
2031 fn appendix_b_string() {
2032 assert_eq!(parses("s = \"\";")["s"], "");
2034 assert_eq!(parses("s = \"hello\";")["s"], "hello");
2035 assert_eq!(parses("s = \"line1\nline2\";")["s"], "line1\nline2");
2037 assert_eq!(
2039 parses(r#"s = "\"\\\a\b\f\n\r\t\v";"#)["s"],
2040 "\"\\\x07\x08\x0C\n\r\t\x0B"
2041 );
2042 assert_eq!(parses(r#"s = "\x41\x4212";"#)["s"], "AB12");
2044 rejects(r#"s = "\q";"#);
2046 rejects("s = \"unterminated;");
2047 assert_eq!(parses(r#"s = "a" "b" "c";"#)["s"], "abc");
2049 }
2050}