Support parsing json with tests

This commit is contained in:
Erick Tryzelaar
2014-10-08 21:25:01 -07:00
parent 2c50039c13
commit 671864eef4
3 changed files with 963 additions and 78 deletions
+147 -77
View File
@@ -1,5 +1,6 @@
use std::collections::{HashMap, TreeMap};
use std::hash::Hash;
use std::num;
///////////////////////////////////////////////////////////////////////////////
@@ -30,18 +31,42 @@ pub trait Visitor<D: Deserializer<E>, R, E> {
Err(d.syntax_error())
}
fn visit_int(&mut self, d: &mut D, _v: int) -> Result<R, E> {
fn visit_bool(&mut self, d: &mut D, _v: bool) -> Result<R, E> {
Err(d.syntax_error())
}
fn visit_str(&mut self, d: &mut D, v: &str) -> Result<R, E> {
self.visit_string(d, v.to_string())
fn visit_int(&mut self, d: &mut D, v: int) -> Result<R, E> {
self.visit_i64(d, v as i64)
}
fn visit_string(&mut self, d: &mut D, _v: String) -> Result<R, E> {
fn visit_i64(&mut self, d: &mut D, _v: i64) -> Result<R, E> {
Err(d.syntax_error())
}
fn visit_uint(&mut self, d: &mut D, v: uint) -> Result<R, E> {
self.visit_u64(d, v as u64)
}
fn visit_u64(&mut self, d: &mut D, _v: u64) -> Result<R, E> {
Err(d.syntax_error())
}
fn visit_f32(&mut self, d: &mut D, v: f32) -> Result<R, E> {
self.visit_f64(d, v as f64)
}
fn visit_f64(&mut self, d: &mut D, _v: f64) -> Result<R, E> {
Err(d.syntax_error())
}
fn visit_str(&mut self, d: &mut D, _v: &str) -> Result<R, E> {
Err(d.syntax_error())
}
fn visit_string(&mut self, d: &mut D, v: String) -> Result<R, E> {
self.visit_str(d, v.as_slice())
}
fn visit_option<
V: OptionVisitor<D, E>,
>(&mut self, d: &mut D, _visitor: V) -> Result<R, E> {
@@ -107,24 +132,12 @@ impl<
fn visit_null(&mut self, _d: &mut D) -> Result<(), E> {
Ok(())
}
}
d.visit(&mut Visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<
D: Deserializer<E>,
E,
> Deserialize<D, E> for int {
fn deserialize(d: &mut D) -> Result<int, E> {
struct Visitor;
impl<D: Deserializer<E>, E> self::Visitor<D, int, E> for Visitor {
fn visit_int(&mut self, _d: &mut D, v: int) -> Result<int, E> {
Ok(v)
fn visit_seq<
V: SeqVisitor<D, E>,
>(&mut self, d: &mut D, mut visitor: V) -> Result<(), E> {
try!(visitor.end(d));
Ok(())
}
}
@@ -134,6 +147,67 @@ impl<
///////////////////////////////////////////////////////////////////////////////
impl<
D: Deserializer<E>,
E,
> Deserialize<D, E> for bool {
fn deserialize(d: &mut D) -> Result<bool, E> {
struct Visitor;
impl<D: Deserializer<E>, E> self::Visitor<D, bool, E> for Visitor {
fn visit_bool(&mut self, _d: &mut D, v: bool) -> Result<bool, E> {
Ok(v)
}
}
d.visit(&mut Visitor)
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_deserialize_num_method {
($dst_ty:ty, $src_ty:ty, $method:ident) => {
fn $method(&mut self, d: &mut D, v: $src_ty) -> Result<$dst_ty, E> {
match num::cast(v) {
Some(v) => Ok(v),
None => Err(d.syntax_error()),
}
}
}
}
macro_rules! impl_deserialize_num {
($ty:ty) => {
impl<D: Deserializer<E>, E> Deserialize<D, E> for $ty {
#[inline]
fn deserialize(d: &mut D) -> Result<$ty, E> {
struct Visitor;
impl<D: Deserializer<E>, E> self::Visitor<D, $ty, E> for Visitor {
impl_deserialize_num_method!($ty, int, visit_int)
impl_deserialize_num_method!($ty, i64, visit_i64)
impl_deserialize_num_method!($ty, uint, visit_uint)
impl_deserialize_num_method!($ty, u64, visit_u64)
impl_deserialize_num_method!($ty, f32, visit_f32)
impl_deserialize_num_method!($ty, f64, visit_f64)
}
d.visit(&mut Visitor)
}
}
}
}
impl_deserialize_num!(int)
impl_deserialize_num!(i64)
impl_deserialize_num!(uint)
impl_deserialize_num!(u64)
impl_deserialize_num!(f32)
impl_deserialize_num!(f64)
///////////////////////////////////////////////////////////////////////////////
impl<
D: Deserializer<E>,
E,
@@ -142,6 +216,10 @@ impl<
struct Visitor;
impl<D: Deserializer<E>, E> self::Visitor<D, String, E> for Visitor {
fn visit_str(&mut self, _d: &mut D, v: &str) -> Result<String, E> {
Ok(v.to_string())
}
fn visit_string(&mut self, _d: &mut D, v: String) -> Result<String, E> {
Ok(v)
}
@@ -217,66 +295,58 @@ impl<
}
}
impl<
T0: Deserialize<D, E>,
T1: Deserialize<D, E>,
D: Deserializer<E>,
E,
> Deserialize<D, E> for (T0, T1) {
fn deserialize(d: &mut D) -> Result<(T0, T1), E> {
struct Visitor;
///////////////////////////////////////////////////////////////////////////////
impl<
T0: Deserialize<D, E>,
T1: Deserialize<D, E>,
D: Deserializer<E>,
E,
> self::Visitor<D, (T0, T1), E> for Visitor {
fn visit_seq<
V: SeqVisitor<D, E>,
>(&mut self, d: &mut D, mut visitor: V) -> Result<(T0, T1), E> {
let mut state = 0u;
let mut t0 = None;
let mut t1 = None;
loop {
match state {
0 => {
state += 1;
match try!(visitor.visit(d)) {
Some(value) => {
t0 = Some(value);
}
None => {
return Err(d.end_of_stream_error());
}
}
}
1 => {
state += 1;
match try!(visitor.visit(d)) {
Some(value) => {
t1 = Some(value);
}
None => {
return Err(d.end_of_stream_error());
}
}
}
_ => {
try!(visitor.end(d));
return Ok((t0.unwrap(), t1.unwrap()));
}
}
}
}
}
d.visit(&mut Visitor)
macro_rules! peel {
($name:ident, $($other:ident,)*) => {
impl_deserialize_tuple!($($other,)*)
}
}
macro_rules! impl_deserialize_tuple {
() => {};
( $($name:ident,)+ ) => {
peel!($($name,)*)
impl<
D: Deserializer<E>,
E,
$($name: Deserialize<D, E>),+
> Deserialize<D, E> for ($($name,)+) {
#[inline]
#[allow(non_snake_case)]
fn deserialize(d: &mut D) -> Result<($($name,)+), E> {
struct Visitor;
impl<
D: Deserializer<E>,
E,
$($name: Deserialize<D, E>,)+
> self::Visitor<D, ($($name,)+), E> for Visitor {
fn visit_seq<
V: SeqVisitor<D, E>,
>(&mut self, d: &mut D, mut visitor: V) -> Result<($($name,)+), E> {
$(
let $name = match try!(visitor.visit(d)) {
Some(value) => value,
None => { return Err(d.end_of_stream_error()); }
};
)+;
try!(visitor.end(d));
Ok(($($name,)+))
}
}
d.visit(&mut Visitor)
}
}
}
}
impl_deserialize_tuple! { T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, }
///////////////////////////////////////////////////////////////////////////////
impl<