@@ -34,18 +34,24 @@ which have not been stabilized as of writing these docs.
3434
3535All the other features of this crate are implemented on top of the [ ` const_format::fmt ` ] API:
3636
37+ - [ ` concatc ` ] :
38+ Concatenates many standard library and user defined types into a ` &'static str ` constant.
39+
3740- [ ` 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.
3943
4044- [ ` writec ` ] :
4145[ ` write ` ] -like macro that can format many standard library and user defined types
4246into a type that implements [ ` WriteMarker ` ] .
4347
44-
4548The "derive" feature enables the [ ` ConstDebug ` ] macro, and the "fmt" feature.<br >
4649[ ` ConstDebug ` ] derives the [ ` FormatMarker ` ] trait,
4750and implements an inherent ` const_debug_fmt ` method for compile-time debug formatting.
4851
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.
4955
5056# Examples
5157
@@ -116,102 +122,90 @@ assert_eq!(
116122```
117123
118124
125+
119126### Formatted const panics
120127
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 .
123130
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.
127133
128134``` rust
129- #![feature(const_mut_refs)]
130- #![feature(const_panic)]
135+ #![feature(const_mut_refs)]
131136
132- use const_format :: {StrWriter , strwriter_as_str, writec};
137+ use const_format :: {StrWriter , assertc_ne, strwriter_as_str, writec};
133138use const_format :: utils :: str_eq;
134139
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 ,
150147 );
151- return Err (PizzaError );
152148 }
153- Ok (())
154149}
155150
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" );
175154
155+ # fn main (){}
176156```
177157
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:
179161
180- ```
162+ ``` text
181163error: any use of this value will cause an error
182- --> src/lib.rs:166:9
164+ --> src/lib.rs:140:1
183165 |
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]`)
199168 |
200169 = note: `#[deny(const_err)]` on by default
201170 = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
202171
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+
203194```
204195
205196
197+
198+
206199<div id =" macro-limitations " ></div >
207200
208201# Limitations
209202
210203All of the macros from ` const_format ` have these limitations:
211204
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).
215209
216210- Integer arguments must have a type inferrable from context,
217211[ more details in the Integer arguments section] ( #integer-args ) .
@@ -253,14 +247,26 @@ This feature includes the `formatc`/`writec` formatting macros.
253247provides the ` ConstDebug ` derive macro to format user-defined types at compile-time.<br >
254248This implicitly uses the ` syn ` crate, so clean compiles take a bit longer than without the feature.
255249
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+
256257- "constant_time_as_str": implies the "fmt" feature.
257258An optimization that requires a few additional nightly features,
258259allowing the ` as_bytes_alt ` methods and ` slice_up_to_len_alt ` methods to run
259260in constant time, rather than linear time proportional to the truncated part of the slice.
260261
262+
263+
261264# No-std support
262265
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.
264270
265271# Minimum Supported Rust Version
266272
@@ -270,6 +276,12 @@ Features that require newer versions of Rust, or the nightly compiler,
270276need to be explicitly enabled with cargo features.
271277
272278
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+
273285[ `concatcp` ] : https://docs.rs/const_format/0.2.*/const_format/macro.concatcp.html
274286
275287[ `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.
280292
281293[ `const_format::fmt` ] : https://docs.rs/const_format/0.2.*/const_format/fmt/index.html
282294
295+ [ `concatc` ] : https://docs.rs/const_format/0.2.*/const_format/macro.concatc.html
296+
283297[ `formatc` ] : https://docs.rs/const_format/0.2.*/const_format/macro.formatc.html
284298
285299[ `writec` ] : https://docs.rs/const_format/0.2.*/const_format/macro.writec.html
0 commit comments