memconstruct/
lib.rs

1pub mod alloc;
2
3mod array;
4mod primitive;
5
6pub use memconstruct_macros::MemConstruct;
7
8pub use alloc::construct_box;
9
10use std::mem::MaybeUninit;
11
12pub unsafe trait MemConstruct {
13    type Constructor: MemConstructConstructor<Target = Self>;
14    type ConstructorFinishedToken;
15
16    #[doc(hidden)]
17    fn new_boxed_zst() -> Box<Self>
18    where
19        Self: Sized,
20    {
21        unreachable!("Only zsts should implement this function")
22    }
23}
24
25/// A type used to construct a heap constructable object.
26///
27/// This trait is unsafe to implement and shouldn't be manually implemented. A safe implementation
28/// of this is generated when you derive `MemConstruct` for your type.
29////
30/// # Implementation for Structs:
31/// For normal structs a `set` function is generated for every field, each of these `set` functions
32/// has to be called exactly once, this is checked via typestate.
33///
34/// # Implementation for ZSTs:
35/// For `ZSTs` the generated constructor has no functions and is always "ready". The construct
36/// functions will still be called for ZSTs.
37pub unsafe trait MemConstructConstructor {
38    type Target;
39
40    /// Create a new `MemConstructConstructor`
41    ///
42    /// # Safety
43    ///
44    /// The pointer has to be a valid, non dangling pointer. The pointer must be well
45    /// aligned and non null if not documented otherwise.
46    unsafe fn new(ptr: *mut Self::Target) -> Self;
47}
48
49pub unsafe fn init_ptr<
50    T: MemConstruct,
51    F: FnOnce(T::Constructor) -> T::ConstructorFinishedToken,
52>(
53    ptr: *mut T,
54    func: F,
55) {
56    func(T::Constructor::new(ptr));
57}
58
59pub fn init_maybe_uninit<
60    T: MemConstruct,
61    F: FnOnce(T::Constructor) -> T::ConstructorFinishedToken,
62>(
63    uninit: &mut MaybeUninit<T>,
64    func: F,
65) {
66    unsafe { init_ptr(uninit.as_mut_ptr(), func) }
67}
68