Simplify result serialization and deserialization

This commit is contained in:
Erick Tryzelaar 2015-07-19 14:16:46 -04:00
parent b3cf9375d4
commit 4dd7345568
4 changed files with 84 additions and 145 deletions

View File

@ -858,126 +858,75 @@ impl<T> Deserialize for NonZero<T> where T: Deserialize + PartialEq + Zeroable +
///////////////////////////////////////////////////////////////////////////////
impl<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
fn deserialize<D>(deserializer: &mut D) -> Result<Result<T, E>, D::Error>
where D: Deserializer {
enum Field {
Field0,
Field1,
Ok,
Err,
}
impl Deserialize for Field {
#[inline]
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
where D: Deserializer {
struct FieldVisitor<D> {
phantom: PhantomData<D>,
}
where D: Deserializer
{
struct FieldVisitor;
impl<D> ::de::Visitor for FieldVisitor<D> where D: Deserializer {
impl ::de::Visitor for FieldVisitor {
type Value = Field;
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
match value {
"Ok" => Ok(Field::Field0),
"Err" => Ok(Field::Field1),
"Ok" => Ok(Field::Ok),
"Err" => Ok(Field::Err),
_ => Err(Error::unknown_field_error(value)),
}
}
fn visit_bytes<E>(&mut self, value: &[u8]) -> Result<Field, E> where E: Error {
match str::from_utf8(value) {
Ok(s) => self.visit_str(s),
_ => Err(Error::syntax_error()),
match value {
b"Ok" => Ok(Field::Ok),
b"Err" => Ok(Field::Err),
_ => {
match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_field_error(value)),
Err(_) => Err(Error::syntax_error()),
}
}
}
}
}
deserializer.visit(FieldVisitor::<D> {
phantom: PhantomData,
})
deserializer.visit(FieldVisitor)
}
}
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
where D: Deserializer, T: Deserialize, E: Deserialize;
struct Visitor<T, E>(PhantomData<Result<T, E>>);
impl<D, T, E> EnumVisitor for Visitor<D, T, E> where D: Deserializer,
T: Deserialize,
E: Deserialize {
impl<T, E> EnumVisitor for Visitor<T, E>
where T: Deserialize,
E: Deserialize
{
type Value = Result<T, E>;
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
where V: VariantVisitor {
match match visitor.visit_variant() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
} {
Field::Field0 => {
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
where D: Deserializer,
T: Deserialize,
E: Deserialize;
impl <D, T, E> ::de::Visitor for Visitor<D, T, E> where D: Deserializer,
T: Deserialize,
E: Deserialize {
type Value = Result<T, E>;
fn visit_seq<V>(&mut self, mut visitor: V)
-> Result<Result<T, E>, V::Error> where V: SeqVisitor {
let field0 = match match visitor.visit() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
} {
Some(value) => value,
None => return Err(Error::end_of_stream_error()),
};
match visitor.end() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Result::Ok(field0))
}
}
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
PhantomData,
PhantomData))
where V: VariantVisitor
{
match try!(visitor.visit_variant()) {
Field::Ok => {
let (value,) = try!(visitor.visit_seq(TupleVisitor1::new()));
Ok(Ok(value))
}
Field::Field1 => {
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
where D: Deserializer,
T: Deserialize,
E: Deserialize;
impl <D, T, E> ::de::Visitor for Visitor<D, T, E> where D: Deserializer,
T: Deserialize,
E: Deserialize {
type Value = Result<T, E>;
fn visit_seq<V>(&mut self, mut visitor: V)
-> Result<Result<T, E>, V::Error> where V: SeqVisitor {
let field0 = match match visitor.visit() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
} {
Some(value) => value,
None => return Err(Error::end_of_stream_error()),
};
match visitor.end() {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Result::Err(field0))
}
}
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
PhantomData,
PhantomData))
Field::Err => {
let (value,) = try!(visitor.visit_seq(TupleVisitor1::new()));
Ok(Err(value))
}
}
}
}
deserializer.visit_enum("Result",
Visitor::<D, T, E>(PhantomData, PhantomData, PhantomData))
deserializer.visit_enum("Result", Visitor(PhantomData))
}
}

