Skip to content

Commit

Permalink
refactor: Factor out whitespace skipping into helpers
Browse files Browse the repository at this point in the history
Should hopefully reduce the amount of code being generated
  • Loading branch information
Markus Westerlind committed Jun 30, 2020
1 parent ae8d93d commit 3bc95cc
Showing 1 changed file with 71 additions and 116 deletions.
187 changes: 71 additions & 116 deletions src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,28 @@ impl<'de, R: Read<'de>> Deserializer<R> {
Error::syntax(reason, position.line, position.column)
}

/// Returns the first non-whitespace byte without consuming it, or `Err` if
/// EOF is encountered.
fn parse_whitespace_in_value(&mut self) -> Result<u8> {
match tri!(self.parse_whitespace()) {
Some(b) => Ok(b),
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
}
}

/// Returns the first non-whitespace byte without consuming it, or `Err` if
/// EOF is encountered.
fn parse_whitespace_in_object(&mut self) -> Result<u8> {
match tri!(self.parse_whitespace()) {
Some(b) => Ok(b),
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingObject));
}
}
}

/// Returns the first non-whitespace byte without consuming it, or `None` if
/// EOF is encountered.
fn parse_whitespace(&mut self) -> Result<Option<u8>> {
Expand Down Expand Up @@ -304,12 +326,7 @@ impl<'de, R: Read<'de>> Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'-' => {
Expand Down Expand Up @@ -961,13 +978,12 @@ impl<'de, R: Read<'de>> Deserializer<R> {
}

fn parse_object_colon(&mut self) -> Result<()> {
match tri!(self.parse_whitespace()) {
Some(b':') => {
match tri!(self.parse_whitespace_in_object()) {
b':' => {
self.eat_char();
Ok(())
}
Some(_) => Err(self.peek_error(ErrorCode::ExpectedColon)),
None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
_ => Err(self.peek_error(ErrorCode::ExpectedColon)),
}
}

Expand All @@ -990,14 +1006,13 @@ impl<'de, R: Read<'de>> Deserializer<R> {
}

fn end_map(&mut self) -> Result<()> {
match tri!(self.parse_whitespace()) {
Some(b'}') => {
match tri!(self.parse_whitespace_in_object()) {
b'}' => {
self.eat_char();
Ok(())
}
Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)),
Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
b',' => Err(self.peek_error(ErrorCode::TrailingComma)),
_ => Err(self.peek_error(ErrorCode::TrailingCharacters)),
}
}

Expand All @@ -1006,12 +1021,7 @@ impl<'de, R: Read<'de>> Deserializer<R> {
let mut enclosing = None;

loop {
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let frame = match peek {
b'n' => {
Expand Down Expand Up @@ -1099,16 +1109,14 @@ impl<'de, R: Read<'de>> Deserializer<R> {
}

if frame == b'{' {
match tri!(self.parse_whitespace()) {
Some(b'"') => self.eat_char(),
Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)),
None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
match tri!(self.parse_whitespace_in_object()) {
b'"' => self.eat_char(),
_ => return Err(self.peek_error(ErrorCode::KeyMustBeAString)),
}
tri!(self.read.ignore_str());
match tri!(self.parse_whitespace()) {
Some(b':') => self.eat_char(),
Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)),
None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
match tri!(self.parse_whitespace_in_object()) {
b':' => self.eat_char(),
_ => return Err(self.peek_error(ErrorCode::ExpectedColon)),
}
}

Expand Down Expand Up @@ -1292,12 +1300,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'n' => {
Expand Down Expand Up @@ -1368,12 +1371,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b't' => {
Expand Down Expand Up @@ -1425,15 +1423,12 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
{
let mut buf = String::new();

match tri!(self.parse_whitespace()) {
Some(b'-') => {
match tri!(self.parse_whitespace_in_value()) {
b'-' => {
self.eat_char();
buf.push('-');
}
Some(_) => {}
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
_ => {}
};

tri!(self.scan_integer128(&mut buf));
Expand All @@ -1455,14 +1450,11 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
match tri!(self.parse_whitespace()) {
Some(b'-') => {
match tri!(self.parse_whitespace_in_value()) {
b'-' => {
return Err(self.peek_error(ErrorCode::NumberOutOfRange));
}
Some(_) => {}
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
_ => {}
}

let mut buf = String::new();
Expand Down Expand Up @@ -1493,12 +1485,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'"' => {
Expand Down Expand Up @@ -1600,12 +1587,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'"' => {
Expand Down Expand Up @@ -1654,12 +1636,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'n' => {
Expand Down Expand Up @@ -1704,12 +1681,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'[' => {
Expand Down Expand Up @@ -1755,12 +1727,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'{' => {
Expand Down Expand Up @@ -1792,12 +1759,7 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
let peek = match tri!(self.parse_whitespace()) {
Some(b) => b,
None => {
return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
}
};
let peek = tri!(self.parse_whitespace_in_value());

let value = match peek {
b'[' => {
Expand Down Expand Up @@ -1843,25 +1805,23 @@ impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
where
V: de::Visitor<'de>,
{
match tri!(self.parse_whitespace()) {
Some(b'{') => {
match tri!(self.parse_whitespace_in_value()) {
b'{' => {
check_recursion! {
self.eat_char();
let value = tri!(visitor.visit_enum(VariantAccess::new(self)));
}

match tri!(self.parse_whitespace()) {
Some(b'}') => {
match tri!(self.parse_whitespace_in_object()) {
b'}' => {
self.eat_char();
Ok(value)
}
Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)),
None => Err(self.error(ErrorCode::EofWhileParsingObject)),
_ => Err(self.error(ErrorCode::ExpectedSomeValue)),
}
}
Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)),
Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)),
None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
_ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)),
}
}

Expand Down Expand Up @@ -1905,12 +1865,12 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
}
Some(b',') if !self.first => {
self.de.eat_char();
tri!(self.de.parse_whitespace())
tri!(self.de.parse_whitespace_in_value())
}
Some(b) => {
if self.first {
self.first = false;
Some(b)
b
} else {
return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd));
}
Expand All @@ -1921,9 +1881,8 @@ impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
};

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)),
b']' => Err(self.de.peek_error(ErrorCode::TrailingComma)),
_ => Ok(Some(tri!(seed.deserialize(&mut *self.de)))),
}
}
}
Expand All @@ -1946,32 +1905,28 @@ 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'}') => {
let peek = match tri!(self.de.parse_whitespace_in_object()) {
b'}' => {
return Ok(None);
}
Some(b',') if !self.first => {
b',' if !self.first => {
self.de.eat_char();
tri!(self.de.parse_whitespace())
tri!(self.de.parse_whitespace_in_value())
}
Some(b) => {
b => {
if self.first {
self.first = false;
Some(b)
b
} else {
return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd));
}
}
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)),
b'"' => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
b'}' => Err(self.de.peek_error(ErrorCode::TrailingComma)),
_ => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)),
}
}

Expand Down

0 comments on commit 3bc95cc

Please sign in to comment.