diff --git a/serde2/serde2_macros/src/lib.rs b/serde2/serde2_macros/src/lib.rs index 9a242d6b..92813226 100644 --- a/serde2/serde2_macros/src/lib.rs +++ b/serde2/serde2_macros/src/lib.rs @@ -1265,7 +1265,7 @@ fn deserialize_enum( } } - $state.visit(__Visitor) + $state.visit_enum(__Visitor) }) } diff --git a/serde2/src/de.rs b/serde2/src/de.rs index 87fde400..b5c55444 100644 --- a/serde2/src/de.rs +++ b/serde2/src/de.rs @@ -36,6 +36,17 @@ pub trait Deserializer { { self.visit(visitor) } + + /// The `visit_enum` method allows a `Deserialize` type to inform the + /// `Deserializer` that it's expecting an enum value. This allows + /// deserializers that provide a custom enumeration serialization to + /// properly deserialize the type. + #[inline] + fn visit_enum(&mut self, visitor: V) -> Result + where V: Visitor, + { + self.visit(visitor) + } } pub trait Visitor { @@ -211,6 +222,8 @@ pub trait Visitor { } } +/////////////////////////////////////////////////////////////////////////////// + pub trait SeqVisitor { type Error: Error; @@ -225,6 +238,29 @@ pub trait SeqVisitor { } } +impl<'a, V> SeqVisitor for &'a mut V where V: SeqVisitor { + type Error = V::Error; + + #[inline] + fn visit(&mut self) -> Result, V::Error> + where T: Deserialize + { + (**self).visit() + } + + #[inline] + fn end(&mut self) -> Result<(), V::Error> { + (**self).end() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + +/////////////////////////////////////////////////////////////////////////////// + pub trait MapVisitor { type Error: Error; @@ -256,6 +292,44 @@ pub trait MapVisitor { } } +impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor { + type Error = V_::Error; + + #[inline] + fn visit(&mut self) -> Result, V_::Error> + where K: Deserialize, + V: Deserialize, + { + (**self).visit() + } + + #[inline] + fn visit_key(&mut self) -> Result, V_::Error> + where K: Deserialize + { + (**self).visit_key() + } + + #[inline] + fn visit_value(&mut self) -> Result + where V: Deserialize + { + (**self).visit_value() + } + + #[inline] + fn end(&mut self) -> Result<(), V_::Error> { + (**self).end() + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (**self).size_hint() + } +} + +/////////////////////////////////////////////////////////////////////////////// + pub trait EnumVisitor { type Error: Error; @@ -276,6 +350,8 @@ pub trait EnumVisitor { } } +/////////////////////////////////////////////////////////////////////////////// + pub trait EnumSeqVisitor { type Value; @@ -283,6 +359,8 @@ pub trait EnumSeqVisitor { where V: SeqVisitor; } +/////////////////////////////////////////////////////////////////////////////// + pub trait EnumMapVisitor { type Value; @@ -374,12 +452,12 @@ impl< > self::Visitor for PrimitiveVisitor { type Value = T; - impl_deserialize_num_method!(isize, visit_isize, from_int); + impl_deserialize_num_method!(isize, visit_isize, from_isize); impl_deserialize_num_method!(i8, visit_i8, from_i8); impl_deserialize_num_method!(i16, visit_i16, from_i16); impl_deserialize_num_method!(i32, visit_i32, from_i32); impl_deserialize_num_method!(i64, visit_i64, from_i64); - impl_deserialize_num_method!(usize, visit_usize, from_uint); + impl_deserialize_num_method!(usize, visit_usize, from_usize); impl_deserialize_num_method!(u8, visit_u8, from_u8); impl_deserialize_num_method!(u16, visit_u16, from_u16); impl_deserialize_num_method!(u32, visit_u32, from_u32); diff --git a/serde2/src/json/de.rs b/serde2/src/json/de.rs index 5b6818fe..8f8b25f5 100644 --- a/serde2/src/json/de.rs +++ b/serde2/src/json/de.rs @@ -104,17 +104,11 @@ impl> Deserializer { } b'[' => { self.bump(); - visitor.visit_seq(SeqVisitor { - de: self, - first: true, - }) + visitor.visit_seq(SeqVisitor::new(self)) } b'{' => { self.bump(); - visitor.visit_map(MapVisitor { - de: self, - first: true, - }) + visitor.visit_map(MapVisitor::new(self)) } _ => { Err(self.error(ErrorCode::ExpectedSomeValue)) @@ -367,6 +361,19 @@ impl> Deserializer { } } } + + fn parse_object_colon(&mut self) -> Result<(), Error> { + self.parse_whitespace(); + + if self.ch_is(b':') { + self.bump(); + Ok(()) + } else if self.eof() { + Err(self.error(ErrorCode::EOFWhileParsingObject)) + } else { + Err(self.error(ErrorCode::ExpectedColon)) + } + } } impl> de::Deserializer for Deserializer { @@ -396,6 +403,38 @@ impl> de::Deserializer for Deserializer { visitor.visit_some(self) } } + + #[inline] + fn visit_enum(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + self.parse_whitespace(); + + if self.ch_is(b'{') { + self.bump(); + self.parse_whitespace(); + + try!(self.parse_string()); + try!(self.parse_object_colon()); + + let variant = str::from_utf8(&self.buf).unwrap().to_string(); + + let value = try!(visitor.visit_variant(&variant, EnumVisitor { + de: self, + })); + + self.parse_whitespace(); + + if self.ch_is(b'}') { + self.bump(); + Ok(value) + } else { + return Err(self.error(ErrorCode::ExpectedSomeValue)); + } + } else { + Err(self.error(ErrorCode::ExpectedSomeValue)) + } + } } struct SeqVisitor<'a, Iter: 'a> { @@ -403,7 +442,18 @@ struct SeqVisitor<'a, Iter: 'a> { first: bool, } -impl<'a, Iter: Iterator> de::SeqVisitor for SeqVisitor<'a, Iter> { +impl<'a, Iter> SeqVisitor<'a, Iter> { + fn new(de: &'a mut Deserializer) -> Self { + SeqVisitor { + de: de, + first: true, + } + } +} + +impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter> + where Iter: Iterator +{ type Error = Error; fn visit(&mut self) -> Result, Error> @@ -433,6 +483,8 @@ impl<'a, Iter: Iterator> de::SeqVisitor for SeqVisitor<'a, Iter> { } fn end(&mut self) -> Result<(), Error> { + self.de.parse_whitespace(); + if self.de.ch_is(b']') { self.de.bump(); Ok(()) @@ -449,7 +501,18 @@ struct MapVisitor<'a, Iter: 'a> { first: bool, } -impl<'a, Iter: Iterator> de::MapVisitor for MapVisitor<'a, Iter> { +impl<'a, Iter> MapVisitor<'a, Iter> { + fn new(de: &'a mut Deserializer) -> Self { + MapVisitor { + de: de, + first: true, + } + } +} + +impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter> + where Iter: Iterator +{ type Error = Error; fn visit_key(&mut self) -> Result, Error> @@ -489,22 +552,14 @@ impl<'a, Iter: Iterator> de::MapVisitor for MapVisitor<'a, Iter> { fn visit_value(&mut self) -> Result where V: de::Deserialize, { - self.de.parse_whitespace(); - - if self.de.ch_is(b':') { - self.de.bump(); - } else if self.de.eof() { - return Err(self.de.error(ErrorCode::EOFWhileParsingObject)); - } else { - return Err(self.de.error(ErrorCode::ExpectedColon)); - } - - self.de.parse_whitespace(); + try!(self.de.parse_object_colon()); Ok(try!(de::Deserialize::deserialize(self.de))) } fn end(&mut self) -> Result<(), Error> { + self.de.parse_whitespace(); + if self.de.ch_is(b']') { self.de.bump(); Ok(()) @@ -516,6 +571,44 @@ impl<'a, Iter: Iterator> de::MapVisitor for MapVisitor<'a, Iter> { } } +struct EnumVisitor<'a, Iter: 'a> { + de: &'a mut Deserializer, +} + +impl<'a, Iter: Iterator> de::EnumVisitor for EnumVisitor<'a, Iter> { + type Error = Error; + + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(self.de) + } + + fn visit_seq(&mut self, mut visitor: V) -> Result + where V: de::EnumSeqVisitor, + { + self.de.parse_whitespace(); + + if self.de.ch_is(b'[') { + self.de.bump(); + visitor.visit(SeqVisitor::new(self.de)) + } else { + Err(self.de.error(ErrorCode::ExpectedSomeValue)) + } + } + + fn visit_map(&mut self, mut visitor: V) -> Result + where V: de::EnumMapVisitor, + { + self.de.parse_whitespace(); + + if self.de.ch_is(b'{') { + self.de.bump(); + visitor.visit(MapVisitor::new(self.de)) + } else { + Err(self.de.error(ErrorCode::ExpectedSomeValue)) + } + } +} + /// Decodes a json value from an `Iterator`. pub fn from_iter(iter: I) -> Result where I: Iterator, diff --git a/serde2/src/json/value.rs b/serde2/src/json/value.rs index 6ff77d88..b7698d96 100644 --- a/serde2/src/json/value.rs +++ b/serde2/src/json/value.rs @@ -46,11 +46,6 @@ impl de::Deserialize for Value { impl de::Visitor for ValueVisitor { type Value = Value; - #[inline] - fn visit_unit(&mut self) -> Result { - Ok(Value::Null) - } - #[inline] fn visit_bool(&mut self, value: bool) -> Result { Ok(Value::Bool(value)) @@ -90,6 +85,11 @@ impl de::Deserialize for Value { de::Deserialize::deserialize(deserializer) } + #[inline] + fn visit_unit(&mut self) -> Result { + Ok(Value::Null) + } + #[inline] fn visit_seq(&mut self, visitor: V) -> Result where V: de::SeqVisitor, @@ -157,7 +157,7 @@ impl Serializer { pub fn unwrap(mut self) -> Value { match self.state.pop().unwrap() { State::Value(value) => value, - _ => panic!(), + state => panic!("expected value, found {:?}", state), } } } @@ -258,12 +258,12 @@ impl ser::Visitor for Serializer { while let Some(()) = try!(visitor.visit(self)) { } - match self.state.pop().unwrap() { - State::Array(values) => { - self.state.push(State::Value(Value::Array(values))); - } - _ => panic!(), - } + let values = match self.state.pop().unwrap() { + State::Array(values) => values, + state => panic!("Expected array, found {:?}", state), + }; + + self.state.push(State::Value(Value::Array(values))); Ok(()) } @@ -276,7 +276,7 @@ impl ser::Visitor for Serializer { let value = match self.state.pop().unwrap() { State::Value(value) => value, - _ => panic!(), + state => panic!("expected value, found {:?}", state), }; let mut object = BTreeMap::new(); @@ -296,12 +296,12 @@ impl ser::Visitor for Serializer { let value = match self.state.pop().unwrap() { State::Value(value) => value, - _ => panic!(), + state => panic!("expected value, found {:?}", state), }; match *self.state.last_mut().unwrap() { State::Array(ref mut values) => { values.push(value); } - _ => panic!(), + ref state => panic!("expected array, found {:?}", state), } Ok(()) @@ -317,12 +317,12 @@ impl ser::Visitor for Serializer { while let Some(()) = try!(visitor.visit(self)) { } - match self.state.pop().unwrap() { - State::Object(values) => { - self.state.push(State::Value(Value::Object(values))); - } - _ => panic!(), - } + let values = match self.state.pop().unwrap() { + State::Object(values) => values, + state => panic!("expected object, found {:?}", state), + }; + + self.state.push(State::Value(Value::Object(values))); Ok(()) } @@ -335,7 +335,7 @@ impl ser::Visitor for Serializer { let value = match self.state.pop().unwrap() { State::Value(value) => value, - _ => panic!(), + state => panic!("expected value, found {:?}", state), }; let mut object = BTreeMap::new(); @@ -436,6 +436,46 @@ impl de::Deserializer for Deserializer { None => Err(de::Error::end_of_stream_error()), } } + + #[inline] + fn visit_enum(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + let value = match self.value.take() { + Some(Value::Object(value)) => value, + Some(_) => { return Err(de::Error::syntax_error()); } + None => { return Err(de::Error::end_of_stream_error()); } + }; + + let mut iter = value.into_iter(); + + let value = match iter.next() { + Some((variant, Value::Array(fields))) => { + let len = fields.len(); + try!(visitor.visit_variant(&variant, SeqDeserializer { + de: self, + iter: fields.into_iter(), + len: len, + })) + } + Some((variant, Value::Object(fields))) => { + let len = fields.len(); + try!(visitor.visit_variant(&variant, MapDeserializer { + de: self, + iter: fields.into_iter(), + value: None, + len: len, + })) + } + Some(_) => { return Err(de::Error::syntax_error()); } + None => { return Err(de::Error::syntax_error()); } + }; + + match iter.next() { + Some(_) => Err(de::Error::syntax_error()), + None => Ok(value) + } + } } struct SeqDeserializer<'a> { @@ -473,6 +513,24 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> { } } +impl<'a> de::EnumVisitor for SeqDeserializer<'a> { + type Error = Error; + + fn visit_unit(&mut self) -> Result<(), Error> { + if self.len == 0 { + Ok(()) + } else { + Err(de::Error::syntax_error()) + } + } + + fn visit_seq(&mut self, mut visitor: V) -> Result + where V: de::EnumSeqVisitor, + { + visitor.visit(self) + } +} + struct MapDeserializer<'a> { de: &'a mut Deserializer, iter: btree_map::IntoIter, @@ -518,6 +576,16 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> { } } +impl<'a> de::EnumVisitor for MapDeserializer<'a> { + type Error = Error; + + fn visit_map(&mut self, mut visitor: V) -> Result + where V: de::EnumMapVisitor, + { + visitor.visit(self) + } +} + /// Shortcut function to encode a `T` into a JSON `Value` pub fn to_value(value: &T) -> Value where T: ser::Serialize diff --git a/serde2/tests/test_json.rs b/serde2/tests/test_json.rs index f9c8d4d9..e0b8efdc 100644 --- a/serde2/tests/test_json.rs +++ b/serde2/tests/test_json.rs @@ -1,4 +1,4 @@ -#![feature(io, plugin, test)] +#![feature(plugin, test)] #![plugin(serde2_macros)] extern crate test; @@ -13,9 +13,7 @@ use serde2::ser; use serde2::json::{ self, - Deserializer, Error, - Serializer, Value, from_str, from_value, @@ -556,19 +554,17 @@ fn test_parse_f64() { } #[test] -fn test_parse_string_errors() { +fn test_parse_string() { test_parse_err::(&[ ("\"", SyntaxError(EOFWhileParsingString, 1, 2)), ("\"lol", SyntaxError(EOFWhileParsingString, 1, 5)), ("\"lol\"a", SyntaxError(TrailingCharacters, 1, 6)), ]); -} -#[test] -fn test_parse_string() { test_parse_ok(&[ ("\"\"", "".to_string()), ("\"foo\"", "foo".to_string()), + (" \"foo\" ", "foo".to_string()), ("\"\\\"\"", "\"".to_string()), ("\"\\b\"", "\x08".to_string()), ("\"\\n\"", "\n".to_string()), @@ -595,7 +591,7 @@ fn test_parse_list() { ("[]", vec!()), ("[ ]", vec!()), ("[null]", vec!(())), - ("[ null ]", vec!(())), + (" [ null ] ", vec!(())), ]); test_parse_ok(&[ @@ -604,7 +600,7 @@ fn test_parse_list() { test_parse_ok(&[ ("[3,1]", vec!(3, 1)), - ("[ 3 , 1 ]", vec!(3, 1)), + (" [ 3 , 1 ] ", vec!(3, 1)), ]); test_parse_ok(&[ @@ -652,7 +648,7 @@ fn test_parse_object() { treemap!("a".to_string() => 3, "b".to_string() => 4) ), ( - "{ \"a\" : 3 , \"b\" : 4 }", + " { \"a\" : 3 , \"b\" : 4 } ", treemap!("a".to_string() => 3, "b".to_string() => 4), ), ]); @@ -716,25 +712,47 @@ fn test_parse_option() { ]); } -/* #[test] fn test_parse_enum() { + /* + test_parse_err::(&[ + ("{", SyntaxError(EOFWhileParsingString, 1, 2)), + ("{ ", SyntaxError(EOFWhileParsingString, 1, 3)), + ("{1", SyntaxError(KeyMustBeAString, 1, 2)), + ("{ \"a\"", SyntaxError(EOFWhileParsingObject, 1, 6)), + ("{\"a\"", SyntaxError(EOFWhileParsingObject, 1, 5)), + ("{\"a\" ", SyntaxError(EOFWhileParsingObject, 1, 6)), + ("{\"a\" 1", SyntaxError(ExpectedColon, 1, 6)), + ("{\"a\":", SyntaxError(EOFWhileParsingValue, 1, 6)), + ("{\"a\":1", SyntaxError(EOFWhileParsingObject, 1, 7)), + ("{\"a\":1 1", SyntaxError(ExpectedObjectCommaOrEnd, 1, 8)), + ("{\"a\":1,", SyntaxError(EOFWhileParsingValue, 1, 8)), + ("{}a", SyntaxError(TrailingCharacters, 1, 3)), + ]); + */ + test_parse_ok(&[ - ("{\"Dog\": []}", Animal::Dog), + ("{\"Dog\":[]}", Animal::Dog), + (" { \"Dog\" : [ ] } ", Animal::Dog), ( - "{\"Frog\": [\"Henry\", []]}", + "{\"Frog\":[\"Henry\",[]]}", Animal::Frog("Henry".to_string(), vec!()), ), ( - "{\"Frog\": [\"Henry\", [349]]}", - Animal::Frog("Henry".to_string(), vec!(349)), + " { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ", + Animal::Frog("Henry".to_string(), vec!(349, 102)), ), ( - "{\"Frog\": [\"Henry\", [349, 102]]}", - Animal::Frog("Henry".to_string(), vec!(349, 102)), + "{\"Cat\": {\"age\": 5, \"name\": \"Kate\"}}", + Animal::Cat { age: 5, name: "Kate".to_string() }, + ), + ( + " { \"Cat\" : { \"age\" : 5 , \"name\" : \"Kate\" } } ", + Animal::Cat { age: 5, name: "Kate".to_string() }, ), ]); + /* test_parse_ok(&[ ( concat!( @@ -749,17 +767,10 @@ fn test_parse_enum() { ) ), ]); + */ } -#[test] -fn test_json_deserialize_enum() { - test_json_deserialize_ok(&[ - Animal::Dog, - Animal::Frog("Henry".to_string(), vec!()), - Animal::Frog("Henry".to_string(), vec!(349)), - Animal::Frog("Henry".to_string(), vec!(349, 102)), - ]); -} +/* #[test] fn test_multiline_errors() {