Skip to content
This repository was archived by the owner on Sep 24, 2022. It is now read-only.

Commit c74293f

Browse files
authored
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
1 parent 940fcf9 commit c74293f

File tree

4 files changed

+41
-13
lines changed

4 files changed

+41
-13
lines changed

src/de.rs

+22-3
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,9 @@ enum ErrorKind {
191191
available: &'static [&'static str],
192192
},
193193

194+
/// Unquoted string was found when quoted one was expected
195+
UnquotedString,
196+
194197
#[doc(hidden)]
195198
__Nonexhaustive,
196199
}
@@ -1428,7 +1431,7 @@ impl<'a> Deserializer<'a> {
14281431
start,
14291432
end,
14301433
},
1431-
Some((span, Token::Keylike(key))) => self.number_or_date(span, key)?,
1434+
Some((span, Token::Keylike(key))) => self.parse_keylike(at, span, key)?,
14321435
Some((span, Token::Plus)) => self.number_leading_plus(span)?,
14331436
Some((Span { start, .. }, Token::LeftBrace)) => {
14341437
self.inline_table().map(|(Span { end, .. }, table)| Value {
@@ -1451,13 +1454,25 @@ impl<'a> Deserializer<'a> {
14511454
expected: "a value",
14521455
found: token.1.describe(),
14531456
},
1454-
))
1457+
));
14551458
}
14561459
None => return Err(self.eof()),
14571460
};
14581461
Ok(value)
14591462
}
14601463

1464+
fn parse_keylike(&mut self, at: usize, span: Span, key: &'a str) -> Result<Value<'a>, Error> {
1465+
if key == "inf" || key == "nan" {
1466+
return self.number_or_date(span, key);
1467+
}
1468+
1469+
let first_char = key.chars().next().expect("key should not be empty here");
1470+
match first_char {
1471+
'-' | '0'..='9' => self.number_or_date(span, key),
1472+
_ => Err(self.error(at, ErrorKind::UnquotedString)),
1473+
}
1474+
}
1475+
14611476
fn number_or_date(&mut self, span: Span, s: &'a str) -> Result<Value<'a>, Error> {
14621477
if s.contains('T')
14631478
|| s.contains('t')
@@ -2076,7 +2091,7 @@ impl std::convert::From<Error> for std::io::Error {
20762091

20772092
impl fmt::Display for Error {
20782093
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2079-
match self.inner.kind {
2094+
match &self.inner.kind {
20802095
ErrorKind::UnexpectedEof => "unexpected eof encountered".fmt(f)?,
20812096
ErrorKind::InvalidCharInString(c) => write!(
20822097
f,
@@ -2131,6 +2146,10 @@ impl fmt::Display for Error {
21312146
"unexpected keys in table: `{:?}`, available keys: `{:?}`",
21322147
keys, available
21332148
)?,
2149+
ErrorKind::UnquotedString => write!(
2150+
f,
2151+
"invalid TOML value, did you mean to use a quoted string?"
2152+
)?,
21342153
ErrorKind::__Nonexhaustive => panic!(),
21352154
}
21362155

test-suite/tests/datetime.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,15 @@ fn bad_times() {
6868
);
6969
bad!(
7070
"foo = T",
71-
"failed to parse datetime for key `foo` at line 1 column 7"
71+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
7272
);
7373
bad!(
7474
"foo = T.",
75-
"expected newline, found a period at line 1 column 8"
75+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
7676
);
7777
bad!(
7878
"foo = TZ",
79-
"failed to parse datetime for key `foo` at line 1 column 7"
79+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
8080
);
8181
bad!(
8282
"foo = 1997-09-09T09:09:09.09+",

test-suite/tests/invalid.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ test!(
197197
test!(
198198
text_after_array_entries,
199199
include_str!("invalid/text-after-array-entries.toml"),
200-
"invalid number at line 2 column 46"
200+
"invalid TOML value, did you mean to use a quoted string? at line 2 column 46"
201201
);
202202
test!(
203203
text_after_integer,
@@ -222,5 +222,5 @@ test!(
222222
test!(
223223
text_in_array,
224224
include_str!("invalid/text-in-array.toml"),
225-
"invalid number at line 3 column 3"
225+
"invalid TOML value, did you mean to use a quoted string? at line 3 column 3"
226226
);

test-suite/tests/parser.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -491,7 +491,10 @@ fn number_underscores() {
491491
fn bad_underscores() {
492492
bad!("foo = 0_", "invalid number at line 1 column 7");
493493
bad!("foo = 0__0", "invalid number at line 1 column 7");
494-
bad!("foo = __0", "invalid number at line 1 column 7");
494+
bad!(
495+
"foo = __0",
496+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
497+
);
495498
bad!("foo = 1_0_", "invalid number at line 1 column 7");
496499
}
497500

@@ -537,14 +540,20 @@ fn booleans() {
537540

538541
bad!(
539542
"foo = true2",
540-
"failed to parse datetime for key `foo` at line 1 column 7"
543+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
544+
);
545+
bad!(
546+
"foo = false2",
547+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
541548
);
542-
bad!("foo = false2", "invalid number at line 1 column 7");
543549
bad!(
544550
"foo = t1",
545-
"failed to parse datetime for key `foo` at line 1 column 7"
551+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
552+
);
553+
bad!(
554+
"foo = f2",
555+
"invalid TOML value, did you mean to use a quoted string? at line 1 column 7"
546556
);
547-
bad!("foo = f2", "invalid number at line 1 column 7");
548557
}
549558

550559
#[test]

0 commit comments

Comments
 (0)