devela/code/util/asserts/static/
const.rs

1// devela::code::util::asserts::static::const
2//
3//! Compile-time assertions.
4//
5
6/// Asserts various comparisons on constants.
7#[macro_export]
8#[cfg_attr(cargo_primary_package, doc(hidden))]
9macro_rules! const_assert {
10    (
11        // Asserts that a single expression evaluates to `true`.
12        $x:expr $(,)?) => {
13        const _: $crate::True = $crate::num::const_bool!($x);
14    };
15    (
16        // Asserts that constants are equal in value.
17        eq $x:expr, $($y:expr),+ $(,)?) => {
18        $crate::const_assert!($($x == $y)&&+);
19    };
20    (
21        // Asserts that byte slice buffers are equal in value.
22        eq_buf $buf:expr, $($other:expr),+ $(,)?) => {
23        $( $crate::const_assert!($crate::Slice::<u8>::eq($buf, $other)); )+
24    };
25    (
26        // Asserts that string slices are equal in value.
27        eq_str $str:expr, $($other:expr),+ $(,)?) => {
28        $( $crate::const_assert!($crate::Slice::<&str>::eq($str, $other)); )+
29    };
30    ( // FIXME
31        // Asserts that slices string slices are equal in value.
32        eq_buf_str $str:expr, $($other:expr),+ $(,)?) => {
33        $( $crate::const_assert!($crate::Slice::<&[&str]>::eq($str, $other)); )+
34    };
35    (
36        // Asserts that constants of type `usize` are equal in value.
37        // (Allows for inspecting the values in error messages).
38        eq_usize $x:expr, $($y:expr),+ $(,)?) => {
39        $(const _: [(); $x] = [(); $y];)+
40    };
41    (
42        // Asserts that constants are not equal in value.
43        ne $x:expr, $($y:expr),+ $(,)?) => {
44        $crate::const_assert!($($x != $y)&&+);
45    };
46   (
47        // Asserts that constants are less than each other.
48        lt $x:expr, $($y:expr),+ $(,)?) => {
49        $crate::const_assert!(@build $x, $($y),+; <);
50    };
51    (
52        // Asserts that constants are less than or equal to each other.
53        le $x:expr, $($y:expr),+ $(,)?) => {
54        $crate::const_assert!(@build $x, $($y),+; <=);
55    };
56    (
57        // Asserts that constants are greater than each other.
58        gt $x:expr, $($y:expr),+ $(,)?) => {
59        $crate::const_assert!(@build $x, $($y),+; >);
60    };
61    (
62        // Asserts that constants are greater than or equal to each other.
63        ge $x:expr, $($y:expr),+ $(,)?) => {
64        $crate::const_assert!(@build $x, $($y),+; >=);
65    };
66
67    // receives the expressions and the operator, and performs the appropriate comparison.
68    (
69    /* private arms*/
70
71        @build $x:expr, $($y:expr),+; $op:tt) => {
72        $crate::const_assert!($x $op $crate::code::capture_first!(expr $($y),+)); // keep code path
73        $crate::const_assert!(@build $($y),+; $op);
74    };
75    // terminates recursion when there’s only one expression left.
76    (
77        @build $x:expr; $op:tt) => {};
78}
79#[doc(inline)]
80pub use const_assert;
81
82#[cfg(test)]
83mod tests {
84    pub use super::*;
85
86    #[test]
87    const fn const_assert() {
88        const_assert!(true && (true != false));
89        const_assert!((true && true) != false);
90        const_assert!(eq false, false);
91        const_assert!(ne true, false);
92
93        #[allow(dead_code)]
94        const FIVE: usize = 5;
95
96        const_assert!(FIVE * 2 == 10);
97        const_assert!(FIVE > 2);
98
99        const_assert!(le 1, 1, 2, 3, 4, 4);
100        const_assert!(lt 1, 2, 3);
101        const_assert!(ge 4, 4, 3, 2, 1, 1);
102        const_assert!(gt 4, 3, 2, 1);
103    }
104}