devela/code/util/asserts/static/
const.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
// devela::code::util::asserts::static::const
//
//! Compile-time assertions.
//

/// Asserts various comparisons on constants.
#[macro_export]
#[cfg_attr(cargo_primary_package, doc(hidden))]
macro_rules! const_assert {
    (
        // Asserts that a single expression evaluates to `true`.
        $x:expr $(,)?) => {
        const _: $crate::True = $crate::num::const_bool!($x);
    };
    (
        // Asserts that constants are equal in value.
        eq $x:expr, $($y:expr),+ $(,)?) => {
        $crate::const_assert!($($x == $y)&&+);
    };
    (
        // Asserts that byte slice buffers are equal in value.
        eq_buf $buf:expr, $($other:expr),+ $(,)?) => {
        $( $crate::const_assert!($crate::Slice::<u8>::eq($buf, $other)); )+
    };
    (
        // Asserts that string slices are equal in value.
        eq_str $str:expr, $($other:expr),+ $(,)?) => {
        $(
            $crate::const_assert!($crate::Slice::<u8>::eq({$str}.as_bytes(), {$other}.as_bytes()));
        )+
    };
    (
        // Asserts that constants of type `usize` are equal in value.
        // (Allows for inspecting the values in error messages).
        eq_usize $x:expr, $($y:expr),+ $(,)?) => {
        $(const _: [(); $x] = [(); $y];)+
    };
    (
        // Asserts that constants are not equal in value.
        ne $x:expr, $($y:expr),+ $(,)?) => {
        $crate::const_assert!($($x != $y)&&+);
    };
   (
        // Asserts that constants are less than each other.
        lt $x:expr, $($y:expr),+ $(,)?) => {
        $crate::const_assert!(@build $x, $($y),+; <);
    };
    (
        // Asserts that constants are less than or equal to each other.
        le $x:expr, $($y:expr),+ $(,)?) => {
        $crate::const_assert!(@build $x, $($y),+; <=);
    };
    (
        // Asserts that constants are greater than each other.
        gt $x:expr, $($y:expr),+ $(,)?) => {
        $crate::const_assert!(@build $x, $($y),+; >);
    };
    (
        // Asserts that constants are greater than or equal to each other.
        ge $x:expr, $($y:expr),+ $(,)?) => {
        $crate::const_assert!(@build $x, $($y),+; >=);
    };

    // receives the expressions and the operator, and performs the appropriate comparison.
    (
    /* private arms*/

        @build $x:expr, $($y:expr),+; $op:tt) => {
        $crate::const_assert!($x $op $crate::code::capture_first!(expr $($y),+)); // keep code path
        $crate::const_assert!(@build $($y),+; $op);
    };
    // terminates recursion when there’s only one expression left.
    (
        @build $x:expr; $op:tt) => {};
}
#[doc(inline)]
pub use const_assert;

#[cfg(test)]
mod tests {
    pub use super::*;

    #[test]
    const fn const_assert() {
        const_assert!(true && (true != false));
        const_assert!((true && true) != false);
        const_assert!(eq false, false);
        const_assert!(ne true, false);

        #[allow(dead_code)]
        const FIVE: usize = 5;

        const_assert!(FIVE * 2 == 10);
        const_assert!(FIVE > 2);

        const_assert!(le 1, 1, 2, 3, 4, 4);
        const_assert!(lt 1, 2, 3);
        const_assert!(ge 4, 4, 3, 2, 1, 1);
        const_assert!(gt 4, 3, 2, 1);
    }
}