From c74293f7a87cea3ce60a4df1c905501d4b749067 Mon Sep 17 00:00:00 2001 From: Alex Tokarev Date: Sun, 11 Oct 2020 20:30:55 +0300 Subject: Improve error message when parsing unquoted string (#385) * Improve error message when parsing unquoted string * Remove conversion to lowercase in parse_keylike() Converting keys to lowercase goes against TOML specification for floats. * Change error message for unquoted string --- src/de.rs | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/de.rs b/src/de.rs index 6c18ae3..6411293 100644 --- a/src/de.rs +++ b/src/de.rs @@ -191,6 +191,9 @@ enum ErrorKind { available: &'static [&'static str], }, + /// Unquoted string was found when quoted one was expected + UnquotedString, + #[doc(hidden)] __Nonexhaustive, } @@ -1428,7 +1431,7 @@ impl<'a> Deserializer<'a> { start, end, }, - Some((span, Token::Keylike(key))) => self.number_or_date(span, key)?, + Some((span, Token::Keylike(key))) => self.parse_keylike(at, span, key)?, Some((span, Token::Plus)) => self.number_leading_plus(span)?, Some((Span { start, .. }, Token::LeftBrace)) => { self.inline_table().map(|(Span { end, .. }, table)| Value { @@ -1451,13 +1454,25 @@ impl<'a> Deserializer<'a> { expected: "a value", found: token.1.describe(), }, - )) + )); } None => return Err(self.eof()), }; Ok(value) } + fn parse_keylike(&mut self, at: usize, span: Span, key: &'a str) -> Result, Error> { + if key == "inf" || key == "nan" { + return self.number_or_date(span, key); + } + + let first_char = key.chars().next().expect("key should not be empty here"); + match first_char { + '-' | '0'..='9' => self.number_or_date(span, key), + _ => Err(self.error(at, ErrorKind::UnquotedString)), + } + } + fn number_or_date(&mut self, span: Span, s: &'a str) -> Result, Error> { if s.contains('T') || s.contains('t') @@ -2076,7 +2091,7 @@ impl std::convert::From for std::io::Error { impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - match self.inner.kind { + match &self.inner.kind { ErrorKind::UnexpectedEof => "unexpected eof encountered".fmt(f)?, ErrorKind::InvalidCharInString(c) => write!( f, @@ -2131,6 +2146,10 @@ impl fmt::Display for Error { "unexpected keys in table: `{:?}`, available keys: `{:?}`", keys, available )?, + ErrorKind::UnquotedString => write!( + f, + "invalid TOML value, did you mean to use a quoted string?" + )?, ErrorKind::__Nonexhaustive => panic!(), } -- cgit v1.2.3