Skip to main content

extern_trait/
lib.rs

1#![no_std]
2#![doc = include_str!("../README.md")]
3
4pub use extern_trait_impl::*;
5
6/// Opaque representation used to store implementation types in proxy structs.
7///
8/// This type is two pointers in size, which means implementation types must be
9/// at most `2 * size_of::<usize>()` bytes (16 bytes on 64-bit, 8 bytes on 32-bit).
10///
11/// The size constraint is checked at compile time.
12#[doc(hidden)]
13#[repr(C)]
14pub struct Repr(*const (), *const ());
15
16impl Repr {
17    #[doc(hidden)]
18    #[inline]
19    pub fn from_value<T: Sized>(value: T) -> Self {
20        const { assert!(core::mem::size_of::<T>() <= core::mem::size_of::<Repr>()) };
21        let mut repr = core::mem::MaybeUninit::<Repr>::zeroed();
22        // SAFETY: We just asserted that size_of::<T>() <= size_of::<Repr>()
23        unsafe {
24            core::ptr::write(repr.as_mut_ptr().cast::<T>(), value);
25            repr.assume_init()
26        }
27    }
28
29    #[doc(hidden)]
30    #[inline]
31    pub fn into_value<T: Sized>(self) -> T {
32        const { assert!(core::mem::size_of::<T>() <= core::mem::size_of::<Repr>()) };
33        // SAFETY: We require that size_of::<T>() <= size_of::<Repr>(),
34        // and the caller ensures the Repr was created from a valid T.
35        unsafe { core::ptr::read((&self as *const Repr).cast::<T>()) }
36    }
37}
38
39#[doc(hidden)]
40pub mod __private {
41    #[doc(hidden)]
42    pub use typeid::ConstTypeId;
43}