summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs')
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs82
1 files changed, 82 insertions, 0 deletions
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs
new file mode 100644
index 0000000000..64c69e4d8e
--- /dev/null
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs
@@ -0,0 +1,82 @@
+{#
+// For each Callback Interface definition, we assume that there is a corresponding trait defined in Rust client code.
+// If the UDL callback interface and Rust trait's methods don't match, the Rust compiler will complain.
+// We generate:
+// * an init function to accept that `ForeignCallback` from the foreign language, and stores it.
+// * a holder for a `ForeignCallback`, of type `uniffi::ForeignCallbackInternals`.
+// * a proxy `struct` which implements the `trait` that the Callback Interface corresponds to. This
+// is the object that client code interacts with.
+// - for each method, arguments will be packed into a `RustBuffer` and sent over the `ForeignCallback` to be
+// unpacked and called. The return value is packed into another `RustBuffer` and sent back to Rust.
+// - a `Drop` `impl`, which tells the foreign language to forget about the real callback object.
+#}
+{% let trait_name = cbi.name() -%}
+{% let trait_impl = format!("UniFFICallbackHandler{}", trait_name) %}
+{% let foreign_callback_internals = format!("foreign_callback_{}_internals", trait_name)|upper -%}
+
+// Register a foreign callback for getting across the FFI.
+#[doc(hidden)]
+static {{ foreign_callback_internals }}: uniffi::ForeignCallbackInternals = uniffi::ForeignCallbackInternals::new();
+
+#[doc(hidden)]
+#[no_mangle]
+pub extern "C" fn {{ cbi.ffi_init_callback().name() }}(callback: uniffi::ForeignCallback, _: &mut uniffi::RustCallStatus) {
+ {{ foreign_callback_internals }}.set_callback(callback);
+ // The call status should be initialized to CALL_SUCCESS, so no need to modify it.
+}
+
+// Make an implementation which will shell out to the foreign language.
+#[doc(hidden)]
+#[derive(Debug)]
+struct {{ trait_impl }} {
+ handle: u64
+}
+
+impl {{ trait_impl }} {
+ fn new(handle: u64) -> Self {
+ Self { handle }
+ }
+}
+
+impl Drop for {{ trait_impl }} {
+ fn drop(&mut self) {
+ {{ foreign_callback_internals }}.invoke_callback::<(), crate::UniFfiTag>(
+ self.handle, uniffi::IDX_CALLBACK_FREE, Default::default()
+ )
+ }
+}
+
+uniffi::deps::static_assertions::assert_impl_all!({{ trait_impl }}: Send);
+
+impl r#{{ trait_name }} for {{ trait_impl }} {
+ {%- for meth in cbi.methods() %}
+
+ {#- Method declaration #}
+ fn r#{{ meth.name() -}}
+ ({% call rs::arg_list_decl_with_prefix("&self", meth) %})
+ {%- match (meth.return_type(), meth.throws_type()) %}
+ {%- when (Some(return_type), None) %} -> {{ return_type.borrow()|type_rs }}
+ {%- when (Some(return_type), Some(err)) %} -> ::std::result::Result<{{ return_type.borrow()|type_rs }}, {{ err|type_rs }}>
+ {%- when (None, Some(err)) %} -> ::std::result::Result<(), {{ err|type_rs }}>
+ {% else -%}
+ {%- endmatch -%} {
+ {#- Method body #}
+
+ {#- Packing args into a RustBuffer #}
+ {% if meth.arguments().len() == 0 -%}
+ let args_buf = Vec::new();
+ {% else -%}
+ let mut args_buf = Vec::new();
+ {% endif -%}
+ {%- for arg in meth.arguments() %}
+ {{ arg.as_type().borrow()|ffi_trait("Lower") }}::write(r#{{ arg.name() }}, &mut args_buf);
+ {%- endfor -%}
+ let args_rbuf = uniffi::RustBuffer::from_vec(args_buf);
+
+ {#- Calling into foreign code. #}
+ {{ foreign_callback_internals }}.invoke_callback::<{{ meth|return_type }}, crate::UniFfiTag>(self.handle, {{ loop.index }}, args_rbuf)
+ }
+ {%- endfor %}
+}
+
+::uniffi::scaffolding_ffi_converter_callback_interface!(r#{{ trait_name }}, {{ trait_impl }});