const_str/__ctfe/
compare.rs1use core::cmp::Ordering;
2
3pub struct Compare<T1, T2>(pub T1, pub T2);
4
5impl Compare<&[u8], &[u8]> {
6 pub const fn const_eval(&self) -> Ordering {
7 crate::bytes::compare(self.0, self.1)
8 }
9}
10
11impl<const L1: usize, const L2: usize> Compare<&[u8; L1], &[u8; L2]> {
12 pub const fn const_eval(&self) -> Ordering {
13 crate::bytes::compare(self.0, self.1)
14 }
15}
16
17impl Compare<&str, &str> {
18 pub const fn const_eval(&self) -> Ordering {
19 crate::str::compare(self.0, self.1)
20 }
21}
22
23#[macro_export]
51macro_rules! compare {
52 (<, $lhs: expr, $rhs: expr) => {{
53 use ::core::cmp::Ordering;
54 let ordering = $crate::__ctfe::Compare($lhs, $rhs).const_eval();
55 matches!(ordering, Ordering::Less)
56 }};
57 (>, $lhs: expr, $rhs: expr) => {{
58 use ::core::cmp::Ordering;
59 let ordering = $crate::__ctfe::Compare($lhs, $rhs).const_eval();
60 matches!(ordering, Ordering::Greater)
61 }};
62 (==, $lhs: expr, $rhs: expr) => {{
63 use ::core::cmp::Ordering;
64 let ordering = $crate::__ctfe::Compare($lhs, $rhs).const_eval();
65 matches!(ordering, Ordering::Equal)
66 }};
67 (<=, $lhs: expr, $rhs: expr) => {{
68 use ::core::cmp::Ordering;
69 let ordering = $crate::__ctfe::Compare($lhs, $rhs).const_eval();
70 matches!(ordering, Ordering::Less | Ordering::Equal)
71 }};
72 (>=, $lhs: expr, $rhs: expr) => {{
73 use ::core::cmp::Ordering;
74 let ordering = $crate::__ctfe::Compare($lhs, $rhs).const_eval();
75 matches!(ordering, Ordering::Greater | Ordering::Equal)
76 }};
77 ($lhs: expr, $rhs: expr) => {
78 $crate::__ctfe::Compare($lhs, $rhs).const_eval()
79 };
80}
81
82#[cfg(test)]
83mod tests {
84 use core::cmp::Ordering;
85
86 #[test]
87 fn test_compare_str() {
88 const A: &str = "apple";
89 const B: &str = "banana";
90 const C: &str = "apple";
91
92 const ORD1: Ordering = compare!(A, B);
93 const ORD2: Ordering = compare!(B, A);
94 const ORD3: Ordering = compare!(A, C);
95
96 assert_eq!(ORD1, Ordering::Less);
97 assert_eq!(ORD2, Ordering::Greater);
98 assert_eq!(ORD3, Ordering::Equal);
99
100 let lt = compare!(<, A, B);
101 let gt = compare!(>, B, A);
102 let eq = compare!(==, A, C);
103 let le1 = compare!(<=, A, B);
104 let le2 = compare!(<=, A, C);
105 let ge1 = compare!(>=, B, A);
106 let ge2 = compare!(>=, A, C);
107
108 assert!(lt);
109 assert!(gt);
110 assert!(eq);
111 assert!(le1);
112 assert!(le2);
113 assert!(ge1);
114 assert!(ge2);
115 }
116
117 #[test]
118 fn test_compare_bytes() {
119 const A: &[u8] = b"apple";
120 const B: &[u8] = b"banana";
121 const C: &[u8] = b"apple";
122
123 const ORD1: Ordering = compare!(A, B);
124 const ORD2: Ordering = compare!(B, A);
125 const ORD3: Ordering = compare!(A, C);
126
127 assert_eq!(ORD1, Ordering::Less);
128 assert_eq!(ORD2, Ordering::Greater);
129 assert_eq!(ORD3, Ordering::Equal);
130 }
131
132 #[test]
133 fn test_compare_byte_arrays() {
134 const A: &[u8; 5] = b"apple";
135 const B: &[u8; 6] = b"banana";
136 const C: &[u8; 5] = b"apple";
137
138 const ORD1: Ordering = compare!(A, B);
139 const ORD2: Ordering = compare!(B, A);
140 const ORD3: Ordering = compare!(A, C);
141
142 assert_eq!(ORD1, Ordering::Less);
143 assert_eq!(ORD2, Ordering::Greater);
144 assert_eq!(ORD3, Ordering::Equal);
145 }
146
147 #[test]
148 fn test_compare_runtime() {
149 use super::*;
150
151 let cmp_str = Compare("apple", "banana");
153 assert_eq!(cmp_str.const_eval(), Ordering::Less);
154
155 let cmp_str2 = Compare("zebra", "apple");
156 assert_eq!(cmp_str2.const_eval(), Ordering::Greater);
157
158 let cmp_str3 = Compare("test", "test");
159 assert_eq!(cmp_str3.const_eval(), Ordering::Equal);
160
161 let cmp_bytes = Compare(b"hello".as_slice(), b"world".as_slice());
163 assert_eq!(cmp_bytes.const_eval(), Ordering::Less);
164
165 let arr1: &[u8; 3] = b"abc";
167 let arr2: &[u8; 3] = b"xyz";
168 let cmp_arr = Compare(arr1, arr2);
169 assert_eq!(cmp_arr.const_eval(), Ordering::Less);
170 }
171}