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