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);
};
match *arg {
shared::TYPE_NUMBER => {
shared::TYPE_ENUM | shared::TYPE_NUMBER => {
// TODO: TS for Enum
dst_ts.push_str(": number");
if self.cx.config.debug {
self.cx.expose_assert_num();

View File

@ -49,7 +49,8 @@ pub struct Struct {
}
pub struct Enum {
pub name: syn::Ident
pub name: syn::Ident,
pub variants: Vec<syn::Ident>
}
pub enum Type {
@ -211,20 +212,17 @@ impl Program {
_ => 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 {
syn::Fields::Unit => true,
_ => false
syn::Fields::Unit => (),
_ => 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,

View File

@ -516,26 +516,35 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
fn bindgen_enum(e: &ast::Enum, into: &mut Tokens) {
let name = &e.name;
let c = shared::name_to_descriptor(name.as_ref()) as u32;
(my_quote! {
impl #name {
fn from_usize(n: usize) -> #name {
#name::Blue
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| {
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 {
type Js = u32;
const DESCRIPTOR: u32 = #c;
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 {
let js = js as *mut usize;
::wasm_bindgen::__rt::assert_not_null(js);
let js = Box::from_raw(js);
#name::from_usize(*js)
#name::from_u32(js)
}
}
}).to_tokens(into);