mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-19 07:51:26 +00:00
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:
@ -59,7 +59,7 @@ pub enum Descriptor {
|
||||
Vector(Box<Descriptor>),
|
||||
String,
|
||||
Anyref,
|
||||
Enum,
|
||||
Enum { hole: u32 },
|
||||
RustStruct(String),
|
||||
Char,
|
||||
Option(Box<Descriptor>),
|
||||
@ -128,7 +128,7 @@ impl Descriptor {
|
||||
OPTIONAL => Descriptor::Option(Box::new(Descriptor::_decode(data))),
|
||||
STRING => Descriptor::String,
|
||||
ANYREF => Descriptor::Anyref,
|
||||
ENUM => Descriptor::Enum,
|
||||
ENUM => Descriptor::Enum { hole: get(data) },
|
||||
RUST_STRUCT => {
|
||||
let name = (0..get(data))
|
||||
.map(|_| char::from_u32(get(data)).unwrap())
|
||||
@ -159,7 +159,7 @@ impl Descriptor {
|
||||
| Descriptor::U32
|
||||
| Descriptor::F32
|
||||
| Descriptor::F64
|
||||
| Descriptor::Enum => true,
|
||||
| Descriptor::Enum { .. } => true,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
|
@ -306,6 +306,14 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
.push(format!("isLikeNone({0}) ? 0 : {0}.codePointAt(0)", name));
|
||||
return Ok(self);
|
||||
}
|
||||
Descriptor::Enum { hole } => {
|
||||
self.cx.expose_is_like_none();
|
||||
self.js_arguments
|
||||
.push((name.clone(), "number | undefined".to_string()));
|
||||
self.rust_arguments
|
||||
.push(format!("isLikeNone({0}) ? {1} : {0}", name, hole));
|
||||
return Ok(self);
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional argument type for calling Rust function from JS: {:?}",
|
||||
arg
|
||||
@ -609,6 +617,14 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
.to_string();
|
||||
return Ok(self);
|
||||
}
|
||||
Descriptor::Enum { hole } => {
|
||||
self.ret_ty = "number | undefined".to_string();
|
||||
self.ret_expr = format!("
|
||||
const ret = RET;
|
||||
return ret === {} ? undefined : ret;
|
||||
", hole);
|
||||
return Ok(self);
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional return type for calling Rust function from JS: {:?}",
|
||||
ty
|
||||
|
@ -200,6 +200,11 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
.push(format!("{0} === 0xFFFFFF ? undefined : {0} !== 0", abi));
|
||||
return Ok(());
|
||||
}
|
||||
Descriptor::Enum { hole } => {
|
||||
self.js_arguments
|
||||
.push(format!("{0} === {1} ? undefined : {0}", abi, hole));
|
||||
return Ok(());
|
||||
}
|
||||
Descriptor::Char => {
|
||||
let value = self.shim_argument();
|
||||
self.js_arguments.push(format!(
|
||||
@ -441,6 +446,14 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
.to_string();
|
||||
return Ok(());
|
||||
}
|
||||
Descriptor::Enum { hole } => {
|
||||
self.cx.expose_is_like_none();
|
||||
self.ret_expr = format!("
|
||||
const val = JS;
|
||||
return isLikeNone(val) ? {} : val;
|
||||
", hole);
|
||||
return Ok(());
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional return type for calling JS function from Rust: {:?}",
|
||||
ty
|
||||
|
Reference in New Issue
Block a user