diff --git a/src/de/impls.rs b/src/de/impls.rs index f73b3e52..ac340115 100644 --- a/src/de/impls.rs +++ b/src/de/impls.rs @@ -4,6 +4,7 @@ use std::marker::PhantomData; use std::path; use std::rc::Rc; use std::sync::Arc; +use std::str; use num::FromPrimitive; @@ -56,6 +57,16 @@ impl Visitor for BoolVisitor { { Ok(v) } + + fn visit_str(&mut self, s: &str) -> Result + where E: Error, + { + match s.trim() { + "true" => Ok(true), + "false" => Ok(false), + _ => Err(Error::syntax_error()), + } + } } impl Deserialize for bool { @@ -82,6 +93,10 @@ macro_rules! impl_deserialize_num_method { } } +pub struct NumericVisitor { + marker: PhantomData, +} + pub struct PrimitiveVisitor { marker: PhantomData, } @@ -95,6 +110,41 @@ impl PrimitiveVisitor { } } +impl NumericVisitor { + #[inline] + pub fn new() -> Self { + NumericVisitor { + marker: PhantomData, + } + } +} + +impl< + T: Deserialize + FromPrimitive + str::FromStr +> Visitor for NumericVisitor { + type Value = T; + + impl_deserialize_num_method!(isize, visit_isize, from_isize); + impl_deserialize_num_method!(i8, visit_i8, from_i8); + impl_deserialize_num_method!(i16, visit_i16, from_i16); + impl_deserialize_num_method!(i32, visit_i32, from_i32); + impl_deserialize_num_method!(i64, visit_i64, from_i64); + impl_deserialize_num_method!(usize, visit_usize, from_usize); + impl_deserialize_num_method!(u8, visit_u8, from_u8); + impl_deserialize_num_method!(u16, visit_u16, from_u16); + impl_deserialize_num_method!(u32, visit_u32, from_u32); + impl_deserialize_num_method!(u64, visit_u64, from_u64); + impl_deserialize_num_method!(f32, visit_f32, from_f32); + impl_deserialize_num_method!(f64, visit_f64, from_f64); + + #[inline] + fn visit_str(&mut self, v: &str) -> Result + where E: Error, + { + str::FromStr::from_str(v.trim()).or(Err(Error::syntax_error())) + } +} + impl< T: Deserialize + FromPrimitive > Visitor for PrimitiveVisitor { @@ -121,7 +171,7 @@ macro_rules! impl_deserialize_num { fn deserialize(deserializer: &mut D) -> Result<$ty, D::Error> where D: Deserializer, { - deserializer.visit(PrimitiveVisitor::new()) + deserializer.visit(NumericVisitor::new()) } } } @@ -394,7 +444,7 @@ impl Deserialize for Vec fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer, { - deserializer.visit(VecVisitor::new()) + deserializer.visit_seq(VecVisitor::new()) } } @@ -438,7 +488,7 @@ macro_rules! tuple_impls { fn deserialize(deserializer: &mut D) -> Result<($($name,)+), D::Error> where D: Deserializer, { - deserializer.visit($visitor { marker: PhantomData }) + deserializer.visit_seq($visitor { marker: PhantomData }) } } )+ diff --git a/src/de/mod.rs b/src/de/mod.rs index b10f12c0..51de922a 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -118,7 +118,7 @@ pub trait Deserializer { /////////////////////////////////////////////////////////////////////////////// pub trait Visitor { - type Value; + type Value: Deserialize; fn visit_bool(&mut self, _v: bool) -> Result where E: Error, diff --git a/src/iter.rs b/src/iter.rs index 508ebad1..ddcfbb79 100644 --- a/src/iter.rs +++ b/src/iter.rs @@ -1,7 +1,8 @@ use std::io; +use std::iter::Peekable; pub struct LineColIterator>> { - iter: Iter, + iter: Peekable, line: usize, col: usize, } @@ -9,7 +10,7 @@ pub struct LineColIterator>> { impl>> LineColIterator { pub fn new(iter: Iter) -> LineColIterator { LineColIterator { - iter: iter, + iter: iter.peekable(), line: 1, col: 0, } @@ -22,13 +23,16 @@ impl>> LineColIterator { pub fn col(&self) -> usize { self.col } /// Gets a reference to the underlying iterator. - pub fn get_ref(&self) -> &Iter { &self.iter } + pub fn get_ref(&self) -> &Peekable { &self.iter } /// Gets a mutable reference to the underlying iterator. - pub fn get_mut(&self) -> &Iter { &self.iter } + pub fn get_mut(&mut self) -> &mut Peekable { &mut self.iter } /// Unwraps this `LineColIterator`, returning the underlying iterator. - pub fn into_inner(self) -> Iter { self.iter } + pub fn into_inner(self) -> Peekable { self.iter } + + /// peeks at the next value + pub fn peek(&mut self) -> Option<&io::Result> { self.iter.peek() } } impl>> Iterator for LineColIterator {