1use std::borrow::Cow;
4use std::fmt;
5use std::fmt::Debug;
6use std::fmt::Display;
7use std::num::ParseIntError;
8
9use nom::branch::alt;
10use nom::bytes::complete::escaped_transform;
11use nom::bytes::complete::is_not;
12use nom::bytes::complete::tag;
13use nom::bytes::complete::take_while;
14use nom::bytes::complete::take_while1;
15use nom::character::complete::alphanumeric1;
16use nom::character::complete::anychar;
17use nom::character::complete::char;
18use nom::character::complete::none_of;
19use nom::combinator::map;
20use nom::combinator::map_res;
21use nom::combinator::opt;
22use nom::combinator::peek;
23use nom::combinator::recognize;
24use nom::combinator::value;
25use nom::combinator::verify;
26use nom::sequence::delimited;
27use nom::sequence::pair;
28use nom::sequence::tuple;
29use nom::AsChar;
30use nom::Finish;
31use nom::IResult;
32use num_traits::Num;
33use remain::sorted;
34use serde::de;
35use serde::Deserialize;
36use serde::Deserializer;
37use thiserror::Error;
38
39#[derive(Debug, Error, PartialEq, Eq)]
40#[sorted]
41#[non_exhaustive]
42#[allow(missing_docs)]
43pub enum ErrorKind {
45 #[error("unexpected end of input")]
46 Eof,
47 #[error("expected a boolean")]
48 ExpectedBoolean,
49 #[error("expected ']'")]
50 ExpectedCloseBracket,
51 #[error("expected ','")]
52 ExpectedComma,
53 #[error("expected '='")]
54 ExpectedEqual,
55 #[error("expected an identifier")]
56 ExpectedIdentifier,
57 #[error("expected '['")]
58 ExpectedOpenBracket,
59 #[error("expected a string")]
60 ExpectedString,
61 #[error("\" and ' can only be used in quoted strings")]
62 InvalidCharInString,
63 #[error("invalid characters for number or number does not fit into its destination type")]
64 InvalidNumber,
65 #[error("serde error: {0}")]
66 SerdeError(String),
67 #[error("remaining characters in input")]
68 TrailingCharacters,
69}
70
71#[derive(Debug, Error, PartialEq, Eq)]
73pub struct ParseError {
74 pub kind: ErrorKind,
76 pub pos: usize,
78}
79
80impl From<ParseError> for crate::Error {
81 fn from(e: ParseError) -> Self {
82 crate::Error::invalid_data(e)
83 }
84}
85
86impl Display for ParseError {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match &self.kind {
89 ErrorKind::SerdeError(s) => write!(f, "{}", s),
90 _ => write!(f, "{} at position {}", self.kind, self.pos),
91 }
92 }
93}
94
95impl de::Error for ParseError {
96 fn custom<T>(msg: T) -> Self
97 where
98 T: fmt::Display,
99 {
100 Self {
101 kind: ErrorKind::SerdeError(msg.to_string()),
102 pos: 0,
103 }
104 }
105}
106
107type Result<T> = std::result::Result<T, ParseError>;
108
109fn is_separator(c: Option<char>) -> bool {
111 matches!(c, Some(',' | ']') | None)
112}
113
114fn any_separator(s: &str) -> IResult<&str, Option<char>> {
116 let next_char = s.chars().next();
117
118 if is_separator(next_char) {
119 let pos = if let Some(c) = next_char {
120 c.len_utf8()
121 } else {
122 0
123 };
124 Ok((&s[pos..], next_char))
125 } else {
126 Err(nom::Err::Error(nom::error::Error::new(
127 s,
128 nom::error::ErrorKind::Char,
129 )))
130 }
131}
132
133fn any_string(s: &str) -> IResult<&str, Cow<str>> {
142 let double_quoted = delimited(
145 char('"'),
146 alt((
147 map(
148 escaped_transform(
149 none_of(r#"\""#),
150 '\\',
151 alt((value("\"", char('"')), value("\\", char('\\')))),
152 ),
153 Cow::Owned,
154 ),
155 map(tag(""), Cow::Borrowed),
156 )),
157 char('"'),
158 );
159
160 let single_quoted = map(
162 delimited(char('\''), alt((is_not(r"'"), tag(""))), char('\'')),
163 Cow::Borrowed,
164 );
165
166 let unquoted = map(
169 take_while1(|c: char| c != ',' && c != '"' && c != '\'' && c != '[' && c != ']'),
170 Cow::Borrowed,
171 );
172
173 alt((double_quoted, single_quoted, unquoted))(s)
174}
175
176fn any_number<T>(s: &str) -> IResult<&str, T>
180where
181 T: Num<FromStrRadixErr = ParseIntError>,
182{
183 fn parse_number(s: &str) -> IResult<&str, (Cow<str>, u32)> {
189 let sign = char('-');
191
192 let radix = alt((
194 value(16, tag("0x")),
195 value(8, tag("0o")),
196 value(2, tag("0b")),
197 ));
198
199 let separator = peek(any_separator);
201
202 map(
208 tuple((opt(sign), opt(radix), alphanumeric1, separator)),
209 |(sign, radix, number, _)| {
210 let num_string = if let Some(sign) = sign {
214 Cow::Owned(sign.to_string() + number)
215 } else {
216 Cow::Borrowed(number)
217 };
218
219 (num_string, radix.unwrap_or(10))
220 },
221 )(s)
222 }
223
224 map_res(parse_number, |(num_string, radix)| {
225 T::from_str_radix(&num_string, radix)
226 })(s)
227}
228
229fn any_bool(s: &str) -> IResult<&str, bool> {
231 let mut boolean = alt((value(true, tag("true")), value(false, tag("false"))));
232
233 boolean(s)
234}
235
236fn any_identifier(s: &str) -> IResult<&str, &str> {
242 let mut ident = recognize(pair(
243 verify(anychar, |&c| c.is_alphanum() || c == '_'),
244 take_while(|c: char| c.is_alphanum() || c == '_' || c == '-'),
245 ));
246
247 ident(s)
248}
249
250pub struct KeyValueDeserializer<'de> {
252 original_input: &'de str,
254 input: &'de str,
256 next_identifier: Option<&'de str>,
266 has_equal: bool,
269 top_struct_parsed: bool,
272}
273
274impl<'de> From<&'de str> for KeyValueDeserializer<'de> {
275 fn from(input: &'de str) -> Self {
276 Self {
277 original_input: input,
278 input,
279 next_identifier: None,
280 has_equal: false,
281 top_struct_parsed: false,
282 }
283 }
284}
285
286impl<'de> KeyValueDeserializer<'de> {
287 pub fn error_here(&self, kind: ErrorKind) -> ParseError {
289 ParseError {
290 kind,
291 pos: self.original_input.len() - self.input.len(),
292 }
293 }
294
295 pub fn peek_char(&self) -> Option<char> {
298 self.input.chars().next()
299 }
300
301 pub fn skip_char(&mut self) {
303 let _ = self.next_char();
304 }
305
306 pub fn next_char(&mut self) -> Option<char> {
309 let c = self.peek_char()?;
310 self.input = &self.input[c.len_utf8()..];
311 Some(c)
312 }
313
314 fn confirm_separator(&mut self) -> Result<()> {
317 match self.peek_char() {
319 Some(',') => {
320 let _ = self.next_char();
321 Ok(())
322 }
323 Some(']') | None => Ok(()),
324 Some(_) => Err(self.error_here(ErrorKind::ExpectedComma)),
325 }
326 }
327
328 pub fn parse_identifier(&mut self) -> Result<&'de str> {
330 let (remainder, res) = any_identifier(self.input)
331 .finish()
332 .map_err(|_| self.error_here(ErrorKind::ExpectedIdentifier))?;
333
334 self.input = remainder;
335 Ok(res)
336 }
337
338 pub fn parse_string(&mut self) -> Result<Cow<'de, str>> {
340 let (remainder, res) =
341 any_string(self.input)
342 .finish()
343 .map_err(|e: nom::error::Error<_>| {
344 self.input = e.input;
345 self.error_here(ErrorKind::ExpectedString)
347 })?;
348
349 self.input = remainder;
350
351 if is_separator(self.peek_char()) {
354 Ok(res)
355 } else {
356 Err(self.error_here(ErrorKind::InvalidCharInString))
357 }
358 }
359
360 pub fn parse_bool(&mut self) -> Result<bool> {
362 let (remainder, res) =
363 any_bool(self.input)
364 .finish()
365 .map_err(|e: nom::error::Error<_>| {
366 self.input = e.input;
367 self.error_here(ErrorKind::ExpectedBoolean)
368 })?;
369
370 self.input = remainder;
371 Ok(res)
372 }
373
374 pub fn parse_number<T>(&mut self) -> Result<T>
376 where
377 T: Num<FromStrRadixErr = ParseIntError>,
378 {
379 let (remainder, val) = any_number(self.input)
380 .finish()
381 .map_err(|_| self.error_here(ErrorKind::InvalidNumber))?;
382
383 self.input = remainder;
384 Ok(val)
385 }
386
387 pub fn finish(self) -> Result<()> {
392 if self.input.is_empty() {
393 Ok(())
394 } else {
395 Err(self.error_here(ErrorKind::TrailingCharacters))
396 }
397 }
398}
399
400impl<'de> de::MapAccess<'de> for KeyValueDeserializer<'de> {
401 type Error = ParseError;
402
403 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
404 where
405 K: de::DeserializeSeed<'de>,
406 {
407 match self.peek_char() {
409 None | Some(']') => return Ok(None),
410 _ => (),
411 }
412
413 self.has_equal = false;
414
415 let had_implicit_identifier = self.next_identifier.is_some();
416 let val = seed.deserialize(&mut *self).map(Some)?;
417 if had_implicit_identifier {
420 self.has_equal = true;
421 return Ok(val);
422 }
423
424 match self.peek_char() {
425 Some('=') => {
427 self.skip_char();
428 self.has_equal = true;
429 Ok(val)
430 }
431 c if is_separator(c) => Ok(val),
433 _ => Err(self.error_here(ErrorKind::ExpectedEqual)),
434 }
435 }
436
437 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
438 where
439 V: de::DeserializeSeed<'de>,
440 {
441 let val = seed.deserialize(&mut *self)?;
442
443 self.confirm_separator()?;
444
445 Ok(val)
446 }
447}
448
449struct EmptyMapAccess;
483
484impl<'de> de::MapAccess<'de> for EmptyMapAccess {
485 type Error = ParseError;
486
487 fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>>
488 where
489 K: de::DeserializeSeed<'de>,
490 {
491 Ok(None)
492 }
493
494 fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value>
495 where
496 V: de::DeserializeSeed<'de>,
497 {
498 unreachable!()
500 }
501}
502
503impl<'de> de::EnumAccess<'de> for &mut KeyValueDeserializer<'de> {
504 type Error = ParseError;
505 type Variant = Self;
506
507 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
508 where
509 V: de::DeserializeSeed<'de>,
510 {
511 let val = seed.deserialize(&mut *self)?;
512 Ok((val, self))
513 }
514}
515
516impl<'de> de::VariantAccess<'de> for &mut KeyValueDeserializer<'de> {
517 type Error = ParseError;
518
519 fn unit_variant(self) -> Result<()> {
520 Ok(())
521 }
522
523 fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
524 where
525 T: de::DeserializeSeed<'de>,
526 {
527 unimplemented!()
528 }
529
530 fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
531 where
532 V: de::Visitor<'de>,
533 {
534 self.deserialize_tuple(len, visitor)
535 }
536
537 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
538 where
539 V: de::Visitor<'de>,
540 {
541 if self.peek_char() == Some('[') {
542 self.next_char();
543 let val = self.deserialize_map(visitor)?;
544
545 if self.peek_char() == Some(']') {
546 self.next_char();
547 Ok(val)
548 } else {
549 Err(self.error_here(ErrorKind::ExpectedCloseBracket))
550 }
551 } else {
552 visitor
555 .visit_map(EmptyMapAccess)
556 .map_err(|_| self.error_here(ErrorKind::ExpectedOpenBracket))
557 }
558 }
559}
560
561impl<'de> de::SeqAccess<'de> for KeyValueDeserializer<'de> {
562 type Error = ParseError;
563
564 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
565 where
566 T: de::DeserializeSeed<'de>,
567 {
568 if self.peek_char() == Some(']') {
569 return Ok(None);
570 }
571
572 let value = seed.deserialize(&mut *self)?;
573
574 self.confirm_separator()?;
575
576 Ok(Some(value))
577 }
578}
579
580impl<'de> de::Deserializer<'de> for &mut KeyValueDeserializer<'de> {
581 type Error = ParseError;
582
583 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
584 where
585 V: serde::de::Visitor<'de>,
586 {
587 match self.peek_char() {
588 c if is_separator(c) => return self.deserialize_bool(visitor),
590 Some('[') => return self.deserialize_seq(visitor),
592 _ => (),
593 }
594
595 if any_number::<i64>(self.input).is_ok() {
598 self.deserialize_i64(visitor)
599 } else if any_number::<u64>(self.input).is_ok() {
600 self.deserialize_u64(visitor)
601 } else if any_bool(self.input).is_ok() {
602 self.deserialize_bool(visitor)
603 } else {
604 self.deserialize_str(visitor)
605 }
606 }
607
608 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
609 where
610 V: serde::de::Visitor<'de>,
611 {
612 let val = if self.has_equal {
615 self.parse_bool()?
616 } else {
617 true
618 };
619 visitor.visit_bool(val)
620 }
621
622 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
623 where
624 V: serde::de::Visitor<'de>,
625 {
626 visitor.visit_i8(self.parse_number()?)
627 }
628
629 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
630 where
631 V: serde::de::Visitor<'de>,
632 {
633 visitor.visit_i16(self.parse_number()?)
634 }
635
636 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
637 where
638 V: serde::de::Visitor<'de>,
639 {
640 visitor.visit_i32(self.parse_number()?)
641 }
642
643 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
644 where
645 V: serde::de::Visitor<'de>,
646 {
647 visitor.visit_i64(self.parse_number()?)
648 }
649
650 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
651 where
652 V: serde::de::Visitor<'de>,
653 {
654 visitor.visit_u8(self.parse_number()?)
655 }
656
657 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
658 where
659 V: serde::de::Visitor<'de>,
660 {
661 visitor.visit_u16(self.parse_number()?)
662 }
663
664 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
665 where
666 V: serde::de::Visitor<'de>,
667 {
668 visitor.visit_u32(self.parse_number()?)
669 }
670
671 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
672 where
673 V: serde::de::Visitor<'de>,
674 {
675 visitor.visit_u64(self.parse_number()?)
676 }
677
678 fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value>
679 where
680 V: serde::de::Visitor<'de>,
681 {
682 unimplemented!()
683 }
684
685 fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
686 where
687 V: serde::de::Visitor<'de>,
688 {
689 unimplemented!()
690 }
691
692 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
693 where
694 V: serde::de::Visitor<'de>,
695 {
696 visitor.visit_char(
697 self.next_char()
698 .ok_or_else(|| self.error_here(ErrorKind::Eof))?,
699 )
700 }
701
702 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
703 where
704 V: serde::de::Visitor<'de>,
705 {
706 match self.parse_string()? {
707 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
708 Cow::Owned(s) => visitor.visit_string(s),
709 }
710 }
711
712 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
713 where
714 V: serde::de::Visitor<'de>,
715 {
716 self.deserialize_str(visitor)
717 }
718
719 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
720 where
721 V: serde::de::Visitor<'de>,
722 {
723 unimplemented!()
724 }
725
726 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
727 where
728 V: serde::de::Visitor<'de>,
729 {
730 self.deserialize_bytes(visitor)
731 }
732
733 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
734 where
735 V: serde::de::Visitor<'de>,
736 {
737 visitor.visit_some(self)
740 }
741
742 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
743 where
744 V: serde::de::Visitor<'de>,
745 {
746 visitor.visit_unit()
747 }
748
749 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
750 where
751 V: serde::de::Visitor<'de>,
752 {
753 self.deserialize_unit(visitor)
754 }
755
756 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
757 where
758 V: serde::de::Visitor<'de>,
759 {
760 visitor.visit_newtype_struct(self)
761 }
762
763 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
764 where
765 V: serde::de::Visitor<'de>,
766 {
767 if self.peek_char() == Some('[') {
768 self.next_char();
769 let val = visitor.visit_seq(&mut *self)?;
770
771 if self.peek_char() == Some(']') {
772 self.next_char();
773 Ok(val)
774 } else {
775 Err(self.error_here(ErrorKind::ExpectedCloseBracket))
776 }
777 } else {
778 visitor
781 .visit_map(EmptyMapAccess)
782 .map_err(|_| self.error_here(ErrorKind::ExpectedOpenBracket))
783 }
784 }
785
786 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
787 where
788 V: serde::de::Visitor<'de>,
789 {
790 self.deserialize_seq(visitor)
791 }
792
793 fn deserialize_tuple_struct<V>(
794 self,
795 _name: &'static str,
796 _len: usize,
797 _visitor: V,
798 ) -> Result<V::Value>
799 where
800 V: serde::de::Visitor<'de>,
801 {
802 unimplemented!()
803 }
804
805 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
806 where
807 V: serde::de::Visitor<'de>,
808 {
809 self.top_struct_parsed = true;
815
816 visitor.visit_map(self)
817 }
818
819 fn deserialize_struct<V>(
820 self,
821 _name: &'static str,
822 fields: &'static [&'static str],
823 visitor: V,
824 ) -> Result<V::Value>
825 where
826 V: serde::de::Visitor<'de>,
827 {
828 let top_struct_parsed = std::mem::replace(&mut self.top_struct_parsed, true);
831
832 if top_struct_parsed {
833 if self.peek_char() == Some('[') {
834 self.next_char();
835 } else {
836 return visitor
839 .visit_map(EmptyMapAccess)
840 .map_err(|_| self.error_here(ErrorKind::ExpectedOpenBracket));
841 }
842 }
843
844 self.next_identifier = match any_identifier(self.input) {
851 Ok((_, s)) => match self.input.chars().nth(s.chars().count()) {
852 Some('=') => None,
853 _ => {
854 if fields.contains(&s) {
855 None
856 } else {
857 fields.first().copied()
858 }
859 }
860 },
861 Err(_) => fields.first().copied(),
863 };
864
865 let ret = visitor.visit_map(&mut *self)?;
866
867 if top_struct_parsed {
868 if self.peek_char() == Some(']') {
869 self.next_char();
870 } else {
871 return Err(self.error_here(ErrorKind::ExpectedCloseBracket));
872 }
873 }
874
875 Ok(ret)
876 }
877
878 fn deserialize_enum<V>(
879 self,
880 _name: &'static str,
881 _variants: &'static [&'static str],
882 visitor: V,
883 ) -> Result<V::Value>
884 where
885 V: serde::de::Visitor<'de>,
886 {
887 visitor.visit_enum(self)
888 }
889
890 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
891 where
892 V: serde::de::Visitor<'de>,
893 {
894 let identifier = self
895 .next_identifier
896 .take()
897 .map_or_else(|| self.parse_identifier(), Ok)?;
898
899 visitor.visit_borrowed_str(identifier)
900 }
901
902 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
903 where
904 V: serde::de::Visitor<'de>,
905 {
906 self.deserialize_any(visitor)
907 }
908}
909
910pub fn from_key_values<'a, T>(input: &'a str) -> Result<T>
912where
913 T: Deserialize<'a>,
914{
915 let mut deserializer = KeyValueDeserializer::from(input);
916 let ret = T::deserialize(&mut deserializer)?;
917 deserializer.finish()?;
918
919 Ok(ret)
920}
921
922#[cfg(test)]
923mod tests {
924 use std::collections::BTreeSet;
925 use std::path::PathBuf;
926
927 use super::*;
928
929 #[derive(Deserialize, PartialEq, Debug)]
930 struct SingleStruct<T> {
931 m: T,
932 }
933
934 #[test]
935 fn nom_any_separator() {
936 let test_str = ",foo";
937 assert_eq!(any_separator(test_str), Ok((&test_str[1..], Some(','))));
938 let test_str = "]bar";
939 assert_eq!(any_separator(test_str), Ok((&test_str[1..], Some(']'))));
940 let test_str = "";
941 assert_eq!(any_separator(test_str), Ok((test_str, None)));
942
943 let test_str = "something,anything";
944 assert_eq!(
945 any_separator(test_str),
946 Err(nom::Err::Error(nom::error::Error::new(
947 test_str,
948 nom::error::ErrorKind::Char
949 )))
950 );
951 }
952
953 #[test]
954 fn deserialize_number() {
955 let res = from_key_values::<SingleStruct<usize>>("m=54").unwrap();
956 assert_eq!(res.m, 54);
957
958 let res = from_key_values::<SingleStruct<isize>>("m=-54").unwrap();
959 assert_eq!(res.m, -54);
960
961 let res = from_key_values::<SingleStruct<u32>>("m=-54").unwrap_err();
963 assert_eq!(
964 res,
965 ParseError {
966 kind: ErrorKind::InvalidNumber,
967 pos: 2
968 }
969 );
970
971 let val = i32::MAX as u32 + 1;
973 let res = from_key_values::<SingleStruct<i32>>(&format!("m={}", val)).unwrap_err();
974 assert_eq!(
975 res,
976 ParseError {
977 kind: ErrorKind::InvalidNumber,
978 pos: 2
979 }
980 );
981
982 let res = from_key_values::<SingleStruct<usize>>("m=test").unwrap_err();
984 assert_eq!(
985 res,
986 ParseError {
987 kind: ErrorKind::InvalidNumber,
988 pos: 2,
989 }
990 );
991
992 let res: SingleStruct<usize> =
994 from_key_values::<SingleStruct<usize>>("m=0x1234abcd").unwrap();
995 assert_eq!(res.m, 0x1234_abcd);
996 let res: SingleStruct<isize> =
997 from_key_values::<SingleStruct<isize>>("m=-0x1234abcd").unwrap();
998 assert_eq!(res.m, -0x1234_abcd);
999
1000 let res: ParseError = from_key_values::<SingleStruct<usize>>("m=0xg").unwrap_err();
1002 assert_eq!(
1003 res,
1004 ParseError {
1005 kind: ErrorKind::InvalidNumber,
1006 pos: 2,
1007 }
1008 );
1009
1010 let res: SingleStruct<usize> = from_key_values::<SingleStruct<usize>>("m=0o755").unwrap();
1012 assert_eq!(res.m, 0o755);
1013 let res: SingleStruct<isize> = from_key_values::<SingleStruct<isize>>("m=-0o755").unwrap();
1014 assert_eq!(res.m, -0o755);
1015
1016 let res: ParseError = from_key_values::<SingleStruct<usize>>("m=0o8").unwrap_err();
1018 assert_eq!(
1019 res,
1020 ParseError {
1021 kind: ErrorKind::InvalidNumber,
1022 pos: 2,
1023 }
1024 );
1025
1026 let res: SingleStruct<usize> = from_key_values::<SingleStruct<usize>>("m=0b1100").unwrap();
1028 assert_eq!(res.m, 0b1100);
1029 let res: SingleStruct<isize> = from_key_values::<SingleStruct<isize>>("m=-0b1100").unwrap();
1030 assert_eq!(res.m, -0b1100);
1031
1032 let res: ParseError = from_key_values::<SingleStruct<usize>>("m=0b2").unwrap_err();
1034 assert_eq!(
1035 res,
1036 ParseError {
1037 kind: ErrorKind::InvalidNumber,
1038 pos: 2,
1039 }
1040 );
1041 }
1042
1043 #[test]
1044 fn deserialize_string() {
1045 let kv = "m=John";
1046 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1047 assert_eq!(res.m, "John".to_string());
1048
1049 let kv = "m=John Doe";
1051 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1052 assert_eq!(res.m, "John Doe".to_string());
1053
1054 let kv = "m=";
1056 let err = from_key_values::<SingleStruct<String>>(kv).unwrap_err();
1057 assert_eq!(
1058 err,
1059 ParseError {
1060 kind: ErrorKind::ExpectedString,
1061 pos: 2
1062 }
1063 );
1064
1065 let kv = r#"m="John Doe""#;
1067 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1068 assert_eq!(res.m, "John Doe".to_string());
1069 let kv = r"m='John Doe'";
1070 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1071 assert_eq!(res.m, "John Doe".to_string());
1072
1073 let kv = r#"m="""#;
1075 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1076 assert_eq!(res.m, String::new());
1077 let kv = r"m=''";
1078 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1079 assert_eq!(res.m, String::new());
1080
1081 let kv = r#"m="val = [10, 20, 'a']""#;
1083 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1084 assert_eq!(res.m, r"val = [10, 20, 'a']".to_string());
1085
1086 let kv = r#"m=val="a""#;
1088 let err = from_key_values::<SingleStruct<String>>(kv).unwrap_err();
1089 assert_eq!(
1090 err,
1091 ParseError {
1092 kind: ErrorKind::InvalidCharInString,
1093 pos: 6
1094 }
1095 );
1096 let kv = r"m=val='a'";
1097 let err = from_key_values::<SingleStruct<String>>(kv).unwrap_err();
1098 assert_eq!(
1099 err,
1100 ParseError {
1101 kind: ErrorKind::InvalidCharInString,
1102 pos: 6
1103 }
1104 );
1105
1106 let kv = r"m=val=[a]";
1108 let err = from_key_values::<SingleStruct<String>>(kv).unwrap_err();
1109 assert_eq!(
1110 err,
1111 ParseError {
1112 kind: ErrorKind::InvalidCharInString,
1113 pos: 6
1114 }
1115 );
1116
1117 let kv = "m=10";
1119 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1120 assert_eq!(res.m, "10".to_string());
1121 let kv = "m=false";
1122 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1123 assert_eq!(res.m, "false".to_string());
1124
1125 let kv = r#"m="Escaped \" quote""#;
1127 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1128 assert_eq!(res.m, r#"Escaped " quote"#.to_string());
1129
1130 let kv = r#"m="Escaped slash\\""#;
1132 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1133 assert_eq!(res.m, r"Escaped slash\".to_string());
1134
1135 let kv = r#"m='Escaped \" quote'"#;
1137 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1138 assert_eq!(res.m, r#"Escaped \" quote"#.to_string());
1139 let kv = r"m='Escaped slash\\'";
1140 let res = from_key_values::<SingleStruct<String>>(kv).unwrap();
1141 assert_eq!(res.m, r"Escaped slash\\".to_string());
1142 }
1143
1144 #[test]
1145 fn deserialize_unit() {
1146 from_key_values::<SingleStruct<()>>("m").unwrap();
1147 from_key_values::<SingleStruct<()>>("m=").unwrap();
1148
1149 from_key_values::<SingleStruct<()>>("").unwrap_err();
1150 from_key_values::<SingleStruct<()>>("p").unwrap_err();
1151 from_key_values::<SingleStruct<()>>("m=10").unwrap_err();
1152 }
1153
1154 #[test]
1155 fn deserialize_bool() {
1156 let res = from_key_values::<SingleStruct<bool>>("m=true").unwrap();
1157 assert!(res.m);
1158
1159 let res = from_key_values::<SingleStruct<bool>>("m=false").unwrap();
1160 assert!(!res.m);
1161
1162 let res = from_key_values::<SingleStruct<bool>>("m").unwrap();
1163 assert!(res.m);
1164
1165 let res = from_key_values::<SingleStruct<bool>>("m=10").unwrap_err();
1166 assert_eq!(
1167 res,
1168 ParseError {
1169 kind: ErrorKind::ExpectedBoolean,
1170 pos: 2,
1171 }
1172 );
1173
1174 let res = from_key_values::<SingleStruct<bool>>("m=").unwrap_err();
1175 assert_eq!(
1176 res,
1177 ParseError {
1178 kind: ErrorKind::ExpectedBoolean,
1179 pos: 2,
1180 }
1181 );
1182 }
1183
1184 #[test]
1185 fn deserialize_complex_struct() {
1186 #[derive(Deserialize, PartialEq, Debug)]
1187 struct TestStruct {
1188 num: usize,
1189 path: PathBuf,
1190 enable: bool,
1191 }
1192 let kv = "num=54,path=/dev/foomatic,enable=false";
1193 let res = from_key_values::<TestStruct>(kv).unwrap();
1194 assert_eq!(
1195 res,
1196 TestStruct {
1197 num: 54,
1198 path: "/dev/foomatic".into(),
1199 enable: false,
1200 }
1201 );
1202
1203 let kv = "num=0x54,path=/dev/foomatic,enable=false";
1204 let res = from_key_values::<TestStruct>(kv).unwrap();
1205 assert_eq!(
1206 res,
1207 TestStruct {
1208 num: 0x54,
1209 path: "/dev/foomatic".into(),
1210 enable: false,
1211 }
1212 );
1213
1214 let kv = "enable,path=/usr/lib/libossom.so.1,num=12";
1215 let res = from_key_values::<TestStruct>(kv).unwrap();
1216 assert_eq!(
1217 res,
1218 TestStruct {
1219 num: 12,
1220 path: "/usr/lib/libossom.so.1".into(),
1221 enable: true,
1222 }
1223 );
1224
1225 let kv = "[enable,path=/usr/lib/libossom.so.1,num=12]";
1227 assert!(from_key_values::<TestStruct>(kv).is_err());
1228 }
1229
1230 #[test]
1231 fn deserialize_unknown_field() {
1232 #[derive(Deserialize, PartialEq, Debug)]
1233 #[serde(deny_unknown_fields)]
1234 struct TestStruct {
1235 num: usize,
1236 path: PathBuf,
1237 enable: bool,
1238 }
1239
1240 let kv = "enable,path=/usr/lib/libossom.so.1,num=12,foo=bar";
1241 assert!(from_key_values::<TestStruct>(kv).is_err());
1242 }
1243
1244 #[test]
1245 fn deserialize_option() {
1246 #[derive(Deserialize, PartialEq, Debug)]
1247 struct TestStruct {
1248 num: u32,
1249 opt: Option<u32>,
1250 }
1251 let kv = "num=16,opt=12";
1252 let res: TestStruct = from_key_values(kv).unwrap();
1253 assert_eq!(
1254 res,
1255 TestStruct {
1256 num: 16,
1257 opt: Some(12),
1258 }
1259 );
1260
1261 let kv = "num=16";
1262 let res: TestStruct = from_key_values(kv).unwrap();
1263 assert_eq!(res, TestStruct { num: 16, opt: None });
1264
1265 let kv = "";
1266 assert!(from_key_values::<TestStruct>(kv).is_err());
1267 }
1268
1269 #[test]
1270 fn deserialize_optional_struct_with_default() {
1271 #[derive(Deserialize, PartialEq, Debug)]
1272 struct DefaultStruct {
1273 #[serde(default)]
1274 param: u32,
1275 }
1276
1277 #[derive(Deserialize, PartialEq, Debug)]
1278 struct TestStruct {
1279 flag: Option<DefaultStruct>,
1280 }
1281
1282 let kv = "flag=[param=12]";
1284 let res: TestStruct = from_key_values(kv).unwrap();
1285 assert_eq!(
1286 res,
1287 TestStruct {
1288 flag: Some(DefaultStruct { param: 12 })
1289 }
1290 );
1291
1292 let kv = "flag=[]";
1294 let res: TestStruct = from_key_values(kv).unwrap();
1295 assert_eq!(
1296 res,
1297 TestStruct {
1298 flag: Some(DefaultStruct { param: 0 })
1299 }
1300 );
1301
1302 let kv = "flag=";
1304 let res: TestStruct = from_key_values(kv).unwrap();
1305 assert_eq!(
1306 res,
1307 TestStruct {
1308 flag: Some(DefaultStruct { param: 0 })
1309 }
1310 );
1311
1312 let kv = "flag";
1314 let res: TestStruct = from_key_values(kv).unwrap();
1315 assert_eq!(
1316 res,
1317 TestStruct {
1318 flag: Some(DefaultStruct { param: 0 })
1319 }
1320 );
1321
1322 let kv = "flag=[";
1324 assert!(from_key_values::<TestStruct>(kv).is_err());
1325
1326 let kv = "flag=]";
1328 assert!(from_key_values::<TestStruct>(kv).is_err());
1329 }
1330
1331 #[test]
1332 fn deserialize_optional_struct_within_flattened() {
1333 #[derive(Deserialize, PartialEq, Debug)]
1334 struct FlatStruct {
1335 a: u32,
1336 #[serde(default)]
1337 b: String,
1338 }
1339
1340 #[derive(Deserialize, PartialEq, Debug)]
1341 struct DefaultStruct {
1342 #[serde(default)]
1343 param: u32,
1344 }
1345
1346 #[derive(Deserialize, PartialEq, Debug)]
1347 struct TestStruct {
1348 #[serde(flatten)]
1349 flat: FlatStruct,
1350 flag: Option<DefaultStruct>,
1351 }
1352
1353 let kv = "a=10,b=foomatic,flag=[param=24]";
1355 let res: TestStruct = from_key_values(kv).unwrap();
1356 assert_eq!(
1357 res,
1358 TestStruct {
1359 flat: FlatStruct {
1360 a: 10,
1361 b: "foomatic".into(),
1362 },
1363 flag: Some(DefaultStruct { param: 24 })
1364 }
1365 );
1366
1367 let kv = "a=10,b=foomatic,flag";
1369 let res: TestStruct = from_key_values(kv).unwrap();
1370 assert_eq!(
1371 res,
1372 TestStruct {
1373 flat: FlatStruct {
1374 a: 10,
1375 b: "foomatic".into(),
1376 },
1377 flag: Some(DefaultStruct { param: 0 })
1378 }
1379 );
1380
1381 let kv = "a=10,flag=[param=24]";
1383 let res: TestStruct = from_key_values(kv).unwrap();
1384 assert_eq!(
1385 res,
1386 TestStruct {
1387 flat: FlatStruct {
1388 a: 10,
1389 b: <_>::default(),
1390 },
1391 flag: Some(DefaultStruct { param: 24 })
1392 }
1393 );
1394
1395 let kv = "a=10";
1397 let res: TestStruct = from_key_values(kv).unwrap();
1398 assert_eq!(
1399 res,
1400 TestStruct {
1401 flat: FlatStruct {
1402 a: 10,
1403 b: <_>::default(),
1404 },
1405 flag: None,
1406 }
1407 );
1408
1409 let kv = "b=foomatic,flag=[param=24]";
1411 assert!(from_key_values::<TestStruct>(kv).is_err());
1412
1413 let kv = "[a=10,b=foomatic,flag=[param=24]]";
1415 assert!(from_key_values::<TestStruct>(kv).is_err());
1416 }
1417
1418 #[test]
1419 fn deserialize_enum() {
1420 #[derive(Deserialize, PartialEq, Debug)]
1421 enum TestEnum {
1422 #[serde(rename = "first")]
1423 FirstVariant,
1424 #[serde(rename = "second")]
1425 SecondVariant,
1426 }
1427 let res: TestEnum = from_key_values("first").unwrap();
1428 assert_eq!(res, TestEnum::FirstVariant,);
1429
1430 let res: TestEnum = from_key_values("second").unwrap();
1431 assert_eq!(res, TestEnum::SecondVariant,);
1432
1433 from_key_values::<TestEnum>("third").unwrap_err();
1434 }
1435
1436 #[test]
1437 fn deserialize_embedded_enum() {
1438 #[derive(Deserialize, PartialEq, Debug)]
1439 enum TestEnum {
1440 #[serde(rename = "first")]
1441 FirstVariant,
1442 #[serde(rename = "second")]
1443 SecondVariant,
1444 }
1445 #[derive(Deserialize, PartialEq, Debug)]
1446 struct TestStruct {
1447 variant: TestEnum,
1448 #[serde(default)]
1449 active: bool,
1450 }
1451 let res: TestStruct = from_key_values("variant=first").unwrap();
1452 assert_eq!(
1453 res,
1454 TestStruct {
1455 variant: TestEnum::FirstVariant,
1456 active: false,
1457 }
1458 );
1459 let res: TestStruct = from_key_values("variant=second,active=true").unwrap();
1460 assert_eq!(
1461 res,
1462 TestStruct {
1463 variant: TestEnum::SecondVariant,
1464 active: true,
1465 }
1466 );
1467 let res: TestStruct = from_key_values("active=true,variant=second").unwrap();
1468 assert_eq!(
1469 res,
1470 TestStruct {
1471 variant: TestEnum::SecondVariant,
1472 active: true,
1473 }
1474 );
1475 let res: TestStruct = from_key_values("active,variant=second").unwrap();
1476 assert_eq!(
1477 res,
1478 TestStruct {
1479 variant: TestEnum::SecondVariant,
1480 active: true,
1481 }
1482 );
1483 let res: TestStruct = from_key_values("active=false,variant=second").unwrap();
1484 assert_eq!(
1485 res,
1486 TestStruct {
1487 variant: TestEnum::SecondVariant,
1488 active: false,
1489 }
1490 );
1491 }
1492
1493 #[test]
1494 fn deserialize_untagged_enum() {
1495 #[derive(Deserialize, PartialEq, Debug)]
1496 #[serde(untagged)]
1497 enum TestEnum {
1498 FirstVariant { first: u32 },
1499 SecondVariant { second: bool },
1500 }
1501
1502 #[derive(Deserialize, PartialEq, Debug)]
1503 struct TestStruct {
1504 #[serde(flatten)]
1505 variant: TestEnum,
1506 }
1507
1508 let res: TestStruct = from_key_values("first=10").unwrap();
1509 assert_eq!(res.variant, TestEnum::FirstVariant { first: 10 });
1510
1511 let res: TestStruct = from_key_values("second=false").unwrap();
1512 assert_eq!(res.variant, TestEnum::SecondVariant { second: false },);
1513
1514 let res: TestStruct = from_key_values("second").unwrap();
1515 assert_eq!(res.variant, TestEnum::SecondVariant { second: true },);
1516
1517 from_key_values::<TestStruct>("third=10").unwrap_err();
1518 from_key_values::<TestStruct>("first=some_string").unwrap_err();
1519 from_key_values::<TestStruct>("second=10").unwrap_err();
1520 }
1521
1522 #[test]
1523 fn deserialize_first_arg_string() {
1524 #[derive(Deserialize, PartialEq, Debug)]
1525 struct TestStruct {
1526 name: String,
1527 num: u8,
1528 }
1529 let res: TestStruct = from_key_values("name=foo,num=12").unwrap();
1530 assert_eq!(
1531 res,
1532 TestStruct {
1533 name: "foo".into(),
1534 num: 12,
1535 }
1536 );
1537
1538 let res: TestStruct = from_key_values("foo,num=12").unwrap();
1539 assert_eq!(
1540 res,
1541 TestStruct {
1542 name: "foo".into(),
1543 num: 12,
1544 }
1545 );
1546 }
1547
1548 #[test]
1549 fn deserialize_first_arg_int() {
1550 #[derive(Deserialize, PartialEq, Debug)]
1551 struct TestStruct {
1552 num: u8,
1553 name: String,
1554 }
1555 let res: TestStruct = from_key_values("name=foo,num=12").unwrap();
1556 assert_eq!(
1557 res,
1558 TestStruct {
1559 num: 12,
1560 name: "foo".into(),
1561 }
1562 );
1563
1564 let res: TestStruct = from_key_values("12,name=foo").unwrap();
1565 assert_eq!(
1566 res,
1567 TestStruct {
1568 num: 12,
1569 name: "foo".into(),
1570 }
1571 );
1572 }
1573
1574 #[test]
1575 fn deserialize_tuple() {
1576 #[derive(Deserialize, PartialEq, Debug)]
1577 struct TestStruct {
1578 size: (u32, u32),
1579 }
1580
1581 let res: TestStruct = from_key_values("size=[320,200]").unwrap();
1582 assert_eq!(res, TestStruct { size: (320, 200) });
1583
1584 let err = from_key_values::<TestStruct>("size=[320]").unwrap_err();
1586 assert_eq!(
1587 err,
1588 ParseError {
1589 kind: ErrorKind::SerdeError("invalid length 1, expected a tuple of size 2".into()),
1590 pos: 0,
1591 }
1592 );
1593
1594 let err = from_key_values::<TestStruct>("size=[320,200,255]").unwrap_err();
1596 assert_eq!(
1597 err,
1598 ParseError {
1599 kind: ErrorKind::ExpectedCloseBracket,
1600 pos: 14,
1601 }
1602 );
1603
1604 let err = from_key_values::<TestStruct>("size=[320,200").unwrap_err();
1606 assert_eq!(
1607 err,
1608 ParseError {
1609 kind: ErrorKind::ExpectedCloseBracket,
1610 pos: 13,
1611 }
1612 );
1613 }
1614
1615 #[test]
1616 fn deserialize_vector() {
1617 #[derive(Deserialize, PartialEq, Debug)]
1618 struct TestStruct {
1619 numbers: Vec<u32>,
1620 }
1621
1622 let res: TestStruct = from_key_values("numbers=[1,2,4,8,16,32,64]").unwrap();
1623 assert_eq!(
1624 res,
1625 TestStruct {
1626 numbers: vec![1, 2, 4, 8, 16, 32, 64],
1627 }
1628 );
1629 }
1630
1631 #[test]
1632 fn deserialize_vector_of_strings() {
1633 #[derive(Deserialize, PartialEq, Debug)]
1634 struct TestStruct {
1635 strs: Vec<String>,
1636 }
1637
1638 let res: TestStruct =
1640 from_key_values(r"strs=[singleword,camel_cased,kebab-cased]").unwrap();
1641 assert_eq!(
1642 res,
1643 TestStruct {
1644 strs: vec![
1645 "singleword".into(),
1646 "camel_cased".into(),
1647 "kebab-cased".into()
1648 ],
1649 }
1650 );
1651
1652 let res: TestStruct =
1654 from_key_values(r#"strs=["first string","second string","third string"]"#).unwrap();
1655 assert_eq!(
1656 res,
1657 TestStruct {
1658 strs: vec![
1659 "first string".into(),
1660 "second string".into(),
1661 "third string".into()
1662 ],
1663 }
1664 );
1665
1666 let res: TestStruct =
1668 from_key_values(r#"strs=[unquoted,"quoted string",'quoted with escape "']"#).unwrap();
1669 assert_eq!(
1670 res,
1671 TestStruct {
1672 strs: vec![
1673 "unquoted".into(),
1674 "quoted string".into(),
1675 "quoted with escape \"".into()
1676 ],
1677 }
1678 );
1679 }
1680
1681 #[test]
1682 fn deserialize_vector_of_structs() {
1683 #[derive(Deserialize, PartialEq, Debug)]
1684 #[serde(deny_unknown_fields)]
1685 struct Display {
1686 size: (u32, u32),
1687 #[serde(default)]
1688 disabled: bool,
1689 }
1690
1691 #[derive(Deserialize, PartialEq, Debug)]
1692 #[serde(deny_unknown_fields)]
1693 struct TestStruct {
1694 displays: Vec<Display>,
1695 hostname: Option<String>,
1696 }
1697
1698 let res: TestStruct = from_key_values("displays=[[size=[640,480]]]").unwrap();
1699 assert_eq!(
1700 res,
1701 TestStruct {
1702 displays: vec![Display {
1703 size: (640, 480),
1704 disabled: false,
1705 }],
1706 hostname: None,
1707 }
1708 );
1709
1710 let res: TestStruct =
1711 from_key_values("hostname=crosmatic,displays=[[size=[800,600],disabled]]").unwrap();
1712 assert_eq!(
1713 res,
1714 TestStruct {
1715 displays: vec![Display {
1716 size: (800, 600),
1717 disabled: true,
1718 }],
1719 hostname: Some("crosmatic".to_string()),
1720 }
1721 );
1722
1723 let res: TestStruct =
1725 from_key_values("displays=[[[640,480]],[[800,600],disabled]]").unwrap();
1726 assert_eq!(
1727 res,
1728 TestStruct {
1729 displays: vec![
1730 Display {
1731 size: (640, 480),
1732 disabled: false,
1733 },
1734 Display {
1735 size: (800, 600),
1736 disabled: true,
1737 }
1738 ],
1739 hostname: None,
1740 }
1741 );
1742
1743 let res: TestStruct =
1744 from_key_values("displays=[[[1024,768]],[size=[800,600],disabled]],hostname=crosmatic")
1745 .unwrap();
1746 assert_eq!(
1747 res,
1748 TestStruct {
1749 displays: vec![
1750 Display {
1751 size: (1024, 768),
1752 disabled: false,
1753 },
1754 Display {
1755 size: (800, 600),
1756 disabled: true,
1757 }
1758 ],
1759 hostname: Some("crosmatic".to_string()),
1760 }
1761 );
1762 }
1763
1764 #[test]
1765 fn deserialize_set() {
1766 #[derive(Deserialize, PartialEq, Eq, Debug, PartialOrd, Ord)]
1767 #[serde(rename_all = "kebab-case")]
1768 enum Flags {
1769 Awesome,
1770 Fluffy,
1771 Transparent,
1772 }
1773 #[derive(Deserialize, PartialEq, Debug)]
1774 struct TestStruct {
1775 flags: BTreeSet<Flags>,
1776 }
1777
1778 let res: TestStruct = from_key_values("flags=[awesome,fluffy]").unwrap();
1779 assert_eq!(
1780 res,
1781 TestStruct {
1782 flags: BTreeSet::from([Flags::Awesome, Flags::Fluffy]),
1783 }
1784 );
1785
1786 let err = from_key_values::<TestStruct>("flags=[awesome,spiky]").unwrap_err();
1788 assert_eq!(
1789 err,
1790 ParseError {
1791 kind: ErrorKind::SerdeError(
1792 "unknown variant `spiky`, expected one of `awesome`, `fluffy`, `transparent`"
1793 .into()
1794 ),
1795 pos: 0,
1796 }
1797 );
1798 }
1799
1800 #[test]
1801 fn deserialize_struct_and_tuple_enum() {
1802 #[derive(Deserialize, PartialEq, Debug)]
1803 #[serde(rename_all = "kebab-case")]
1804 enum VideoMode {
1805 Fullscreen,
1806 WindowAsTuple(u32, u32),
1807 WindowAsStruct { width: u32, height: u32 },
1808 }
1809
1810 #[derive(Deserialize, PartialEq, Debug)]
1811 struct TestStruct {
1812 mode: VideoMode,
1813 }
1814
1815 let res: TestStruct = from_key_values("mode=fullscreen").unwrap();
1816 assert_eq!(
1817 res,
1818 TestStruct {
1819 mode: VideoMode::Fullscreen
1820 }
1821 );
1822
1823 let res: TestStruct = from_key_values("mode=window-as-tuple[640,480]").unwrap();
1824 assert_eq!(
1825 res,
1826 TestStruct {
1827 mode: VideoMode::WindowAsTuple(640, 480),
1828 }
1829 );
1830
1831 let err = from_key_values::<TestStruct>("mode=window-as-tuple").unwrap_err();
1833 assert_eq!(
1834 err,
1835 ParseError {
1836 kind: ErrorKind::ExpectedOpenBracket,
1837 pos: 20,
1838 }
1839 );
1840
1841 let res: TestStruct =
1842 from_key_values("mode=window-as-struct[width=800,height=600]").unwrap();
1843 assert_eq!(
1844 res,
1845 TestStruct {
1846 mode: VideoMode::WindowAsStruct {
1847 width: 800,
1848 height: 600,
1849 }
1850 }
1851 );
1852
1853 let err = from_key_values::<TestStruct>("mode=window-as-struct").unwrap_err();
1855 assert_eq!(
1856 err,
1857 ParseError {
1858 kind: ErrorKind::ExpectedOpenBracket,
1859 pos: 21,
1860 }
1861 );
1862 }
1863
1864 #[test]
1865 fn deserialize_struct_enum_with_default() {
1866 #[derive(Deserialize, PartialEq, Debug)]
1867 #[serde(rename_all = "kebab-case")]
1868 enum FlipMode {
1869 Inactive,
1870 Active {
1871 #[serde(default)]
1872 switch1: bool,
1873 #[serde(default)]
1874 switch2: bool,
1875 },
1876 }
1877
1878 #[derive(Deserialize, PartialEq, Debug)]
1879 struct TestStruct {
1880 mode: FlipMode,
1881 }
1882
1883 let res: TestStruct = from_key_values("mode=active[switch1=true]").unwrap();
1885 assert_eq!(
1886 res,
1887 TestStruct {
1888 mode: FlipMode::Active {
1889 switch1: true,
1890 switch2: false
1891 }
1892 }
1893 );
1894
1895 let res: TestStruct = from_key_values("mode=active[switch1,switch2]").unwrap();
1897 assert_eq!(
1898 res,
1899 TestStruct {
1900 mode: FlipMode::Active {
1901 switch1: true,
1902 switch2: true
1903 }
1904 }
1905 );
1906
1907 let res: TestStruct = from_key_values("mode=active[]").unwrap();
1909 assert_eq!(
1910 res,
1911 TestStruct {
1912 mode: FlipMode::Active {
1913 switch1: false,
1914 switch2: false
1915 }
1916 }
1917 );
1918
1919 let res: TestStruct = from_key_values("mode=active").unwrap();
1921 assert_eq!(
1922 res,
1923 TestStruct {
1924 mode: FlipMode::Active {
1925 switch1: false,
1926 switch2: false
1927 }
1928 }
1929 );
1930
1931 let res: TestStruct = from_key_values("mode=inactive").unwrap();
1933 assert_eq!(
1934 res,
1935 TestStruct {
1936 mode: FlipMode::Inactive,
1937 }
1938 );
1939
1940 let err = from_key_values::<TestStruct>("mode=inactive[]").unwrap_err();
1942 assert_eq!(
1943 err,
1944 ParseError {
1945 kind: ErrorKind::ExpectedComma,
1946 pos: 13,
1947 }
1948 );
1949 }
1950}