zr/pin_init.rs
1// Copyright 2026 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/// A helper macro to initialize a pinned object in-place using a raw FFI constructor.
6///
7/// This generates a `PinInit` block that passes a type-cast pointer of the allocated
8/// slot to the FFI function, returning `Ok(())`.
9#[macro_export]
10macro_rules! pin_init_ffi {
11 ($ffi_fn:expr) => {
12 unsafe {
13 pin_init::pin_init_from_closure(|slot| {
14 $ffi_fn(slot as *mut _);
15 Ok(())
16 })
17 }
18 };
19 ($ffi_fn:expr, $($args:expr),+ $(,)?) => {
20 unsafe {
21 pin_init::pin_init_from_closure(move |slot| {
22 $ffi_fn(slot as *mut _, $($args),*);
23 Ok(())
24 })
25 }
26 };
27}
28
29/// A helper macro to implement `PinnedDrop` using a raw FFI destructor.
30///
31/// This generates a `PinnedDrop` implementation that calls the FFI function
32/// with a type-cast pointer of the object.
33///
34/// # Safety
35///
36/// The FFI function must take a pointer to the object and correctly clean it up.
37#[macro_export]
38macro_rules! unsafe_pinned_drop_ffi {
39 ($type:ty, $ffi_fn:expr) => {
40 #[pin_init::pinned_drop]
41 impl pin_init::PinnedDrop for $type {
42 fn drop(self: core::pin::Pin<&mut Self>) {
43 unsafe {
44 let me = self.get_unchecked_mut();
45 $ffi_fn($crate::ToMutPtr::to_mut_ptr(me) as *mut _);
46 }
47 }
48 }
49 };
50}