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
This commit is contained in:
parent
af05f537d8
commit
39dcf1384c
25
src/de.rs
25
src/de.rs
|
@ -191,6 +191,9 @@ enum ErrorKind {
|
||||||
available: &'static [&'static str],
|
available: &'static [&'static str],
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// Unquoted string was found when quoted one was expected
|
||||||
|
UnquotedString,
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
__Nonexhaustive,
|
__Nonexhaustive,
|
||||||
}
|
}
|
||||||
|
@ -1428,7 +1431,7 @@ impl<'a> Deserializer<'a> {
|
||||||
start,
|
start,
|
||||||
end,
|
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, Token::Plus)) => self.number_leading_plus(span)?,
|
||||||
Some((Span { start, .. }, Token::LeftBrace)) => {
|
Some((Span { start, .. }, Token::LeftBrace)) => {
|
||||||
self.inline_table().map(|(Span { end, .. }, table)| Value {
|
self.inline_table().map(|(Span { end, .. }, table)| Value {
|
||||||
|
@ -1451,13 +1454,25 @@ impl<'a> Deserializer<'a> {
|
||||||
expected: "a value",
|
expected: "a value",
|
||||||
found: token.1.describe(),
|
found: token.1.describe(),
|
||||||
},
|
},
|
||||||
))
|
));
|
||||||
}
|
}
|
||||||
None => return Err(self.eof()),
|
None => return Err(self.eof()),
|
||||||
};
|
};
|
||||||
Ok(value)
|
Ok(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_keylike(&mut self, at: usize, span: Span, key: &'a str) -> Result<Value<'a>, 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<Value<'a>, Error> {
|
fn number_or_date(&mut self, span: Span, s: &'a str) -> Result<Value<'a>, Error> {
|
||||||
if s.contains('T')
|
if s.contains('T')
|
||||||
|| s.contains('t')
|
|| s.contains('t')
|
||||||
|
@ -2076,7 +2091,7 @@ impl std::convert::From<Error> for std::io::Error {
|
||||||
|
|
||||||
impl fmt::Display for Error {
|
impl fmt::Display for Error {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
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::UnexpectedEof => "unexpected eof encountered".fmt(f)?,
|
||||||
ErrorKind::InvalidCharInString(c) => write!(
|
ErrorKind::InvalidCharInString(c) => write!(
|
||||||
f,
|
f,
|
||||||
|
@ -2131,6 +2146,10 @@ impl fmt::Display for Error {
|
||||||
"unexpected keys in table: `{:?}`, available keys: `{:?}`",
|
"unexpected keys in table: `{:?}`, available keys: `{:?}`",
|
||||||
keys, available
|
keys, available
|
||||||
)?,
|
)?,
|
||||||
|
ErrorKind::UnquotedString => write!(
|
||||||
|
f,
|
||||||
|
"invalid TOML value, did you mean to use a quoted string?"
|
||||||
|
)?,
|
||||||
ErrorKind::__Nonexhaustive => panic!(),
|
ErrorKind::__Nonexhaustive => panic!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,15 +68,15 @@ fn bad_times() {
|
||||||
);
|
);
|
||||||
bad!(
|
bad!(
|
||||||
"foo = T",
|
"foo = T",
|
||||||
"failed to parse datetime for key `foo` at line 1 column 7"
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
);
|
);
|
||||||
bad!(
|
bad!(
|
||||||
"foo = T.",
|
"foo = T.",
|
||||||
"expected newline, found a period at line 1 column 8"
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
);
|
);
|
||||||
bad!(
|
bad!(
|
||||||
"foo = TZ",
|
"foo = TZ",
|
||||||
"failed to parse datetime for key `foo` at line 1 column 7"
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
);
|
);
|
||||||
bad!(
|
bad!(
|
||||||
"foo = 1997-09-09T09:09:09.09+",
|
"foo = 1997-09-09T09:09:09.09+",
|
||||||
|
|
|
@ -197,7 +197,7 @@ test!(
|
||||||
test!(
|
test!(
|
||||||
text_after_array_entries,
|
text_after_array_entries,
|
||||||
include_str!("invalid/text-after-array-entries.toml"),
|
include_str!("invalid/text-after-array-entries.toml"),
|
||||||
"invalid number at line 2 column 46"
|
"invalid TOML value, did you mean to use a quoted string? at line 2 column 46"
|
||||||
);
|
);
|
||||||
test!(
|
test!(
|
||||||
text_after_integer,
|
text_after_integer,
|
||||||
|
@ -222,5 +222,5 @@ test!(
|
||||||
test!(
|
test!(
|
||||||
text_in_array,
|
text_in_array,
|
||||||
include_str!("invalid/text-in-array.toml"),
|
include_str!("invalid/text-in-array.toml"),
|
||||||
"invalid number at line 3 column 3"
|
"invalid TOML value, did you mean to use a quoted string? at line 3 column 3"
|
||||||
);
|
);
|
||||||
|
|
|
@ -491,7 +491,10 @@ fn number_underscores() {
|
||||||
fn bad_underscores() {
|
fn bad_underscores() {
|
||||||
bad!("foo = 0_", "invalid number at line 1 column 7");
|
bad!("foo = 0_", "invalid number at line 1 column 7");
|
||||||
bad!("foo = 0__0", "invalid number at line 1 column 7");
|
bad!("foo = 0__0", "invalid number at line 1 column 7");
|
||||||
bad!("foo = __0", "invalid number at line 1 column 7");
|
bad!(
|
||||||
|
"foo = __0",
|
||||||
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
|
);
|
||||||
bad!("foo = 1_0_", "invalid number at line 1 column 7");
|
bad!("foo = 1_0_", "invalid number at line 1 column 7");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,14 +540,20 @@ fn booleans() {
|
||||||
|
|
||||||
bad!(
|
bad!(
|
||||||
"foo = true2",
|
"foo = true2",
|
||||||
"failed to parse datetime for key `foo` at line 1 column 7"
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
|
);
|
||||||
|
bad!(
|
||||||
|
"foo = false2",
|
||||||
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
);
|
);
|
||||||
bad!("foo = false2", "invalid number at line 1 column 7");
|
|
||||||
bad!(
|
bad!(
|
||||||
"foo = t1",
|
"foo = t1",
|
||||||
"failed to parse datetime for key `foo` at line 1 column 7"
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
|
);
|
||||||
|
bad!(
|
||||||
|
"foo = f2",
|
||||||
|
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
|
||||||
);
|
);
|
||||||
bad!("foo = f2", "invalid number at line 1 column 7");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
Loading…
Reference in a new issue