Pass numbers in js as enums to Rust successfully

This commit is contained in:
Ryan Levick 2018-02-22 10:55:44 +01:00
parent 01c31cb33d
commit 45543c545e
3 changed files with 31 additions and 23 deletions

View File

@ -1051,7 +1051,8 @@ impl<'a, 'b> SubContext<'a, 'b> {
passed_args.push_str(arg); passed_args.push_str(arg);
}; };
match *arg { match *arg {
shared::TYPE_NUMBER => { shared::TYPE_ENUM | shared::TYPE_NUMBER => {
// TODO: TS for Enum
dst_ts.push_str(": number"); dst_ts.push_str(": number");
if self.cx.config.debug { if self.cx.config.debug {
self.cx.expose_assert_num(); self.cx.expose_assert_num();

View File

@ -49,7 +49,8 @@ pub struct Struct {
} }
pub struct Enum { pub struct Enum {
pub name: syn::Ident pub name: syn::Ident,
pub variants: Vec<syn::Ident>
} }
pub enum Type { pub enum Type {
@ -211,20 +212,17 @@ impl Program {
_ => panic!("only public enums are allowed"), _ => panic!("only public enums are allowed"),
} }
let all_fields_unit = item.variants.iter().all(|ref v| { let variants = item.variants.iter().map(|ref v| {
match v.fields { match v.fields {
syn::Fields::Unit => true, syn::Fields::Unit => (),
_ => false _ => panic!("Only C-Style enums allowed")
} }
v.ident
}).collect();
self.enums.push(Enum {
name: item.ident,
variants
}); });
if all_fields_unit {
self.enums.push(Enum {
name: item.ident
});
} else {
panic!("Only C-Style enums allowed")
}
} }
pub fn push_foreign_fn(&mut self, pub fn push_foreign_fn(&mut self,

View File

@ -516,26 +516,35 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) { fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) {
let name = &e.name; let name = &e.name;
let c = shared::name_to_descriptor(name.as_ref()) as u32; let c = shared::TYPE_ENUM as u32;
(my_quote! { let incoming_u32 = quote! { n };
impl #name { let name_as_string = name.to_string();
fn from_usize(n: usize) -> #name { let cast_clauses = e.variants.iter().map(|ident| {
#name::Blue quote! {
if #incoming_u32 == #name::#ident as u32 {
#name::#ident
} }
} }
});
(my_quote! {
impl #name {
fn from_u32(#incoming_u32: u32) -> #name {
#(#cast_clauses else)* {
wasm_bindgen::throw(&format!("Could not cast {} as {}", #incoming_u32, #name_as_string));
}
}
}
impl ::wasm_bindgen::convert::WasmBoundary for #name { impl ::wasm_bindgen::convert::WasmBoundary for #name {
type Js = u32; type Js = u32;
const DESCRIPTOR: u32 = #c; const DESCRIPTOR: u32 = #c;
fn into_js(self) -> u32 { fn into_js(self) -> u32 {
Box::into_raw(Box::new(self as u32)) as u32 self as u32
} }
unsafe fn from_js(js: u32) -> Self { unsafe fn from_js(js: u32) -> Self {
let js = js as *mut usize; #name::from_u32(js)
::wasm_bindgen::__rt::assert_not_null(js);
let js = Box::from_raw(js);
#name::from_usize(*js)
} }
} }
}).to_tokens(into); }).to_tokens(into);