core_extensions/
type_level_bool.rs

1//! Type level booleans
2//!
3//! # Example
4//!
5//! Access of privileges based on renamed Boolean types.
6//!
7#![cfg_attr(feature = "phantom", doc = " ```rust")]
8#![cfg_attr(not(feature = "phantom"), doc = " ```ignore")]
9//! use std::mem;
10//! use std::marker::PhantomData;
11//!
12//! use core_extensions::CovariantPhantom;
13//!
14//! pub use core_extensions::type_level_bool::{
15//!     Boolean as PrivilegeLevel,
16//!     False as Unprivileged,
17//!     True as Privileged,
18//! };
19//!
20//!
21//! #[repr(C)]
22//! #[derive(Debug)]
23//! struct User<P>{
24//!     name: String,
25//!     privilege_level: CovariantPhantom<P>,
26//! }
27//!
28//! impl<P: PrivilegeLevel> User<P>{
29//!     fn new(name: String, privilege_level: P) -> Self {
30//!         Self{name, privilege_level: PhantomData}
31//!     }
32//!     fn name(&self)->&str{
33//!         &self.name
34//!     }
35//!     fn into_unprivileged(self) -> User<Unprivileged> {
36//!         User{name: self.name, privilege_level: PhantomData}
37//!     }
38//!     fn as_unprivileged(self: &mut User<P>) -> &mut User<Unprivileged> {
39//!         // Only the type parameter P changes here
40//!         unsafe{ mem::transmute(self) }
41//!     }
42//! }
43//!
44//! impl User<Privileged>{
45//!     fn set_name(&mut self, name: String){
46//!         self.name = name;
47//!     }
48//! }
49//!
50//! let mut user: User<Privileged> = User::new("bob".into(), Privileged);
51//! assert_eq!(user.name(), "bob");
52//!
53//! user.set_name("paul".into());
54//! assert_eq!(user.name(), "paul");
55//!
56//! {
57//!     let user: &mut User<Unprivileged> = user.as_unprivileged();
58//!
59//!     // Unprivileged Users can't change their name.
60//!     // user.set_name("james".into());
61//!
62//!     assert_eq!(user.name(), "paul");
63//! }
64//!
65//! user.set_name("john".into());
66//! assert_eq!(user.name(), "john");
67//!
68//! ```
69//!
70//!
71
72#[cfg(feature = "const_default")]
73use crate::ConstDefault;
74
75#[cfg(not(feature = "const_default"))]
76use std_::marker::Sized as ConstDefault;
77
78
79
80use std_::fmt::{self, Debug, Display};
81use std_::ops;
82
83#[cfg(feature = "marker_type")]
84use crate::MarkerType;
85
86#[cfg(not(feature = "marker_type"))]
87use std_::marker::Sized as MarkerType;
88
89
90/// Represents a type-level `true`
91#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
92pub struct True;
93
94/// Represents a type-level `false`
95#[derive(Debug, Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
96pub struct False;
97
98impl Display for True {
99    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
100        f.write_str("True")
101    }
102}
103
104impl Display for False {
105    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
106        f.write_str("False")
107    }
108}
109
110mod sealed {
111    use super::{False, True};
112    pub trait Sealed {}
113    impl Sealed for True {}
114    impl Sealed for False {}
115}
116use self::sealed::Sealed;
117
118#[cfg(feature = "marker_type")]
119unsafe impl MarkerType for True {}
120
121#[cfg(feature = "marker_type")]
122unsafe impl MarkerType for False {}
123
124const _: &[[(); 0]] = &[
125    [(); std_::mem::size_of::<True>()],
126    [(); std_::mem::size_of::<False>()],
127    [(); std_::mem::align_of::<True>() - 1],
128    [(); std_::mem::align_of::<False>() - 1],
129];
130
131#[cfg(feature = "const_default")]
132impl ConstDefault for True {
133    const DEFAULT: Self = True;
134}
135
136#[cfg(feature = "const_default")]
137impl ConstDefault for False {
138    const DEFAULT: Self = False;
139}
140
141/// Represents a type-level `bool`
142///
143/// Only implemented on [`True`] and [`False`].
144///
145/// For examples look at [the module-level documentation](./index.html).
146///
147/// This trait is sealed and cannot be implemented for types outside this crate.
148///
149/// [`True`]: ./struct.True.html
150/// [`False`]: ./struct.False.html
151pub trait Boolean:
152    Sealed
153    + MarkerType
154    + ConstDefault
155    + Default
156    + Sized
157    + Debug
158    + Copy
159    + Clone
160    + ops::Not
161    + ops::BitAnd<True, Output = Self>
162    + ops::BitAnd<False, Output = False>
163    + ops::BitAnd<Self, Output = Self>
164    + ops::BitOr<True, Output = True>
165    + ops::BitOr<False, Output = Self>
166    + ops::BitOr<Self, Output = Self>
167    + ops::BitXor<True, Output = <Self as ops::Not>::Output>
168    + ops::BitXor<False, Output = Self>
169    + ops::BitXor<Self, Output = False>
170{
171    /// The `bool` value of this type
172    const VALUE: bool;
173}
174
175impl Boolean for True {
176    const VALUE: bool = true;
177}
178impl Boolean for False {
179    const VALUE: bool = false;
180}
181
182mod internals {
183    #[cfg(feature = "const_default")]
184    use crate::ConstDefault;
185
186    use super::{Boolean, False, True, Not};
187
188    use std_::ops;
189
190    impl ops::Not for True {
191        type Output = False;
192        fn not(self) -> Self::Output {
193            False
194        }
195    }
196    impl ops::Not for False {
197        type Output = True;
198        fn not(self) -> Self::Output {
199            True
200        }
201    }
202
203    impl<B> ops::BitAnd<B> for False {
204        type Output = False;
205        fn bitand(self, _: B) -> Self::Output {
206            False
207        }
208    }
209    impl<B> ops::BitAnd<B> for True {
210        type Output = B;
211        fn bitand(self, v: B) -> Self::Output {
212            v
213        }
214    }
215
216    impl<B> ops::BitOr<B> for True {
217        type Output = True;
218        fn bitor(self, _: B) -> Self::Output {
219            True
220        }
221    }
222    impl<B> ops::BitOr<B> for False {
223        type Output = B;
224        fn bitor(self, v: B) -> Self::Output {
225            v
226        }
227    }
228
229    impl<B: Boolean> ops::BitXor<B> for True 
230    where
231        Not<B>: Boolean
232    {
233        type Output = Not<B>;
234
235        fn bitxor(self, _: B) -> Self::Output {
236            #[cfg(feature = "const_default")]
237            {
238                Not::<B>::DEFAULT
239            }
240            #[cfg(not(feature = "const_default"))]
241            {
242                Not::<B>::default()
243            }
244        }
245    }
246    impl<B> ops::BitXor<B> for False {
247        type Output = B;
248        fn bitxor(self, v: B) -> Self::Output {
249            v
250        }
251    }
252}
253
254/// Negates a [Boolean](./trait.Boolean.html).
255///
256///     # use core_extensions::type_level_bool::*;
257///     assert_eq!(Not::<True >::VALUE, false);
258///     assert_eq!(Not::<False>::VALUE, true);
259///
260pub type Not<T> = <T as ops::Not>::Output;
261
262/// `And`s two [Boolean](./trait.Boolean.html)s
263///
264///
265///     # use core_extensions::type_level_bool::*;
266///     assert_eq!(And::<True , True >::VALUE, true);
267///     assert_eq!(And::<False, True >::VALUE, false);
268///     assert_eq!(And::<True , False>::VALUE, false);
269///     assert_eq!(And::<False, False>::VALUE, false);
270///
271pub type And<L, R> = <L as ops::BitAnd<R>>::Output;
272
273/// `Or`s two [Boolean](./trait.Boolean.html)s
274///
275///
276///     # use core_extensions::type_level_bool::*;
277///     assert_eq!(Or::<True , True >::VALUE, true);
278///     assert_eq!(Or::<False, True >::VALUE, true);
279///     assert_eq!(Or::<True , False>::VALUE, true);
280///     assert_eq!(Or::<False, False>::VALUE, false);
281///
282pub type Or<L, R> = <L as ops::BitOr<R>>::Output;
283
284/// `Xor`s two [Boolean](./trait.Boolean.html)s
285///
286///
287///     # use core_extensions::type_level_bool::*;
288///     assert_eq!(Xor::<True , True >::VALUE, false);
289///     assert_eq!(Xor::<False, True >::VALUE, true);
290///     assert_eq!(Xor::<True , False>::VALUE, true);
291///     assert_eq!(Xor::<False, False>::VALUE, false);
292///
293pub type Xor<L, R> = <L as ops::BitXor<R>>::Output;