Rewrite enum deserialization to not require allocations

This commit is contained in:
Erick Tryzelaar
2015-03-15 22:04:17 -07:00
parent b40d8f7bac
commit 78137ee3a4
7 changed files with 273 additions and 147 deletions
+38 -6
View File
@@ -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,
{