diff --git a/src/iterator.rs b/src/iterator.rs new file mode 100644 index 00000000..521a15e8 --- /dev/null +++ b/src/iterator.rs @@ -0,0 +1,46 @@ +use std::iter::Peekable; +use std::io; + +pub struct LineColIterator>> { + rdr: Peekable, + line: usize, + col: usize, +} + +impl>> LineColIterator { + pub fn new(iter: Iter) -> LineColIterator { + LineColIterator { + line: 1, + col: 0, + rdr: iter.peekable(), + } + } + fn peek(&mut self) -> Option { + match self.rdr.peek() { + None => None, + Some(&Ok(c)) => Some(c), + Some(&Err(_)) => None, + } + } + pub fn line(&self) -> usize { self.line } + pub fn col(&self) -> usize { self.col } +} + +impl>> Iterator for LineColIterator { + type Item = io::Result; + fn next(&mut self) -> Option> { + match self.rdr.next() { + None => None, + Some(Ok(b'\n')) => { + self.line += 1; + self.col = 0; + Some(Ok(b'\n')) + }, + Some(Ok(c)) => { + self.col += 1; + Some(Ok(c)) + }, + Some(Err(e)) => Some(Err(e)), + } + } +} diff --git a/src/json/de.rs b/src/json/de.rs index f1653d33..2e978f2d 100644 --- a/src/json/de.rs +++ b/src/json/de.rs @@ -4,12 +4,11 @@ use std::str; use de; use super::error::{Error, ErrorCode}; +use iterator::LineColIterator; -pub struct Deserializer { - rdr: Iter, +pub struct Deserializer>> { + rdr: LineColIterator, ch: Option, - line: usize, - col: usize, str_buf: Vec, } @@ -20,10 +19,8 @@ impl Deserializer #[inline] pub fn new(rdr: Iter) -> Result, Error> { let mut deserializer = Deserializer { - rdr: rdr, + rdr: LineColIterator::new(rdr), ch: None, - line: 1, - col: 0, str_buf: Vec::with_capacity(128), }; @@ -53,13 +50,6 @@ impl Deserializer None => None, }; - if self.ch_is(b'\n') { - self.line += 1; - self.col = 1; - } else { - self.col += 1; - } - Ok(()) } @@ -73,7 +63,7 @@ impl Deserializer } fn error(&mut self, reason: ErrorCode) -> Error { - Error::SyntaxError(reason, self.line, self.col) + Error::SyntaxError(reason, self.rdr.line(), self.rdr.col()) } fn parse_whitespace(&mut self) -> Result<(), Error> { @@ -476,12 +466,12 @@ impl de::Deserializer for Deserializer } } -struct SeqVisitor<'a, Iter: 'a> { +struct SeqVisitor<'a, Iter: 'a + Iterator>> { de: &'a mut Deserializer, first: bool, } -impl<'a, Iter> SeqVisitor<'a, Iter> { +impl<'a, Iter: Iterator>> SeqVisitor<'a, Iter> { fn new(de: &'a mut Deserializer) -> Self { SeqVisitor { de: de, @@ -533,12 +523,12 @@ impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter> } } -struct MapVisitor<'a, Iter: 'a> { +struct MapVisitor<'a, Iter: 'a + Iterator>> { de: &'a mut Deserializer, first: bool, } -impl<'a, Iter> MapVisitor<'a, Iter> { +impl<'a, Iter: Iterator>> MapVisitor<'a, Iter> { fn new(de: &'a mut Deserializer) -> Self { MapVisitor { de: de, diff --git a/src/lib.rs b/src/lib.rs index 5359d69d..cac66ca4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -16,3 +16,4 @@ pub mod ser; pub mod de; pub mod json; pub mod bytes; +mod iterator; diff --git a/tests/test_json.rs b/tests/test_json.rs index f7e29791..2135f0c5 100644 --- a/tests/test_json.rs +++ b/tests/test_json.rs @@ -668,8 +668,8 @@ fn test_parse_err(errors: Vec<(&'static str, Error)>) #[test] fn test_parse_null() { test_parse_err::<()>(vec![ - ("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)), - ("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)), + ("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)), + ("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)), ("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)), ]); @@ -681,9 +681,9 @@ fn test_parse_null() { #[test] fn test_parse_bool() { test_parse_err::(vec![ - ("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)), + ("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)), ("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)), - ("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)), + ("f", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)), ("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)), ("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)), ("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)), @@ -702,11 +702,11 @@ fn test_parse_number_errors() { test_parse_err::(vec![ ("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), (".", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), - ("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), + ("-", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 1)), ("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), - ("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), - ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), - ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)), + ("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), + ("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)), + ("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)), ("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)), ]); } @@ -745,8 +745,8 @@ fn test_parse_f64() { #[test] fn test_parse_string() { test_parse_err::(vec![ - ("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)), - ("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)), + ("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 1)), + ("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 4)), ("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)), ]); @@ -767,10 +767,10 @@ fn test_parse_string() { #[test] fn test_parse_list() { test_parse_err::>(vec![ - ("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)), - ("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)), - ("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)), - ("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)), + ("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)), + ("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)), + ("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)), + ("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)), ("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)), ("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)), ("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)), @@ -819,17 +819,17 @@ fn test_parse_list() { #[test] fn test_parse_object() { test_parse_err::>(vec![ - ("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)), - ("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)), + ("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)), + ("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)), ("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 1, 2)), - ("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)), - ("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)), - ("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)), + ("{ \"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)), + ("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 4)), + ("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)), ("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)), - ("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)), - ("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)), + ("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 5)), + ("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)), ("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)), - ("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)), + ("{\"a\":1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)), ("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)), ]); @@ -870,8 +870,8 @@ fn test_parse_object() { #[test] fn test_parse_struct() { test_parse_err::(vec![ - ("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)), - ("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)), + ("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)), + ("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)), ("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)), ]); @@ -933,7 +933,7 @@ fn test_parse_option() { fn test_parse_enum_errors() { test_parse_err::(vec![ ("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)), - ("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 8)), + ("{\"Dog\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 7)), ("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)), ("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)), ("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)), @@ -994,7 +994,7 @@ fn test_parse_trailing_whitespace() { #[test] fn test_multiline_errors() { test_parse_err::>(vec![ - ("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)), + ("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 6)), ]); }