Optimize away one state in enums

This commit is contained in:
Erick Tryzelaar 2014-05-24 14:11:25 -07:00
parent cb1b006b0f
commit ec32fc9a78
2 changed files with 12 additions and 29 deletions

View File

@ -2,7 +2,7 @@ use test::Bencher;
use serialize::{Decoder, Decodable}; 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 super::{Animal, Dog, Frog, Error, EndOfStream, SyntaxError};
use de::Deserializer; use de::Deserializer;
use de::{Token, Int, StrBuf, EnumStart, EnumVariant, End}; use de::{Token, Int, StrBuf, EnumStart, End};
enum State { enum State {
AnimalState(Animal), AnimalState(Animal),
DogState,
FrogState,
IntState(int), IntState(int),
StrState(StrBuf), StrState(StrBuf),
EndState, EndState,
@ -225,21 +223,13 @@ mod deserializer {
match self.stack.pop() { match self.stack.pop() {
Some(AnimalState(Dog)) => { Some(AnimalState(Dog)) => {
self.stack.push(EndState); self.stack.push(EndState);
self.stack.push(DogState); Some(Ok(EnumStart("Animal", "Dog")))
Some(Ok(EnumStart("Animal")))
} }
Some(AnimalState(Frog(x0, x1))) => { Some(AnimalState(Frog(x0, x1))) => {
self.stack.push(EndState); self.stack.push(EndState);
self.stack.push(IntState(x1)); self.stack.push(IntState(x1));
self.stack.push(StrState(x0)); self.stack.push(StrState(x0));
self.stack.push(FrogState); Some(Ok(EnumStart("Animal", "Frog")))
Some(Ok(EnumStart("Animal")))
}
Some(DogState) => {
Some(Ok(EnumVariant("Dog")))
}
Some(FrogState) => {
Some(Ok(EnumVariant("Frog")))
} }
Some(IntState(x)) => { Some(IntState(x)) => {
Some(Ok(Int(x))) Some(Ok(Int(x)))

19
de.rs
View File

@ -31,8 +31,7 @@ pub enum Token {
StructStart(&'static str), StructStart(&'static str),
StructField(&'static str), StructField(&'static str),
EnumStart(&'static str), EnumStart(&'static str, &'static str),
EnumVariant(&'static str),
SeqStart(uint), SeqStart(uint),
MapStart(uint), MapStart(uint),
@ -212,16 +211,12 @@ pub trait Deserializer<E>: Iterator<Result<Token, E>> {
#[inline] #[inline]
fn expect_enum_start<'a>(&mut self, token: Token, name: &str, variants: &[&str]) -> Result<uint, E> { fn expect_enum_start<'a>(&mut self, token: Token, name: &str, variants: &[&str]) -> Result<uint, E> {
match token { match token {
EnumStart(n) => { EnumStart(n, v) => {
if name == n { if name == n {
match_token! { match variants.iter().position(|variant| *variant == v) {
EnumVariant(n) => {
match variants.iter().position(|variant| *variant == n) {
Some(position) => Ok(position), Some(position) => Ok(position),
None => Err(self.syntax_error()), None => Err(self.syntax_error()),
} }
}
}
} else { } else {
Err(self.syntax_error()) Err(self.syntax_error())
} }
@ -466,7 +461,7 @@ mod tests {
use serialize::Decoder; use serialize::Decoder;
use super::{Token, Null, Int, Uint, Str, StrBuf, Char, Option}; 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::{SeqStart, MapStart, Sep, End};
use super::{Deserializer, Deserializable}; use super::{Deserializer, Deserializable};
@ -783,8 +778,7 @@ mod tests {
#[test] #[test]
fn test_tokens_enum() { fn test_tokens_enum() {
let tokens = vec!( let tokens = vec!(
EnumStart("Animal"), EnumStart("Animal", "Dog"),
EnumVariant("Dog"),
End, End,
); );
@ -794,8 +788,7 @@ mod tests {
assert_eq!(value, Dog); assert_eq!(value, Dog);
let tokens = vec!( let tokens = vec!(
EnumStart("Animal"), EnumStart("Animal", "Frog"),
EnumVariant("Frog"),
StrBuf("Henry".to_strbuf()), StrBuf("Henry".to_strbuf()),
Int(349), Int(349),
End, End,