From 5fbdadefb237e3ee6a5e6f0d6d4fe3b0c858d00f Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 24 Feb 2017 13:47:04 -0800 Subject: [PATCH] Deserializing enums in serde_test --- serde_test/src/de.rs | 78 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 77 insertions(+), 1 deletion(-) diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index 816c7d37..2a36a28d 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -2,7 +2,7 @@ use std::iter; use serde::de::{self, Deserialize, DeserializeSeed, EnumVisitor, MapVisitor, SeqVisitor, VariantVisitor, Visitor}; -use serde::de::value::ValueDeserializer; +use serde::de::value::{ValueDeserializer, MapVisitorDeserializer, SeqVisitorDeserializer}; use error::Error; use token::Token; @@ -129,6 +129,13 @@ impl<'a, I> de::Deserializer for &'a mut Deserializer Some(Token::StructStart(_, len)) => { self.visit_map(Some(len), Token::StructSep, Token::StructEnd, visitor) } + Some(Token::EnumUnit(_, variant)) => visitor.visit_str(variant), + Some(Token::EnumStart(variant)) | + Some(Token::EnumNewType(_, variant)) | + Some(Token::EnumSeqStart(_, variant, _)) | + Some(Token::EnumMapStart(_, variant, _)) => { + visitor.visit_map(EnumMapVisitor::new(self, variant)) + } Some(token) => Err(Error::UnexpectedToken(token)), None => Err(Error::EndOfTokens), } @@ -541,3 +548,72 @@ impl<'a, I> VariantVisitor for DeserializerEnumVisitor<'a, I> } } } + +////////////////////////////////////////////////////////////////////////// + +struct EnumMapVisitor<'a, I: 'a> + where I: Iterator> +{ + de: &'a mut Deserializer, + variant: Option<&'a str>, +} + +impl<'a, I: 'a> EnumMapVisitor<'a, I> + where I: Iterator> +{ + fn new(de: &'a mut Deserializer, variant: &'a str) -> Self { + EnumMapVisitor { + de: de, + variant: Some(variant), + } + } +} + +impl<'a, I: 'a> MapVisitor for EnumMapVisitor<'a, I> + where I: Iterator> +{ + type Error = Error; + + fn visit_key_seed(&mut self, seed: K) -> Result, Error> + where K: DeserializeSeed + { + match self.variant.take() { + Some(variant) => seed.deserialize(variant.into_deserializer()).map(Some), + None => Ok(None), + } + } + + fn visit_value_seed(&mut self, seed: V) -> Result + where V: DeserializeSeed + { + match self.de.tokens.peek() { + Some(&Token::EnumSeqSep) => { + let value = { + let visitor = DeserializerSeqVisitor { + de: self.de, + len: None, + sep: Token::EnumSeqSep, + end: Token::EnumSeqEnd, + }; + try!(seed.deserialize(SeqVisitorDeserializer::new(visitor))) + }; + try!(self.de.expect_token(Token::EnumSeqEnd)); + Ok(value) + } + Some(&Token::EnumMapSep) => { + let value = { + let visitor = DeserializerMapVisitor { + de: self.de, + len: None, + sep: Token::EnumMapSep, + end: Token::EnumMapEnd, + }; + try!(seed.deserialize(MapVisitorDeserializer::new(visitor))) + }; + try!(self.de.expect_token(Token::EnumMapEnd)); + Ok(value) + } + _ => seed.deserialize(&mut *self.de), + } + } +}