Skip to content

Commit a074160

Browse files
committed
Improve error messages when deserializing enums
1 parent 0903de4 commit a074160

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

src/de.rs

+10-4
Original file line numberDiff line numberDiff line change
@@ -1873,7 +1873,14 @@ impl<'de, R: Read<'de>> de::Deserializer<'de> for &mut Deserializer<R> {
18731873
Some(b'{') => {
18741874
check_recursion! {
18751875
self.eat_char();
1876-
let ret = visitor.visit_enum(VariantAccess::new(self));
1876+
let ret = match tri!(self.parse_whitespace()) {
1877+
Some(b'}') => Err(self.fix_position(de::Error::invalid_value(
1878+
Unexpected::Other("empty map"),
1879+
&"enum variant",
1880+
))),
1881+
Some(_) => visitor.visit_enum(VariantAccess::new(self)),
1882+
None => Err(self.error(ErrorCode::EofWhileParsingObject)),
1883+
};
18771884
}
18781885
let value = tri!(ret);
18791886

@@ -1882,12 +1889,11 @@ impl<'de, R: Read<'de>> de::Deserializer<'de> for &mut Deserializer<R> {
18821889
self.eat_char();
18831890
Ok(value)
18841891
}
1885-
Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)),
1892+
Some(_) => Err(self.error(ErrorCode::ExpectedObjectCommaOrEnd)),
18861893
None => Err(self.error(ErrorCode::EofWhileParsingObject)),
18871894
}
18881895
}
1889-
Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)),
1890-
Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)),
1896+
Some(_) => visitor.visit_enum(UnitVariantAccess::new(self)),
18911897
None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
18921898
}
18931899
}

tests/test.rs

+41-2
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,12 @@ enum Animal {
7070
AntHive(Vec<String>),
7171
}
7272

73+
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
74+
enum BoardGame {
75+
Chess,
76+
Checkers,
77+
}
78+
7379
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
7480
struct Inner {
7581
a: (),
@@ -1304,12 +1310,14 @@ fn test_parse_option() {
13041310
fn test_parse_enum_errors() {
13051311
test_parse_err::<Animal>(
13061312
&[
1307-
("{}", "expected value at line 1 column 2"),
1308-
("[]", "expected value at line 1 column 1"),
1313+
("{}", "invalid value: empty map, expected enum variant at line 1 column 1"),
1314+
("[]", "invalid type: sequence, expected variant identifier at line 1 column 0"),
13091315
("\"unknown\"",
13101316
"unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 9"),
13111317
("{\"unknown\":null}",
13121318
"unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 10"),
1319+
("{\"AntHive\": []", "EOF while parsing an object at line 1 column 14"),
1320+
("{\"AntHive\": []\"", "expected `,` or `}` at line 1 column 14"),
13131321
("{\"Dog\":", "EOF while parsing a value at line 1 column 7"),
13141322
("{\"Dog\":}", "expected value at line 1 column 8"),
13151323
("{\"Dog\":{}}", "invalid type: map, expected unit at line 1 column 7"),
@@ -1331,6 +1339,37 @@ fn test_parse_enum_errors() {
13311339
);
13321340
}
13331341

1342+
#[test]
1343+
fn test_parse_value_less_enum_errors() {
1344+
test_parse_err::<BoardGame>(&[
1345+
(
1346+
"1",
1347+
"invalid type: integer `1`, expected variant identifier at line 1 column 1",
1348+
),
1349+
(
1350+
"null",
1351+
"invalid type: null, expected variant identifier at line 1 column 4",
1352+
),
1353+
(
1354+
"true",
1355+
"invalid type: boolean `true`, expected variant identifier at line 1 column 4",
1356+
),
1357+
(
1358+
"[]",
1359+
"invalid type: sequence, expected variant identifier at line 1 column 0",
1360+
),
1361+
("{}", "invalid value: empty map, expected enum variant"),
1362+
(
1363+
"{\"unknown\": \"unknown\"}",
1364+
"unknown variant `unknown`, expected `Chess` or `Checkers` at line 1 column 10",
1365+
),
1366+
(
1367+
"{\"Chess\": \"unknown\"}",
1368+
"invalid type: string \"unknown\", expected unit at line 1 column 19",
1369+
),
1370+
]);
1371+
}
1372+
13341373
#[test]
13351374
fn test_parse_enum() {
13361375
test_parse_ok(vec![

0 commit comments

Comments
 (0)