mirror of
https://github.com/fluencelabs/wasm-bindgen
synced 2025-06-13 13:01:22 +00:00
Support Option<RustStruct>
in arguments/returns
Add all the necessary support in a few locations and we should be good to go! Closes #1252
This commit is contained in:
@ -313,6 +313,18 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
.push(format!("isLikeNone({0}) ? {1} : {0}", name, hole));
|
||||
return Ok(self);
|
||||
}
|
||||
Descriptor::RustStruct(ref s) => {
|
||||
self.js_arguments.push((name.clone(), format!("{} | undefined", s)));
|
||||
self.prelude(&format!("let ptr{} = 0;", i));
|
||||
self.prelude(&format!("if ({0} !== null && {0} !== undefined) {{", name));
|
||||
self.assert_class(&name, s);
|
||||
self.assert_not_moved(&name);
|
||||
self.prelude(&format!("ptr{} = {}.ptr;", i, name));
|
||||
self.prelude(&format!("{}.ptr = 0;", name));
|
||||
self.prelude("}");
|
||||
self.rust_arguments.push(format!("ptr{}", i));
|
||||
return Ok(self);
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional argument type for calling Rust function from JS: {:?}",
|
||||
arg
|
||||
@ -322,44 +334,13 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
|
||||
if let Some(s) = arg.rust_struct() {
|
||||
self.js_arguments.push((name.clone(), s.to_string()));
|
||||
|
||||
if self.cx.config.debug {
|
||||
self.cx.expose_assert_class();
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
_assertClass({arg}, {struct_});\n\
|
||||
",
|
||||
arg = name,
|
||||
struct_ = s
|
||||
));
|
||||
}
|
||||
|
||||
self.assert_class(&name, s);
|
||||
self.assert_not_moved(&name);
|
||||
if arg.is_by_ref() {
|
||||
self.rust_arguments.push(format!("{}.ptr", name));
|
||||
} else {
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
const ptr{i} = {arg}.ptr;\n\
|
||||
",
|
||||
i = i,
|
||||
arg = name
|
||||
));
|
||||
if self.cx.config.debug {
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
if (ptr{i} === 0) {{
|
||||
throw new Error('Attempt to use a moved value');
|
||||
}}
|
||||
",
|
||||
i = i,
|
||||
));
|
||||
}
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
{arg}.ptr = 0;\n\
|
||||
",
|
||||
arg = name
|
||||
));
|
||||
self.prelude(&format!("const ptr{} = {}.ptr;", i, name));
|
||||
self.prelude(&format!("{}.ptr = 0;", name));
|
||||
self.rust_arguments.push(format!("ptr{}", i));
|
||||
}
|
||||
return Ok(self);
|
||||
@ -627,6 +608,17 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
);
|
||||
return Ok(self);
|
||||
}
|
||||
Descriptor::RustStruct(ref name) => {
|
||||
self.ret_ty = format!("{} | undefined", name);
|
||||
self.cx.require_class_wrap(name);
|
||||
self.ret_expr = format!("
|
||||
const ptr = RET;
|
||||
return ptr === 0 ? undefined : {}.__wrap(ptr);
|
||||
",
|
||||
name,
|
||||
);
|
||||
return Ok(self);
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional return type for calling Rust function from JS: {:?}",
|
||||
ty
|
||||
@ -764,4 +756,26 @@ impl<'a, 'b> Js2Rust<'a, 'b> {
|
||||
ts.push(';');
|
||||
(js, ts, self.js_doc_comments())
|
||||
}
|
||||
|
||||
fn assert_class(&mut self, arg: &str, class: &str) {
|
||||
if !self.cx.config.debug {
|
||||
return
|
||||
}
|
||||
self.cx.expose_assert_class();
|
||||
self.prelude(&format!("_assertClass({}, {});", arg, class));
|
||||
}
|
||||
|
||||
fn assert_not_moved(&mut self, arg: &str) {
|
||||
if !self.cx.config.debug {
|
||||
return
|
||||
}
|
||||
self.prelude(&format!(
|
||||
"\
|
||||
if ({0}.ptr === 0) {{
|
||||
throw new Error('Attempt to use a moved value');
|
||||
}}
|
||||
",
|
||||
arg,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -213,6 +213,13 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
));
|
||||
return Ok(());
|
||||
}
|
||||
Descriptor::RustStruct(ref class) => {
|
||||
self.cx.require_class_wrap(class);
|
||||
let assign = format!("let c{0} = {0} === 0 ? undefined : {1}.__wrap({0});", abi, class);
|
||||
self.prelude(&assign);
|
||||
self.js_arguments.push(format!("c{}", abi));
|
||||
return Ok(());
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional argument type for calling JS function from Rust: {:?}",
|
||||
arg
|
||||
@ -456,6 +463,24 @@ impl<'a, 'b> Rust2Js<'a, 'b> {
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
Descriptor::RustStruct(ref class) => {
|
||||
// Like below, assert the type
|
||||
self.ret_expr = format!(
|
||||
"\
|
||||
const val = JS;
|
||||
if (val === undefined || val === null)
|
||||
return 0;
|
||||
if (!(val instanceof {0})) {{
|
||||
throw new Error('expected value of type {0}');
|
||||
}}
|
||||
const ret = val.ptr;
|
||||
val.ptr = 0;
|
||||
return ret;\
|
||||
",
|
||||
class
|
||||
);
|
||||
return Ok(());
|
||||
}
|
||||
_ => bail!(
|
||||
"unsupported optional return type for calling JS function from Rust: {:?}",
|
||||
ty
|
||||
|
Reference in New Issue
Block a user