eva_common/
serde_keyvalue.rs

1// This code is based on the code copyright 2022 The ChromiumOS Authors under a BSD-style license
2
3use 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)]
43/// Different kinds of errors that can be returned by the parser.
44pub 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/// Error that may be thown while parsing a key-values string.
72#[derive(Debug, Error, PartialEq, Eq)]
73pub struct ParseError {
74    /// Detailed error that occurred.
75    pub kind: ErrorKind,
76    /// Index of the error in the input string.
77    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
109/// Returns `true` if `c` is a valid separator character.
110fn is_separator(c: Option<char>) -> bool {
111    matches!(c, Some(',' | ']') | None)
112}
113
114/// Nom parser for valid separators.
115fn 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
133/// Nom parser for valid strings.
134///
135/// A string can be quoted (using single or double quotes) or not. If it is not quoted, the string
136/// is assumed to continue until the next comma, [, or ] character. If it is escaped, it continues
137/// until the next non-escaped quote.
138///
139/// The returned value is a slice into the current input if no characters to unescape were met,
140/// or a fully owned string if we had to unescape some characters.
141fn any_string(s: &str) -> IResult<&str, Cow<str>> {
142    // Double-quoted strings may escape " and \ characters. Since escaped strings are modified,
143    // we need to return an owned `String` instead of just a slice in the input string.
144    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    // Single-quoted strings do not escape characters.
161    let single_quoted = map(
162        delimited(char('\''), alt((is_not(r"'"), tag(""))), char('\'')),
163        Cow::Borrowed,
164    );
165
166    // Unquoted strings end with the next comma or bracket and may not contain a quote or bracket
167    // character or be empty.
168    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
176/// Nom parser for valid positive of negative numbers.
177///
178/// Hexadecimal, octal, and binary values can be specified with the `0x`, `0o` and `0b` prefixes.
179fn any_number<T>(s: &str) -> IResult<&str, T>
180where
181    T: Num<FromStrRadixErr = ParseIntError>,
182{
183    // Parses the number input and returns a tuple including the number itself (with its sign) and
184    // its radix.
185    //
186    // We move this non-generic part into its own function so it doesn't get monomorphized, which
187    // would increase the binary size more than needed.
188    fn parse_number(s: &str) -> IResult<&str, (Cow<str>, u32)> {
189        // Recognizes the sign prefix.
190        let sign = char('-');
191
192        // Recognizes the radix prefix.
193        let radix = alt((
194            value(16, tag("0x")),
195            value(8, tag("0o")),
196            value(2, tag("0b")),
197        ));
198
199        // Recognizes the trailing separator but do not consume it.
200        let separator = peek(any_separator);
201
202        // Chain of parsers: sign (optional) and radix (optional), then sequence of alphanumerical
203        // characters.
204        //
205        // Then we take all 3 recognized elements and turn them into the string and radix to pass to
206        // `from_str_radix`.
207        map(
208            tuple((opt(sign), opt(radix), alphanumeric1, separator)),
209            |(sign, radix, number, _)| {
210                // If the sign was specified, we need to build a string that contains it for
211                // `from_str_radix` to parse the number accurately. Otherwise, simply borrow the
212                // remainder of the input.
213                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
229/// Nom parser for booleans.
230fn 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
236/// Nom parser for identifiers. An identifier may contain any alphanumeric character, as well as
237/// '_' and '-' at any place excepted the first one which cannot be '-'.
238///
239/// Usually identifiers are not allowed to start with a number, but we chose to allow this
240/// here otherwise options like "mode=2d" won't parse if "2d" is an alias for an enum variant.
241fn 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
250/// Serde deserializer for key-values strings.
251pub struct KeyValueDeserializer<'de> {
252    /// Full input originally received for parsing.
253    original_input: &'de str,
254    /// Input currently remaining to parse.
255    input: &'de str,
256    /// If set, then `deserialize_identifier` will take and return its content the next time it is
257    /// called instead of trying to parse an identifier from the input. This is needed to allow the
258    /// name of the first field of a struct to be omitted, e.g.
259    ///
260    ///   --block "/path/to/disk.img,ro=true"
261    ///
262    /// instead of
263    ///
264    ///   --block "path=/path/to/disk.img,ro=true"
265    next_identifier: Option<&'de str>,
266    /// Whether the '=' sign has been parsed after a key. The absence of '=' is only valid for
267    /// boolean fields, in which case the field's value will be `true`.
268    has_equal: bool,
269    /// Whether the top structure has been parsed yet or not. The top structure is the only one that
270    /// does not require to be enclosed within braces.
271    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    /// Return an `kind` error for the current position of the input.
288    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    /// Returns the next char in the input string without consuming it, or None
296    /// if we reached the end of input.
297    pub fn peek_char(&self) -> Option<char> {
298        self.input.chars().next()
299    }
300
301    /// Skip the next char in the input string.
302    pub fn skip_char(&mut self) {
303        let _ = self.next_char();
304    }
305
306    /// Returns the next char in the input string and consume it, or returns
307    /// None if we reached the end of input.
308    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    /// Confirm that we have a separator (i.e. ',' or ']') character or have reached the end of the
315    /// input string.
316    fn confirm_separator(&mut self) -> Result<()> {
317        // We must have a comma or end of input after a value.
318        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    /// Attempts to parse an identifier, either for a key or for the value of an enum type.
329    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    /// Attempts to parse a string.
339    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                    // Any error means we did not have a well-formed string.
346                    self.error_here(ErrorKind::ExpectedString)
347                })?;
348
349        self.input = remainder;
350
351        // The character following a string will be either a comma, a closing bracket, or EOS. If
352        // we have something else, this means an unquoted string should probably have been quoted.
353        if is_separator(self.peek_char()) {
354            Ok(res)
355        } else {
356            Err(self.error_here(ErrorKind::InvalidCharInString))
357        }
358    }
359
360    /// Attempt to parse a boolean.
361    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    /// Attempt to parse a positive or negative number.
375    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    /// Consume this deserializer and return a `TrailingCharacters` error if some input was
388    /// remaining.
389    ///
390    /// This is useful to confirm that the whole input has been consumed without any extra elements.
391    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        // Detect end of input or struct.
408        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        // We just "deserialized" the content of `next_identifier`, so there should be no equal
418        // character in the input. We can return now.
419        if had_implicit_identifier {
420            self.has_equal = true;
421            return Ok(val);
422        }
423
424        match self.peek_char() {
425            // We expect an equal after an identifier.
426            Some('=') => {
427                self.skip_char();
428                self.has_equal = true;
429                Ok(val)
430            }
431            // Ok if we are parsing a boolean where an empty value means true.
432            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
449/// `MapAccess` for a map with no members specified.
450///
451/// This is used to allow a struct enum type to be specified without `[` and `]`, in which case
452/// all its members will take their default value:
453///
454/// ```
455/// # use eva_common::serde_keyvalue::from_key_values;
456/// # use serde::Deserialize;
457/// #[derive(Deserialize, PartialEq, Eq, Debug)]
458/// #[serde(rename_all = "kebab-case")]
459/// enum FlipMode {
460///     Active {
461///         #[serde(default)]
462///         switch1: bool,
463///         #[serde(default)]
464///         switch2: bool,
465///     },
466/// }
467/// #[derive(Deserialize, PartialEq, Eq, Debug)]
468/// struct TestStruct {
469///     mode: FlipMode,
470/// }
471/// let res: TestStruct = from_key_values("mode=active").unwrap();
472/// assert_eq!(
473///     res,
474///     TestStruct {
475///         mode: FlipMode::Active {
476///             switch1: false,
477///             switch2: false
478///         }
479///     }
480///  );
481/// ```
482struct 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        // Never reached because `next_key_seed` never returns a valid key.
499        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            // The `EmptyMapAccess` failing to parse means that this enum must take arguments, i.e.
553            // that an opening bracket is expected.
554            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            // If we have no value following, then we are dealing with a boolean flag.
589            c if is_separator(c) => return self.deserialize_bool(visitor),
590            // Opening bracket means we have a sequence.
591            Some('[') => return self.deserialize_seq(visitor),
592            _ => (),
593        }
594
595        // This is ambiguous as technically any argument could be an unquoted string. However we
596        // don't have any type information here, so try to guess it on a best-effort basis...
597        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        // It is valid to just mention a bool as a flag and not specify its value - in this case
613        // the value is set as `true`.
614        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        // The fact that an option is specified implies that is exists, hence we always visit
738        // Some() here.
739        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            // The `EmptyMapAccess` failing to parse means that this sequence must take arguments,
779            // i.e. that an opening bracket is expected.
780            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        // The top structure (i.e. the first structure that we will ever parse) does not need to be
810        // enclosed in braces, but inner structures do.
811        //
812        // We need to do this here as well as in `deserialize_struct` because the top-element of
813        // flattened structs will be a map, not a struct.
814        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        // The top structure (i.e. the first structure that we will ever parse) does not need to be
829        // enclosed in braces, but inner structures do.
830        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                // The `EmptyMapAccess` failing to parse means that this struct must take
837                // arguments, i.e. that an opening bracket is expected.
838                return visitor
839                    .visit_map(EmptyMapAccess)
840                    .map_err(|_| self.error_here(ErrorKind::ExpectedOpenBracket));
841            }
842        }
843
844        // The name of the first field of a struct can be omitted (see documentation of
845        // `next_identifier` for details).
846        //
847        // To detect this, peek the next identifier, and check if the character following is '='. If
848        // it is not, then we may have a value in first position, unless the value is identical to
849        // one of the field's name - in this case, assume this is a boolean using the flag syntax.
850        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            // Not an identifier, probably means this is a value for the first field then.
862            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
910/// Attempts to deserialize `T` from the key-values string `input`.
911pub 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        // Parsing a signed into an unsigned?
962        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        // Value too big for a signed?
972        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        // Not a number.
983        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        // Parsing hex values
993        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        // Hex value outside range
1001        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        // Parsing octal values
1011        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        // Octal value outside range
1017        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        // Parsing binary values
1027        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        // Binary value outside range
1033        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        // Spaces are valid (but not recommended) in unquoted strings.
1050        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        // Empty string is not valid if unquoted
1055        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        // Quoted strings.
1066        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        // Empty quoted strings.
1074        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        // "=", ",", "[", "]" and "'" in quote.
1082        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        // Quotes in unquoted strings are forbidden.
1087        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        // Brackets in unquoted strings are forbidden.
1107        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        // Numbers and booleans are technically valid strings.
1118        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        // Escaped quote.
1126        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        // Escaped slash at end of string.
1131        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        // Characters within single quotes should not be escaped.
1136        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        // Braces specified at top-level.
1226        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        // Specify member explicitly
1283        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        // No member specified, braces present.
1293        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        // No member specified, no braces.
1303        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        // No member specified, no braces, no equal sign.
1313        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        // No closing brace.
1323        let kv = "flag=[";
1324        assert!(from_key_values::<TestStruct>(kv).is_err());
1325
1326        // No opening brace.
1327        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        // Everything specified.
1354        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        // Flag left to default value.
1368        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        // Flattened default value unspecified.
1382        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        // No optional, no default value.
1396        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        // Required member unspecified.
1410        let kv = "b=foomatic,flag=[param=24]";
1411        assert!(from_key_values::<TestStruct>(kv).is_err());
1412
1413        // Braces specified at top-level.
1414        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        // Unterminated tuple.
1585        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        // Too many elements in tuple.
1595        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        // Non-closed sequence is invalid.
1605        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        // Unquoted strings
1639        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        // All quoted strings
1653        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        // Mix
1667        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        // First field of a struct does not need to be named even if it is not the top-level struct.
1724        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        // Unknown enum variant?
1787        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        // Missing values
1832        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        // Missing values.
1854        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        // Only specify one member and expect the other to be default.
1884        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        // Specify boolean members without explicit value.
1896        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        // No member specified, braces present.
1908        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        // No member specified and no braces.
1920        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        // Non-struct variant should be recognized without braces.
1932        let res: TestStruct = from_key_values("mode=inactive").unwrap();
1933        assert_eq!(
1934            res,
1935            TestStruct {
1936                mode: FlipMode::Inactive,
1937            }
1938        );
1939
1940        // Non-struct variant should not accept braces.
1941        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}