Optimize away one state in enums
This commit is contained in:
parent
cb1b006b0f
commit
ec32fc9a78
@ -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)))
|
||||||
|
23
de.rs
23
de.rs
@ -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,15 +211,11 @@ 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) => {
|
Some(position) => Ok(position),
|
||||||
match variants.iter().position(|variant| *variant == n) {
|
None => Err(self.syntax_error()),
|
||||||
Some(position) => Ok(position),
|
|
||||||
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,
|
||||||
|
Loading…
Reference in New Issue
Block a user