Simplify result serialization and deserialization
This commit is contained in:
parent
b3cf9375d4
commit
4dd7345568
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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![
|
||||
|
@ -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)),
|
||||
|
Loading…
x
Reference in New Issue
Block a user