View File

@ -15,7 +15,6 @@ use std::collections::vec_map::VecMap;
use std::hash::Hash;
#[cfg(feature = "nightly")]
use std::iter;
use std::marker::PhantomData;
#[cfg(feature = "nightly")]
use std::num;
#[cfg(feature = "nightly")]
@ -612,31 +611,17 @@ impl<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned, {
impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
match *self {
Result::Ok(ref field0) => {
struct Visitor<'a, T, E>
where T: Serialize + 'a,
E: Serialize + 'a
{
state: usize,
value: (&'a T,),
_structure_ty: PhantomData<&'a Result<T, E>>,
}
Result::Ok(ref value) => {
struct Visitor<'a, T: 'a>(Option<&'a T>);
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
E: Serialize + 'a {
impl<'a, T> SeqVisitor for Visitor<'a, T> where T: Serialize + 'a {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer {
match self.state {
0 => {
self.state += 1;
let v = match serializer.visit_seq_elt(&self.value.0) {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Some(v))
}
_ => Ok(None),
where S: Serializer
{
match self.0.take() {
Some(value) => Ok(Some(try!(serializer.visit_seq_elt(value)))),
None => Ok(None),
}
}
@ -646,40 +631,18 @@ impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
}
}
let field0: &T = field0;
let data: PhantomData<&Result<&T,E>> = PhantomData;
let visitor = Visitor {
value: (&field0,),
state: 0,
_structure_ty: data
};
serializer.visit_enum_seq("Result", 0, "Ok", visitor)
serializer.visit_enum_seq("Result", 0, "Ok", Visitor(Some(value)))
}
Result::Err(ref field0) => {
struct Visitor<'a, T, E>
where T: Serialize + 'a,
E: Serialize + 'a
{
state: usize,
value: (&'a E,),
_structure_ty: PhantomData<&'a Result<T, E>>,
}
Result::Err(ref value) => {
struct Visitor<'a, E: 'a>(Option<&'a E>);
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
E: Serialize + 'a {
impl<'a, E> SeqVisitor for Visitor<'a, E> where E: Serialize + 'a {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer {
match self.state {
0 => {
self.state += 1;
let v = match serializer.visit_seq_elt(&self.value.0) {
Ok(val) => val,
Err(err) => return Err(From::from(err)),
};
Ok(Some(v))
}
_ => Ok(None),
match self.0.take() {
Some(value) => Ok(Some(try!(serializer.visit_seq_elt(value)))),
None => Ok(None),
}
}
@ -689,14 +652,7 @@ impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
}
}
let field0: &E = field0;
let data: PhantomData<&Result<T,&E>> = PhantomData;
let visitor = Visitor {
value: (&field0,),
state: 0,
_structure_ty: data
};
serializer.visit_enum_seq("Result", 1, "Err", visitor)
serializer.visit_enum_seq("Result", 1, "Err", Visitor(Some(value)))
}
}
}

View File

@ -491,6 +491,26 @@ declare_tests! {
Token::I32(1),
],
}
test_result {
Ok::<i32, i32>(0) => vec![
Token::EnumStart("Result"),
Token::Str("Ok"),
Token::SeqStart(1),
Token::SeqSep,
Token::I32(0),
Token::SeqEnd,
Token::EnumEnd,
],
Err::<i32, i32>(1) => vec![
Token::EnumStart("Result"),
Token::Str("Err"),
Token::SeqStart(1),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::EnumEnd,
],
}
test_unit {
() => vec![Token::Unit],
() => vec![

View File

@ -380,6 +380,20 @@ declare_tests! {
Token::I32(1),
],
}
test_result {
Ok::<i32, i32>(0) => vec![
Token::EnumSeqStart("Result", "Ok", Some(1)),
Token::SeqSep,
Token::I32(0),
Token::SeqEnd,
],
Err::<i32, i32>(1) => vec![
Token::EnumSeqStart("Result", "Err", Some(1)),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
}
test_slice {
&[0][..0] => vec![
Token::SeqStart(Some(0)),