Support Option with custom enums in JS

Find a hole automatically to use a sentinel value for `None`, and then
just wire everything up!

Closes #1198
This commit is contained in:
Alex Crichton
2019-01-28 14:12:02 -08:00
parent 03e52c7045
commit 9224455077
8 changed files with 119 additions and 5 deletions

View File

@ -207,6 +207,7 @@ pub struct Enum {
pub name: Ident,
pub variants: Vec<Variant>,
pub comments: Vec<String>,
pub hole: u32,
}
#[cfg_attr(feature = "extra-traits", derive(Debug, PartialEq, Eq))]

View File

@ -1013,6 +1013,7 @@ impl<'a> ToTokens for DescribeImport<'a> {
impl ToTokens for ast::Enum {
fn to_tokens(&self, into: &mut TokenStream) {
let enum_name = &self.name;
let hole = &self.hole;
let cast_clauses = self.variants.iter().map(|variant| {
let variant_name = &variant.name;
quote! {
@ -1034,6 +1035,7 @@ impl ToTokens for ast::Enum {
impl ::wasm_bindgen::convert::FromWasmAbi for #enum_name {
type Abi = u32;
#[inline]
unsafe fn from_abi(
js: u32,
_extra: &mut ::wasm_bindgen::convert::Stack,
@ -1044,10 +1046,21 @@ impl ToTokens for ast::Enum {
}
}
impl ::wasm_bindgen::convert::OptionFromWasmAbi for #enum_name {
#[inline]
fn is_none(val: &u32) -> bool { *val == #hole }
}
impl ::wasm_bindgen::convert::OptionIntoWasmAbi for #enum_name {
#[inline]
fn none() -> Self::Abi { #hole }
}
impl ::wasm_bindgen::describe::WasmDescribe for #enum_name {
fn describe() {
use wasm_bindgen::describe::*;
inform(ENUM);
inform(#hole);
}
}
})