This commit is contained in:
Erick Tryzelaar 2015-01-09 17:52:46 -08:00
parent 063a957e03
commit 8a434721c2
3 changed files with 210 additions and 74 deletions

View File

@ -1,7 +1,9 @@
/*
use std::collections::{HashMap, BTreeMap}; use std::collections::{HashMap, BTreeMap};
use std::collections::hash_map::Hasher; use std::collections::hash_map::Hasher;
use std::hash::Hash; use std::hash::Hash;
use std::num::FromPrimitive; use std::num::FromPrimitive;
*/
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -11,19 +13,18 @@ pub trait Error {
fn end_of_stream_error() -> Self; fn end_of_stream_error() -> Self;
} }
pub trait Deserialize<S: Deserializer> { pub trait Deserialize {
type Visitor: Visitor<S, Self>; fn deserialize<
S: Deserializer,
fn deserialize(state: &mut S) -> Result<Self, S::Error>; >(state: &mut S) -> Result<Self, S::Error>;
} }
pub trait Deserializer { pub trait Deserializer {
type Error: Error; type Error: Error;
fn visit< fn visit<
R, V: Visitor,
V: Visitor<Self, R>, >(&mut self, visitor: &mut V) -> Result<V::Value, Self::Error>;
>(&mut self, visitor: &mut V) -> Result<R, Self::Error>;
/* /*
fn visit_option< fn visit_option<
@ -35,8 +36,12 @@ pub trait Deserializer {
*/ */
} }
pub trait Visitor<S: Deserializer, R> { pub trait Visitor {
fn visit_null(&mut self) -> Result<R, S::Error> { type Value;
fn visit_unit<
E: Error,
>(&mut self) -> Result<Self::Value, E> {
Err(Error::syntax_error()) Err(Error::syntax_error())
} }
@ -106,13 +111,15 @@ pub trait Visitor<S: Deserializer, R> {
>(&mut self, _visitor: V) -> Result<R, S::Error> { >(&mut self, _visitor: V) -> Result<R, S::Error> {
Err(Error::syntax_error()) Err(Error::syntax_error())
} }
*/
fn visit_seq< fn visit_seq<
V: SeqVisitor<S, E>, V: SeqVisitor,
>(&mut self, _visitor: V) -> Result<R, S::Error> { >(&mut self, _visitor: V) -> Result<Self::Value, V::Error> {
Err(Error::syntax_error()) Err(Error::syntax_error())
} }
/*
fn visit_map< fn visit_map<
V: MapVisitor<S, E>, V: MapVisitor<S, E>,
>(&mut self, _visitor: V) -> Result<R, S::Error> { >(&mut self, _visitor: V) -> Result<R, S::Error> {
@ -127,13 +134,16 @@ pub trait OptionVisitor<S, E> {
T: Deserialize<S, E>, T: Deserialize<S, E>,
>(&mut self) -> Result<Option<T>, E>; >(&mut self) -> Result<Option<T>, E>;
} }
*/
pub trait SeqVisitor {
type Error: Error;
pub trait SeqVisitor<S, E> {
fn visit< fn visit<
T: Deserialize<S, E>, T: Deserialize,
>(&mut self) -> Result<Option<T>, E>; >(&mut self) -> Result<Option<T>, Self::Error>;
fn end(&mut self) -> Result<(), E>; fn end(&mut self) -> Result<(), Self::Error>;
#[inline] #[inline]
fn size_hint(&self) -> (uint, Option<uint>) { fn size_hint(&self) -> (uint, Option<uint>) {
@ -141,6 +151,7 @@ pub trait SeqVisitor<S, E> {
} }
} }
/*
pub trait MapVisitor<S, E> { pub trait MapVisitor<S, E> {
fn visit< fn visit<
K: Deserialize<S, E>, K: Deserialize<S, E>,
@ -176,10 +187,12 @@ pub trait MapVisitor<S, E> {
struct UnitVisitor; struct UnitVisitor;
impl< impl Visitor for UnitVisitor {
S: Deserializer, type Value = ();
> Visitor<S, ()> for UnitVisitor {
fn visit_null(&mut self) -> Result<(), S::Error> { fn visit_unit<
E: Error,
>(&mut self) -> Result<(), E> {
Ok(()) Ok(())
} }
@ -193,12 +206,10 @@ impl<
*/ */
} }
impl< impl Deserialize for () {
S: Deserializer, fn deserialize<
> Deserialize<S> for () { S: Deserializer,
type Visitor = UnitVisitor; >(state: &mut S) -> Result<(), S::Error> {
fn deserialize(state: &mut S) -> Result<(), S::Error> {
state.visit(&mut UnitVisitor) state.visit(&mut UnitVisitor)
} }
} }
@ -349,45 +360,36 @@ impl<
} }
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
*/
impl< struct VecVisitor<T>;
T: Deserialize<S, E>,
S: Deserializer<E>,
E: Error,
> Deserialize<S, E> for Vec<T> {
fn deserialize(state: &mut S) -> Result<Vec<T>, E> {
struct Visitor;
impl< impl<T: Deserialize> Visitor for VecVisitor<T> {
T: Deserialize<S, E>, type Value = Vec<T>;
S: Deserializer<E>,
E: Error,
> self::Visitor<S, Vec<T>, E> for Visitor {
fn visit_seq<
V: SeqVisitor<S, E>,
>(&mut self, mut visitor: V) -> Result<Vec<T>, E> {
let (len, _) = visitor.size_hint();
let mut values = Vec::with_capacity(len);
loop { fn visit_seq<
match try!(visitor.visit()) { V: SeqVisitor,
Some(value) => { >(&mut self, mut visitor: V) -> Result<Vec<T>, V::Error> {
values.push(value); let (len, _) = visitor.size_hint();
} let mut values = Vec::with_capacity(len);
None => {
break;
}
}
}
Ok(values) while let Some(value) = try!(visitor.visit()) {
} values.push(value);
} }
state.visit(&mut Visitor) Ok(values)
} }
} }
impl<T: Deserialize> Deserialize for Vec<T> {
fn deserialize<
S: Deserializer,
>(state: &mut S) -> Result<Vec<T>, S::Error> {
state.visit(&mut VecVisitor)
}
}
/*
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
macro_rules! peel { macro_rules! peel {
@ -521,3 +523,142 @@ impl<
} }
} }
*/ */
#[cfg(test)]
mod tests {
use super::{Deserialize, Deserializer, Visitor};
use std::vec;
enum Token {
Unit,
SeqStart(uint),
SeqSep,
SeqEnd,
}
struct TokenDeserializer {
tokens: vec::IntoIter<Token>,
}
impl TokenDeserializer {
fn new(tokens: Vec<Token>) -> TokenDeserializer {
TokenDeserializer {
tokens: tokens.into_iter(),
}
}
}
#[derive(Copy, PartialEq, Show)]
enum Error {
SyntaxError,
EndOfStreamError,
}
impl super::Error for Error {
fn syntax_error() -> Error { Error::SyntaxError }
fn end_of_stream_error() -> Error { Error::EndOfStreamError }
}
impl Deserializer for TokenDeserializer {
type Error = Error;
fn visit<
V: Visitor,
>(&mut self, visitor: &mut V) -> Result<V::Value, Error> {
match self.tokens.next() {
Some(Token::Unit) => visitor.visit_unit(),
Some(Token::SeqStart(len)) => {
visitor.visit_seq(TokenDeserializerSeqVisitor {
de: self,
len: len,
})
}
Some(Token::SeqSep) | Some(Token::SeqEnd) => {
Err(Error::SyntaxError)
}
None => Err(Error::EndOfStreamError),
}
}
}
struct TokenDeserializerSeqVisitor<'a> {
de: &'a mut TokenDeserializer,
len: uint,
}
impl<'a> super::SeqVisitor for TokenDeserializerSeqVisitor<'a> {
type Error = Error;
fn visit<
T: Deserialize,
>(&mut self) -> Result<Option<T>, Error> {
match self.de.tokens.next() {
Some(Token::SeqSep) => {
self.len -= 1;
Ok(Some(try!(Deserialize::deserialize(self.de))))
}
Some(Token::SeqEnd) => Ok(None),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn end(&mut self) -> Result<(), Error> {
match self.de.tokens.next() {
Some(Token::SeqEnd) => Ok(()),
Some(_) => Err(Error::SyntaxError),
None => Err(Error::EndOfStreamError),
}
}
fn size_hint(&self) -> (uint, Option<uint>) {
(self.len, Some(self.len))
}
}
macro_rules! declare_test {
($name:ident { $($value:expr => $tokens:expr,)+ }) => {
#[test]
fn $name() {
$(
let mut de = TokenDeserializer::new($tokens);
let value: Result<_, Error> = Deserialize::deserialize(&mut de);
assert_eq!(value, Ok($value));
)+
}
}
}
macro_rules! declare_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$(
declare_test!($name { $($value => $tokens,)+ });
)+
}
}
declare_tests! {
test_unit {
() => vec![Token::Unit],
}
test_vec {
Vec::<()>::new() => vec![
Token::SeqStart(0),
Token::SeqEnd,
],
vec![(), (), ()] => vec![
Token::SeqStart(3),
Token::SeqSep,
Token::Unit,
Token::SeqSep,
Token::Unit,
Token::SeqSep,
Token::Unit,
Token::SeqEnd,
],
}
}
}

