mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-03-16 02:00:51 +00:00
Create Rust wrapping code for enums
This commit is contained in:
parent
0f8524da3c
commit
01c31cb33d
@ -9,6 +9,7 @@ use syn;
|
||||
pub struct Program {
|
||||
pub exports: Vec<Export>,
|
||||
pub imports: Vec<Import>,
|
||||
pub enums: Vec<Enum>,
|
||||
pub imported_types: Vec<(syn::Visibility, syn::Ident)>,
|
||||
pub structs: Vec<Struct>,
|
||||
}
|
||||
@ -47,6 +48,10 @@ pub struct Struct {
|
||||
pub name: syn::Ident,
|
||||
}
|
||||
|
||||
pub struct Enum {
|
||||
pub name: syn::Ident
|
||||
}
|
||||
|
||||
pub enum Type {
|
||||
// special
|
||||
Vector(VectorType, bool),
|
||||
@ -110,8 +115,13 @@ impl Program {
|
||||
let opts = opts.unwrap_or_else(|| BindgenAttrs::find(&mut f.attrs));
|
||||
self.push_foreign_mod(f, opts);
|
||||
}
|
||||
syn::Item::Enum(mut e) => {
|
||||
let opts = opts.unwrap_or_else(|| BindgenAttrs::find(&mut e.attrs));
|
||||
e.to_tokens(tokens);
|
||||
self.push_enum(e, opts);
|
||||
}
|
||||
_ => panic!("#[wasm_bindgen] can only be applied to a function, \
|
||||
struct, impl, or extern block"),
|
||||
struct, enum, impl, or extern block"),
|
||||
}
|
||||
}
|
||||
|
||||
@ -195,6 +205,28 @@ impl Program {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_enum(&mut self, item: syn::ItemEnum, opts: BindgenAttrs) {
|
||||
match item.vis {
|
||||
syn::Visibility::Public(_) => {}
|
||||
_ => panic!("only public enums are allowed"),
|
||||
}
|
||||
|
||||
let all_fields_unit = item.variants.iter().all(|ref v| {
|
||||
match v.fields {
|
||||
syn::Fields::Unit => true,
|
||||
_ => false
|
||||
}
|
||||
});
|
||||
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,
|
||||
mut f: syn::ForeignItemFn,
|
||||
module_opts: &BindgenAttrs) {
|
||||
@ -301,6 +333,7 @@ impl Program {
|
||||
let names = self.exports.iter()
|
||||
.filter_map(|e| e.class)
|
||||
.chain(self.structs.iter().map(|s| s.name))
|
||||
.chain(self.enums.iter().map(|s| s.name))
|
||||
.collect::<BTreeSet<_>>();
|
||||
a.list(&names, |s, a| {
|
||||
let val = shared::name_to_descriptor(s.as_ref());
|
||||
|
@ -50,6 +50,9 @@ fn generate_wrappers(program: ast::Program, tokens: &mut Tokens) {
|
||||
for i in program.imports.iter() {
|
||||
bindgen_import(i, tokens);
|
||||
}
|
||||
for e in program.enums.iter() {
|
||||
bindgen_enum(e, tokens);
|
||||
}
|
||||
for &(ref vis, ref t) in program.imported_types.iter() {
|
||||
bindgen_imported_type(vis, t, tokens);
|
||||
}
|
||||
@ -510,3 +513,30 @@ fn bindgen_import(import: &ast::Import, tokens: &mut Tokens) {
|
||||
invocation.to_tokens(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
|
||||
}
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}).to_tokens(into);
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ pub fn mangled_import_name(struct_: Option<&str>, f: &str) -> String {
|
||||
|
||||
pub type Type = char;
|
||||
|
||||
pub const TYPE_ENUM: char = '\u{5d}';
|
||||
pub const TYPE_NUMBER: char = '\u{5e}';
|
||||
pub const TYPE_BORROWED_STR: char = '\u{5f}';
|
||||
pub const TYPE_STRING: char = '\u{60}';
|
||||
|
Loading…
x
Reference in New Issue
Block a user