Skip to content

Commit

Permalink
Simplify discriminant matching
Browse files Browse the repository at this point in the history
We don't actually need to know the expressions assigned to each variant,
nor compute offsets for those without an expression.  We can just cast
each `#name::#ident` directly to `i64` for comparison.
  • Loading branch information
cuviper committed Feb 10, 2018
1 parent 6f8d5e6 commit 53f2b33
Showing 1 changed file with 5 additions and 32 deletions.
37 changes: 5 additions & 32 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
};

let from_i64_var = quote! { n };
let mut expr = quote! { 0i64 };
let mut offset = 0i64;
let clauses: Vec<_> = variants.iter()
.map(|variant| {
let ident = &variant.ident;
Expand All @@ -47,21 +45,8 @@ pub fn from_primitive(input: TokenStream) -> TokenStream {
},
}

let discriminant_expr = match variant.discriminant {
Some((_, ref const_expr)) => {
expr = quote! { (#const_expr) as i64 };
offset = 1;
expr.clone()
}
None => {
let tt = quote! { #expr + #offset };
offset += 1;
tt
}
};

quote! {
if #from_i64_var == #discriminant_expr {
if #from_i64_var == #name::#ident as i64 {
Some(#name::#ident)
}
}
Expand Down Expand Up @@ -105,8 +90,6 @@ pub fn to_primitive(input: TokenStream) -> TokenStream {
_ => panic!("`ToPrimitive` can be applied only to the enums, {} is not an enum", name)
};

let mut expr = quote! { 0i64 };
let mut offset = 0i64;
let variants: Vec<_> = variants.iter()
.map(|variant| {
let ident = &variant.ident;
Expand All @@ -117,20 +100,10 @@ pub fn to_primitive(input: TokenStream) -> TokenStream {
},
}

let discriminant_expr = match variant.discriminant {
Some((_, ref const_expr)) => {
expr = quote! { (#const_expr) as i64 };
offset = 1;
expr.clone()
}
None => {
let tt = quote! { #expr + #offset };
offset += 1;
tt
}
};

quote!(#name::#ident => (#discriminant_expr))
// NB: We have to check each variant individually, because we'll only have `&self`
// for the input. We can't move from that, and it might not be `Clone` or `Copy`.
// (Otherwise we could just do `*self as i64` without a `match` at all.)
quote!(#name::#ident => #name::#ident as i64)
})
.collect();

Expand Down

0 comments on commit 53f2b33

Please sign in to comment.