mirror of
https://github.com/rustwasm/wasm-bindgen.git
synced 2024-11-28 05:52:21 +03:00
Support C-Style enums with custom int values
This commit is contained in:
parent
71880b8a83
commit
f783876192
@ -1434,10 +1434,8 @@ impl<'a, 'b> SubContext<'a, 'b> {
|
||||
pub fn generate_enum(&mut self, enum_: &shared::Enum) {
|
||||
let mut variants = String::new();
|
||||
|
||||
let mut value = 0;
|
||||
for variant in enum_.variants.iter() {
|
||||
variants.push_str(&format!("{}:{},", variant.name, value));
|
||||
value = value + 1;
|
||||
variants.push_str(&format!("{}:{},", variant.name, variant.value));
|
||||
}
|
||||
self.cx.globals.push_str(&format!("export const {} = {{", enum_.name));
|
||||
self.cx.globals.push_str(&variants);
|
||||
|
@ -50,7 +50,7 @@ pub struct Struct {
|
||||
|
||||
pub struct Enum {
|
||||
pub name: syn::Ident,
|
||||
pub variants: Vec<syn::Ident>
|
||||
pub variants: Vec<(syn::Ident, u32)>
|
||||
}
|
||||
|
||||
pub enum Type {
|
||||
@ -212,12 +212,25 @@ impl Program {
|
||||
_ => panic!("only public enums are allowed"),
|
||||
}
|
||||
|
||||
let mut i = 0;
|
||||
let variants = item.variants.iter().map(|ref v| {
|
||||
match v.fields {
|
||||
syn::Fields::Unit => (),
|
||||
_ => panic!("Only C-Style enums allowed")
|
||||
}
|
||||
v.ident
|
||||
let value = match v.discriminant {
|
||||
Some((_, syn::Expr::Lit(syn::ExprLit {attrs: _, lit: syn::Lit::Int(ref int_lit)}))) => {
|
||||
if int_lit.value() > <u32>::max_value() as u64 {
|
||||
panic!("Enums can only support numbers that can be represented as u32");
|
||||
}
|
||||
int_lit.value() as u32
|
||||
},
|
||||
None => i,
|
||||
_ => panic!("Enums may only have number literal values")
|
||||
};
|
||||
|
||||
i = i + 1;
|
||||
(v.ident, value)
|
||||
}).collect();
|
||||
self.enums.push(Enum {
|
||||
name: item.ident,
|
||||
@ -670,7 +683,9 @@ impl Enum {
|
||||
a.fields(&[
|
||||
("name", &|a| a.str(self.name.as_ref())),
|
||||
("variants", &|a| a.list(&self.variants, |v, a| {
|
||||
a.fields(&[("name", &|a| a.str(v.as_ref()))])
|
||||
let &(name, value) = v;
|
||||
a.fields(&[("name", &|a| a.str(name.as_ref())),
|
||||
("value", &|a| a.append(&format!("{}", value)))])
|
||||
})),
|
||||
]);
|
||||
}
|
||||
|
@ -515,27 +515,28 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
}
|
||||
|
||||
fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) {
|
||||
let name = &e.name;
|
||||
let enum_name = &e.name;
|
||||
let c = shared::TYPE_ENUM as u32;
|
||||
let incoming_u32 = quote! { n };
|
||||
let name_as_string = name.to_string();
|
||||
let cast_clauses = e.variants.iter().map(|ident| {
|
||||
let enum_name_as_string = enum_name.to_string();
|
||||
let cast_clauses = e.variants.iter().map(|variant| {
|
||||
let &(variant_name, _) = variant;
|
||||
quote! {
|
||||
if #incoming_u32 == #name::#ident as u32 {
|
||||
#name::#ident
|
||||
if #incoming_u32 == #enum_name::#variant_name as u32 {
|
||||
#enum_name::#variant_name
|
||||
}
|
||||
}
|
||||
});
|
||||
(my_quote! {
|
||||
impl #name {
|
||||
fn from_u32(#incoming_u32: u32) -> #name {
|
||||
impl #enum_name {
|
||||
fn from_u32(#incoming_u32: u32) -> #enum_name {
|
||||
#(#cast_clauses else)* {
|
||||
wasm_bindgen::throw(&format!("Could not cast {} as {}", #incoming_u32, #name_as_string));
|
||||
wasm_bindgen::throw(&format!("Could not cast {} as {}", #incoming_u32, #enum_name_as_string));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ::wasm_bindgen::convert::WasmBoundary for #name {
|
||||
impl ::wasm_bindgen::convert::WasmBoundary for #enum_name {
|
||||
type Js = u32;
|
||||
const DESCRIPTOR: u32 = #c;
|
||||
|
||||
@ -544,7 +545,7 @@ fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) {
|
||||
}
|
||||
|
||||
unsafe fn from_js(js: u32) -> Self {
|
||||
#name::from_u32(js)
|
||||
#enum_name::from_u32(js)
|
||||
}
|
||||
}
|
||||
}).to_tokens(into);
|
||||
|
@ -41,7 +41,8 @@ pub struct Enum {
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct EnumVariant {
|
||||
pub name: String
|
||||
pub name: String,
|
||||
pub value: u32
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
|
Loading…
Reference in New Issue
Block a user