mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-26 10:57:55 +00:00
Add Deserializer::visit_enum to help json enum deserialization
This commit is contained in:
+114
-21
@@ -104,17 +104,11 @@ impl<Iter: Iterator<Item=u8>> Deserializer<Iter> {
|
||||
}
|
||||
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<Iter: Iterator<Item=u8>> Deserializer<Iter> {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
|
||||
@@ -396,6 +403,38 @@ impl<Iter: Iterator<Item=u8>> de::Deserializer for Deserializer<Iter> {
|
||||
visitor.visit_some(self)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
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<Item=u8>> de::SeqVisitor for SeqVisitor<'a, Iter> {
|
||||
impl<'a, Iter> SeqVisitor<'a, Iter> {
|
||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||
SeqVisitor {
|
||||
de: de,
|
||||
first: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Iter> de::SeqVisitor for SeqVisitor<'a, Iter>
|
||||
where Iter: Iterator<Item=u8>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit<T>(&mut self) -> Result<Option<T>, Error>
|
||||
@@ -433,6 +483,8 @@ impl<'a, Iter: Iterator<Item=u8>> 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<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
|
||||
impl<'a, Iter> MapVisitor<'a, Iter> {
|
||||
fn new(de: &'a mut Deserializer<Iter>) -> Self {
|
||||
MapVisitor {
|
||||
de: de,
|
||||
first: true,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
|
||||
where Iter: Iterator<Item=u8>
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_key<K>(&mut self) -> Result<Option<K>, Error>
|
||||
@@ -489,22 +552,14 @@ impl<'a, Iter: Iterator<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
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<Item=u8>> de::MapVisitor for MapVisitor<'a, Iter> {
|
||||
}
|
||||
}
|
||||
|
||||
struct EnumVisitor<'a, Iter: 'a> {
|
||||
de: &'a mut Deserializer<Iter>,
|
||||
}
|
||||
|
||||
impl<'a, Iter: Iterator<Item=u8>> de::EnumVisitor for EnumVisitor<'a, Iter> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
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<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
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<u8>`.
|
||||
pub fn from_iter<I, T>(iter: I) -> Result<T, Error>
|
||||
where I: Iterator<Item=u8>,
|
||||
|
||||
+90
-22
@@ -46,11 +46,6 @@ impl de::Deserialize for Value {
|
||||
impl de::Visitor for ValueVisitor {
|
||||
type Value = Value;
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<Value, E> {
|
||||
Ok(Value::Null)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_bool<E>(&mut self, value: bool) -> Result<Value, E> {
|
||||
Ok(Value::Bool(value))
|
||||
@@ -90,6 +85,11 @@ impl de::Deserialize for Value {
|
||||
de::Deserialize::deserialize(deserializer)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_unit<E>(&mut self) -> Result<Value, E> {
|
||||
Ok(Value::Null)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<Value, V::Error>
|
||||
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<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
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<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumSeqVisitor,
|
||||
{
|
||||
visitor.visit(self)
|
||||
}
|
||||
}
|
||||
|
||||
struct MapDeserializer<'a> {
|
||||
de: &'a mut Deserializer,
|
||||
iter: btree_map::IntoIter<String, Value>,
|
||||
@@ -518,6 +576,16 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> de::EnumVisitor for MapDeserializer<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumMapVisitor,
|
||||
{
|
||||
visitor.visit(self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Shortcut function to encode a `T` into a JSON `Value`
|
||||
pub fn to_value<T>(value: &T) -> Value
|
||||
where T: ser::Serialize
|
||||
|
||||
Reference in New Issue
Block a user