From ec32fc9a78045e172c2130a0180fc74d424ec2b4 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Sat, 24 May 2014 14:11:25 -0700 Subject: [PATCH] Optimize away one state in enums --- bench_enum.rs | 18 ++++-------------- de.rs | 23 ++++++++--------------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/bench_enum.rs b/bench_enum.rs index 80089115..226bcb5b 100644 --- a/bench_enum.rs +++ b/bench_enum.rs @@ -2,7 +2,7 @@ use test::Bencher; use serialize::{Decoder, Decodable}; -use de::{Deserializer, Deserializable, Token, End}; +use de::{Deserializer, Deserializable, Token}; ////////////////////////////////////////////////////////////////////////////// @@ -194,12 +194,10 @@ mod deserializer { use super::{Animal, Dog, Frog, Error, EndOfStream, SyntaxError}; use de::Deserializer; - use de::{Token, Int, StrBuf, EnumStart, EnumVariant, End}; + use de::{Token, Int, StrBuf, EnumStart, End}; enum State { AnimalState(Animal), - DogState, - FrogState, IntState(int), StrState(StrBuf), EndState, @@ -225,21 +223,13 @@ mod deserializer { match self.stack.pop() { Some(AnimalState(Dog)) => { self.stack.push(EndState); - self.stack.push(DogState); - Some(Ok(EnumStart("Animal"))) + Some(Ok(EnumStart("Animal", "Dog"))) } Some(AnimalState(Frog(x0, x1))) => { self.stack.push(EndState); self.stack.push(IntState(x1)); self.stack.push(StrState(x0)); - self.stack.push(FrogState); - Some(Ok(EnumStart("Animal"))) - } - Some(DogState) => { - Some(Ok(EnumVariant("Dog"))) - } - Some(FrogState) => { - Some(Ok(EnumVariant("Frog"))) + Some(Ok(EnumStart("Animal", "Frog"))) } Some(IntState(x)) => { Some(Ok(Int(x))) diff --git a/de.rs b/de.rs index 54783230..2c0c6385 100644 --- a/de.rs +++ b/de.rs @@ -31,8 +31,7 @@ pub enum Token { StructStart(&'static str), StructField(&'static str), - EnumStart(&'static str), - EnumVariant(&'static str), + EnumStart(&'static str, &'static str), SeqStart(uint), MapStart(uint), @@ -212,15 +211,11 @@ pub trait Deserializer: Iterator> { #[inline] fn expect_enum_start<'a>(&mut self, token: Token, name: &str, variants: &[&str]) -> Result { match token { - EnumStart(n) => { + EnumStart(n, v) => { if name == n { - match_token! { - EnumVariant(n) => { - match variants.iter().position(|variant| *variant == n) { - Some(position) => Ok(position), - None => Err(self.syntax_error()), - } - } + match variants.iter().position(|variant| *variant == v) { + Some(position) => Ok(position), + None => Err(self.syntax_error()), } } else { Err(self.syntax_error()) @@ -466,7 +461,7 @@ mod tests { use serialize::Decoder; use super::{Token, Null, Int, Uint, Str, StrBuf, Char, Option}; - use super::{TupleStart, StructStart, StructField, EnumStart, EnumVariant}; + use super::{TupleStart, StructStart, StructField, EnumStart}; use super::{SeqStart, MapStart, Sep, End}; use super::{Deserializer, Deserializable}; @@ -783,8 +778,7 @@ mod tests { #[test] fn test_tokens_enum() { let tokens = vec!( - EnumStart("Animal"), - EnumVariant("Dog"), + EnumStart("Animal", "Dog"), End, ); @@ -794,8 +788,7 @@ mod tests { assert_eq!(value, Dog); let tokens = vec!( - EnumStart("Animal"), - EnumVariant("Frog"), + EnumStart("Animal", "Frog"), StrBuf("Henry".to_strbuf()), Int(349), End,