|
9 | 9 | pub struct Program {
|
10 | 10 | pub exports: Vec<Export>,
|
11 | 11 | pub imports: Vec<Import>,
|
| 12 | + pub enums: Vec<Enum>, |
12 | 13 | pub imported_types: Vec<(syn::Visibility, syn::Ident)>,
|
13 | 14 | pub structs: Vec<Struct>,
|
14 | 15 | }
|
@@ -47,6 +48,11 @@ pub struct Struct {
|
47 | 48 | pub name: syn::Ident,
|
48 | 49 | }
|
49 | 50 |
|
| 51 | +pub struct Enum { |
| 52 | + pub name: syn::Ident, |
| 53 | + pub variants: Vec<(syn::Ident, u32)> |
| 54 | +} |
| 55 | + |
50 | 56 | pub enum Type {
|
51 | 57 | // special
|
52 | 58 | Vector(VectorType, bool),
|
@@ -110,8 +116,13 @@ impl Program {
|
110 | 116 | let opts = opts.unwrap_or_else(|| BindgenAttrs::find(&mut f.attrs));
|
111 | 117 | self.push_foreign_mod(f, opts);
|
112 | 118 | }
|
| 119 | + syn::Item::Enum(mut e) => { |
| 120 | + let opts = opts.unwrap_or_else(|| BindgenAttrs::find(&mut e.attrs)); |
| 121 | + e.to_tokens(tokens); |
| 122 | + self.push_enum(e, opts); |
| 123 | + } |
113 | 124 | _ => panic!("#[wasm_bindgen] can only be applied to a function, \
|
114 |
| - struct, impl, or extern block"), |
| 125 | + struct, enum, impl, or extern block"), |
115 | 126 | }
|
116 | 127 | }
|
117 | 128 |
|
@@ -195,6 +206,36 @@ impl Program {
|
195 | 206 | }
|
196 | 207 | }
|
197 | 208 |
|
| 209 | + pub fn push_enum(&mut self, item: syn::ItemEnum, _opts: BindgenAttrs) { |
| 210 | + match item.vis { |
| 211 | + syn::Visibility::Public(_) => {} |
| 212 | + _ => panic!("only public enums are allowed"), |
| 213 | + } |
| 214 | + |
| 215 | + let variants = item.variants.iter().enumerate().map(|(i, v)| { |
| 216 | + match v.fields { |
| 217 | + syn::Fields::Unit => (), |
| 218 | + _ => panic!("Only C-Style enums allowed") |
| 219 | + } |
| 220 | + let value = match v.discriminant { |
| 221 | + Some((_, syn::Expr::Lit(syn::ExprLit {attrs: _, lit: syn::Lit::Int(ref int_lit)}))) => { |
| 222 | + if int_lit.value() > <u32>::max_value() as u64 { |
| 223 | + panic!("Enums can only support numbers that can be represented as u32"); |
| 224 | + } |
| 225 | + int_lit.value() as u32 |
| 226 | + }, |
| 227 | + None => i as u32, |
| 228 | + _ => panic!("Enums may only have number literal values") |
| 229 | + }; |
| 230 | + |
| 231 | + (v.ident, value) |
| 232 | + }).collect(); |
| 233 | + self.enums.push(Enum { |
| 234 | + name: item.ident, |
| 235 | + variants |
| 236 | + }); |
| 237 | + } |
| 238 | + |
198 | 239 | pub fn push_foreign_fn(&mut self,
|
199 | 240 | mut f: syn::ForeignItemFn,
|
200 | 241 | module_opts: &BindgenAttrs) {
|
@@ -297,6 +338,7 @@ impl Program {
|
297 | 338 | a.fields(&[
|
298 | 339 | ("exports", &|a| a.list(&self.exports, Export::wbg_literal)),
|
299 | 340 | ("imports", &|a| a.list(&self.imports, Import::wbg_literal)),
|
| 341 | + ("enums", &|a| a.list(&self.enums, Enum::wbg_literal)), |
300 | 342 | ("custom_type_names", &|a| {
|
301 | 343 | let names = self.exports.iter()
|
302 | 344 | .filter_map(|e| e.class)
|
@@ -634,6 +676,19 @@ impl Import {
|
634 | 676 | }
|
635 | 677 | }
|
636 | 678 |
|
| 679 | +impl Enum { |
| 680 | + fn wbg_literal(&self, a: &mut LiteralBuilder) { |
| 681 | + a.fields(&[ |
| 682 | + ("name", &|a| a.str(self.name.as_ref())), |
| 683 | + ("variants", &|a| a.list(&self.variants, |v, a| { |
| 684 | + let &(name, value) = v; |
| 685 | + a.fields(&[("name", &|a| a.str(name.as_ref())), |
| 686 | + ("value", &|a| a.append(&format!("{}", value)))]) |
| 687 | + })), |
| 688 | + ]); |
| 689 | + } |
| 690 | +} |
| 691 | + |
637 | 692 | impl Struct {
|
638 | 693 | fn from(s: syn::ItemStruct, _opts: BindgenAttrs) -> Struct {
|
639 | 694 | Struct { name: s.ident }
|
|
0 commit comments