diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 9184e75a..d00e483d 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -858,126 +858,75 @@ impl Deserialize for NonZero where T: Deserialize + PartialEq + Zeroable + /////////////////////////////////////////////////////////////////////////////// + impl Deserialize for Result where T: Deserialize, E: Deserialize { fn deserialize(deserializer: &mut D) -> Result, D::Error> where D: Deserializer { enum Field { - Field0, - Field1, + Ok, + Err, } impl Deserialize for Field { #[inline] fn deserialize(deserializer: &mut D) -> Result - where D: Deserializer { - struct FieldVisitor { - phantom: PhantomData, - } + where D: Deserializer + { + struct FieldVisitor; - impl ::de::Visitor for FieldVisitor where D: Deserializer { + impl ::de::Visitor for FieldVisitor { type Value = Field; fn visit_str(&mut self, value: &str) -> Result 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(&mut self, value: &[u8]) -> Result 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:: { - phantom: PhantomData, - }) + deserializer.visit(FieldVisitor) } } - struct Visitor(PhantomData, PhantomData, PhantomData) - where D: Deserializer, T: Deserialize, E: Deserialize; + struct Visitor(PhantomData>); - impl EnumVisitor for Visitor where D: Deserializer, - T: Deserialize, - E: Deserialize { + impl EnumVisitor for Visitor + where T: Deserialize, + E: Deserialize + { type Value = Result; fn visit(&mut self, mut visitor: V) -> Result, V::Error> - where V: VariantVisitor { - match match visitor.visit_variant() { - Ok(val) => val, - Err(err) => return Err(From::from(err)), - } { - Field::Field0 => { - struct Visitor(PhantomData, PhantomData, PhantomData) - where D: Deserializer, - T: Deserialize, - E: Deserialize; - impl ::de::Visitor for Visitor where D: Deserializer, - T: Deserialize, - E: Deserialize { - type Value = Result; - - fn visit_seq(&mut self, mut visitor: V) - -> Result, 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::(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(PhantomData, PhantomData, PhantomData) - where D: Deserializer, - T: Deserialize, - E: Deserialize; - impl ::de::Visitor for Visitor where D: Deserializer, - T: Deserialize, - E: Deserialize { - type Value = Result; - - fn visit_seq(&mut self, mut visitor: V) - -> Result, 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::(PhantomData, - PhantomData, - PhantomData)) + Field::Err => { + let (value,) = try!(visitor.visit_seq(TupleVisitor1::new())); + Ok(Err(value)) } } } } - deserializer.visit_enum("Result", - Visitor::(PhantomData, PhantomData, PhantomData)) + deserializer.visit_enum("Result", Visitor(PhantomData)) } } diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 3efa6545..a8efe18a 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -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 Serialize for Result where T: Serialize, E: Serialize { fn serialize(&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>, - } + 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(&mut self, serializer: &mut S) -> Result, 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 Serialize for Result 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>, - } + 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(&mut self, serializer: &mut S) -> Result, 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 Serialize for Result where T: Serialize, E: Serialize { } } - let field0: &E = field0; - let data: PhantomData<&Result> = 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))) } } } diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index 17be434f..9b789c84 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -491,6 +491,26 @@ declare_tests! { Token::I32(1), ], } + test_result { + Ok::(0) => vec![ + Token::EnumStart("Result"), + Token::Str("Ok"), + Token::SeqStart(1), + Token::SeqSep, + Token::I32(0), + Token::SeqEnd, + Token::EnumEnd, + ], + Err::(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![ diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index a06ef952..950b5b82 100644 --- a/serde_tests/tests/test_ser.rs +++ b/serde_tests/tests/test_ser.rs @@ -380,6 +380,20 @@ declare_tests! { Token::I32(1), ], } + test_result { + Ok::(0) => vec![ + Token::EnumSeqStart("Result", "Ok", Some(1)), + Token::SeqSep, + Token::I32(0), + Token::SeqEnd, + ], + Err::(1) => vec![ + Token::EnumSeqStart("Result", "Err", Some(1)), + Token::SeqSep, + Token::I32(1), + Token::SeqEnd, + ], + } test_slice { &[0][..0] => vec![ Token::SeqStart(Some(0)),