Merge pull request #1205 from dtolnay/hasnext

Reduce duplicative instantiation of logic in SeqAccess and MapAccess
This commit is contained in:
David Tolnay 2024-10-19 09:20:49 -07:00 committed by GitHub
commit 4cb90ce66d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -1926,31 +1926,41 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
let peek = match tri!(self.de.parse_whitespace()) { fn has_next_element<'de, 'a, R: Read<'de> + 'a>(
seq: &mut SeqAccess<'a, R>,
) -> Result<bool> {
let peek = match tri!(seq.de.parse_whitespace()) {
Some(b']') => { Some(b']') => {
return Ok(None); return Ok(false);
} }
Some(b',') if !self.first => { Some(b',') if !seq.first => {
self.de.eat_char(); seq.de.eat_char();
tri!(self.de.parse_whitespace()) tri!(seq.de.parse_whitespace())
} }
Some(b) => { Some(b) => {
if self.first { if seq.first {
self.first = false; seq.first = false;
Some(b) Some(b)
} else { } else {
return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); return Err(seq.de.peek_error(ErrorCode::ExpectedListCommaOrEnd));
} }
} }
None => { None => {
return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); return Err(seq.de.peek_error(ErrorCode::EofWhileParsingList));
} }
}; };
match peek { match peek {
Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)), Some(b']') => Err(seq.de.peek_error(ErrorCode::TrailingComma)),
Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))), Some(_) => Ok(true),
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), None => Err(seq.de.peek_error(ErrorCode::EofWhileParsingValue)),
}
}
if tri!(has_next_element(self)) {
Ok(Some(tri!(seed.deserialize(&mut *self.de))))
} else {
Ok(None)
} }
} }
} }
@ -1973,32 +1983,40 @@ impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> {
where where
K: de::DeserializeSeed<'de>, K: de::DeserializeSeed<'de>,
{ {
let peek = match tri!(self.de.parse_whitespace()) { fn has_next_key<'de, 'a, R: Read<'de> + 'a>(map: &mut MapAccess<'a, R>) -> Result<bool> {
let peek = match tri!(map.de.parse_whitespace()) {
Some(b'}') => { Some(b'}') => {
return Ok(None); return Ok(false);
} }
Some(b',') if !self.first => { Some(b',') if !map.first => {
self.de.eat_char(); map.de.eat_char();
tri!(self.de.parse_whitespace()) tri!(map.de.parse_whitespace())
} }
Some(b) => { Some(b) => {
if self.first { if map.first {
self.first = false; map.first = false;
Some(b) Some(b)
} else { } else {
return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); return Err(map.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd));
} }
} }
None => { None => {
return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)); return Err(map.de.peek_error(ErrorCode::EofWhileParsingObject));
} }
}; };
match peek { match peek {
Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some), Some(b'"') => Ok(true),
Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)), Some(b'}') => Err(map.de.peek_error(ErrorCode::TrailingComma)),
Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)), Some(_) => Err(map.de.peek_error(ErrorCode::KeyMustBeAString)),
None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), None => Err(map.de.peek_error(ErrorCode::EofWhileParsingValue)),
}
}
if tri!(has_next_key(self)) {
Ok(Some(tri!(seed.deserialize(MapKey { de: &mut *self.de }))))
} else {
Ok(None)
} }
} }