summaryrefslogtreecommitdiffstats
path: root/third_party/rust/uniffi_bindgen/src/scaffolding/templates
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/uniffi_bindgen/src/scaffolding/templates')
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs93
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs13
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs10
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs2
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/ObjectTemplate.rs34
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs8
-rw-r--r--third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs5
7 files changed, 44 insertions, 121 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
index 64c69e4d8e..658f4c8de5 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/CallbackInterfaceTemplate.rs
@@ -1,82 +1,17 @@
-{#
-// 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 }} {
+#[::uniffi::export_for_udl(callback_interface)]
+pub trait r#{{ cbi.name() }} {
{%- 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 -%}
+ fn r#{{ meth.name() }}(
+ {% if meth.takes_self_by_arc()%}self: Arc<Self>{% else %}&self{% 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 %}
+ r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }},
+ {%- endfor %}
+ )
+ {%- match (meth.return_type(), meth.throws_type()) %}
+ {%- when (Some(return_type), None) %} -> {{ return_type|type_rs }};
+ {%- when (Some(return_type), Some(error_type)) %} -> ::std::result::Result::<{{ return_type|type_rs }}, {{ error_type|type_rs }}>;
+ {%- when (None, Some(error_type)) %} -> ::std::result::Result::<(), {{ error_type|type_rs }}>;
+ {%- when (None, None) %};
+ {%- endmatch %}
+ {% endfor %}
}
-
-::uniffi::scaffolding_ffi_converter_callback_interface!(r#{{ trait_name }}, {{ trait_impl }});
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs
index 6b9f96f224..f918ef2f3a 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs
@@ -1,13 +1,12 @@
{#
-// For each enum declared in the UDL, we assume the caller has provided a corresponding
-// rust `enum`. We provide the traits for sending it across the FFI, which will fail to
-// compile if the provided struct has a different shape to the one declared in the UDL.
-//
-// We define a unit-struct to implement the trait to sidestep Rust's orphan rule (ADR-0006). It's
-// public so other crates can refer to it via an `[External='crate'] typedef`
+// Forward work to `uniffi_macros` This keeps macro-based and UDL-based generated code consistent.
#}
-#[::uniffi::derive_enum_for_udl]
+#[::uniffi::derive_enum_for_udl(
+ {%- if e.is_non_exhaustive() -%}
+ non_exhaustive,
+ {%- endif %}
+)]
enum r#{{ e.name() }} {
{%- for variant in e.variants() %}
r#{{ variant.name() }} {
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs
index 94538ecaa8..64f48e2334 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs
@@ -1,10 +1,5 @@
{#
-// For each error declared in the UDL, we assume the caller has provided a corresponding
-// rust `enum`. We provide the traits for sending it across the FFI, which will fail to
-// compile if the provided struct has a different shape to the one declared in the UDL.
-//
-// We define a unit-struct to implement the trait to sidestep Rust's orphan rule (ADR-0006). It's
-// public so other crates can refer to it via an `[External='crate'] typedef`
+// Forward work to `uniffi_macros` This keeps macro-based and UDL-based generated code consistent.
#}
#[::uniffi::derive_error_for_udl(
@@ -14,6 +9,9 @@
with_try_read,
{%- endif %}
{%- endif %}
+ {%- if e.is_non_exhaustive() -%}
+ non_exhaustive,
+ {%- endif %}
)]
enum r#{{ e.name() }} {
{%- for variant in e.variants() %}
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs
index ade1578897..d67e172cc2 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs
@@ -10,6 +10,8 @@
::uniffi::ffi_converter_forward!(r#{{ name }}, ::{{ crate_name|crate_name_rs }}::UniFfiTag, crate::UniFfiTag);
{%- when ExternalKind::Interface %}
::uniffi::ffi_converter_arc_forward!(r#{{ name }}, ::{{ crate_name|crate_name_rs }}::UniFfiTag, crate::UniFfiTag);
+{%- when ExternalKind::Trait %}
+::uniffi::ffi_converter_arc_forward!(dyn r#{{ name }}, ::{{ crate_name|crate_name_rs }}::UniFfiTag, crate::UniFfiTag);
{%- endmatch %}
{% endif %}
{%- endfor %}
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ObjectTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ObjectTemplate.rs
index e2445c670d..e752878af5 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ObjectTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ObjectTemplate.rs
@@ -1,24 +1,15 @@
-// For each Object definition, we assume the caller has provided an appropriately-shaped `struct T`
-// with an `impl` for each method on the object. We create an `Arc<T>` for "safely" handing out
-// references to these structs to foreign language code, and we provide a `pub extern "C"` function
-// corresponding to each method.
-//
-// (Note that "safely" is in "scare quotes" - that's because we use functions on an `Arc` that
-// that are inherently unsafe, but the code we generate is safe in practice.)
-//
-// If the caller's implementation of the struct does not match with the methods or types specified
-// in the UDL, then the rust compiler will complain with a (hopefully at least somewhat helpful!)
-// error message when processing this generated code.
+{#
+// Forward work to `uniffi_macros` This keeps macro-based and UDL-based generated code consistent.
+#}
-{%- match obj.imp() -%}
-{%- when ObjectImpl::Trait %}
-#[::uniffi::export_for_udl]
+{%- if obj.is_trait_interface() %}
+#[::uniffi::export_for_udl{% if obj.has_callback_interface() %}(with_foreign){% endif %}]
pub trait r#{{ obj.name() }} {
{%- for meth in obj.methods() %}
- fn {{ meth.name() }}(
+ {% if meth.is_async() %}async {% endif %}fn r#{{ meth.name() }}(
{% if meth.takes_self_by_arc()%}self: Arc<Self>{% else %}&self{% endif %},
{%- for arg in meth.arguments() %}
- {{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }},
+ r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }},
{%- endfor %}
)
{%- match (meth.return_type(), meth.throws_type()) %}
@@ -29,7 +20,7 @@ pub trait r#{{ obj.name() }} {
{%- endmatch %}
{% endfor %}
}
-{% when ObjectImpl::Struct %}
+{%- else %}
{%- for tm in obj.uniffi_traits() %}
{% match tm %}
{% when UniffiTrait::Debug { fmt }%}
@@ -46,9 +37,10 @@ pub trait r#{{ obj.name() }} {
struct {{ obj.rust_name() }} { }
{%- for cons in obj.constructors() %}
-#[::uniffi::export_for_udl(constructor)]
+#[::uniffi::export_for_udl]
impl {{ obj.rust_name() }} {
- pub fn r#{{ cons.name() }}(
+ #[uniffi::constructor]
+ pub {% if cons.is_async() %}async {% endif %}fn r#{{ cons.name() }}(
{%- for arg in cons.arguments() %}
r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }},
{%- endfor %}
@@ -68,7 +60,7 @@ impl {{ obj.rust_name() }} {
{%- for meth in obj.methods() %}
#[::uniffi::export_for_udl]
impl {{ obj.rust_name() }} {
- pub fn r#{{ meth.name() }}(
+ pub {% if meth.is_async() %}async {% endif %}fn r#{{ meth.name() }}(
{% if meth.takes_self_by_arc()%}self: Arc<Self>{% else %}&self{% endif %},
{%- for arg in meth.arguments() %}
r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }},
@@ -86,4 +78,4 @@ impl {{ obj.rust_name() }} {
}
{%- endfor %}
-{% endmatch %}
+{% endif %}
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs
index 85e131dd8c..a7affdf7b8 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs
@@ -1,11 +1,5 @@
{#
-// For each record declared in the UDL, we assume the caller has provided a corresponding
-// rust `struct` with the declared fields. We provide the traits for sending it across the FFI.
-// If the caller's struct does not match the shape and types declared in the UDL then the rust
-// compiler will complain with a type error.
-//
-// We define a unit-struct to implement the trait to sidestep Rust's orphan rule (ADR-0006). It's
-// public so other crates can refer to it via an `[External='crate'] typedef`
+// Forward work to `uniffi_macros` This keeps macro-based and UDL-based generated code consistent.
#}
#[::uniffi::derive_record_for_udl]
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs
index eeee0f5ee2..27f3686b9f 100644
--- a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs
+++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs
@@ -1,5 +1,8 @@
+{#
+// Forward work to `uniffi_macros` This keeps macro-based and UDL-based generated code consistent.
+#}
#[::uniffi::export_for_udl]
-pub fn r#{{ func.name() }}(
+pub {% if func.is_async() %}async {% endif %}fn r#{{ func.name() }}(
{%- for arg in func.arguments() %}
r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }},
{%- endfor %}