mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-22 18:27:54 +00:00
Rewrite enum deserialization to not require allocations
This commit is contained in:
@@ -43,10 +43,10 @@ pub trait Deserializer {
|
||||
/// deserializers that provide a custom enumeration serialization to
|
||||
/// properly deserialize the type.
|
||||
#[inline]
|
||||
fn visit_enum<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: Visitor,
|
||||
fn visit_enum<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: EnumVisitor,
|
||||
{
|
||||
self.visit(visitor)
|
||||
Err(Error::syntax_error())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -204,23 +204,6 @@ pub trait Visitor {
|
||||
{
|
||||
self.visit_map(visitor)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_enum<V>(&mut self,
|
||||
_name: &str,
|
||||
_variant: &str,
|
||||
_visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: EnumVisitor,
|
||||
{
|
||||
Err(Error::syntax_error())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_variant<V>(&mut self, _name: &str, _visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: EnumVisitor,
|
||||
{
|
||||
Err(Error::syntax_error())
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
@@ -338,22 +321,53 @@ impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub trait EnumVisitor {
|
||||
type Value;
|
||||
|
||||
fn visit<V>(&mut self, visitor: V) -> Result<Self::Value, V::Error>
|
||||
where V: VariantVisitor;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub trait VariantVisitor {
|
||||
type Error: Error;
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Self::Error> {
|
||||
Err(Error::syntax_error())
|
||||
}
|
||||
fn visit_variant<V>(&mut self) -> Result<V, Self::Error>
|
||||
where V: Deserialize;
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Self::Error>;
|
||||
|
||||
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: EnumSeqVisitor,
|
||||
{
|
||||
Err(Error::syntax_error())
|
||||
}
|
||||
where V: EnumSeqVisitor;
|
||||
|
||||
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where V: EnumMapVisitor,
|
||||
where V: EnumMapVisitor;
|
||||
}
|
||||
|
||||
impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
|
||||
type Error = T::Error;
|
||||
|
||||
fn visit_variant<V>(&mut self) -> Result<V, T::Error>
|
||||
where V: Deserialize
|
||||
{
|
||||
Err(Error::syntax_error())
|
||||
(**self).visit_variant()
|
||||
}
|
||||
|
||||
{
|
||||
fn visit_unit(&mut self) -> Result<(), T::Error> {
|
||||
(**self).visit_unit()
|
||||
}
|
||||
|
||||
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
|
||||
where V: EnumSeqVisitor
|
||||
{
|
||||
(**self).visit_seq(visitor)
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
|
||||
where V: EnumMapVisitor
|
||||
{
|
||||
(**self).visit_map(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+40
-30
@@ -409,8 +409,8 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumVisitor,
|
||||
{
|
||||
self.parse_whitespace();
|
||||
|
||||
@@ -418,14 +418,9 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
|
||||
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,
|
||||
}));
|
||||
let value = {
|
||||
try!(visitor.visit(&mut *self))
|
||||
};
|
||||
|
||||
self.parse_whitespace();
|
||||
|
||||
@@ -433,7 +428,7 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
|
||||
self.bump();
|
||||
Ok(value)
|
||||
} else {
|
||||
return Err(self.error(ErrorCode::ExpectedSomeValue));
|
||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||
}
|
||||
} else {
|
||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||
@@ -541,7 +536,6 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
|
||||
}
|
||||
|
||||
if self.de.eof() {
|
||||
println!("here3");
|
||||
return Err(self.de.error(ErrorCode::EOFWhileParsingValue));
|
||||
}
|
||||
|
||||
@@ -599,42 +593,58 @@ impl<'a, Iter> de::MapVisitor for MapVisitor<'a, Iter>
|
||||
}
|
||||
}
|
||||
|
||||
struct EnumVisitor<'a, Iter: 'a> {
|
||||
de: &'a mut Deserializer<Iter>,
|
||||
}
|
||||
|
||||
impl<'a, Iter> de::EnumVisitor for EnumVisitor<'a, Iter>
|
||||
impl<Iter> de::VariantVisitor for Deserializer<Iter>
|
||||
where Iter: Iterator<Item=u8>,
|
||||
{
|
||||
type Error = Error;
|
||||
|
||||
fn visit_variant<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize
|
||||
{
|
||||
de::Deserialize::deserialize(self)
|
||||
}
|
||||
|
||||
/*
|
||||
fn visit_value<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize
|
||||
{
|
||||
de::Deserialize::deserialize(self)
|
||||
}
|
||||
*/
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||
de::Deserialize::deserialize(self.de)
|
||||
try!(self.parse_object_colon());
|
||||
|
||||
de::Deserialize::deserialize(self)
|
||||
}
|
||||
|
||||
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumSeqVisitor,
|
||||
where V: de::EnumSeqVisitor
|
||||
{
|
||||
self.de.parse_whitespace();
|
||||
try!(self.parse_object_colon());
|
||||
|
||||
if self.de.ch_is(b'[') {
|
||||
self.de.bump();
|
||||
visitor.visit(SeqVisitor::new(self.de))
|
||||
self.parse_whitespace();
|
||||
|
||||
if self.ch_is(b'[') {
|
||||
self.bump();
|
||||
visitor.visit(SeqVisitor::new(self))
|
||||
} else {
|
||||
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumMapVisitor,
|
||||
where V: de::EnumMapVisitor
|
||||
{
|
||||
self.de.parse_whitespace();
|
||||
try!(self.parse_object_colon());
|
||||
|
||||
if self.de.ch_is(b'{') {
|
||||
self.de.bump();
|
||||
visitor.visit(MapVisitor::new(self.de))
|
||||
self.parse_whitespace();
|
||||
|
||||
if self.ch_is(b'{') {
|
||||
self.bump();
|
||||
visitor.visit(MapVisitor::new(self))
|
||||
} else {
|
||||
Err(self.de.error(ErrorCode::ExpectedSomeValue))
|
||||
Err(self.error(ErrorCode::ExpectedSomeValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+38
-6
@@ -420,8 +420,8 @@ impl de::Deserializer for Deserializer {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn visit_enum<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::Visitor,
|
||||
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumVisitor,
|
||||
{
|
||||
let value = match self.value.take() {
|
||||
Some(Value::Object(value)) => value,
|
||||
@@ -433,16 +433,20 @@ impl de::Deserializer for Deserializer {
|
||||
|
||||
let value = match iter.next() {
|
||||
Some((variant, Value::Array(fields))) => {
|
||||
self.value = Some(Value::String(variant));
|
||||
|
||||
let len = fields.len();
|
||||
try!(visitor.visit_variant(&variant, SeqDeserializer {
|
||||
try!(visitor.visit(SeqDeserializer {
|
||||
de: self,
|
||||
iter: fields.into_iter(),
|
||||
len: len,
|
||||
}))
|
||||
}
|
||||
Some((variant, Value::Object(fields))) => {
|
||||
self.value = Some(Value::String(variant));
|
||||
|
||||
let len = fields.len();
|
||||
try!(visitor.visit_variant(&variant, MapDeserializer {
|
||||
try!(visitor.visit(MapDeserializer {
|
||||
de: self,
|
||||
iter: fields.into_iter(),
|
||||
value: None,
|
||||
@@ -495,9 +499,15 @@ impl<'a> de::SeqVisitor for SeqDeserializer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> de::EnumVisitor for SeqDeserializer<'a> {
|
||||
impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_variant<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||
if self.len == 0 {
|
||||
Ok(())
|
||||
@@ -511,6 +521,12 @@ impl<'a> de::EnumVisitor for SeqDeserializer<'a> {
|
||||
{
|
||||
visitor.visit(self)
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumMapVisitor
|
||||
{
|
||||
Err(de::Error::syntax_error())
|
||||
}
|
||||
}
|
||||
|
||||
struct MapDeserializer<'a> {
|
||||
@@ -583,9 +599,25 @@ impl<'a> de::MapVisitor for MapDeserializer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> de::EnumVisitor for MapDeserializer<'a> {
|
||||
impl<'a> de::VariantVisitor for MapDeserializer<'a> {
|
||||
type Error = Error;
|
||||
|
||||
fn visit_variant<V>(&mut self) -> Result<V, Error>
|
||||
where V: de::Deserialize,
|
||||
{
|
||||
de::Deserialize::deserialize(self.de)
|
||||
}
|
||||
|
||||
fn visit_unit(&mut self) -> Result<(), Error> {
|
||||
Err(de::Error::syntax_error())
|
||||
}
|
||||
|
||||
fn visit_seq<V>(&mut self, _visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumSeqVisitor
|
||||
{
|
||||
Err(de::Error::syntax_error())
|
||||
}
|
||||
|
||||
fn visit_map<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
|
||||
where V: de::EnumMapVisitor,
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user