Skip to main content

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}