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 {
|
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>
|
fn deserialize<D>(deserializer: &mut D) -> Result<Result<T, E>, D::Error>
|
||||||
where D: Deserializer {
|
where D: Deserializer {
|
||||||
enum Field {
|
enum Field {
|
||||||
Field0,
|
Ok,
|
||||||
Field1,
|
Err,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Deserialize for Field {
|
impl Deserialize for Field {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
|
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
|
||||||
where D: Deserializer {
|
where D: Deserializer
|
||||||
struct FieldVisitor<D> {
|
{
|
||||||
phantom: PhantomData<D>,
|
struct FieldVisitor;
|
||||||
}
|
|
||||||
|
|
||||||
impl<D> ::de::Visitor for FieldVisitor<D> where D: Deserializer {
|
impl ::de::Visitor for FieldVisitor {
|
||||||
type Value = Field;
|
type Value = Field;
|
||||||
|
|
||||||
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
|
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
|
||||||
match value {
|
match value {
|
||||||
"Ok" => Ok(Field::Field0),
|
"Ok" => Ok(Field::Ok),
|
||||||
"Err" => Ok(Field::Field1),
|
"Err" => Ok(Field::Err),
|
||||||
_ => Err(Error::unknown_field_error(value)),
|
_ => Err(Error::unknown_field_error(value)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_bytes<E>(&mut self, value: &[u8]) -> Result<Field, E> where E: Error {
|
fn visit_bytes<E>(&mut self, value: &[u8]) -> Result<Field, E> where E: Error {
|
||||||
|
match value {
|
||||||
|
b"Ok" => Ok(Field::Ok),
|
||||||
|
b"Err" => Ok(Field::Err),
|
||||||
|
_ => {
|
||||||
match str::from_utf8(value) {
|
match str::from_utf8(value) {
|
||||||
Ok(s) => self.visit_str(s),
|
Ok(value) => Err(Error::unknown_field_error(value)),
|
||||||
_ => Err(Error::syntax_error()),
|
Err(_) => Err(Error::syntax_error()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.visit(FieldVisitor::<D> {
|
|
||||||
phantom: PhantomData,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
|
deserializer.visit(FieldVisitor)
|
||||||
where D: Deserializer, T: Deserialize, E: Deserialize;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl<D, T, E> EnumVisitor for Visitor<D, T, E> where D: Deserializer,
|
struct Visitor<T, E>(PhantomData<Result<T, E>>);
|
||||||
T: Deserialize,
|
|
||||||
E: Deserialize {
|
impl<T, E> EnumVisitor for Visitor<T, E>
|
||||||
|
where T: Deserialize,
|
||||||
|
E: Deserialize
|
||||||
|
{
|
||||||
type Value = Result<T, E>;
|
type Value = Result<T, E>;
|
||||||
|
|
||||||
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
|
fn visit<V>(&mut self, mut visitor: V) -> Result<Result<T, E>, V::Error>
|
||||||
where V: VariantVisitor {
|
where V: VariantVisitor
|
||||||
match match visitor.visit_variant() {
|
{
|
||||||
Ok(val) => val,
|
match try!(visitor.visit_variant()) {
|
||||||
Err(err) => return Err(From::from(err)),
|
Field::Ok => {
|
||||||
} {
|
let (value,) = try!(visitor.visit_seq(TupleVisitor1::new()));
|
||||||
Field::Field0 => {
|
Ok(Ok(value))
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
}
|
Field::Err => {
|
||||||
visitor.visit_seq(Visitor::<D, T, E>(PhantomData,
|
let (value,) = try!(visitor.visit_seq(TupleVisitor1::new()));
|
||||||
PhantomData,
|
Ok(Err(value))
|
||||||
PhantomData))
|
|
||||||
}
|
|
||||||
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))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
deserializer.visit_enum("Result",
|
deserializer.visit_enum("Result", Visitor(PhantomData))
|
||||||
Visitor::<D, T, E>(PhantomData, PhantomData, PhantomData))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,6 @@ use std::collections::vec_map::VecMap;
|
|||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use std::iter;
|
use std::iter;
|
||||||
use std::marker::PhantomData;
|
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use std::num;
|
use std::num;
|
||||||
#[cfg(feature = "nightly")]
|
#[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 {
|
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 {
|
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
|
||||||
match *self {
|
match *self {
|
||||||
Result::Ok(ref field0) => {
|
Result::Ok(ref value) => {
|
||||||
struct Visitor<'a, T, E>
|
struct Visitor<'a, T: 'a>(Option<&'a T>);
|
||||||
where T: Serialize + 'a,
|
|
||||||
E: Serialize + 'a
|
|
||||||
{
|
|
||||||
state: usize,
|
|
||||||
value: (&'a T,),
|
|
||||||
_structure_ty: PhantomData<&'a Result<T, E>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
|
impl<'a, T> SeqVisitor for Visitor<'a, T> where T: Serialize + 'a {
|
||||||
E: Serialize + 'a {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
||||||
where S: Serializer {
|
where S: Serializer
|
||||||
match self.state {
|
{
|
||||||
0 => {
|
match self.0.take() {
|
||||||
self.state += 1;
|
Some(value) => Ok(Some(try!(serializer.visit_seq_elt(value)))),
|
||||||
let v = match serializer.visit_seq_elt(&self.value.0) {
|
None => Ok(None),
|
||||||
Ok(val) => val,
|
|
||||||
Err(err) => return Err(From::from(err)),
|
|
||||||
};
|
|
||||||
Ok(Some(v))
|
|
||||||
}
|
|
||||||
_ => Ok(None),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -646,40 +631,18 @@ impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let field0: &T = field0;
|
serializer.visit_enum_seq("Result", 0, "Ok", Visitor(Some(value)))
|
||||||
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)
|
|
||||||
}
|
|
||||||
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,
|
impl<'a, E> SeqVisitor for Visitor<'a, E> where E: Serialize + 'a {
|
||||||
E: Serialize + 'a {
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
|
||||||
where S: Serializer {
|
where S: Serializer {
|
||||||
match self.state {
|
match self.0.take() {
|
||||||
0 => {
|
Some(value) => Ok(Some(try!(serializer.visit_seq_elt(value)))),
|
||||||
self.state += 1;
|
None => Ok(None),
|
||||||
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),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,14 +652,7 @@ impl<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let field0: &E = field0;
|
serializer.visit_enum_seq("Result", 1, "Err", Visitor(Some(value)))
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,6 +491,26 @@ declare_tests! {
|
|||||||
Token::I32(1),
|
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 {
|
test_unit {
|
||||||
() => vec![Token::Unit],
|
() => vec![Token::Unit],
|
||||||
() => vec![
|
() => vec![
|
||||||
|
@ -380,6 +380,20 @@ declare_tests! {
|
|||||||
Token::I32(1),
|
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 {
|
test_slice {
|
||||||
&[0][..0] => vec![
|
&[0][..0] => vec![
|
||||||
Token::SeqStart(Some(0)),
|
Token::SeqStart(Some(0)),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user