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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
use crate::{emplacer::Emplacer, error::Error, utils::mem::check_align_and_min_size};
use core::{
    mem::{align_of, size_of},
    ptr,
};

/// Basic flat type properties.
pub unsafe trait FlatBase: Send + Sync {
    /// Align of the type.
    const ALIGN: usize;
    /// Minimal size of an instance of the type.
    const MIN_SIZE: usize;

    /// Size of an instance of the type.
    fn size(&self) -> usize;
}

/// Dynamically-sized flat type. Like `?Sized` but for `Flat`.
///
/// *For now has to be implemented for all [`Flat`] types because there is no mutually exclusive traits in Rust yet.*
pub unsafe trait FlatUnsized: FlatBase {
    /// Sized type that has the same alignment as `Self`.
    type AlignAs: Sized + Send + Sync;

    unsafe fn ptr_from_bytes(bytes: *mut [u8]) -> *mut Self;
    unsafe fn ptr_to_bytes(this: *mut Self) -> *mut [u8];

    unsafe fn from_bytes_unchecked(bytes: &[u8]) -> &Self {
        &*Self::ptr_from_bytes(bytes as *const _ as *mut _)
    }
    unsafe fn from_mut_bytes_unchecked(bytes: &mut [u8]) -> &mut Self {
        &mut *Self::ptr_from_bytes(bytes)
    }
    fn as_bytes(&self) -> &[u8] {
        unsafe { &*Self::ptr_to_bytes(self as *const _ as *mut _) }
    }
    /// # Safety
    ///
    /// Modification of returned bytes must not make `self` invalid.
    unsafe fn as_mut_bytes(&mut self) -> &mut [u8] {
        unsafe { &mut *Self::ptr_to_bytes(self as *mut _) }
    }

    /// Create a new instance of `Self` initializing raw memory into default state of `Self`.
    fn new_in_place<I: Emplacer<Self>>(bytes: &mut [u8], emplacer: I) -> Result<&mut Self, Error> {
        emplacer.emplace(bytes)?;
        Ok(unsafe { Self::from_mut_bytes_unchecked(bytes) })
    }
    fn assign_in_place<I: Emplacer<Self>>(&mut self, emplacer: I) -> Result<&mut Self, Error> {
        unsafe {
            let bytes = self.as_mut_bytes();
            emplacer.emplace_unchecked(bytes)?;
            Ok(Self::from_mut_bytes_unchecked(bytes))
        }
    }
}

/// Flat type runtime checking.
pub unsafe trait FlatValidate: FlatUnsized {
    unsafe fn validate_unchecked(bytes: &[u8]) -> Result<(), Error>;

    unsafe fn validate_ptr(this: *const Self) -> Result<(), Error> {
        unsafe { Self::validate_unchecked(&*Self::ptr_to_bytes(this as *mut _)) }
    }

    /// Check that memory contents of `this` is valid for `Self`.
    fn validate(bytes: &[u8]) -> Result<(), Error> {
        check_align_and_min_size::<Self>(bytes)?;
        unsafe { Self::validate_unchecked(bytes) }
    }

    fn from_bytes(bytes: &[u8]) -> Result<&Self, Error> {
        Self::validate(bytes)?;
        Ok(unsafe { Self::from_bytes_unchecked(bytes) })
    }
    fn from_mut_bytes(bytes: &mut [u8]) -> Result<&mut Self, Error> {
        Self::validate(bytes)?;
        Ok(unsafe { Self::from_mut_bytes_unchecked(bytes) })
    }
}

/// Flat type.
///
/// *If you want to implement this type for your custom type it's recommended to use safe `#[flat]` attribute macro instead.*
///
/// # Safety
///
/// By implementing this trait by yourself you guarantee:
///
/// + `Self` has stable binary representation that will not change in future.
///   (But the representation could be differ across different platforms. If you need stronger guarantees consider using `Portable` types.)
/// + `Self` don't own any resources outside of it.
/// + `Self` could be trivially copied as bytes. (We cannot require `Self: `[`Copy`] because it `?Sized`.)
/// + All methods of dependent traits have proper implementation and will not cause an UB.
pub unsafe trait Flat: FlatBase + FlatUnsized + FlatValidate {}

/// Statically-sized flat type.
///
/// # Safety
///
/// `SIZE` must match `Self` size.
pub unsafe trait FlatSized: FlatUnsized + Sized {
    /// Static size of the type.
    const SIZE: usize = size_of::<Self>();
}

unsafe impl<T: Flat> FlatSized for T {}

unsafe impl<T: FlatSized> FlatBase for T {
    const ALIGN: usize = align_of::<Self>();

    const MIN_SIZE: usize = Self::SIZE;

    fn size(&self) -> usize {
        Self::SIZE
    }
}

unsafe impl<T: FlatSized> FlatUnsized for T {
    type AlignAs = T;

    unsafe fn ptr_from_bytes(bytes: *mut [u8]) -> *mut Self {
        bytes as *mut Self
    }
    unsafe fn ptr_to_bytes(this: *mut Self) -> *mut [u8] {
        ptr::slice_from_raw_parts_mut(this as *mut u8, Self::SIZE)
    }
}

/// Flat types that can be initialized to default state.
///
/// # Safety
///
/// Methods must properly initialize memory.
pub trait FlatDefault: Flat {
    type DefaultEmplacer: Emplacer<Self>;

    /// Initialize uninitialized memory into valid default state.
    ///
    /// This method returned `Ok` must guaratee that `this` could be safely transmuted to `Self`.
    fn default_emplacer() -> Self::DefaultEmplacer;

    /// Create a new instance of `Self` initializing raw memory into default state of `Self`.
    fn default_in_place(bytes: &mut [u8]) -> Result<&mut Self, Error> {
        Self::new_in_place(bytes, Self::default_emplacer())
    }
}

impl<T: Flat + Default> FlatDefault for T {
    type DefaultEmplacer = Self;

    fn default_emplacer() -> Self::DefaultEmplacer {
        Self::default()
    }
}