const_format/macros/assertions/assertcp_macros.rs
1macro_rules! with_shared_docs {(
2 $(#[$before_clarification:meta])*
3 ;clarification
4 $(#[$before_syntax:meta])*
5 ;syntax
6 $(#[$after_syntax:meta])*
7 ;limitations
8 $item:item
9) => (
10 $(#[$before_clarification])*
11 ///
12 /// [For **examples** look here](#examples)
13 ///
14 /// This macro requires the `"assertcp"` feature to be exported.<br>
15 ///
16 $(#[$before_syntax])*
17 /// # Syntax
18 ///
19 /// This macro uses the same syntax
20 /// for the format string and formatting arguments as the
21 /// [`formatcp`](crate::formatcp) macro.
22 ///
23 $(#[$after_syntax])*
24 /// # Limitations
25 ///
26 /// This macro can only take constants of these types as arguments:
27 ///
28 /// - `&str`
29 ///
30 /// - `i*`/`u*` (all the primitive integer types).
31 ///
32 /// - `char`
33 ///
34 /// - `bool`
35 ///
36 /// This macro also has these limitations:
37 ///
38 /// - It can only use constants that involve concrete types,
39 /// so while a `Type::<u8>::FOO` in an argument would be fine,
40 /// `Type::<T>::FOO` would not be (`T` being a type parameter).
41 ///
42 /// - Integer arguments must have a type inferrable from context,
43 /// [as described in the integer arguments section in the root module
44 /// ](./index.html#integer-args).
45 ///
46 $item
47)}
48
49with_shared_docs! {
50 /// Compile-time assertion with formatting.
51 ///
52 ;clarification
53 ;syntax
54 ;limitations
55 ///
56 /// # Examples
57 ///
58 /// ### Passing assertion
59 ///
60 /// ```rust
61 /// use const_format::assertcp;
62 ///
63 /// use std::mem::align_of;
64 ///
65 /// assertcp!(
66 /// align_of::<&str>() == align_of::<usize>(),
67 /// "The alignment of `&str`({} bytes) and `usize`({} bytes) isn't the same?!?!",
68 /// align_of::<&str>(),
69 /// align_of::<usize>(),
70 /// );
71 ///
72 /// # fn main(){}
73 /// ```
74 ///
75 /// ### Failing assertion
76 ///
77 /// This example demonstrates a failing assertion,
78 /// and how the compiler error looks like as of 2023-10-14.
79 ///
80 /// ```compile_fail
81 /// use const_format::assertcp;
82 ///
83 /// const L: u64 = 2;
84 /// const R: u32 = 5;
85 ///
86 /// assertcp!(L.pow(R) == 64, "{L} to the {R} isn't 64, it's {}", L.pow(R));
87 ///
88 /// # fn main(){}
89 /// ```
90 ///
91 /// This is the compiler output:
92 ///
93 /// ```text
94 /// error[E0080]: evaluation of constant value failed
95 /// --> const_format/src/macros/assertions/assertcp_macros.rs:116:11
96 /// |
97 /// 9 | assertcp!(L.pow(R) == 64, "{L} to the {R} isn't 64, it's {}", L.pow(R));
98 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
99 /// assertion failed.
100 /// 2 to the 5 isn't 64, it's 32
101 /// ', const_format/src/macros/assertions/assertcp_macros.rs:9:11
102 ///
103 /// ```
104 ///
105 #[cfg_attr(feature = "__docsrs", doc(cfg(feature = "assertcp")))]
106 #[macro_export]
107 macro_rules! assertcp {
108 ($($parameters:tt)*) => (
109 $crate::__assertc_inner!{
110 __formatcp_if_impl
111 ($($parameters)*)
112 ($($parameters)*)
113 }
114 );
115 }
116}
117
118#[doc(hidden)]
119#[macro_export]
120macro_rules! __assertcp_equality_inner {
121 (
122 ($($parameters:tt)*)
123 (
124 $left:expr,
125 $right:expr
126 $(, $fmt_literal:expr $(,$fmt_arg:expr)*)? $(,)?
127 )
128 ($($op:tt)*)
129 ($op_str:expr)
130 )=>{
131 #[allow(non_snake_case)]
132 const _: () = {
133 use $crate::__cf_osRcTFl4A;
134 const ARGS_NHPMWYD3NJA:
135 ($crate::pmr::bool, $crate::pmr::PArgument, $crate::pmr::PArgument)
136 = {
137 let left = $crate::PWrapper($left);
138 let right = $crate::pmr::PConvWrapper($right);
139 let cond = left.const_eq(&right.0);
140 let fmt = $crate::pmr::FormattingFlags::NEW.set_alternate(true);
141 (
142 cond,
143 $crate::pmr::PConvWrapper(left.0).to_pargument_debug(fmt),
144 right.to_pargument_debug(fmt),
145 )
146 };
147
148 $crate::__assertc_common!{
149 __formatcp_if_impl
150 ($($parameters)*)
151 (ARGS_NHPMWYD3NJA.0 $($op)* true)
152 (
153 concat!(
154 "\nassertion failed: `(left ",
155 $op_str,
156 " right)`\n",
157 " left: `{left_NHPMWYD3NJA:#?}`\n\
158 right: `{right_NHPMWYD3NJA:#?}`",
159 $("\n", $fmt_literal, "\n")?
160 ),
161 $($($fmt_arg,)*)?
162 left_NHPMWYD3NJA = ARGS_NHPMWYD3NJA.1,
163 right_NHPMWYD3NJA = ARGS_NHPMWYD3NJA.2
164 )
165 }
166 };
167 }
168}
169
170with_shared_docs! {
171 /// Compile-time equality assertion with formatting.
172 ///
173 ;clarification
174 ;syntax
175 ;limitations
176 ///
177 /// # Examples
178 ///
179 /// ### Passing assertion
180 ///
181 /// ```rust
182 /// use const_format::assertcp_eq;
183 ///
184 /// const NAME: &str = "Bob";
185 ///
186 /// assertcp_eq!(NAME, "Bob", "Guessed wrong, the right value is {}", NAME);
187 ///
188 /// const SUM: u8 = 1 + 2 + 3;
189 /// assertcp_eq!(6u8, SUM, "Guessed wrong, the right value is {}", SUM);
190 /// ```
191 ///
192 /// ### Failing assertion
193 ///
194 /// This example demonstrates a failing assertion,
195 /// and how the compiler error looks like as of 2023-10-14.
196 ///
197 /// ```compile_fail
198 /// use const_format::assertcp_eq;
199 ///
200 /// use std::mem::size_of;
201 ///
202 /// #[repr(C)]
203 /// struct Type(u16, u16, u16);
204 ///
205 /// assertcp_eq!(size_of::<Type>(), size_of::<[u16; 2]>(), "Whoops, `Type` is too large");
206 ///
207 /// ```
208 ///
209 /// This is the compiler output:
210 ///
211 /// ```text
212 /// error[E0080]: evaluation of constant value failed
213 /// --> const_format/src/macros/assertions/assertcp_macros.rs:235:14
214 /// |
215 /// 12 | assertcp_eq!(size_of::<Type>(), size_of::<[u16; 2]>(), "Whoops, `Type` is too large");
216 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
217 /// assertion failed: `(left == right)`
218 /// left: `6`
219 /// right: `4`
220 /// Whoops, `Type` is too large
221 /// ', const_format/src/macros/assertions/assertcp_macros.rs:12:14
222 ///
223 /// ```
224 ///
225 #[cfg_attr(feature = "__docsrs", doc(cfg(feature = "assertcp")))]
226 #[macro_export]
227 macro_rules! assertcp_eq {
228 ($($parameters:tt)*) => (
229 $crate::__assertcp_equality_inner!{
230 ($($parameters)*)
231 ($($parameters)*)
232 ( == )
233 ("==")
234 }
235 );
236 }
237}
238with_shared_docs! {
239 /// Compile-time inequality assertion with formatting.
240 ///
241 ;clarification
242 ;syntax
243 ;limitations
244 ///
245 /// # Examples
246 ///
247 /// ### Passing assertion
248 ///
249 /// ```rust
250 /// use const_format::assertcp_ne;
251 ///
252 /// assertcp_ne!(std::mem::size_of::<usize>(), 1usize, "Oh no, usize is tiny!");
253 ///
254 /// const CHAR: char = ';';
255 /// assertcp_ne!(CHAR, '.', "CHAR must not be a dot!");
256 /// ```
257 ///
258 /// ### Failing assertion
259 ///
260 /// This example demonstrates a failing assertion,
261 /// and how the compiler error looks like as of 2023-10-14.
262 ///
263 /// ```compile_fail
264 /// use const_format::assertcp_ne;
265 ///
266 /// const NAME: &str = "";
267 /// assertcp_ne!(NAME, "", "NAME must not be empty!");
268 ///
269 /// ```
270 ///
271 /// This is the compiler output:
272 ///
273 /// ```text
274 /// error[E0080]: evaluation of constant value failed
275 /// --> const_format/src/macros/assertions/assertcp_macros.rs:297:14
276 /// |
277 /// 8 | assertcp_ne!(NAME, "", "NAME must not be empty!");
278 /// | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at '
279 /// assertion failed: `(left != right)`
280 /// left: `""`
281 /// right: `""`
282 /// NAME must not be empty!
283 /// ', const_format/src/macros/assertions/assertcp_macros.rs:8:14
284 /// ```
285 ///
286 #[cfg_attr(feature = "__docsrs", doc(cfg(feature = "assertcp")))]
287 #[macro_export]
288 macro_rules! assertcp_ne {
289 ($($parameters:tt)*) => (
290 $crate::__assertcp_equality_inner!{
291 ($($parameters)*)
292 ($($parameters)*)
293 ( != )
294 ("!=")
295 }
296 );
297 }
298}