serde_keyvalue_prim/
key_values.rs

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