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

@ -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

View File

@ -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