Implement serialization for Result
.
Servo wants this.
This commit is contained in:
parent
bcc9e15b05
commit
e24f52d3ae
@ -12,9 +12,11 @@ use num::FromPrimitive;
|
||||
use de::{
|
||||
Deserialize,
|
||||
Deserializer,
|
||||
EnumVisitor,
|
||||
Error,
|
||||
MapVisitor,
|
||||
SeqVisitor,
|
||||
VariantVisitor,
|
||||
Visitor,
|
||||
};
|
||||
|
||||
@ -865,3 +867,130 @@ impl<'a, T: ?Sized> Deserialize for Cow<'a, T> where T: ToOwned, T::Owned: Deser
|
||||
Ok(Cow::Owned(val))
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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,
|
||||
}
|
||||
|
||||
impl Deserialize for Field {
|
||||
#[inline]
|
||||
fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
|
||||
where D: Deserializer {
|
||||
struct FieldVisitor<D> {
|
||||
phantom: PhantomData<D>,
|
||||
}
|
||||
|
||||
impl<D> ::de::Visitor for FieldVisitor<D> where D: Deserializer {
|
||||
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),
|
||||
_ => 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()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
deserializer.visit(FieldVisitor::<D> {
|
||||
phantom: PhantomData,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
struct Visitor<D, T, E>(PhantomData<D>, PhantomData<T>, PhantomData<E>)
|
||||
where D: Deserializer, T: Deserialize, E: Deserialize;
|
||||
|
||||
impl<D, T, E> EnumVisitor for Visitor<D, T, E> where D: Deserializer,
|
||||
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))
|
||||
}
|
||||
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",
|
||||
Visitor::<D, T, E>(PhantomData, PhantomData, PhantomData))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
use std::borrow::Cow;
|
||||
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
|
||||
use std::hash::Hash;
|
||||
use std::marker::PhantomData;
|
||||
use std::path;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
@ -530,6 +531,95 @@ 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>>,
|
||||
}
|
||||
|
||||
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> Option<usize> {
|
||||
Some(1)
|
||||
}
|
||||
}
|
||||
|
||||
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", "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>>,
|
||||
}
|
||||
|
||||
impl<'a, T, E> SeqVisitor for Visitor<'a, T, E> where T: Serialize + 'a,
|
||||
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),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> Option<usize> {
|
||||
Some(1)
|
||||
}
|
||||
}
|
||||
|
||||
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", "Err", visitor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
impl Serialize for path::Path {
|
||||
fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
|
||||
where S: Serializer,
|
||||
|
Loading…
x
Reference in New Issue
Block a user