mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-06-14 02:21:01 +00:00
Merge pull request #58 from oli-obk/separate_line_col
separate out the line/column counting from character iteration
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
use std::iter::Peekable;
|
||||||
|
use std::io;
|
||||||
|
|
||||||
|
pub struct LineColIterator<Iter: Iterator<Item=io::Result<u8>>> {
|
||||||
|
rdr: Peekable<Iter>,
|
||||||
|
line: usize,
|
||||||
|
col: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Iter: Iterator<Item=io::Result<u8>>> LineColIterator<Iter> {
|
||||||
|
pub fn new(iter: Iter) -> LineColIterator<Iter> {
|
||||||
|
LineColIterator {
|
||||||
|
line: 1,
|
||||||
|
col: 0,
|
||||||
|
rdr: iter.peekable(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn peek(&mut self) -> Option<u8> {
|
||||||
|
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<Iter: Iterator<Item=io::Result<u8>>> Iterator for LineColIterator<Iter> {
|
||||||
|
type Item = io::Result<u8>;
|
||||||
|
fn next(&mut self) -> Option<io::Result<u8>> {
|
||||||
|
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)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+9
-19
@@ -4,12 +4,11 @@ use std::str;
|
|||||||
|
|
||||||
use de;
|
use de;
|
||||||
use super::error::{Error, ErrorCode};
|
use super::error::{Error, ErrorCode};
|
||||||
|
use iterator::LineColIterator;
|
||||||
|
|
||||||
pub struct Deserializer<Iter> {
|
pub struct Deserializer<Iter: Iterator<Item=io::Result<u8>>> {
|
||||||
rdr: Iter,
|
rdr: LineColIterator<Iter>,
|
||||||
ch: Option<u8>,
|
ch: Option<u8>,
|
||||||
line: usize,
|
|
||||||
col: usize,
|
|
||||||
str_buf: Vec<u8>,
|
str_buf: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,10 +19,8 @@ impl<Iter> Deserializer<Iter>
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
|
pub fn new(rdr: Iter) -> Result<Deserializer<Iter>, Error> {
|
||||||
let mut deserializer = Deserializer {
|
let mut deserializer = Deserializer {
|
||||||
rdr: rdr,
|
rdr: LineColIterator::new(rdr),
|
||||||
ch: None,
|
ch: None,
|
||||||
line: 1,
|
|
||||||
col: 0,
|
|
||||||
str_buf: Vec::with_capacity(128),
|
str_buf: Vec::with_capacity(128),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -53,13 +50,6 @@ impl<Iter> Deserializer<Iter>
|
|||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.ch_is(b'\n') {
|
|
||||||
self.line += 1;
|
|
||||||
self.col = 1;
|
|
||||||
} else {
|
|
||||||
self.col += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +63,7 @@ impl<Iter> Deserializer<Iter>
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn error(&mut self, reason: ErrorCode) -> Error {
|
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> {
|
fn parse_whitespace(&mut self) -> Result<(), Error> {
|
||||||
@@ -476,12 +466,12 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SeqVisitor<'a, Iter: 'a> {
|
struct SeqVisitor<'a, Iter: 'a + Iterator<Item=io::Result<u8>>> {
|
||||||
de: &'a mut Deserializer<Iter>,
|
de: &'a mut Deserializer<Iter>,
|
||||||
first: bool,
|
first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Iter> SeqVisitor<'a, Iter> {
|
impl<'a, Iter: Iterator<Item=io::Result<u8>>> SeqVisitor<'a, Iter> {
|
||||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
SeqVisitor {
|
SeqVisitor {
|
||||||
de: de,
|
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<Item=io::Result<u8>>> {
|
||||||
de: &'a mut Deserializer<Iter>,
|
de: &'a mut Deserializer<Iter>,
|
||||||
first: bool,
|
first: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, Iter> MapVisitor<'a, Iter> {
|
impl<'a, Iter: Iterator<Item=io::Result<u8>>> MapVisitor<'a, Iter> {
|
||||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||||
MapVisitor {
|
MapVisitor {
|
||||||
de: de,
|
de: de,
|
||||||
|
|||||||
@@ -16,3 +16,4 @@ pub mod ser;
|
|||||||
pub mod de;
|
pub mod de;
|
||||||
pub mod json;
|
pub mod json;
|
||||||
pub mod bytes;
|
pub mod bytes;
|
||||||
|
mod iterator;
|
||||||
|
|||||||
+26
-26
@@ -668,8 +668,8 @@ fn test_parse_err<T>(errors: Vec<(&'static str, Error)>)
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_null() {
|
fn test_parse_null() {
|
||||||
test_parse_err::<()>(vec![
|
test_parse_err::<()>(vec![
|
||||||
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
|
("n", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
|
||||||
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
|
("nul", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
|
||||||
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
("nulla", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -681,9 +681,9 @@ fn test_parse_null() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_bool() {
|
fn test_parse_bool() {
|
||||||
test_parse_err::<bool>(vec![
|
test_parse_err::<bool>(vec![
|
||||||
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 2)),
|
("t", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 1)),
|
||||||
("truz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 4)),
|
("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)),
|
("faz", Error::SyntaxError(ErrorCode::ExpectedSomeIdent, 1, 3)),
|
||||||
("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
("truea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 5)),
|
||||||
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
("falsea", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
||||||
@@ -702,11 +702,11 @@ fn test_parse_number_errors() {
|
|||||||
test_parse_err::<f64>(vec![
|
test_parse_err::<f64>(vec![
|
||||||
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
("+", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
||||||
(".", 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)),
|
("00", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
||||||
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
|
("1.", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
||||||
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
|
("1e", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 2)),
|
||||||
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 4)),
|
("1e+", Error::SyntaxError(ErrorCode::InvalidNumber, 1, 3)),
|
||||||
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
|
("1a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 2)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
@@ -745,8 +745,8 @@ fn test_parse_f64() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_string() {
|
fn test_parse_string() {
|
||||||
test_parse_err::<String>(vec![
|
test_parse_err::<String>(vec![
|
||||||
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 2)),
|
("\"", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 1)),
|
||||||
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 5)),
|
("\"lol", Error::SyntaxError(ErrorCode::EOFWhileParsingString, 1, 4)),
|
||||||
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
("\"lol\"a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 6)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -767,10 +767,10 @@ fn test_parse_string() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_list() {
|
fn test_parse_list() {
|
||||||
test_parse_err::<Vec<f64>>(vec![
|
test_parse_err::<Vec<f64>>(vec![
|
||||||
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
("[", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
|
||||||
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
|
("[ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
||||||
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 3)),
|
("[1", Error::SyntaxError(ErrorCode::EOFWhileParsingList, 1, 2)),
|
||||||
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 4)),
|
("[1,", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
|
||||||
("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
|
("[1,]", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 4)),
|
||||||
("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
|
("[1 2]", Error::SyntaxError(ErrorCode::ExpectedListCommaOrEnd, 1, 4)),
|
||||||
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
("[]a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
||||||
@@ -819,17 +819,17 @@ fn test_parse_list() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_object() {
|
fn test_parse_object() {
|
||||||
test_parse_err::<BTreeMap<String, u32>>(vec![
|
test_parse_err::<BTreeMap<String, u32>>(vec![
|
||||||
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
("{", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 1)),
|
||||||
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 3)),
|
("{ ", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 2)),
|
||||||
("{1", Error::SyntaxError(ErrorCode::KeyMustBeAString, 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, 5)),
|
("{\"a\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 4)),
|
||||||
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
|
("{\"a\" ", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 5)),
|
||||||
("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
|
("{\"a\" 1", Error::SyntaxError(ErrorCode::ExpectedColon, 1, 6)),
|
||||||
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 6)),
|
("{\"a\":", Error::SyntaxError(ErrorCode::EOFWhileParsingValue, 1, 5)),
|
||||||
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 7)),
|
("{\"a\":1", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 1, 6)),
|
||||||
("{\"a\":1 1", Error::SyntaxError(ErrorCode::ExpectedObjectCommaOrEnd, 1, 8)),
|
("{\"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)),
|
("{}a", Error::SyntaxError(ErrorCode::TrailingCharacters, 1, 3)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -870,8 +870,8 @@ fn test_parse_object() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_parse_struct() {
|
fn test_parse_struct() {
|
||||||
test_parse_err::<Outer>(vec![
|
test_parse_err::<Outer>(vec![
|
||||||
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
|
("5", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 1)),
|
||||||
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
|
("\"hello\"", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 7)),
|
||||||
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
|
("{\"inner\": true}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 15)),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -933,7 +933,7 @@ fn test_parse_option() {
|
|||||||
fn test_parse_enum_errors() {
|
fn test_parse_enum_errors() {
|
||||||
test_parse_err::<Animal>(vec![
|
test_parse_err::<Animal>(vec![
|
||||||
("{}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 2)),
|
("{}", 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)),
|
("{\"Dog\":}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 8)),
|
||||||
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)),
|
("{\"unknown\":[]}", Error::SyntaxError(ErrorCode::UnknownField("unknown".to_string()), 1, 11)),
|
||||||
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
|
("{\"Dog\":{}}", Error::SyntaxError(ErrorCode::ExpectedSomeValue, 1, 9)),
|
||||||
@@ -994,7 +994,7 @@ fn test_parse_trailing_whitespace() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_multiline_errors() {
|
fn test_multiline_errors() {
|
||||||
test_parse_err::<BTreeMap<String, String>>(vec![
|
test_parse_err::<BTreeMap<String, String>>(vec![
|
||||||
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 8)),
|
("{\n \"foo\":\n \"bar\"", Error::SyntaxError(ErrorCode::EOFWhileParsingObject, 3, 6)),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user