View File

@ -5,5 +5,5 @@ extern crate unicode;
//pub use ser::GatherTokens; //pub use ser::GatherTokens;
pub mod ser; pub mod ser;
//pub mod de; pub mod de;
//pub mod json; //pub mod json;

View File

@ -1047,6 +1047,19 @@ mod tests {
} }
} }
macro_rules! btreemap {
() => {
BTreeMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = BTreeMap::new();
$(map.insert($key, $value);)+
map
}
}
}
macro_rules! declare_test { macro_rules! declare_test {
($name:ident { $($value:expr => $tokens:expr,)+ }) => { ($name:ident { $($value:expr => $tokens:expr,)+ }) => {
#[test] #[test]
@ -1070,29 +1083,11 @@ mod tests {
} }
} }
macro_rules! btreemap {
() => {
BTreeMap::new()
};
($($key:expr => $value:expr),+) => {
{
let mut map = BTreeMap::new();
$(map.insert($key, $value);)+
map
}
}
}
macro_rules! declare_tests { macro_rules! declare_tests {
($($name:ident { $($value:expr => $tokens:expr,)+ })+) => { ($($name:ident { $($value:expr => $tokens:expr,)+ })+) => {
$( $(
declare_test!($name { $($value => $tokens,)+ }); declare_test!($name { $($value => $tokens,)+ });
)+ )+
};
($($name:ident { $($value:expr: $ty:ty => $tokens:expr,)+ })+) => {
$(
declare_test!($($name { $($value:$ty => $tokens,)+ })+);
)+
} }
} }