diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 00:47:55 +0000 |
commit | 26a029d407be480d791972afb5975cf62c9360a6 (patch) | |
tree | f435a8308119effd964b339f76abb83a57c29483 /third_party/rust/uniffi_bindgen/src/scaffolding | |
parent | Initial commit. (diff) | |
download | firefox-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')
13 files changed, 507 insertions, 0 deletions
diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/mod.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/mod.rs new file mode 100644 index 0000000000..f3759cf6fa --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/mod.rs @@ -0,0 +1,109 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use anyhow::Result; +use askama::Template; +use std::borrow::Borrow; + +use super::interface::*; +use heck::{ToShoutySnakeCase, ToSnakeCase}; + +#[derive(Template)] +#[template(syntax = "rs", escape = "none", path = "scaffolding_template.rs")] +pub struct RustScaffolding<'a> { + ci: &'a ComponentInterface, + udl_base_name: &'a str, +} +impl<'a> RustScaffolding<'a> { + pub fn new(ci: &'a ComponentInterface, udl_base_name: &'a str) -> Self { + Self { ci, udl_base_name } + } +} +mod filters { + use super::*; + + pub fn type_rs(type_: &Type) -> Result<String, askama::Error> { + Ok(match type_ { + Type::Int8 => "i8".into(), + Type::UInt8 => "u8".into(), + Type::Int16 => "i16".into(), + Type::UInt16 => "u16".into(), + Type::Int32 => "i32".into(), + Type::UInt32 => "u32".into(), + Type::Int64 => "i64".into(), + Type::UInt64 => "u64".into(), + Type::Float32 => "f32".into(), + Type::Float64 => "f64".into(), + Type::Boolean => "bool".into(), + Type::String => "String".into(), + Type::Bytes => "Vec<u8>".into(), + Type::Timestamp => "std::time::SystemTime".into(), + Type::Duration => "std::time::Duration".into(), + Type::Enum { name, .. } | Type::Record { name, .. } => format!("r#{name}"), + Type::Object { name, imp, .. } => { + format!("std::sync::Arc<{}>", imp.rust_name_for(name)) + } + Type::CallbackInterface { name, .. } => format!("Box<dyn r#{name}>"), + Type::ForeignExecutor => "::uniffi::ForeignExecutor".into(), + Type::Optional { inner_type } => { + format!("std::option::Option<{}>", type_rs(inner_type)?) + } + Type::Sequence { inner_type } => format!("std::vec::Vec<{}>", type_rs(inner_type)?), + Type::Map { + key_type, + value_type, + } => format!( + "std::collections::HashMap<{}, {}>", + type_rs(key_type)?, + type_rs(value_type)? + ), + Type::Custom { name, .. } => format!("r#{name}"), + Type::External { + name, + kind: ExternalKind::Interface, + .. + } => format!("::std::sync::Arc<r#{name}>"), + Type::External { name, .. } => format!("r#{name}"), + }) + } + + // Map a type to Rust code that specifies the FfiConverter implementation. + // + // This outputs something like `<MyStruct as Lift<crate::UniFfiTag>>` + pub fn ffi_trait(type_: &Type, trait_name: &str) -> Result<String, askama::Error> { + Ok(match type_ { + Type::External { + name, + kind: ExternalKind::Interface, + .. + } => { + format!("<::std::sync::Arc<r#{name}> as ::uniffi::{trait_name}<crate::UniFfiTag>>") + } + _ => format!( + "<{} as ::uniffi::{trait_name}<crate::UniFfiTag>>", + type_rs(type_)? + ), + }) + } + + pub fn return_type<T: Callable>(callable: &T) -> Result<String, askama::Error> { + let return_type = match callable.return_type() { + Some(t) => type_rs(&t)?, + None => "()".to_string(), + }; + match callable.throws_type() { + Some(t) => type_rs(&t)?, + None => "()".to_string(), + }; + Ok(match callable.throws_type() { + Some(e) => format!("::std::result::Result<{return_type}, {}>", type_rs(&e)?), + None => return_type, + }) + } + + // Turns a `crate-name` into the `crate_name` the .rs code needs to specify. + pub fn crate_name_rs(nm: &str) -> Result<String, askama::Error> { + Ok(format!("r#{}", nm.to_string().to_snake_case())) + } +} 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 }}); diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/Checksums.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/Checksums.rs new file mode 100644 index 0000000000..a59009d169 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/Checksums.rs @@ -0,0 +1,7 @@ +{%- for (name, checksum) in ci.iter_checksums() %} +#[no_mangle] +#[doc(hidden)] +pub extern "C" fn r#{{ name }}() -> u16 { + {{ checksum }} +} +{%- endfor %} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs new file mode 100644 index 0000000000..6b9f96f224 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/EnumTemplate.rs @@ -0,0 +1,19 @@ +{# +// 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` +#} + +#[::uniffi::derive_enum_for_udl] +enum r#{{ e.name() }} { + {%- for variant in e.variants() %} + r#{{ variant.name() }} { + {%- for field in variant.fields() %} + r#{{ field.name() }}: {{ field.as_type().borrow()|type_rs }}, + {%- endfor %} + }, + {%- endfor %} +} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs new file mode 100644 index 0000000000..94538ecaa8 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ErrorTemplate.rs @@ -0,0 +1,26 @@ +{# +// 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` +#} + +#[::uniffi::derive_error_for_udl( + {% if e.is_flat() -%} + flat_error, + {% if ci.should_generate_error_read(e) -%} + with_try_read, + {%- endif %} + {%- endif %} +)] +enum r#{{ e.name() }} { + {%- for variant in e.variants() %} + r#{{ variant.name() }} { + {%- for field in variant.fields() %} + r#{{ field.name() }}: {{ field.as_type().borrow()|type_rs }}, + {%- endfor %} + }, + {%- endfor %} +} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs new file mode 100644 index 0000000000..ade1578897 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ExternalTypesTemplate.rs @@ -0,0 +1,20 @@ +// Support for external types. + +// Types with an external `FfiConverter`... +{% for (name, crate_name, kind, tagged) in ci.iter_external_types() %} +// The FfiConverter for `{{ name }}` is defined in `{{ crate_name }}` +// If it has its existing FfiConverter defined with a UniFFITag, it needs forwarding. +{% if tagged %} +{%- match kind %} +{%- when ExternalKind::DataClass %} +::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); +{%- endmatch %} +{% endif %} +{%- endfor %} + +// We generate support for each Custom Type and the builtin type it uses. +{%- for (name, builtin) in ci.iter_custom_types() %} +::uniffi::custom_type!(r#{{ name }}, {{builtin|type_rs}}); +{%- 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 new file mode 100644 index 0000000000..e2445c670d --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ObjectTemplate.rs @@ -0,0 +1,89 @@ +// 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. + +{%- match obj.imp() -%} +{%- when ObjectImpl::Trait %} +#[::uniffi::export_for_udl] +pub trait r#{{ obj.name() }} { + {%- for meth in obj.methods() %} + fn {{ 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 }}, + {%- 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 %} +} +{% when ObjectImpl::Struct %} +{%- for tm in obj.uniffi_traits() %} +{% match tm %} +{% when UniffiTrait::Debug { fmt }%} +#[uniffi::export(Debug)] +{% when UniffiTrait::Display { fmt }%} +#[uniffi::export(Display)] +{% when UniffiTrait::Hash { hash }%} +#[uniffi::export(Hash)] +{% when UniffiTrait::Eq { eq, ne }%} +#[uniffi::export(Eq)] +{% endmatch %} +{% endfor %} +#[::uniffi::derive_object_for_udl] +struct {{ obj.rust_name() }} { } + +{%- for cons in obj.constructors() %} +#[::uniffi::export_for_udl(constructor)] +impl {{ obj.rust_name() }} { + pub fn r#{{ cons.name() }}( + {%- for arg in cons.arguments() %} + r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }}, + {%- endfor %} + ) + {%- match (cons.return_type(), cons.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 %} + { + unreachable!() + } +} +{%- endfor %} + +{%- for meth in obj.methods() %} +#[::uniffi::export_for_udl] +impl {{ obj.rust_name() }} { + pub 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 }}, + {%- 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 %} + { + unreachable!() + } +} +{%- endfor %} + +{% endmatch %} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs new file mode 100644 index 0000000000..85e131dd8c --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/RecordTemplate.rs @@ -0,0 +1,16 @@ +{# +// 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` +#} + +#[::uniffi::derive_record_for_udl] +struct r#{{ rec.name() }} { + {%- for field in rec.fields() %} + r#{{ field.name() }}: {{ field.as_type().borrow()|type_rs }}, + {%- endfor %} +} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ReexportUniFFIScaffolding.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ReexportUniFFIScaffolding.rs new file mode 100644 index 0000000000..0707feef27 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/ReexportUniFFIScaffolding.rs @@ -0,0 +1,28 @@ +// Code to re-export the UniFFI scaffolding functions. +// +// Rust won't always re-export the functions from dependencies +// ([rust-lang#50007](https://github.com/rust-lang/rust/issues/50007)) +// +// A workaround for this is to have the dependent crate reference a function from its dependency in +// an extern "C" function. This is clearly hacky and brittle, but at least we have some unittests +// that check if this works (fixtures/reexport-scaffolding-macro). +// +// The main way we use this macro is for that contain multiple UniFFI components (libxul, +// megazord). The combined library has a cargo dependency for each component and calls +// uniffi_reexport_scaffolding!() for each one. + +#[allow(missing_docs)] +#[doc(hidden)] +pub const fn uniffi_reexport_hack() {} + +#[doc(hidden)] +#[macro_export] +macro_rules! uniffi_reexport_scaffolding { + () => { + #[doc(hidden)] + #[no_mangle] + pub extern "C" fn {{ ci.namespace() }}_uniffi_reexport_hack() { + $crate::uniffi_reexport_hack() + } + }; +} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs new file mode 100644 index 0000000000..eeee0f5ee2 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/TopLevelFunctionTemplate.rs @@ -0,0 +1,15 @@ +#[::uniffi::export_for_udl] +pub fn r#{{ func.name() }}( + {%- for arg in func.arguments() %} + r#{{ arg.name() }}: {% if arg.by_ref() %}&{% endif %}{{ arg.as_type().borrow()|type_rs }}, + {%- endfor %} +) +{%- match (func.return_type(), func.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 %} +{ + unreachable!() +} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/UdlMetadata.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/UdlMetadata.rs new file mode 100644 index 0000000000..0b800343d6 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/UdlMetadata.rs @@ -0,0 +1,16 @@ + +/// Export info about the UDL while used to create us +/// See `uniffi_bindgen::macro_metadata` for how this is used. + +// ditto for info about the UDL which spawned us. +{%- let const_udl_var = "UNIFFI_META_CONST_UDL_{}"|format(ci.namespace().to_shouty_snake_case()) %} +{%- let static_udl_var = "UNIFFI_META_UDL_{}"|format(ci.namespace().to_shouty_snake_case()) %} + +const {{ const_udl_var }}: ::uniffi::MetadataBuffer = ::uniffi::MetadataBuffer::from_code(::uniffi::metadata::codes::UDL_FILE) + .concat_str("{{ ci.types.namespace.crate_name }}") + .concat_str("{{ ci.namespace() }}") + .concat_str("{{ udl_base_name }}"); + +#[doc(hidden)] +#[no_mangle] +pub static {{ static_udl_var }}: [u8; {{ const_udl_var }}.size] = {{ const_udl_var }}.into_array(); diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/macros.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/macros.rs new file mode 100644 index 0000000000..8b1f94cd1c --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/macros.rs @@ -0,0 +1,28 @@ +{# +// Template to receive calls into rust. + +// Arglist as used in the _UniFFILib function declarations. +// Note unfiltered name but type_ffi filters. +-#} +{%- macro arg_list_ffi_decl(func) %} + {%- for arg in func.arguments() %} + r#{{- arg.name() }}: {{ arg.type_().borrow()|type_ffi -}}, + {%- endfor %} + call_status: &mut uniffi::RustCallStatus +{%- endmacro -%} + +{%- macro arg_list_decl_with_prefix(prefix, meth) %} + {{- prefix -}} + {%- if meth.arguments().len() > 0 %}, {# whitespace #} + {%- for arg in meth.arguments() %} + r#{{- arg.name() }}: {{ arg.as_type().borrow()|type_rs -}}{% if loop.last %}{% else %},{% endif %} + {%- endfor %} + {%- endif %} +{%- endmacro -%} + +{% macro return_signature(func) %} +{%- match func.return_type() %} +{%- when Some with (return_type) %} -> {{ return_type|ffi_trait("LowerReturn") }}::ReturnType +{%- else -%} +{%- endmatch -%} +{%- endmacro -%} diff --git a/third_party/rust/uniffi_bindgen/src/scaffolding/templates/scaffolding_template.rs b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/scaffolding_template.rs new file mode 100644 index 0000000000..c88e204e97 --- /dev/null +++ b/third_party/rust/uniffi_bindgen/src/scaffolding/templates/scaffolding_template.rs @@ -0,0 +1,52 @@ +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! +{% import "macros.rs" as rs %} + +::uniffi::setup_scaffolding!("{{ ci.namespace() }}"); + +{% include "UdlMetadata.rs" %} + +{% for ty in ci.iter_types() %} +{%- match ty %} +{%- when Type::Map { key_type: k, value_type: v } -%} +{# Next comment MUST be after the line to be in the compiler output #} +uniffi::deps::static_assertions::assert_impl_all!({{ k|type_rs }}: ::std::cmp::Eq, ::std::hash::Hash); // record<{{ k|type_rs }}, {{ v|type_rs }}> +{%- else %} +{%- endmatch %} +{% endfor %} + +{% for e in ci.enum_definitions() %} +{% if ci.is_name_used_as_error(e.name()) %} +// Error definitions, corresponding to `error` in the UDL. +{% include "ErrorTemplate.rs" %} +{% else %} +// Enum definitions, corresponding to `enum` in UDL. +{% include "EnumTemplate.rs" %} +{% endif %} +{% endfor %} + +// Record definitions, implemented as method-less structs, corresponding to `dictionary` objects. +{% for rec in ci.record_definitions() %} +{% include "RecordTemplate.rs" %} +{% endfor %} + +// Top level functions, corresponding to UDL `namespace` functions. +{%- for func in ci.function_definitions() %} +{% include "TopLevelFunctionTemplate.rs" %} +{% endfor -%} + +// Object definitions, corresponding to UDL `interface` definitions. +{% for obj in ci.object_definitions() %} +{% include "ObjectTemplate.rs" %} +{% endfor %} + +// Callback Interface definitions, corresponding to UDL `callback interface` definitions. +{% for cbi in ci.callback_interface_definitions() %} +{% include "CallbackInterfaceTemplate.rs" %} +{% endfor %} + +// External and Wrapped types +{% include "ExternalTypesTemplate.rs" %} + +// Export scaffolding checksums for UDL items +{% include "Checksums.rs" %} |