1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
use crate::{
    error::Error,
    traits::{FlatSized, FlatUnsized},
    utils::mem::check_align_and_min_size,
};

/// In-place initializer of flat type.
pub unsafe trait Emplacer<T: FlatUnsized + ?Sized>: Sized {
    unsafe fn emplace_unchecked(self, bytes: &mut [u8]) -> Result<(), Error>;

    /// Apply initializer for uninitialized memory.
    fn emplace(self, bytes: &mut [u8]) -> Result<(), Error> {
        check_align_and_min_size::<T>(bytes)?;
        unsafe { self.emplace_unchecked(bytes) }
    }
}

/// Emplacer that cannot be instantiated and used as a placeholder for unused parameters.
pub enum NeverEmplacer {}

unsafe impl<T: FlatUnsized + ?Sized> Emplacer<T> for NeverEmplacer {
    unsafe fn emplace_unchecked(self, _: &mut [u8]) -> Result<(), Error> {
        unreachable!()
    }
}

unsafe impl<T: FlatSized> Emplacer<T> for T {
    unsafe fn emplace_unchecked(self, bytes: &mut [u8]) -> Result<(), Error> {
        unsafe { (Self::ptr_from_bytes(bytes) as *mut Self).write(self) };
        Ok(())
    }
}