1use std::cell::Cell;
4
5use serde::Deserialize;
6use serde::de::{self, DeserializeSeed, IntoDeserializer, MapAccess, SeqAccess, Visitor};
7
8use crate::error::{Error, Result};
9
10thread_local! {
11 static IS_LIST_CONTEXT: Cell<bool> = const { Cell::new(false) };
14}
15
16pub(crate) fn is_list_context() -> bool {
18 IS_LIST_CONTEXT.with(|c| c.get())
19}
20
21pub struct Deserializer<'de> {
23 input: &'de str,
24}
25
26impl<'de> Deserializer<'de> {
27 pub fn from_str(input: &'de str) -> Self {
29 Deserializer { input }
30 }
31
32 fn peek_char(&self) -> Result<char> {
34 self.input.chars().next().ok_or(Error::Eof)
35 }
36
37 fn next_char(&mut self) -> Result<char> {
39 let ch = self.peek_char()?;
40 self.input = &self.input[ch.len_utf8()..];
41 Ok(ch)
42 }
43
44 fn skip_whitespace(&mut self) {
46 loop {
47 self.input = self.input.trim_start();
49
50 if self.input.is_empty() {
51 return;
52 }
53
54 if self.input.starts_with('#') {
56 if let Some(pos) = self.input.find('\n') {
58 self.input = &self.input[pos + 1..];
59 } else {
60 self.input = "";
61 return;
62 }
63 } else if self.input.starts_with("//") {
64 if let Some(pos) = self.input.find('\n') {
66 self.input = &self.input[pos + 1..];
67 } else {
68 self.input = "";
69 return;
70 }
71 } else if self.input.starts_with("/*") {
72 if let Some(pos) = self.input.find("*/") {
74 self.input = &self.input[pos + 2..];
75 } else {
76 self.input = "";
77 return;
78 }
79 } else {
80 return;
81 }
82 }
83 }
84
85 fn is_implicit_group_start(&self) -> bool {
90 let input = self.input;
91
92 let mut len = 0;
94 let mut first = true;
95 for ch in input.chars() {
96 if first {
97 if ch.is_ascii_alphabetic() || ch == '*' {
98 len += ch.len_utf8();
99 first = false;
100 } else {
101 return false;
102 }
103 } else if ch.is_alphanumeric() || ch == '_' || ch == '-' || ch == '*' {
104 len += ch.len_utf8();
105 } else {
106 break;
107 }
108 }
109
110 if len == 0 {
111 return false;
112 }
113
114 let rest = input[len..].trim_start();
116
117 matches!(rest.chars().next(), Some('=' | ':'))
119 }
120
121 fn parse_bool(&mut self) -> Result<bool> {
123 self.skip_whitespace();
124 if self.input.len() >= 4
125 && self.input[..4].eq_ignore_ascii_case("true")
126 && !self.input[4..]
127 .chars()
128 .next()
129 .map_or(false, |c| c.is_alphanumeric() || c == '_')
130 {
131 self.input = &self.input[4..];
132 Ok(true)
133 } else if self.input.len() >= 5
134 && self.input[..5].eq_ignore_ascii_case("false")
135 && !self.input[5..]
136 .chars()
137 .next()
138 .map_or(false, |c| c.is_alphanumeric() || c == '_')
139 {
140 self.input = &self.input[5..];
141 Ok(false)
142 } else {
143 Err(Error::ExpectedBoolean)
144 }
145 }
146
147 fn parse_identifier(&mut self) -> Result<&'de str> {
150 self.skip_whitespace();
151 let start = self.input;
152 let mut len = 0;
153 let mut first = true;
154
155 for ch in self.input.chars() {
156 if first {
157 if ch.is_ascii_alphabetic() || ch == '*' {
158 len += ch.len_utf8();
159 first = false;
160 } else {
161 break;
162 }
163 } else if ch.is_alphanumeric() || ch == '_' || ch == '-' || ch == '*' {
164 len += ch.len_utf8();
165 } else {
166 break;
167 }
168 }
169
170 if len == 0 {
171 return Err(Error::ExpectedIdentifier);
172 }
173
174 let ident = &start[..len];
175 self.input = &self.input[len..];
176 Ok(ident)
177 }
178
179 fn parse_single_string(&mut self) -> Result<String> {
181 if self.next_char()? != '"' {
182 return Err(Error::ExpectedString);
183 }
184
185 let mut result = String::new();
186 let mut escape = false;
187
188 loop {
189 if self.input.is_empty() {
190 return Err(Error::Eof);
191 }
192
193 let ch = self.next_char()?;
194
195 if escape {
196 match ch {
197 '"' => result.push('"'),
198 '\\' => result.push('\\'),
199 'n' => result.push('\n'),
200 'r' => result.push('\r'),
201 't' => result.push('\t'),
202 'f' => result.push('\x0C'),
203 'b' => result.push('\x08'),
204 'v' => result.push('\x0B'),
205 'a' => result.push('\x07'),
206 'x' => {
207 if self.input.len() < 2 {
209 return Err(Error::InvalidEscape);
210 }
211 let hex = &self.input[..2];
212 if let Ok(byte) = u8::from_str_radix(hex, 16) {
213 result.push(byte as char);
214 self.input = &self.input[2..];
215 } else {
216 return Err(Error::InvalidEscape);
217 }
218 }
219 _ => return Err(Error::InvalidEscape),
220 }
221 escape = false;
222 } else if ch == '\\' {
223 escape = true;
224 } else if ch == '"' {
225 break;
226 } else {
227 result.push(ch);
228 }
229 }
230
231 Ok(result)
232 }
233
234 fn parse_string(&mut self) -> Result<String> {
237 self.skip_whitespace();
238 let mut result = self.parse_single_string()?;
239
240 loop {
242 self.skip_whitespace();
243 if self.input.starts_with('"') {
244 result.push_str(&self.parse_single_string()?);
245 } else {
246 break;
247 }
248 }
249
250 Ok(result)
251 }
252
253 fn parse_number(&mut self) -> Result<Number> {
255 self.skip_whitespace();
256 let start = self.input;
257 let mut len = 0;
258 let mut is_float = false;
259 let mut is_long = false;
260 let mut is_hex = false;
261 let mut is_binary = false;
262 let mut is_octal = false;
263 let mut has_sign = false;
264
265 if let Some(ch) = self.input.chars().next() {
267 if ch == '-' || ch == '+' {
268 has_sign = true;
269 len += 1;
270 }
271 }
272
273 if self.input[len..].starts_with('.') {
275 is_float = true;
276 len += 1;
277 }
278 else if !has_sign
280 && (self.input[len..].starts_with("0x") || self.input[len..].starts_with("0X"))
281 {
282 is_hex = true;
283 len += 2;
284 } else if !has_sign
285 && (self.input[len..].starts_with("0b") || self.input[len..].starts_with("0B"))
286 {
287 is_binary = true;
288 len += 2;
289 } else if !has_sign
290 && (self.input[len..].starts_with("0o")
291 || self.input[len..].starts_with("0O")
292 || self.input[len..].starts_with("0q")
293 || self.input[len..].starts_with("0Q"))
294 {
295 is_octal = true;
296 len += 2;
297 }
298
299 let mut digit_count = 0usize;
301 for ch in self.input[len..].chars() {
302 if is_hex && ch.is_ascii_hexdigit() {
303 len += ch.len_utf8();
304 digit_count += 1;
305 } else if is_binary && (ch == '0' || ch == '1') {
306 len += ch.len_utf8();
307 digit_count += 1;
308 } else if is_octal && ch.is_digit(8) {
309 len += ch.len_utf8();
310 digit_count += 1;
311 } else if !is_hex && !is_binary && !is_octal && ch.is_ascii_digit() {
312 len += ch.len_utf8();
313 digit_count += 1;
314 } else if ch == '.' && !is_hex && !is_binary && !is_octal && !is_float {
315 is_float = true;
316 len += ch.len_utf8();
317 } else if (ch == 'e' || ch == 'E') && !is_hex && !is_binary && !is_octal {
318 is_float = true;
319 len += ch.len_utf8();
320 if let Some(next_ch) = self.input[len..].chars().next() {
322 if next_ch == '+' || next_ch == '-' {
323 len += 1;
324 }
325 }
326 } else if ch == 'L' {
327 is_long = true;
328 len += ch.len_utf8();
329 break;
330 } else {
331 break;
332 }
333 }
334
335 if len == 0
336 || (len == 1 && has_sign)
337 || (is_float && digit_count == 0)
338 || ((is_hex || is_binary || is_octal) && digit_count == 0)
339 {
340 return Err(Error::ExpectedInteger);
341 }
342
343 let num_str = &start[..len];
344 self.input = &self.input[len..];
345
346 if is_float {
347 let val = num_str.parse::<f64>().map_err(|_| Error::InvalidNumber)?;
348 Ok(Number::Float(val))
349 } else if is_hex {
350 let hex_str = num_str
351 .trim_start_matches("0x")
352 .trim_start_matches("0X")
353 .trim_end_matches('L');
354 let val = i64::from_str_radix(hex_str, 16).map_err(|_| Error::InvalidNumber)?;
355 if is_long || digit_count > 8 {
356 Ok(Number::I64(val))
357 } else {
358 Ok(Number::I32(val as i32))
359 }
360 } else if is_binary {
361 let bin_str = num_str
362 .trim_start_matches("0b")
363 .trim_start_matches("0B")
364 .trim_end_matches('L');
365 let val = i64::from_str_radix(bin_str, 2).map_err(|_| Error::InvalidNumber)?;
366 if is_long || digit_count > 32 {
367 Ok(Number::I64(val))
368 } else {
369 Ok(Number::I32(val as i32))
370 }
371 } else if is_octal {
372 let oct_str = num_str
373 .trim_start_matches("0o")
374 .trim_start_matches("0O")
375 .trim_start_matches("0q")
376 .trim_start_matches("0Q")
377 .trim_end_matches('L');
378 let val = i64::from_str_radix(oct_str, 8).map_err(|_| Error::InvalidNumber)?;
379 if is_long || digit_count > 10 {
380 Ok(Number::I64(val))
381 } else {
382 Ok(Number::I32(val as i32))
383 }
384 } else {
385 let trimmed = num_str.trim_end_matches('L');
386 if is_long {
387 let val = trimmed.parse::<i64>().map_err(|_| Error::InvalidNumber)?;
388 Ok(Number::I64(val))
389 } else {
390 match trimmed.parse::<i32>() {
392 Ok(val) => Ok(Number::I32(val)),
393 Err(_) => {
394 let val = trimmed.parse::<i64>().map_err(|_| Error::InvalidNumber)?;
395 Ok(Number::I64(val))
396 }
397 }
398 }
399 }
400 }
401}
402
403pub fn from_str<'a, T>(s: &'a str) -> Result<T>
405where
406 T: Deserialize<'a>,
407{
408 let mut deserializer = Deserializer::from_str(s);
409 let t = T::deserialize(&mut deserializer)?;
410 deserializer.skip_whitespace();
411 if deserializer.input.is_empty() {
412 Ok(t)
413 } else {
414 Err(Error::TrailingCharacters)
415 }
416}
417
418#[derive(Debug, Clone)]
419enum Number {
420 I32(i32),
421 I64(i64),
422 Float(f64),
423}
424
425impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
426 type Error = Error;
427
428 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
429 where
430 V: Visitor<'de>,
431 {
432 self.skip_whitespace();
433 match self.peek_char()? {
434 't' | 'T' | 'f' | 'F' => {
435 if self.is_implicit_group_start() {
438 visitor.visit_map(ImplicitGroupAccess::new(self))
439 } else {
440 self.deserialize_bool(visitor)
441 }
442 }
443 '"' => self.deserialize_string(visitor),
444 '[' => self.deserialize_seq(visitor),
445 '(' => self.deserialize_seq(visitor), '{' => self.deserialize_map(visitor),
447 '-' | '+' | '0'..='9' | '.' => {
448 let num = self.parse_number()?;
450 match num {
451 Number::I32(v) => visitor.visit_i32(v),
452 Number::I64(v) => visitor.visit_i64(v),
453 Number::Float(v) => visitor.visit_f64(v),
454 }
455 }
456 c if c.is_ascii_alphabetic() || c == '*' => {
457 visitor.visit_map(ImplicitGroupAccess::new(self))
459 }
460 _ => Err(Error::Syntax),
461 }
462 }
463
464 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
465 where
466 V: Visitor<'de>,
467 {
468 visitor.visit_bool(self.parse_bool()?)
469 }
470
471 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
472 where
473 V: Visitor<'de>,
474 {
475 let num = self.parse_number()?;
476 match num {
477 Number::I32(v) => visitor.visit_i8(v as i8),
478 Number::I64(v) => visitor.visit_i8(v as i8),
479 Number::Float(v) => visitor.visit_i8(v as i8),
480 }
481 }
482
483 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
484 where
485 V: Visitor<'de>,
486 {
487 let num = self.parse_number()?;
488 match num {
489 Number::I32(v) => visitor.visit_i16(v as i16),
490 Number::I64(v) => visitor.visit_i16(v as i16),
491 Number::Float(v) => visitor.visit_i16(v as i16),
492 }
493 }
494
495 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
496 where
497 V: Visitor<'de>,
498 {
499 let num = self.parse_number()?;
500 match num {
501 Number::I32(v) => visitor.visit_i32(v),
502 Number::I64(v) => visitor.visit_i32(v as i32),
503 Number::Float(v) => visitor.visit_i32(v as i32),
504 }
505 }
506
507 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
508 where
509 V: Visitor<'de>,
510 {
511 let num = self.parse_number()?;
512 match num {
513 Number::I32(v) => visitor.visit_i64(v as i64),
514 Number::I64(v) => visitor.visit_i64(v),
515 Number::Float(v) => visitor.visit_i64(v as i64),
516 }
517 }
518
519 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
520 where
521 V: Visitor<'de>,
522 {
523 let num = self.parse_number()?;
524 match num {
525 Number::I32(v) => visitor.visit_u8(v as u8),
526 Number::I64(v) => visitor.visit_u8(v as u8),
527 Number::Float(v) => visitor.visit_u8(v as u8),
528 }
529 }
530
531 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
532 where
533 V: Visitor<'de>,
534 {
535 let num = self.parse_number()?;
536 match num {
537 Number::I32(v) => visitor.visit_u16(v as u16),
538 Number::I64(v) => visitor.visit_u16(v as u16),
539 Number::Float(v) => visitor.visit_u16(v as u16),
540 }
541 }
542
543 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
544 where
545 V: Visitor<'de>,
546 {
547 let num = self.parse_number()?;
548 match num {
549 Number::I32(v) => visitor.visit_u32(v as u32),
550 Number::I64(v) => visitor.visit_u32(v as u32),
551 Number::Float(v) => visitor.visit_u32(v as u32),
552 }
553 }
554
555 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
556 where
557 V: Visitor<'de>,
558 {
559 let num = self.parse_number()?;
560 match num {
561 Number::I32(v) => visitor.visit_u64(v as u64),
562 Number::I64(v) => visitor.visit_u64(v as u64),
563 Number::Float(v) => visitor.visit_u64(v as u64),
564 }
565 }
566
567 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
568 where
569 V: Visitor<'de>,
570 {
571 let num = self.parse_number()?;
572 match num {
573 Number::I32(v) => visitor.visit_f32(v as f32),
574 Number::I64(v) => visitor.visit_f32(v as f32),
575 Number::Float(v) => visitor.visit_f32(v as f32),
576 }
577 }
578
579 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
580 where
581 V: Visitor<'de>,
582 {
583 let num = self.parse_number()?;
584 match num {
585 Number::I32(v) => visitor.visit_f64(v as f64),
586 Number::I64(v) => visitor.visit_f64(v as f64),
587 Number::Float(v) => visitor.visit_f64(v),
588 }
589 }
590
591 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
592 where
593 V: Visitor<'de>,
594 {
595 let s = self.parse_string()?;
596 let mut chars = s.chars();
597 let ch = chars.next().ok_or(Error::ExpectedString)?;
598 if chars.next().is_some() {
599 return Err(Error::ExpectedString);
600 }
601 visitor.visit_char(ch)
602 }
603
604 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
605 where
606 V: Visitor<'de>,
607 {
608 self.skip_whitespace();
609 if self.peek_char()? == '"' {
611 visitor.visit_string(self.parse_string()?)
612 } else {
613 visitor.visit_str(self.parse_identifier()?)
615 }
616 }
617
618 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
619 where
620 V: Visitor<'de>,
621 {
622 self.skip_whitespace();
623 if self.peek_char()? == '"' {
625 visitor.visit_string(self.parse_string()?)
626 } else {
627 visitor.visit_string(self.parse_identifier()?.to_string())
629 }
630 }
631
632 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
633 where
634 V: Visitor<'de>,
635 {
636 self.deserialize_seq(visitor)
637 }
638
639 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
640 where
641 V: Visitor<'de>,
642 {
643 self.deserialize_seq(visitor)
644 }
645
646 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
647 where
648 V: Visitor<'de>,
649 {
650 visitor.visit_some(self)
651 }
652
653 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
654 where
655 V: Visitor<'de>,
656 {
657 visitor.visit_unit()
658 }
659
660 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
661 where
662 V: Visitor<'de>,
663 {
664 self.deserialize_unit(visitor)
665 }
666
667 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
668 where
669 V: Visitor<'de>,
670 {
671 visitor.visit_newtype_struct(self)
672 }
673
674 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
675 where
676 V: Visitor<'de>,
677 {
678 self.skip_whitespace();
679 let ch = self.peek_char()?;
680
681 if ch == '[' {
682 self.next_char()?;
683 IS_LIST_CONTEXT.with(|c| c.set(false));
684 let value = visitor.visit_seq(ArrayAccess::new(self, ']', false))?;
685 self.skip_whitespace();
686 if self.next_char()? == ']' {
687 Ok(value)
688 } else {
689 Err(Error::ExpectedArrayEnd)
690 }
691 } else if ch == '(' {
692 self.next_char()?;
693 IS_LIST_CONTEXT.with(|c| c.set(true));
694 let value = visitor.visit_seq(ArrayAccess::new(self, ')', true))?;
695 self.skip_whitespace();
696 if self.next_char()? == ')' {
697 Ok(value)
698 } else {
699 Err(Error::ExpectedListEnd)
700 }
701 } else {
702 Err(Error::ExpectedArray)
703 }
704 }
705
706 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
707 where
708 V: Visitor<'de>,
709 {
710 self.deserialize_seq(visitor)
711 }
712
713 fn deserialize_tuple_struct<V>(
714 self,
715 _name: &'static str,
716 _len: usize,
717 visitor: V,
718 ) -> Result<V::Value>
719 where
720 V: Visitor<'de>,
721 {
722 self.deserialize_seq(visitor)
723 }
724
725 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
726 where
727 V: Visitor<'de>,
728 {
729 self.skip_whitespace();
730 if self.next_char()? == '{' {
731 let value = visitor.visit_map(GroupAccess::new(self))?;
732 self.skip_whitespace();
733 if self.next_char()? == '}' {
734 Ok(value)
735 } else {
736 Err(Error::ExpectedGroupEnd)
737 }
738 } else {
739 Err(Error::ExpectedGroup)
740 }
741 }
742
743 fn deserialize_struct<V>(
744 self,
745 _name: &'static str,
746 _fields: &'static [&'static str],
747 visitor: V,
748 ) -> Result<V::Value>
749 where
750 V: Visitor<'de>,
751 {
752 self.skip_whitespace();
753 if self.peek_char()? == '{' {
755 self.deserialize_map(visitor)
756 } else {
757 let value = visitor.visit_map(ImplicitGroupAccess::new(self))?;
759 Ok(value)
760 }
761 }
762
763 fn deserialize_enum<V>(
764 self,
765 _name: &'static str,
766 _variants: &'static [&'static str],
767 visitor: V,
768 ) -> Result<V::Value>
769 where
770 V: Visitor<'de>,
771 {
772 self.skip_whitespace();
773 if self.peek_char()? == '"' {
774 visitor.visit_enum(self.parse_string()?.into_deserializer())
776 } else {
777 Err(Error::TypeNotSupported("complex enum variants".to_string()))
779 }
780 }
781
782 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
783 where
784 V: Visitor<'de>,
785 {
786 visitor.visit_str(self.parse_identifier()?)
787 }
788
789 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
790 where
791 V: Visitor<'de>,
792 {
793 self.deserialize_any(visitor)
794 }
795}
796
797struct ArrayAccess<'a, 'de: 'a> {
798 de: &'a mut Deserializer<'de>,
799 first: bool,
800 end_char: char,
801 is_list: bool,
802}
803
804impl<'a, 'de> ArrayAccess<'a, 'de> {
805 fn new(de: &'a mut Deserializer<'de>, end_char: char, is_list: bool) -> Self {
806 ArrayAccess {
807 de,
808 first: true,
809 end_char,
810 is_list,
811 }
812 }
813}
814
815impl<'de, 'a> SeqAccess<'de> for ArrayAccess<'a, 'de> {
816 type Error = Error;
817
818 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
819 where
820 T: DeserializeSeed<'de>,
821 {
822 self.de.skip_whitespace();
823
824 if self.de.peek_char()? == self.end_char {
826 return Ok(None);
827 }
828
829 if !self.first {
831 if self.de.peek_char()? == ',' {
832 self.de.next_char()?;
833 self.de.skip_whitespace();
834 if self.de.peek_char()? == self.end_char {
836 return Ok(None);
837 }
838 } else {
839 return Err(Error::ExpectedArrayComma);
840 }
841 }
842 self.first = false;
843
844 IS_LIST_CONTEXT.with(|c| c.set(self.is_list));
846
847 seed.deserialize(&mut *self.de).map(Some)
848 }
849}
850
851struct GroupAccess<'a, 'de: 'a> {
852 de: &'a mut Deserializer<'de>,
853 first: bool,
854}
855
856impl<'a, 'de> GroupAccess<'a, 'de> {
857 fn new(de: &'a mut Deserializer<'de>) -> Self {
858 GroupAccess { de, first: true }
859 }
860}
861
862struct ImplicitGroupAccess<'a, 'de: 'a> {
863 de: &'a mut Deserializer<'de>,
864 first: bool,
865}
866
867impl<'a, 'de> ImplicitGroupAccess<'a, 'de> {
868 fn new(de: &'a mut Deserializer<'de>) -> Self {
869 ImplicitGroupAccess { de, first: true }
870 }
871}
872
873impl<'de, 'a> MapAccess<'de> for GroupAccess<'a, 'de> {
874 type Error = Error;
875
876 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
877 where
878 K: DeserializeSeed<'de>,
879 {
880 self.de.skip_whitespace();
881
882 if self.de.peek_char()? == '}' {
884 return Ok(None);
885 }
886
887 if !self.first {
889 let ch = self.de.peek_char()?;
890 if ch == ';' || ch == ',' {
891 self.de.next_char()?;
892 self.de.skip_whitespace();
893 if self.de.peek_char()? == '}' {
895 return Ok(None);
896 }
897 }
898 }
900 self.first = false;
901
902 seed.deserialize(&mut *self.de).map(Some)
903 }
904
905 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
906 where
907 V: DeserializeSeed<'de>,
908 {
909 self.de.skip_whitespace();
910
911 let ch = self.de.next_char()?;
913 if ch != '=' && ch != ':' {
914 return Err(Error::ExpectedEquals);
915 }
916
917 seed.deserialize(&mut *self.de)
918 }
919}
920
921impl<'de, 'a> MapAccess<'de> for ImplicitGroupAccess<'a, 'de> {
922 type Error = Error;
923
924 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
925 where
926 K: DeserializeSeed<'de>,
927 {
928 self.de.skip_whitespace();
929
930 if self.de.input.is_empty() {
932 return Ok(None);
933 }
934
935 if !self.first {
937 let ch = self.de.peek_char()?;
938 if ch == ';' || ch == ',' {
939 self.de.next_char()?;
940 self.de.skip_whitespace();
941 if self.de.input.is_empty() {
943 return Ok(None);
944 }
945 }
946 }
948 self.first = false;
949
950 seed.deserialize(&mut *self.de).map(Some)
951 }
952
953 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
954 where
955 V: DeserializeSeed<'de>,
956 {
957 self.de.skip_whitespace();
958
959 let ch = self.de.next_char()?;
961 if ch != '=' && ch != ':' {
962 return Err(Error::ExpectedEquals);
963 }
964
965 seed.deserialize(&mut *self.de)
966 }
967}
968
969#[cfg(test)]
970mod tests {
971 use super::*;
972 use serde::Deserialize;
973
974 #[test]
975 fn test_deserialize_primitives() {
976 assert_eq!(from_str::<u32>("42").unwrap(), 42);
977 assert_eq!(from_str::<i64>("42L").unwrap(), 42);
978 assert_eq!(from_str::<f64>("3.14").unwrap(), 3.14);
979 assert_eq!(from_str::<bool>("true").unwrap(), true);
980 assert_eq!(from_str::<String>("\"hello\"").unwrap(), "hello");
981 }
982
983 #[test]
984 fn test_deserialize_array() {
985 let arr: Vec<i32> = from_str("[1, 2, 3]").unwrap();
986 assert_eq!(arr, vec![1, 2, 3]);
987 }
988
989 #[test]
990 fn test_deserialize_struct() {
991 #[derive(Debug, Deserialize, PartialEq)]
992 struct Test {
993 a: i32,
994 b: String,
995 }
996
997 let input = r#"{ a = 42; b = "hello"; }"#;
998 let result: Test = from_str(input).unwrap();
999 assert_eq!(
1000 result,
1001 Test {
1002 a: 42,
1003 b: "hello".to_string()
1004 }
1005 );
1006 }
1007
1008 #[test]
1009 fn test_deserialize_with_comments() {
1010 let input = r#"
1011 # This is a comment
1012 {
1013 // Another comment
1014 a = 42; /* inline comment */
1015 b = "hello";
1016 }
1017 "#;
1018
1019 #[derive(Debug, Deserialize, PartialEq)]
1020 struct Test {
1021 a: i32,
1022 b: String,
1023 }
1024
1025 let result: Test = from_str(input).unwrap();
1026 assert_eq!(
1027 result,
1028 Test {
1029 a: 42,
1030 b: "hello".to_string()
1031 }
1032 );
1033 }
1034
1035 #[test]
1036 fn test_case_insensitive_booleans() {
1037 assert_eq!(from_str::<bool>("true").unwrap(), true);
1038 assert_eq!(from_str::<bool>("True").unwrap(), true);
1039 assert_eq!(from_str::<bool>("TRUE").unwrap(), true);
1040 assert_eq!(from_str::<bool>("false").unwrap(), false);
1041 assert_eq!(from_str::<bool>("False").unwrap(), false);
1042 assert_eq!(from_str::<bool>("FALSE").unwrap(), false);
1043 assert_eq!(from_str::<bool>("FaLsE").unwrap(), false);
1044 }
1045
1046 #[test]
1047 fn test_bool_word_boundary() {
1048 assert!(from_str::<bool>("trueblah").is_err());
1050 assert!(from_str::<bool>("falsehood").is_err());
1051 }
1052
1053 #[test]
1054 fn test_adjacent_string_concatenation() {
1055 let result: String = from_str(r#""hello" " world""#).unwrap();
1056 assert_eq!(result, "hello world");
1057
1058 let result: String = from_str(r#""a" "b" "c""#).unwrap();
1059 assert_eq!(result, "abc");
1060 }
1061
1062 #[test]
1063 fn test_integer_auto_promotion() {
1064 let val: i64 = from_str("3000000000").unwrap();
1066 assert_eq!(val, 3_000_000_000i64);
1067 }
1068
1069 #[test]
1070 fn test_hex_binary_octal() {
1071 assert_eq!(from_str::<i32>("0xFF").unwrap(), 255);
1072 assert_eq!(from_str::<i32>("0b1010").unwrap(), 10);
1073 assert_eq!(from_str::<i32>("0o17").unwrap(), 15);
1074 assert_eq!(from_str::<i32>("0q17").unwrap(), 15);
1075 }
1076
1077 #[test]
1078 fn test_hex_auto_promotion_by_digit_count() {
1079 let val: i64 = from_str("0x1FFFFFFFF").unwrap();
1081 assert_eq!(val, 0x1FFFFFFFFi64);
1082 }
1083
1084 #[test]
1085 fn test_float_leading_dot() {
1086 let val: f64 = from_str(".5").unwrap();
1087 assert_eq!(val, 0.5);
1088 }
1089
1090 #[test]
1091 fn test_list_deserialization() {
1092 let arr: Vec<i32> = from_str("(1, 2, 3)").unwrap();
1093 assert_eq!(arr, vec![1, 2, 3]);
1094 }
1095
1096 #[test]
1097 fn test_implicit_group_as_value() {
1098 use crate::Value;
1099
1100 let raw_string = r#"
1101 title = "My HTTP server";
1102 listen_ports = [ 80, 443 ];
1103 misc = {
1104 owner = "Chuck Norris";
1105 location = "CA";
1106 contact = {
1107 phone = "415-256-9999";
1108 emails = ["chuck@norris.com", "chuck.norris@gmail.com"];
1109 };
1110 };"#;
1111
1112 let parsed_value: Value = from_str(raw_string).expect("Failed to parse value");
1113 assert_eq!(parsed_value["title"], "My HTTP server");
1114 assert_eq!(parsed_value["listen_ports"][0], 80);
1115 assert_eq!(parsed_value["listen_ports"][1], 443);
1116 assert_eq!(parsed_value["misc"]["owner"], "Chuck Norris");
1117 assert_eq!(parsed_value["misc"]["contact"]["phone"], "415-256-9999");
1118 }
1119
1120 #[test]
1121 fn test_implicit_group_bool_key() {
1122 use crate::Value;
1124
1125 let input = r#"flag = true; total = 100;"#;
1126 let v: Value = from_str(input).expect("Failed to parse");
1127 assert_eq!(v["flag"], true);
1128 assert_eq!(v["total"], 100);
1129 }
1130
1131 #[test]
1132 fn test_standalone_bool_still_works() {
1133 assert_eq!(from_str::<bool>("true").unwrap(), true);
1135 assert_eq!(from_str::<bool>("false").unwrap(), false);
1136
1137 use crate::Value;
1138 let v: Value = from_str("true").unwrap();
1139 assert_eq!(v, Value::Bool(true));
1140
1141 let v: Value = from_str("false").unwrap();
1142 assert_eq!(v, Value::Bool(false));
1143 }
1144
1145 #[test]
1146 fn test_optional_semicolons() {
1147 #[derive(Debug, Deserialize, PartialEq)]
1148 struct Test {
1149 a: i32,
1150 b: i32,
1151 c: i32,
1152 }
1153
1154 let result: Test = from_str(r#"{ a = 1; b = 2; c = 3; }"#).unwrap();
1156 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1157
1158 let result: Test = from_str("{ a = 1\n b = 2\n c = 3 }").unwrap();
1160 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1161
1162 let result: Test = from_str("{ a = 1; b = 2\n c = 3 }").unwrap();
1164 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1165
1166 let result: Test = from_str(r#"{ a = 1; b = 2; c = 3; }"#).unwrap();
1168 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1169 }
1170
1171 #[test]
1172 fn test_commas_as_setting_separators() {
1173 #[derive(Debug, Deserialize, PartialEq)]
1174 struct Test {
1175 a: i32,
1176 b: i32,
1177 c: i32,
1178 }
1179
1180 let result: Test = from_str(r#"{ a = 1, b = 2, c = 3 }"#).unwrap();
1182 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1183
1184 let result: Test = from_str(r#"{ a = 1, b = 2, c = 3, }"#).unwrap();
1186 assert_eq!(result, Test { a: 1, b: 2, c: 3 });
1187 }
1188
1189 #[test]
1190 fn test_optional_separators_in_implicit_group() {
1191 use crate::Value;
1192
1193 let v: Value = from_str("a = 1\nb = 2\nc = 3").unwrap();
1195 assert_eq!(v["a"], 1);
1196 assert_eq!(v["b"], 2);
1197 assert_eq!(v["c"], 3);
1198
1199 let v: Value = from_str("a = 1; b = 2; c = 3;").unwrap();
1201 assert_eq!(v["a"], 1);
1202 assert_eq!(v["b"], 2);
1203 assert_eq!(v["c"], 3);
1204 }
1205
1206 #[test]
1207 fn test_auto_promotion_i64_via_value() {
1208 use crate::Value;
1209
1210 let v: Value = from_str("42").unwrap();
1212 assert!(v.is_i32());
1213 assert_eq!(v, Value::Integer(42));
1214
1215 let v: Value = from_str("3000000000").unwrap();
1217 assert!(v.is_i64());
1218 assert_eq!(v.as_i64(), Some(3_000_000_000i64));
1219
1220 let v: Value = from_str("42L").unwrap();
1222 assert!(v.is_i64());
1223 assert_eq!(v.as_i64(), Some(42i64));
1224
1225 let v: Value = from_str("-3000000000").unwrap();
1227 assert!(v.is_i64());
1228 assert_eq!(v.as_i64(), Some(-3_000_000_000i64));
1229
1230 let v: Value = from_str("2147483647").unwrap();
1232 assert!(v.is_i32());
1233
1234 let v: Value = from_str("2147483648").unwrap();
1236 assert!(v.is_i64());
1237 }
1238
1239 #[test]
1240 fn test_negative_numbers() {
1241 assert_eq!(from_str::<i32>("-42").unwrap(), -42);
1243 assert_eq!(from_str::<i32>("-1").unwrap(), -1);
1244
1245 assert_eq!(from_str::<i64>("-42L").unwrap(), -42);
1247
1248 assert_eq!(from_str::<f64>("-3.14").unwrap(), -3.14);
1250 assert_eq!(from_str::<f64>("-0.5").unwrap(), -0.5);
1251
1252 #[derive(Debug, Deserialize, PartialEq)]
1254 struct Coords {
1255 x: i32,
1256 y: i32,
1257 z: f64,
1258 }
1259
1260 let result: Coords = from_str(r#"{ x = -10; y = -20; z = -1.5; }"#).unwrap();
1261 assert_eq!(
1262 result,
1263 Coords {
1264 x: -10,
1265 y: -20,
1266 z: -1.5,
1267 }
1268 );
1269
1270 use crate::Value;
1272 let v: Value = from_str("-42").unwrap();
1273 assert_eq!(v, Value::Integer(-42));
1274
1275 let v: Value = from_str("-3.14").unwrap();
1276 assert_eq!(v, Value::Float(-3.14));
1277 }
1278
1279 #[test]
1280 fn test_identifier_must_start_with_letter_or_asterisk() {
1281 #[derive(Debug, Deserialize)]
1282 #[allow(dead_code)]
1283 struct Test {
1284 a: i32,
1285 }
1286 let _: Test = from_str(r#"{ a = 1; }"#).unwrap();
1288
1289 assert!(from_str::<Test>(r#"{ 1a = 1; }"#).is_err());
1291 }
1292}