tola_caps/primitives/
bool.rs

1//! Type-level boolean logic.
2//!
3//! Core types: `Present` (true), `Absent` (false), `Bool` trait.
4
5use crate::spec::dispatch::StaticMethodImpl;
6
7/// Type-level boolean.
8pub trait Bool: 'static {
9    const VALUE: bool;
10    /// Type-level conditional: If<Then, Else> (General Type Selector)
11    type If<Then, Else>;
12
13    /// Type-level boolean conditional: Then<T, E> where T, E are Bool.
14    /// Returns a type guaranteed to implement Bool.
15    type Elif<Then: Bool, Else: Bool>: Bool;
16
17    /// Logical AND
18    type And<Other: Bool>: Bool;
19
20    /// Logical OR
21    type Or<Other: Bool>: Bool;
22
23    /// Call a static method based on this boolean value.
24    /// If true (Present), calls Then::call().
25    /// If false (Absent), calls Else::call().
26    fn static_dispatch<Then, Else, Output>() -> Output
27    where
28        Then: StaticMethodImpl<Output>,
29        Else: StaticMethodImpl<Output>;
30}
31
32/// Type-level True.
33#[derive(Debug)]
34pub struct Present;
35
36/// Type-level False.
37#[derive(Debug)]
38pub struct Absent;
39
40impl Bool for Present {
41    const VALUE: bool = true;
42    type If<Then, Else> = Then;
43    type Elif<Then: Bool, Else: Bool> = Then;
44
45    type And<Other: Bool> = Other;
46    type Or<Other: Bool> = Present;
47
48    #[inline(always)]
49    fn static_dispatch<Then, Else, Output>() -> Output
50    where
51        Then: StaticMethodImpl<Output>,
52        Else: StaticMethodImpl<Output>,
53    {
54        Then::call()
55    }
56}
57
58impl Bool for Absent {
59    const VALUE: bool = false;
60    type If<Then, Else> = Else;
61    type Elif<Then: Bool, Else: Bool> = Else;
62
63    type And<Other: Bool> = Absent;
64    type Or<Other: Bool> = Other;
65
66    #[inline(always)]
67    fn static_dispatch<Then, Else, Output>() -> Output
68    where
69        Then: StaticMethodImpl<Output>,
70        Else: StaticMethodImpl<Output>,
71    {
72        Else::call()
73    }
74}
75
76// Deprecated separate traits (kept for compatibility if needed, or remove?)
77// Let's alias them to the new associated types to minimize breakage
78pub trait BoolAnd<Other: Bool>: Bool {
79    type Out: Bool;
80}
81impl<A: Bool, B: Bool> BoolAnd<B> for A {
82    type Out = A::And<B>;
83}
84
85pub trait BoolOr<Other: Bool>: Bool {
86    type Out: Bool;
87}
88impl<A: Bool, B: Bool> BoolOr<B> for A {
89    type Out = A::Or<B>;
90}
91
92
93
94
95/// Type-level NOT.
96pub trait BoolNot: Bool {
97    type Out: Bool;
98}
99
100impl BoolNot for Present {
101    type Out = Absent;
102}
103
104impl BoolNot for Absent {
105    type Out = Present;
106}
107
108/// Convert const bool to type-level Bool.
109pub trait SelectBool<const B: bool> {
110    type Out: Bool;
111}
112
113impl SelectBool<true> for () {
114    type Out = Present;
115}
116
117impl SelectBool<false> for () {
118    type Out = Absent;
119}
120
121/// Conditional Type Alias
122pub type If<const C: bool, T, E> = <<() as SelectBool<C>>::Out as Bool>::If<T, E>;
123
124/// Strict Conditional Type Alias (Result is Bool)
125pub type Elif<const C: bool, T, E> = <<() as SelectBool<C>>::Out as Bool>::Elif<T, E>;
126