wiwi/builder.rs
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
extern crate wiwiwiwiwi;
use crate::prelude::*;
use self::private::*;
pub use wiwiwiwiwi::builder;
pub struct Uninit {
__private: ()
}
pub trait IsUninit: IsUninitSealed {}
impl IsUninit for Uninit {}
impl IsUninitSealed for Uninit {}
pub struct Init {
__private: ()
}
pub trait IsInit: IsInitSealed {}
impl IsInit for Init {}
impl IsInitSealed for Init {}
/// Compile-time known value for if the current type encodes initialised or not
///
/// This can be used for example for a state that has a default variant, where
/// it doesn't matter if it has been set or not before buliding. However, we
/// cannot call `assume_init` on uninitialised values! We can therefore use this
/// value to check if something has been initialised (and the type changed to
/// reflect it), and act accordingly.
///
/// Since the value is a constant known at compile time, the optimiser is
/// very likely able to elide the check.
///
/// # Safety
///
/// Implementing this trait is a promise that your
/// [`IS_INIT`](InitialisationStatus::IS_INIT)
/// value is actually reflective of initialisation state, and
/// [`InvertInitialisationStatus`](InitialisationStatus::InvertInitialisationStatus)
/// is too, assuming the types have been used correctly.
pub unsafe trait InitialisationStatus: InitialisationStatusSealed {
const IS_INIT: bool;
const IS_UNINIT: bool = !Self::IS_INIT;
type InvertInitialisationStatus: InitialisationStatus;
}
// SAFETY: `Uninit` represents being uninitialised
unsafe impl InitialisationStatus for Uninit {
const IS_INIT: bool = false;
type InvertInitialisationStatus = Init;
}
impl InitialisationStatusSealed for Uninit {}
// SAFETY: `Init` represents being initialised
unsafe impl InitialisationStatus for Init {
const IS_INIT: bool = true;
type InvertInitialisationStatus = Uninit;
}
impl InitialisationStatusSealed for Init {}
/// Trait for required items that can take [`None`] for convenience, because
/// they implement [`Default`]
pub trait AcceptDefault<T>
where
Self: AcceptDefaultSealed<T>
{
fn unwrap_or_default(self) -> T;
}
impl<T> AcceptDefault<T> for T {
#[inline]
fn unwrap_or_default(self) -> T {
self
}
}
impl<T> AcceptDefaultSealed<T> for T {}
impl<T> AcceptDefault<T> for Option<T>
where
T: Default
{
#[inline]
fn unwrap_or_default(self) -> T {
self.unwrap_or_default()
}
}
impl<T> AcceptDefaultSealed<T> for Option<T> {}
pub type PhantomDataInvariant<T> = PhantomData<fn(T) -> T>;
/// notouchie
mod private {
/// notouchie
pub trait IsUninitSealed {}
/// notouchie
pub trait IsInitSealed {}
/// notouchie
pub trait InitialisationStatusSealed {}
/// notouchie
pub trait AcceptDefaultSealed<T> {}
}