@@ -34,18 +34,24 @@ which have not been stabilized as of writing these docs.
34
34
35
35
All the other features of this crate are implemented on top of the [ ` const_format::fmt ` ] API:
36
36
37
+ - [ ` concatc ` ] :
38
+ Concatenates many standard library and user defined types into a ` &'static str ` constant.
39
+
37
40
- [ ` formatc ` ] :
38
- [ ` format ` ] -like macro that can format many standard library and user defined types.
41
+ [ ` format ` ] -like macro that can format many standard library and user defined types into
42
+ a ` &'static str ` constant.
39
43
40
44
- [ ` writec ` ] :
41
45
[ ` write ` ] -like macro that can format many standard library and user defined types
42
46
into a type that implements [ ` WriteMarker ` ] .
43
47
44
-
45
48
The "derive" feature enables the [ ` ConstDebug ` ] macro, and the "fmt" feature.<br >
46
49
[ ` ConstDebug ` ] derives the [ ` FormatMarker ` ] trait,
47
50
and implements an inherent ` const_debug_fmt ` method for compile-time debug formatting.
48
51
52
+ The "assert" feature enables the [ ` assertc ` ] , [ ` assertc_eq ` ] , [ ` assertc_ne ` ] macros,
53
+ and the "fmt" feature.<br >
54
+ These macros are like the standard library assert macros, but evaluated at compile-time.
49
55
50
56
# Examples
51
57
@@ -116,102 +122,90 @@ assert_eq!(
116
122
```
117
123
118
124
125
+
119
126
### Formatted const panics
120
127
121
- This example demonstrates how you can use a [ ` StrWriter ` ] to format
122
- a compile-time panic message .
128
+ This example demonstrates how you can use the [ ` assertc_ne ` ] macro to
129
+ do compile-time inequality assertions with formatted error messages .
123
130
124
- As of writing these docs (2020-08-29), panicking at compile-time requires a
125
- nightly feature, and only supports passing a ` &'static str ` argument,
126
- so this only works in the initialization block of ` const ` items.
131
+ This requires the "assert" feature,because as of writing these docs (2020-09-XX),
132
+ panicking at compile-time requires a nightly feature.
127
133
128
134
``` rust
129
- #![feature(const_mut_refs)]
130
- #![feature(const_panic)]
135
+ #![feature(const_mut_refs)]
131
136
132
- use const_format :: {StrWriter , strwriter_as_str, writec};
137
+ use const_format :: {StrWriter , assertc_ne, strwriter_as_str, writec};
133
138
use const_format :: utils :: str_eq;
134
139
135
- struct PizzaError ;
136
-
137
- const fn write_message (
138
- buffer : & mut StrWriter ,
139
- bought_by : & str ,
140
- topping : & str ,
141
- ) -> Result <(), PizzaError > {
142
- buffer . clear ();
143
- let mut writer = buffer . as_mut ();
144
- if str_eq (topping , " pineapple" ) {
145
- let _ = writec! (
146
- writer ,
147
- " \ n {SEP}\ n\ n You can't put pineapple on pizza, {}.\ n\ n {SEP}\ n" ,
148
- bought_by ,
149
- SEP = " ----------------------------------------------------------------"
140
+ macro_rules! check_valid_pizza {
141
+ ($ user : expr , $ topping : expr ) => {
142
+ assertc_ne! (
143
+ $ topping ,
144
+ " pineapple" ,
145
+ " You can't put pineapple on pizza, {}" ,
146
+ $ user ,
150
147
);
151
- return Err (PizzaError );
152
148
}
153
- Ok (())
154
149
}
155
150
156
- const CAP : usize = 256 ;
157
- // Defined a `const fn` as a workaround for mutable references not
158
- // being allowed in `const`ants.
159
- const fn message_and_result (
160
- bought_by : & str ,
161
- topping : & str ,
162
- ) -> (StrWriter <[u8 ; CAP ]>, Result <(), PizzaError >) {
163
- let mut buffer = StrWriter :: new ([0 ; CAP ]);
164
- let res = write_message (& mut buffer , bought_by , topping );
165
- (buffer , res )
166
- }
167
-
168
- const _ : () = {
169
- if let (buffer , Err (_ )) = message_and_result (" Bob" , " pineapple" ) {
170
- let promoted : & 'static StrWriter = & {buffer };
171
- let message = strwriter_as_str! (promoted );
172
- panic! (message );
173
- }
174
- };
151
+ check_valid_pizza! (" John" , " salami" );
152
+ check_valid_pizza! (" Dave" , " sausage" );
153
+ check_valid_pizza! (" Bob" , " pineapple" );
175
154
155
+ # fn main (){}
176
156
```
177
157
178
- This is what it prints in rust nightly :
158
+ This is the compiler output,
159
+ the first compilation error is there to have an indicator of what assertion failed,
160
+ and the second is the assertion failure:
179
161
180
- ```
162
+ ``` text
181
163
error: any use of this value will cause an error
182
- --> src/lib.rs:166:9
164
+ --> src/lib.rs:140:1
183
165
|
184
- 43 | / const _: () = {
185
- 44 | | if let (buffer, Err(_)) = message_and_result("Bob", "pineapple") {
186
- 45 | | let promoted: &'static StrWriter = &{buffer};
187
- 46 | | let message = strwriter_as_str!(promoted);
188
- 47 | | panic!(message);
189
- | | ^^^^^^^^^^^^^^^^ the evaluated program panicked at '
190
- ----------------------------------------------------------------
191
-
192
- You can't put pineapple on pizza, Bob.
193
-
194
- ----------------------------------------------------------------
195
- ', src/lib.rs:47:9
196
- 48 | | }
197
- 49 | | };
198
- | |__-
166
+ 22 | check_valid_pizza!("Bob", "pineapple");
167
+ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`)
199
168
|
200
169
= note: `#[deny(const_err)]` on by default
201
170
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
202
171
172
+ error[E0080]: could not evaluate constant
173
+ --> /const_format/src/panicking.rs:32:5
174
+ |
175
+ 32 | .
176
+ | ^ the evaluated program panicked at '
177
+ --------------------------------------------------------------------------------
178
+ module_path: rust_out
179
+ line: 22
180
+
181
+ assertion failed: LEFT != RIGHT
182
+
183
+ left: "pineapple"
184
+ right: "pineapple"
185
+
186
+ You can't put pineapple on pizza, Bob
187
+ --------------------------------------------------------------------------------
188
+ ', /const_format/src/panicking.rs:31:1
189
+ |
190
+ = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
191
+
192
+ error: aborting due to 2 previous errors
193
+
203
194
```
204
195
205
196
197
+
198
+
206
199
<div id =" macro-limitations " ></div >
207
200
208
201
# Limitations
209
202
210
203
All of the macros from ` const_format ` have these limitations:
211
204
212
- - The formatting macros that expand to
213
- ` &'static str ` s can only use constants of concrete types,
214
- so while ` Type::<u8>::FOO ` is fine,` Type::<T>::FOO ` is not (` T ` being a type parameter).
205
+ - The formatting macros that expand to
206
+ ` &'static str ` s can only use constants from concrete types,
207
+ so while a ` Type::<u8>::FOO ` argument would be fine,
208
+ ` Type::<T>::FOO ` would not be (` T ` being a type parameter).
215
209
216
210
- Integer arguments must have a type inferrable from context,
217
211
[ more details in the Integer arguments section] ( #integer-args ) .
@@ -253,14 +247,26 @@ This feature includes the `formatc`/`writec` formatting macros.
253
247
provides the ` ConstDebug ` derive macro to format user-defined types at compile-time.<br >
254
248
This implicitly uses the ` syn ` crate, so clean compiles take a bit longer than without the feature.
255
249
250
+ - "assert": implies the "fmt" feature,
251
+ enables the assertion macros.<br >
252
+ This is a separate cargo feature because:
253
+ - It uses nightly Rust features that are less stable than the "fmt" feature does.<br >
254
+ - It requires the ` std ` crate, because ` core::panic ` requires a string literal argument.
255
+
256
+
256
257
- "constant_time_as_str": implies the "fmt" feature.
257
258
An optimization that requires a few additional nightly features,
258
259
allowing the ` as_bytes_alt ` methods and ` slice_up_to_len_alt ` methods to run
259
260
in constant time, rather than linear time proportional to the truncated part of the slice.
260
261
262
+
263
+
261
264
# No-std support
262
265
263
- ` const_format ` is unconditionally ` #![no_std] ` , it can be used anywhere Rust can be used.
266
+ ` const_format ` is ` #![no_std] ` , it can be used anywhere Rust can be used.
267
+
268
+ Caveat: The opt-in "assert" feature uses the ` std::panic ` macro to panic,
269
+ as of 2020-09-06 ` core::panic ` requires the argument to be a literal.
264
270
265
271
# Minimum Supported Rust Version
266
272
@@ -270,6 +276,12 @@ Features that require newer versions of Rust, or the nightly compiler,
270
276
need to be explicitly enabled with cargo features.
271
277
272
278
279
+ [ `assertc` ] : https://docs.rs/const_format/0.2.*/const_format/macro.assertc.html
280
+
281
+ [ `assertc_eq` ] : https://docs.rs/const_format/0.2.*/const_format/macro.assertc_eq.html
282
+
283
+ [ `assertc_ne` ] : https://docs.rs/const_format/0.2.*/const_format/macro.assertc_ne.html
284
+
273
285
[ `concatcp` ] : https://docs.rs/const_format/0.2.*/const_format/macro.concatcp.html
274
286
275
287
[ `formatcp` ] : https://docs.rs/const_format/0.2.*/const_format/macro.formatcp.html
@@ -280,6 +292,8 @@ need to be explicitly enabled with cargo features.
280
292
281
293
[ `const_format::fmt` ] : https://docs.rs/const_format/0.2.*/const_format/fmt/index.html
282
294
295
+ [ `concatc` ] : https://docs.rs/const_format/0.2.*/const_format/macro.concatc.html
296
+
283
297
[ `formatc` ] : https://docs.rs/const_format/0.2.*/const_format/macro.formatc.html
284
298
285
299
[ `writec` ] : https://docs.rs/const_format/0.2.*/const_format/macro.writec.html
0 commit comments