/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use proc_macro2::TokenStream; use quote::{format_ident, quote}; use syn::Result;
usecrate::util::mod_path; use uniffi_meta::UNIFFI_CONTRACT_VERSION;
pubfn setup_scaffolding(namespace: String) -> Result<TokenStream> { let module_path = mod_path()?; let ffi_contract_version_ident = format_ident!("ffi_{module_path}_uniffi_contract_version"); let namespace_upper = namespace.to_ascii_uppercase(); let namespace_const_ident = format_ident!("UNIFFI_META_CONST_NAMESPACE_{namespace_upper}"); let namespace_static_ident = format_ident!("UNIFFI_META_NAMESPACE_{namespace_upper}"); let ffi_rustbuffer_alloc_ident = format_ident!("ffi_{module_path}_rustbuffer_alloc"); let ffi_rustbuffer_from_bytes_ident = format_ident!("ffi_{module_path}_rustbuffer_from_bytes"); let ffi_rustbuffer_free_ident = format_ident!("ffi_{module_path}_rustbuffer_free"); let ffi_rustbuffer_reserve_ident = format_ident!("ffi_{module_path}_rustbuffer_reserve"); let reexport_hack_ident = format_ident!("{module_path}_uniffi_reexport_hack"); let ffi_rust_future_scaffolding_fns = rust_future_scaffolding_fns(&module_path);
// Everybody gets basic buffer support, since it's needed for passing complex types over the FFI. // // See `uniffi/src/ffi/rustbuffer.rs` for documentation on these functions
// 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.
// A trait that's in our crate for our external wrapped types to implement. #[allow(unused)] #[doc(hidden)] pubtrait UniffiCustomTypeConverter { type Builtin; fn into_custom(val: Self::Builtin) -> ::uniffi::Result<Self> where Self: ::std::marker::Sized; fn from_custom(obj: Self) -> Self::Builtin;
}
})
}
/// Generates the rust_future_* functions /// /// The foreign side uses a type-erased `Handle` to interact with futures, which presents /// a problem when creating scaffolding functions. What is the `ReturnType` parameter of `RustFutureFfi`? /// /// Handle this by using some brute-force monomorphization. For each possible ffi type, we /// generate a set of scaffolding functions. The bindings code is responsible for calling the one /// corresponds the scaffolding function that created the `Handle`. /// /// This introduces safety issues, but we do get some type checking. If the bindings code calls /// the wrong rust_future_complete function, they should get an unexpected return type, which /// hopefully will result in a compile-time error. fn rust_future_scaffolding_fns(module_path: &str) -> TokenStream { let fn_info = [
(quote! { u8 }, "u8"),
(quote! { i8 }, "i8"),
(quote! { u16 }, "u16"),
(quote! { i16 }, "i16"),
(quote! { u32 }, "u32"),
(quote! { i32 }, "i32"),
(quote! { u64 }, "u64"),
(quote! { i64 }, "i64"),
(quote! { f32 }, "f32"),
(quote! { f64 }, "f64"),
(quote! { *const ::std::ffi::c_void }, "pointer"),
(quote! { ::uniffi::RustBuffer }, "rust_buffer"),
(quote! { () }, "void"),
];
fn_info.iter()
.map(|(return_type, fn_suffix)| { let ffi_rust_future_poll = format_ident!("ffi_{module_path}_rust_future_poll_{fn_suffix}"); let ffi_rust_future_cancel = format_ident!("ffi_{module_path}_rust_future_cancel_{fn_suffix}"); let ffi_rust_future_complete = format_ident!("ffi_{module_path}_rust_future_complete_{fn_suffix}"); let ffi_rust_future_free = format_ident!("ffi_{module_path}_rust_future_free_{fn_suffix}");
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.