From b71ccd2d8f6aabaa0ac6cb889f8e18989038d968 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sat, 19 Oct 2024 08:50:31 -0700 Subject: [PATCH] Reduce duplicative instantiation of logic in SeqAccess and MapAccess --- src/de.rs | 108 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 45 deletions(-) diff --git a/src/de.rs b/src/de.rs index 7959a6635..d6cb502da 100644 --- a/src/de.rs +++ b/src/de.rs @@ -1926,31 +1926,41 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> { where T: de::DeserializeSeed<'de>, { - let peek = match tri!(self.de.parse_whitespace()) { - Some(b']') => { - return Ok(None); - } - Some(b',') if !self.first => { - self.de.eat_char(); - tri!(self.de.parse_whitespace()) - } - Some(b) => { - if self.first { - self.first = false; - Some(b) - } else { - return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); + fn has_next_element<'de, 'a, R: Read<'de> + 'a>( + seq: &mut SeqAccess<'a, R>, + ) -> Result { + let peek = match tri!(seq.de.parse_whitespace()) { + Some(b']') => { + return Ok(false); } + Some(b',') if !seq.first => { + seq.de.eat_char(); + tri!(seq.de.parse_whitespace()) + } + Some(b) => { + if seq.first { + seq.first = false; + Some(b) + } else { + return Err(seq.de.peek_error(ErrorCode::ExpectedListCommaOrEnd)); + } + } + None => { + return Err(seq.de.peek_error(ErrorCode::EofWhileParsingList)); + } + }; + + match peek { + Some(b']') => Err(seq.de.peek_error(ErrorCode::TrailingComma)), + Some(_) => Ok(true), + None => Err(seq.de.peek_error(ErrorCode::EofWhileParsingValue)), } - None => { - return Err(self.de.peek_error(ErrorCode::EofWhileParsingList)); - } - }; + } - match peek { - Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)), - Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))), - None => Err(self.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 K: de::DeserializeSeed<'de>, { - let peek = match tri!(self.de.parse_whitespace()) { - Some(b'}') => { - return Ok(None); - } - Some(b',') if !self.first => { - self.de.eat_char(); - tri!(self.de.parse_whitespace()) - } - Some(b) => { - if self.first { - self.first = false; - Some(b) - } else { - return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); + fn has_next_key<'de, 'a, R: Read<'de> + 'a>(map: &mut MapAccess<'a, R>) -> Result { + let peek = match tri!(map.de.parse_whitespace()) { + Some(b'}') => { + return Ok(false); } + Some(b',') if !map.first => { + map.de.eat_char(); + tri!(map.de.parse_whitespace()) + } + Some(b) => { + if map.first { + map.first = false; + Some(b) + } else { + return Err(map.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd)); + } + } + None => { + return Err(map.de.peek_error(ErrorCode::EofWhileParsingObject)); + } + }; + + match peek { + Some(b'"') => Ok(true), + Some(b'}') => Err(map.de.peek_error(ErrorCode::TrailingComma)), + Some(_) => Err(map.de.peek_error(ErrorCode::KeyMustBeAString)), + None => Err(map.de.peek_error(ErrorCode::EofWhileParsingValue)), } - None => { - return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject)); - } - }; + } - match peek { - Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some), - Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)), - Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)), - None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)), + if tri!(has_next_key(self)) { + Ok(Some(tri!(seed.deserialize(MapKey { de: &mut *self.de })))) + } else { + Ok(None) } }