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