wip
This commit is contained in:
parent
063a957e03
commit
8a434721c2
251
serde2/src/de.rs
251
serde2/src/de.rs
@ -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,
|
||||||
|
],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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,)+ })+);
|
|
||||||
)+
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user