Skip to content

Commit 1509d87

Browse files
committed
Split out peek logic from seed generic
1 parent 62839b7 commit 1509d87

File tree

2 files changed

+51
-63
lines changed

2 files changed

+51
-63
lines changed

src/de.rs

Lines changed: 45 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,13 @@ impl ParserNumber {
133133
}
134134
}
135135

136+
enum PeekResult {
137+
Char(u8),
138+
EndOfSeq,
139+
EofSeq,
140+
Eof,
141+
}
142+
136143
impl<'de, R: Read<'de>> Deserializer<R> {
137144
/// The `Deserializer::end` method should be called after a value has been fully deserialized.
138145
/// This allows the `Deserializer` to validate that the input stream is at the end or that it
@@ -259,6 +266,28 @@ impl<'de, R: Read<'de>> Deserializer<R> {
259266
}
260267
}
261268

269+
fn peek_next_elem<const END: u8>(&mut self, first: &mut bool) -> Result<PeekResult> {
270+
match tri!(self.parse_whitespace()) {
271+
Some(c) if c == END => Ok(PeekResult::EndOfSeq),
272+
Some(b',') if !*first => {
273+
self.eat_char();
274+
self.parse_whitespace().map(|c| match c {
275+
Some(c) => PeekResult::Char(c),
276+
None => PeekResult::Eof,
277+
})
278+
}
279+
Some(b) => {
280+
if *first {
281+
*first = false;
282+
Ok(PeekResult::Char(b))
283+
} else {
284+
Err(self.peek_error(ErrorCode::ExpectedNextOrEnd { end: END }))
285+
}
286+
}
287+
None => Ok(PeekResult::EofSeq),
288+
}
289+
}
290+
262291
#[cold]
263292
fn peek_invalid_type(&mut self, exp: &dyn Expected) -> Error {
264293
let err = match self.peek_or_null().unwrap_or(b'\x00') {
@@ -1163,8 +1192,8 @@ impl<'de, R: Read<'de>> Deserializer<R> {
11631192
Some(_) => {
11641193
if accept_comma {
11651194
return Err(self.peek_error(match frame {
1166-
b'[' => ErrorCode::ExpectedListCommaOrEnd,
1167-
b'{' => ErrorCode::ExpectedObjectCommaOrEnd,
1195+
b'[' => ErrorCode::ExpectedNextOrEnd { end: b'[' },
1196+
b'{' => ErrorCode::ExpectedNextOrEnd { end: b'{' },
11681197
_ => unreachable!(),
11691198
}));
11701199
} else {
@@ -1909,7 +1938,7 @@ struct SeqAccess<'a, R: 'a> {
19091938
first: bool,
19101939
}
19111940

1912-
impl<'a, R: 'a> SeqAccess<'a, R> {
1941+
impl<'de, 'a, R: Read<'de> + 'a> SeqAccess<'a, R> {
19131942
fn new(de: &'a mut Deserializer<R>) -> Self {
19141943
SeqAccess { de, first: true }
19151944
}
@@ -1922,31 +1951,12 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
19221951
where
19231952
T: de::DeserializeSeed<'de>,
19241953
{
1925-
let peek = match tri!(self.de.parse_whitespace()) {
1926-
Some(b']') => {
1927-
return Ok(None);
1928-
}
1929-
Some(b',') if !self.first => {
1930-
self.de.eat_char();
1931-
tri!(self.de.parse_whitespace())
1932-
}
1933-
Some(b) => {
1934-
if self.first {
1935-
self.first = false;
1936-
Some(b)
1937-
} else {
1938-
return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd));
1939-
}
1940-
}
1941-
None => {
1942-
return Err(self.de.peek_error(ErrorCode::EofWhileParsingList));
1943-
}
1944-
};
1945-
1946-
match peek {
1947-
Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
1948-
Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))),
1949-
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
1954+
match tri!(self.de.peek_next_elem::<b']'>(&mut self.first)) {
1955+
PeekResult::EndOfSeq => Ok(None),
1956+
PeekResult::Char(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
1957+
PeekResult::Char(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))),
1958+
PeekResult::Eof => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
1959+
PeekResult::EofSeq => Err(self.de.peek_error(ErrorCode::EofWhileParsingList)),
19501960
}
19511961
}
19521962
}
@@ -1969,32 +1979,13 @@ impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> {
19691979
where
19701980
K: de::DeserializeSeed<'de>,
19711981
{
1972-
let peek = match tri!(self.de.parse_whitespace()) {
1973-
Some(b'}') => {
1974-
return Ok(None);
1975-
}
1976-
Some(b',') if !self.first => {
1977-
self.de.eat_char();
1978-
tri!(self.de.parse_whitespace())
1979-
}
1980-
Some(b) => {
1981-
if self.first {
1982-
self.first = false;
1983-
Some(b)
1984-
} else {
1985-
return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd));
1986-
}
1987-
}
1988-
None => {
1989-
return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject));
1990-
}
1991-
};
1992-
1993-
match peek {
1994-
Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
1995-
Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
1996-
Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)),
1997-
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
1982+
match tri!(self.de.peek_next_elem::<b'}'>(&mut self.first)) {
1983+
PeekResult::EndOfSeq => Ok(None),
1984+
PeekResult::Char(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
1985+
PeekResult::Char(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
1986+
PeekResult::Char(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)),
1987+
PeekResult::Eof => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
1988+
PeekResult::EofSeq => Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)),
19981989
}
19991990
}
20001991

src/error.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@ impl Error {
6060
| ErrorCode::EofWhileParsingString
6161
| ErrorCode::EofWhileParsingValue => Category::Eof,
6262
ErrorCode::ExpectedColon
63-
| ErrorCode::ExpectedListCommaOrEnd
64-
| ErrorCode::ExpectedObjectCommaOrEnd
63+
| ErrorCode::ExpectedNextOrEnd { .. }
6564
| ErrorCode::ExpectedSomeIdent
6665
| ErrorCode::ExpectedSomeValue
6766
| ErrorCode::ExpectedDoubleQuote
@@ -255,11 +254,8 @@ pub(crate) enum ErrorCode {
255254
/// Expected this character to be a `':'`.
256255
ExpectedColon,
257256

258-
/// Expected this character to be either a `','` or a `']'`.
259-
ExpectedListCommaOrEnd,
260-
261-
/// Expected this character to be either a `','` or a `'}'`.
262-
ExpectedObjectCommaOrEnd,
257+
/// Expected this character to be either ',' or end.
258+
ExpectedNextOrEnd { end: u8 },
263259

264260
/// Expected to parse either a `true`, `false`, or a `null`.
265261
ExpectedSomeIdent,
@@ -356,8 +352,9 @@ impl Display for ErrorCode {
356352
ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"),
357353
ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"),
358354
ErrorCode::ExpectedColon => f.write_str("expected `:`"),
359-
ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"),
360-
ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"),
355+
ErrorCode::ExpectedNextOrEnd { end } => {
356+
write!(f, "expected `,` or `{}`", *end as char)
357+
}
361358
ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"),
362359
ErrorCode::ExpectedSomeValue => f.write_str("expected value"),
363360
ErrorCode::ExpectedDoubleQuote => f.write_str("expected `\"`"),

0 commit comments

Comments
 (0)