Skip to main content

wiwi_builder/
lib.rs

1pub struct Uninit {
2	__private: ()
3}
4
5pub struct Init<T = (), M = ()>
6where
7	T: ?Sized,
8	M: ?Sized + Marker
9{
10	__marker_t: PhantomDataInvariant<T>,
11	__marker_m: PhantomDataInvariant<M>,
12}
13
14pub trait Marker {}
15
16impl Marker for () {}
17
18/// # Safety
19///
20/// [`IS_INIT`] and [`IS_UNINIT`] must both be set correctly to acccurately
21/// represent the state of the field.
22pub unsafe trait InitStatus {
23	const IS_INIT: bool;
24	const IS_UNINIT: bool = !Self::IS_INIT;
25}
26
27// SAFETY: `Uninit` represents uninitialised state
28unsafe impl InitStatus for Uninit {
29	const IS_INIT: bool = false;
30}
31
32// SAFETY: `Init` represents initialised state
33unsafe impl<T, M> InitStatus for Init<T, M>
34where
35	T: ?Sized,
36	M: ?Sized + Marker
37{
38	const IS_INIT: bool = true;
39}
40
41/// # Safety
42///
43/// Marker struct must actually represent an uninitialised state.
44pub unsafe trait IsUninit: InitStatus {}
45
46// SAFETY: `Uninit` represents uninitialised state
47unsafe impl IsUninit for Uninit {}
48
49/// # Safety
50///
51/// Marker struct must actually represent an initialised state.
52pub unsafe trait IsInit: InitStatus {}
53
54// SAFETY: `Init` represents initialised state
55unsafe impl<T, M> IsInit for Init<T, M>
56where
57	T: ?Sized,
58	M: ?Sized + Marker
59{}
60
61type PhantomDataInvariant<T> = core::marker::PhantomData<fn(T) -> T>;