aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Tokarev <aleksator@gmail.com>2020-10-11 20:30:55 +0300
committerGitHub <noreply@github.com>2020-10-11 12:30:55 -0500
commitc74293f7a87cea3ce60a4df1c905501d4b749067 (patch)
tree60b020ad5cd7ce36bcd90e6660b8ba2a6a3b0d45
parent940fcf9e183ab4f29204ef4f3ea92c01de8cc08a (diff)
downloadmilf-rs-c74293f7a87cea3ce60a4df1c905501d4b749067.tar.gz
milf-rs-c74293f7a87cea3ce60a4df1c905501d4b749067.zip
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
-rw-r--r--src/de.rs25
-rw-r--r--test-suite/tests/datetime.rs6
-rw-r--r--test-suite/tests/invalid.rs4
-rw-r--r--test-suite/tests/parser.rs19
4 files changed, 41 insertions, 13 deletions
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<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> {
if s.contains('T')
|| s.contains('t')
@@ -2076,7 +2091,7 @@ impl std::convert::From<Error> 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!(),
}
diff --git a/test-suite/tests/datetime.rs b/test-suite/tests/datetime.rs
index 74b5939..6c08748 100644
--- a/test-suite/tests/datetime.rs
+++ b/test-suite/tests/datetime.rs
@@ -68,15 +68,15 @@ fn bad_times() {
);
bad!(
"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!(
"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!(
"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!(
"foo = 1997-09-09T09:09:09.09+",
diff --git a/test-suite/tests/invalid.rs b/test-suite/tests/invalid.rs
index ccc9338..f04d860 100644
--- a/test-suite/tests/invalid.rs
+++ b/test-suite/tests/invalid.rs
@@ -197,7 +197,7 @@ test!(
test!(
text_after_array_entries,
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!(
text_after_integer,
@@ -222,5 +222,5 @@ test!(
test!(
text_in_array,
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"
);
diff --git a/test-suite/tests/parser.rs b/test-suite/tests/parser.rs
index eab9f5a..169df79 100644
--- a/test-suite/tests/parser.rs
+++ b/test-suite/tests/parser.rs
@@ -491,7 +491,10 @@ fn number_underscores() {
fn bad_underscores() {
bad!("foo = 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");
}
@@ -537,14 +540,20 @@ fn booleans() {
bad!(
"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!(
"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]