uniffi_core/
ffi_converter_traits.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5//! Traits that define how to transfer values via the FFI layer.
6//!
7//! These traits define how to pass values over the FFI in various ways: as arguments or as return
8//! values, from Rust to the foreign side and vice-versa.  These traits are mainly used by the
9//! proc-macro generated code.  The goal is to allow the proc-macros to go from a type name to the
10//! correct function for a given FFI operation.
11//!
12//! The main traits form a sort-of tree structure from general to specific:
13//! ```ignore
14//!
15//!                         [FfiConverter]
16//!                               |
17//!            -----------------------------------------
18//!            |                                       |
19//!         [Lower]                                  [Lift]
20//!            |                                       |
21//!        -----------------                    --------------
22//!        |               |                    |            |
23//!   [LowerReturn]  [LowerError]          [LiftRef]  [LiftReturn]
24//! ```
25//!
26//! There's also:
27//!   - [TypeId], which is implemented for all types that implement any of the above traits.
28//!   - [ConvertError], which is implement for errors that can be used in callback interfaces.
29//!
30//! The `derive_ffi_traits` macro can be used to derive the specific traits from the general ones.
31//! Here's the main ways we implement these traits:
32//!
33//! * For most types we implement [FfiConverter] and use [derive_ffi_traits] to implement the rest
34//! * If a type can only be lifted/lowered, then we implement [Lift] or [Lower] and use
35//!   [derive_ffi_traits] to implement the rest
36//! * If a type needs special-case handling, like `Result<>` and `()`, we implement the traits
37//!   directly.
38//!
39//! FfiConverter has a generic parameter, that's filled in with a type local to the UniFFI consumer crate.
40//! This allows us to work around the Rust orphan rules for remote types. See
41//! `https://mozilla.github.io/uniffi-rs/internals/lifting_and_lowering.html#code-generation-and-the-fficonverter-trait`
42//! for details.
43//!
44//! ## Safety
45//!
46//! Most traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
47//! that it's safe to pass your type out to foreign-language code and back again. Buggy
48//! implementations of this trait might violate some assumptions made by the generated code,
49//! or might not match with the corresponding code in the generated foreign-language bindings.
50//! These traits should not be used directly, only in generated code, and the generated code should
51//! have fixture tests to test that everything works correctly together.
52
53use std::{borrow::Borrow, mem::ManuallyDrop, sync::Arc};
54
55use anyhow::bail;
56use bytes::Buf;
57
58use crate::{
59    FfiDefault, Handle, LiftArgsError, MetadataBuffer, Result, RustBuffer, RustCallError,
60    RustCallStatus, RustCallStatusCode, UnexpectedUniFFICallbackError,
61};
62
63/// Generalized FFI conversions
64///
65/// This trait is not used directly by the code generation, but implement this and calling
66/// [derive_ffi_traits] is a simple way to implement all the traits that are.
67///
68/// ## Safety
69///
70/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
71/// that it's safe to pass your type out to foreign-language code and back again. Buggy
72/// implementations of this trait might violate some assumptions made by the generated code,
73/// or might not match with the corresponding code in the generated foreign-language bindings.
74/// These traits should not be used directly, only in generated code, and the generated code should
75/// have fixture tests to test that everything works correctly together.
76pub unsafe trait FfiConverter<UT>: Sized {
77    /// The low-level type used for passing values of this type over the FFI.
78    ///
79    /// This must be a C-compatible type (e.g. a numeric primitive, a `#[repr(C)]` struct) into
80    /// which values of the target rust type can be converted.
81    ///
82    /// For complex data types, we currently recommend using `RustBuffer` and serializing
83    /// the data for transfer. In theory it could be possible to build a matching
84    /// `#[repr(C)]` struct for a complex data type and pass that instead, but explicit
85    /// serialization is simpler and safer as a starting point.
86    ///
87    /// If a type implements multiple FFI traits, `FfiType` must be the same for all of them.
88    type FfiType: FfiDefault;
89
90    /// Lower a rust value of the target type, into an FFI value of type Self::FfiType.
91    ///
92    /// This trait method is used for sending data from rust to the foreign language code,
93    /// by (hopefully cheaply!) converting it into something that can be passed over the FFI
94    /// and reconstructed on the other side.
95    ///
96    /// Note that this method takes an owned value; this allows it to transfer ownership in turn to
97    /// the foreign language code, e.g. by boxing the value and passing a pointer.
98    fn lower(obj: Self) -> Self::FfiType;
99
100    /// Lift a rust value of the target type, from an FFI value of type Self::FfiType.
101    ///
102    /// This trait method is used for receiving data from the foreign language code in rust,
103    /// by (hopefully cheaply!) converting it from a low-level FFI value of type Self::FfiType
104    /// into a high-level rust value of the target type.
105    ///
106    /// Since we cannot statically guarantee that the foreign-language code will send valid
107    /// values of type Self::FfiType, this method is fallible.
108    fn try_lift(v: Self::FfiType) -> Result<Self>;
109
110    /// Write a rust value into a buffer, to send over the FFI in serialized form.
111    ///
112    /// This trait method can be used for sending data from rust to the foreign language code,
113    /// in cases where we're not able to use a special-purpose FFI type and must fall back to
114    /// sending serialized bytes.
115    ///
116    /// Note that this method takes an owned value because it's transferring ownership
117    /// to the foreign language code via the RustBuffer.
118    fn write(obj: Self, buf: &mut Vec<u8>);
119
120    /// Read a rust value from a buffer, received over the FFI in serialized form.
121    ///
122    /// This trait method can be used for receiving data from the foreign language code in rust,
123    /// in cases where we're not able to use a special-purpose FFI type and must fall back to
124    /// receiving serialized bytes.
125    ///
126    /// Since we cannot statically guarantee that the foreign-language code will send valid
127    /// serialized bytes for the target type, this method is fallible.
128    ///
129    /// Note the slightly unusual type here - we want a mutable reference to a slice of bytes,
130    /// because we want to be able to advance the start of the slice after reading an item
131    /// from it (but will not mutate the actual contents of the slice).
132    fn try_read(buf: &mut &[u8]) -> Result<Self>;
133
134    /// Type ID metadata, serialized into a [MetadataBuffer].
135    const TYPE_ID_META: MetadataBuffer;
136}
137
138/// FfiConverter for Arc-types
139///
140/// This trait gets around the orphan rule limitations, which prevent library crates from
141/// implementing `FfiConverter` on an Arc. When this is implemented for T, we generate an
142/// `FfiConverter` impl for Arc<T>.
143///
144/// Note: There's no need for `FfiConverterBox`, since Box is a fundamental type.
145///
146/// ## Safety
147///
148/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
149/// that it's safe to pass your type out to foreign-language code and back again. Buggy
150/// implementations of this trait might violate some assumptions made by the generated code,
151/// or might not match with the corresponding code in the generated foreign-language bindings.
152/// These traits should not be used directly, only in generated code, and the generated code should
153/// have fixture tests to test that everything works correctly together.
154#[cfg(not(all(target_arch = "wasm32", feature = "wasm-unstable-single-threaded")))]
155pub unsafe trait FfiConverterArc<UT>: Send + Sync {
156    type FfiType: FfiDefault;
157
158    fn lower(obj: Arc<Self>) -> Self::FfiType;
159    fn try_lift(v: Self::FfiType) -> Result<Arc<Self>>;
160    fn write(obj: Arc<Self>, buf: &mut Vec<u8>);
161    fn try_read(buf: &mut &[u8]) -> Result<Arc<Self>>;
162
163    const TYPE_ID_META: MetadataBuffer;
164}
165
166/// ## Safety
167///
168/// The Safety notice is the same as for `FfiConverterArc`, but this is only used
169/// for WASM targets that are single-threaded. In this case, Send and Sync aren't
170/// necessary to check.
171#[cfg(all(target_arch = "wasm32", feature = "wasm-unstable-single-threaded"))]
172pub unsafe trait FfiConverterArc<UT> {
173    type FfiType: FfiDefault;
174
175    fn lower(obj: Arc<Self>) -> Self::FfiType;
176    fn try_lift(v: Self::FfiType) -> Result<Arc<Self>>;
177    fn write(obj: Arc<Self>, buf: &mut Vec<u8>);
178    fn try_read(buf: &mut &[u8]) -> Result<Arc<Self>>;
179
180    const TYPE_ID_META: MetadataBuffer;
181}
182
183unsafe impl<T, UT> FfiConverter<UT> for Arc<T>
184where
185    T: FfiConverterArc<UT> + ?Sized,
186{
187    type FfiType = T::FfiType;
188
189    fn lower(obj: Self) -> Self::FfiType {
190        T::lower(obj)
191    }
192
193    fn try_lift(v: Self::FfiType) -> Result<Self> {
194        T::try_lift(v)
195    }
196
197    fn write(obj: Self, buf: &mut Vec<u8>) {
198        T::write(obj, buf)
199    }
200
201    fn try_read(buf: &mut &[u8]) -> Result<Self> {
202        T::try_read(buf)
203    }
204
205    const TYPE_ID_META: MetadataBuffer = T::TYPE_ID_META;
206}
207
208/// Lift values passed by the foreign code over the FFI into Rust values
209///
210/// This is used by the code generation to handle arguments.  It's usually derived from
211/// [FfiConverter], except for types that only support lifting but not lowering.
212///
213/// See [FfiConverter] for a discussion of the methods
214///
215/// ## Safety
216///
217/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
218/// that it's safe to pass your type out to foreign-language code and back again. Buggy
219/// implementations of this trait might violate some assumptions made by the generated code,
220/// or might not match with the corresponding code in the generated foreign-language bindings.
221/// These traits should not be used directly, only in generated code, and the generated code should
222/// have fixture tests to test that everything works correctly together.
223pub unsafe trait Lift<UT>: Sized {
224    type FfiType;
225
226    fn try_lift(v: Self::FfiType) -> Result<Self>;
227
228    fn try_read(buf: &mut &[u8]) -> Result<Self>;
229
230    /// Convenience method
231    fn try_lift_from_rust_buffer(v: RustBuffer) -> Result<Self> {
232        let vec = v.destroy_into_vec();
233        let mut buf = vec.as_slice();
234        let value = Self::try_read(&mut buf)?;
235        match Buf::remaining(&buf) {
236            0 => Ok(value),
237            n => bail!("junk data left in buffer after lifting (count: {n})",),
238        }
239    }
240}
241
242/// Lower Rust values to pass them to the foreign code
243///
244/// This is used to pass arguments to callback interfaces. It's usually derived from
245/// [FfiConverter], except for types that only support lowering but not lifting.
246///
247/// See [FfiConverter] for a discussion of the methods
248///
249/// ## Safety
250///
251/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
252/// that it's safe to pass your type out to foreign-language code and back again. Buggy
253/// implementations of this trait might violate some assumptions made by the generated code,
254/// or might not match with the corresponding code in the generated foreign-language bindings.
255/// These traits should not be used directly, only in generated code, and the generated code should
256/// have fixture tests to test that everything works correctly together.
257pub unsafe trait Lower<UT>: Sized {
258    type FfiType: FfiDefault;
259
260    fn lower(obj: Self) -> Self::FfiType;
261
262    fn write(obj: Self, buf: &mut Vec<u8>);
263
264    /// Convenience method
265    fn lower_into_rust_buffer(obj: Self) -> RustBuffer {
266        let mut buf = ::std::vec::Vec::new();
267        Self::write(obj, &mut buf);
268        RustBuffer::from_vec(buf)
269    }
270}
271
272/// Return Rust values to the foreign code
273///
274/// This is usually derived from [Lower], but we special case types like `Result<>` and `()`.
275///
276/// ## Safety
277///
278/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
279/// that it's safe to pass your type out to foreign-language code and back again. Buggy
280/// implementations of this trait might violate some assumptions made by the generated code,
281/// or might not match with the corresponding code in the generated foreign-language bindings.
282/// These traits should not be used directly, only in generated code, and the generated code should
283/// have fixture tests to test that everything works correctly together.
284pub unsafe trait LowerReturn<UT>: Sized {
285    /// The type that should be returned by scaffolding functions for this type.
286    ///
287    /// When derived, it's the same as `FfiType`.
288    type ReturnType: FfiDefault;
289
290    /// Lower the return value from an scaffolding call
291    ///
292    /// Returns values that [rust_call] expects:
293    ///
294    /// - Ok(v) for `Ok` returns and non-result returns, where v is the lowered return value
295    /// - `Err(RustCallError::Error(buf))` for `Err` returns where `buf` is serialized error value.
296    fn lower_return(v: Self) -> Result<Self::ReturnType, RustCallError>;
297
298    /// Lower the return value for failed argument lifts
299    ///
300    /// This is called when we fail to make a scaffolding call, because of an error lifting an
301    /// argument.  It should return a value that [rust_call] expects:
302    ///
303    /// - By default, this is `Err(RustCallError::InternalError(msg))` where `msg` is message
304    ///   describing the failed lift.
305    /// - For Result types, if we can downcast the error to the `Err` value, then return
306    ///   `Err(RustCallError::Error(buf))`. This results in better exception throws on the foreign
307    ///   side.
308    fn handle_failed_lift(error: LiftArgsError) -> Result<Self::ReturnType, RustCallError> {
309        let LiftArgsError { arg_name, error } = error;
310        Err(RustCallError::InternalError(format!(
311            "Failed to convert arg '{arg_name}': {error}"
312        )))
313    }
314}
315
316/// Return Rust error values
317///
318/// This is implemented for types that can be the `E` param in `Result<T, E>`.
319/// It's is usually derived from [Lower], but we sometimes special case it.
320///
321/// ## Safety
322///
323/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
324/// that it's safe to pass your type out to foreign-language code and back again. Buggy
325/// implementations of this trait might violate some assumptions made by the generated code,
326/// or might not match with the corresponding code in the generated foreign-language bindings.
327/// These traits should not be used directly, only in generated code, and the generated code should
328/// have fixture tests to test that everything works correctly together.
329pub unsafe trait LowerError<UT>: Sized {
330    /// Lower this value for scaffolding function return
331    ///
332    /// Lower the type into a RustBuffer.  `RustCallStatus.error_buf` will be set to this.
333    fn lower_error(obj: Self) -> RustBuffer;
334}
335
336/// Return foreign values to Rust
337///
338/// This is usually derived from [Lower], but we special case types like `Result<>` and `()`.
339///
340/// ## Safety
341///
342/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
343/// that it's safe to pass your type out to foreign-language code and back again. Buggy
344/// implementations of this trait might violate some assumptions made by the generated code,
345/// or might not match with the corresponding code in the generated foreign-language bindings.
346/// These traits should not be used directly, only in generated code, and the generated code should
347/// have fixture tests to test that everything works correctly together.
348pub unsafe trait LiftReturn<UT>: Sized {
349    /// FFI return type for trait interfaces
350    type ReturnType;
351
352    /// Lift a successfully returned value from a trait interface
353    fn try_lift_successful_return(v: Self::ReturnType) -> Result<Self>;
354
355    /// Lift a foreign returned value from a trait interface
356    ///
357    /// When we call a foreign-implemented trait interface method, we pass a &mut RustCallStatus
358    /// and get [Self::ReturnType] returned.  This method takes both of those and lifts `Self` from
359    /// it.
360    fn lift_foreign_return(ffi_return: Self::ReturnType, call_status: RustCallStatus) -> Self {
361        match call_status.code {
362            RustCallStatusCode::Success => Self::try_lift_successful_return(ffi_return)
363                .unwrap_or_else(|e| {
364                    Self::handle_callback_unexpected_error(UnexpectedUniFFICallbackError::new(e))
365                }),
366            RustCallStatusCode::Error => {
367                Self::lift_error(ManuallyDrop::into_inner(call_status.error_buf))
368            }
369            _ => {
370                let e = <String as FfiConverter<crate::UniFfiTag>>::try_lift(
371                    ManuallyDrop::into_inner(call_status.error_buf),
372                )
373                .unwrap_or_else(|e| format!("(Error lifting message: {e}"));
374                Self::handle_callback_unexpected_error(UnexpectedUniFFICallbackError::new(e))
375            }
376        }
377    }
378
379    /// Lift a Rust value for a callback interface method error result
380    ///
381    /// This is called for "expected errors" -- the callback method returns a Result<> type and the
382    /// foreign code throws an exception that corresponds to the error type.
383    fn lift_error(_buf: RustBuffer) -> Self {
384        panic!("Callback interface method returned unexpected error")
385    }
386
387    /// Lift a Rust value for an unexpected callback interface error
388    ///
389    /// The main reason this is called is when the callback interface throws an error type that
390    /// doesn't match the Rust trait definition.  It's also called for corner cases, like when the
391    /// foreign code doesn't follow the FFI contract.
392    ///
393    /// The default implementation panics unconditionally.  Errors used in callback interfaces
394    /// handle this using the `From<UnexpectedUniFFICallbackError>` impl that the library author
395    /// must provide.
396    fn handle_callback_unexpected_error(e: UnexpectedUniFFICallbackError) -> Self {
397        panic!("Callback interface failure: {e}")
398    }
399}
400
401/// Lift references
402///
403/// This is usually derived from [Lift] and also implemented for the inner `T` value of smart
404/// pointers.  For example, if `Lift` is implemented for `Arc<T>`, then we implement this to lift
405///
406/// ## Safety
407///
408/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
409/// that it's safe to pass your type out to foreign-language code and back again. Buggy
410/// implementations of this trait might violate some assumptions made by the generated code,
411/// or might not match with the corresponding code in the generated foreign-language bindings.
412/// These traits should not be used directly, only in generated code, and the generated code should
413/// have fixture tests to test that everything works correctly together.
414/// `&T` using the Arc.
415pub unsafe trait LiftRef<UT> {
416    type LiftType: Lift<UT> + Borrow<Self>;
417}
418
419/// Type ID metadata
420///
421/// This is used to build up more complex metadata.  For example, the `MetadataBuffer` for function
422/// signatures includes a copy of this metadata for each argument and return type.
423pub trait TypeId<UT> {
424    const TYPE_ID_META: MetadataBuffer;
425}
426
427pub trait ConvertError<UT>: Sized {
428    fn try_convert_unexpected_callback_error(e: UnexpectedUniFFICallbackError) -> Result<Self>;
429}
430
431/// Manage handles for `Arc<Self>` instances
432///
433/// Handles are used to manage objects that are passed across the FFI.  They general usage is:
434///
435/// * Rust creates an `Arc<>`
436/// * Rust uses `new_handle` to create a handle that represents the Arc reference
437/// * Rust passes the handle to the foreign code as a `u64`
438/// * The foreign code passes the handle back to `Rust` to refer to the object:
439///   * Handle are usually passed as borrowed values.  When an FFI function inputs a handle as an
440///     argument, the foreign code simply passes a copy of the `u64` to Rust, which calls `get_arc`
441///     to get a new `Arc<>` clone for it.
442///   * Handles are returned as owned values.  When an FFI function returns a handle, the foreign
443///     code either stops using the handle after returning it or calls `clone_handle` and returns
444///     the clone.
445/// * Eventually the foreign code may destroy their handle by passing it into a "free" FFI
446///   function. This functions input an owned handle and consume it.
447///
448/// The foreign code also defines their own handles.  These represent foreign objects that are
449/// passed to Rust.  Using foreign handles is essentially the same as above, but in reverse.
450///
451/// Handles must always be `Send` and the objects they reference must always be `Sync`.
452/// This means that it must be safe to send handles to other threads and use them there.
453///
454/// Note: this only needs to be derived for unsized types, there's a blanket impl for `T: Sized`.
455///
456/// ## Safety
457///
458/// All traits are unsafe (implementing it requires `unsafe impl`) because we can't guarantee
459/// that it's safe to pass your type out to foreign-language code and back again. Buggy
460/// implementations of this trait might violate some assumptions made by the generated code,
461/// or might not match with the corresponding code in the generated foreign-language bindings.
462/// These traits should not be used directly, only in generated code, and the generated code should
463/// have fixture tests to test that everything works correctly together.
464/// `&T` using the Arc.
465pub unsafe trait HandleAlloc<UT>: Send + Sync {
466    /// Create a new handle for an Arc value
467    ///
468    /// Use this to lower an Arc into a handle value before passing it across the FFI.
469    /// The newly-created handle will have reference count = 1.
470    fn new_handle(value: Arc<Self>) -> Handle;
471
472    /// Clone a handle
473    ///
474    /// This creates a new handle from an existing one.
475    /// It's used when the foreign code wants to pass back an owned handle and still keep a copy
476    /// for themselves.
477    /// # Safety
478    /// The handle must be valid.
479    unsafe fn clone_handle(handle: Handle) -> Handle;
480
481    /// Get a clone of the `Arc<>` using a "borrowed" handle.
482    ///
483    /// # Safety
484    /// The handle must be valid. Take care that the handle can
485    /// not be destroyed between when it's passed and when
486    /// `get_arc()` is called.  #1797 is a cautionary tale.
487    unsafe fn get_arc(handle: Handle) -> Arc<Self> {
488        Self::consume_handle(Self::clone_handle(handle))
489    }
490
491    /// Consume a handle, getting back the initial `Arc<>`
492    /// # Safety
493    /// The handle must be valid.
494    unsafe fn consume_handle(handle: Handle) -> Arc<Self>;
495}
496
497/// Derive FFI traits
498///
499/// This can be used to derive:
500///   * [Lower] and [Lift] from [FfiConverter]
501///   * [LowerReturn] from [Lower]
502///   * [LiftReturn] and [LiftRef] from [Lift]
503///
504/// Usage:
505/// ```ignore
506///
507/// // Derive everything from [FfiConverter] for all Uniffi tags
508/// ::uniffi::derive_ffi_traits!(blanket Foo)
509/// // Derive everything from [FfiConverter] for the local crate::UniFfiTag
510/// ::uniffi::derive_ffi_traits!(local Foo)
511/// // To derive a specific trait, write out the impl item minus the actual  block
512/// ::uniffi::derive_ffi_traits!(impl<T, UT> LowerReturn<UT> for Option<T>)
513/// ```
514#[macro_export]
515#[allow(clippy::crate_in_macro_def)]
516macro_rules! derive_ffi_traits {
517    (blanket $ty:ty) => {
518        $crate::derive_ffi_traits!(impl<UT> Lower<UT> for $ty);
519        $crate::derive_ffi_traits!(impl<UT> Lift<UT> for $ty);
520        $crate::derive_ffi_traits!(impl<UT> LowerReturn<UT> for $ty);
521        $crate::derive_ffi_traits!(impl<UT> LowerError<UT> for $ty);
522        $crate::derive_ffi_traits!(impl<UT> LiftReturn<UT> for $ty);
523        $crate::derive_ffi_traits!(impl<UT> LiftRef<UT> for $ty);
524        $crate::derive_ffi_traits!(impl<UT> ConvertError<UT> for $ty);
525        $crate::derive_ffi_traits!(impl<UT> TypeId<UT> for $ty);
526    };
527
528    (local $ty:ty) => {
529        $crate::derive_ffi_traits!(impl Lower<crate::UniFfiTag> for $ty);
530        $crate::derive_ffi_traits!(impl Lift<crate::UniFfiTag> for $ty);
531        $crate::derive_ffi_traits!(impl LowerReturn<crate::UniFfiTag> for $ty);
532        $crate::derive_ffi_traits!(impl LowerError<crate::UniFfiTag> for $ty);
533        $crate::derive_ffi_traits!(impl LiftReturn<crate::UniFfiTag> for $ty);
534        $crate::derive_ffi_traits!(impl LiftRef<crate::UniFfiTag> for $ty);
535        $crate::derive_ffi_traits!(impl ConvertError<crate::UniFfiTag> for $ty);
536        $crate::derive_ffi_traits!(impl TypeId<crate::UniFfiTag> for $ty);
537    };
538
539    (impl $(<$($generic:ident),*>)? $(::uniffi::)? Lower<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
540        unsafe impl $(<$($generic),*>)* $crate::Lower<$ut> for $ty $(where $($where)*)*
541        {
542            type FfiType = <Self as $crate::FfiConverter<$ut>>::FfiType;
543
544            fn lower(obj: Self) -> Self::FfiType {
545                <Self as $crate::FfiConverter<$ut>>::lower(obj)
546            }
547
548            fn write(obj: Self, buf: &mut ::std::vec::Vec<u8>) {
549                <Self as $crate::FfiConverter<$ut>>::write(obj, buf)
550            }
551        }
552    };
553
554    (impl $(<$($generic:ident),*>)? $(::uniffi::)? Lift<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
555        unsafe impl $(<$($generic),*>)* $crate::Lift<$ut> for $ty $(where $($where)*)*
556        {
557            type FfiType = <Self as $crate::FfiConverter<$ut>>::FfiType;
558
559            fn try_lift(v: Self::FfiType) -> $crate::deps::anyhow::Result<Self> {
560                <Self as $crate::FfiConverter<$ut>>::try_lift(v)
561            }
562
563            fn try_read(buf: &mut &[u8]) -> $crate::deps::anyhow::Result<Self> {
564                <Self as $crate::FfiConverter<$ut>>::try_read(buf)
565            }
566        }
567    };
568
569    (impl $(<$($generic:ident),*>)? $(::uniffi::)? LowerReturn<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
570        unsafe impl $(<$($generic),*>)* $crate::LowerReturn<$ut> for $ty $(where $($where)*)*
571        {
572            type ReturnType = <Self as $crate::Lower<$ut>>::FfiType;
573
574            fn lower_return(v: Self) -> $crate::deps::anyhow::Result<Self::ReturnType, $crate::RustCallError> {
575                ::std::result::Result::Ok(<Self as $crate::Lower<$ut>>::lower(v))
576            }
577        }
578    };
579
580    (impl $(<$($generic:ident),*>)? $(::uniffi::)? LowerError<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
581        unsafe impl $(<$($generic),*>)* $crate::LowerError<$ut> for $ty $(where $($where)*)*
582        {
583            fn lower_error(obj: Self) -> $crate::RustBuffer {
584                <Self as $crate::Lower<$ut>>::lower_into_rust_buffer(obj)
585            }
586        }
587    };
588
589    (impl $(<$($generic:ident),*>)? $(::uniffi::)? LiftReturn<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
590        unsafe impl $(<$($generic),*>)* $crate::LiftReturn<$ut> for $ty $(where $($where)*)*
591        {
592            type ReturnType = <Self as $crate::Lift<$ut>>::FfiType;
593
594            fn try_lift_successful_return(v: Self::ReturnType) -> $crate::Result<Self> {
595                <Self as $crate::Lift<$ut>>::try_lift(v)
596            }
597        }
598    };
599
600    (impl $(<$($generic:ident),*>)? $(::uniffi::)? LiftRef<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
601        unsafe impl $(<$($generic),*>)* $crate::LiftRef<$ut> for $ty $(where $($where)*)*
602        {
603            type LiftType = Self;
604        }
605    };
606
607    (impl $(<$($generic:ident),*>)? $(::uniffi::)? ConvertError<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
608        impl $(<$($generic),*>)* $crate::ConvertError<$ut> for $ty $(where $($where)*)*
609        {
610            fn try_convert_unexpected_callback_error(e: $crate::UnexpectedUniFFICallbackError) -> $crate::deps::anyhow::Result<Self> {
611                $crate::convert_unexpected_error!(e, $ty)
612            }
613        }
614    };
615
616    (impl $(<$($generic:ident),*>)? $(::uniffi::)? HandleAlloc<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
617        // Derived HandleAlloc implementation.
618        //
619        // This is only needed for !Sized types like `dyn Trait`, below is a blanket implementation
620        // for any sized type.
621        unsafe impl $(<$($generic),*>)* $crate::HandleAlloc<$ut> for $ty $(where $($where)*)*
622        {
623            // To implement HandleAlloc for an unsized type, wrap it with a second Arc which
624            // converts the wide pointer into a normal pointer.
625
626            fn new_handle(value: ::std::sync::Arc<Self>) -> $crate::Handle {
627                $crate::Handle::from_pointer(::std::sync::Arc::into_raw(::std::sync::Arc::new(value)))
628            }
629
630            unsafe fn clone_handle(handle: $crate::Handle) -> $crate::Handle {
631                ::std::sync::Arc::<::std::sync::Arc<Self>>::increment_strong_count(handle.as_pointer::<::std::sync::Arc<Self>>());
632                handle
633            }
634
635            unsafe fn consume_handle(handle: $crate::Handle) -> ::std::sync::Arc<Self> {
636                ::std::sync::Arc::<Self>::clone(
637                    &std::sync::Arc::<::std::sync::Arc::<Self>>::from_raw(handle.as_pointer::<::std::sync::Arc<Self>>())
638                )
639            }
640        }
641    };
642
643    (impl $(<$($generic:ident),*>)? $(::uniffi::)? TypeId<$ut:path> for $ty:ty $(where $($where:tt)*)?) => {
644        impl $(<$($generic),*>)* $crate::TypeId<$ut> for $ty $(where $($where)*)*
645        {
646            const TYPE_ID_META: $crate::MetadataBuffer = <Self as $crate::FfiConverter<$ut>>::TYPE_ID_META;
647        }
648    };
649}
650
651unsafe impl<T: Send + Sync, UT> HandleAlloc<UT> for T {
652    fn new_handle(value: Arc<Self>) -> Handle {
653        Handle::from_pointer(Arc::into_raw(value))
654    }
655
656    unsafe fn clone_handle(handle: Handle) -> Handle {
657        Arc::increment_strong_count(handle.as_pointer::<T>());
658        handle
659    }
660
661    unsafe fn consume_handle(handle: Handle) -> Arc<Self> {
662        Arc::from_raw(handle.as_pointer())
663    }
664}