zr/opaque_bytes.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
5use crate::opaque::Opaque;
6
7/// A generic, safe opaque storage container with exact const size constraints.
8///
9/// This integrates with `Opaque<T>` to guarantee the Rust compiler knows the underlying memory
10/// is interior-mutable (via `UnsafeCell`) and potentially uninitialized (via `MaybeUninit`).
11pub type OpaqueBytes<const SIZE: usize> = Opaque<[u8; SIZE]>;
12
13/// Defines an opaque C++ storage type with explicit size, alignment, and an FFI `init` function.
14#[macro_export]
15macro_rules! define_opaque_storage_ffi {
16 (
17 $(#[$meta:meta])*
18 $vis:vis struct $name:ident(
19 $size:expr,
20 $align_const:expr,
21 $align_literal:literal,
22 $ffi_fn:path
23 $(, $arg:ident : $arg_ty:ty)* $(,)?
24 );
25 ) => {
26 $(#[$meta])*
27 #[repr(C, align($align_literal))]
28 $vis struct $name {
29 inner: $crate::OpaqueBytes<{$size}>,
30 _pinned: ::core::marker::PhantomPinned,
31 }
32
33 $crate::static_assert_size_and_align!($name, $size, $align_const);
34
35 impl $name {
36 $vis unsafe fn init(
37 $( $arg : $arg_ty ),*
38 ) -> impl ::pin_init::PinInit<Self, ::core::convert::Infallible> {
39 $crate::pin_init_ffi!($ffi_fn $(, $arg)*)
40 }
41
42 /// Returns a raw void pointer to the underlying storage.
43 $vis fn as_void_ptr(&self) -> *mut ::core::ffi::c_void {
44 self.inner.get() as *mut ::core::ffi::c_void
45 }
46 }
47 };
48}