I have many repeated constants in the form of:
pub const FOO_REGEX: Regex = Regex::new(r"foo.*").unwrap();
pub const BAR_REGEX: Regex = Regex::new(r"bar.*").unwrap();
I'd like to simply this by using a macro_rules!
macro.
I tried:
macro_rules! pattern {
($value:literal) => {
Regex::new($value).unwrap()
}
}
pub const FOO_REGEX: Regex = pattern!(r"foo.*");
But the compiler complains with:
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> lib.rs:7:9
|
7 | Regex::new($value).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
...
11 | pub const FOO_REGEX: Regex = pattern!(r"foo.*");
| ------------------ in this macro invocation
Per this guide I tried many of the available designators options, like expr
, ident
, but I'm still not able to get macro to compile.
Why does the literal
designator not work for this macro expression?
This has nothing to do with macros: you get the same error if you write the code directly (playground). The problem here is that calling Regex::new
is not a literal (1) and cannot be evaluated at compile-time (yet?). You will need to use something like the lazy_static
crate to ensure that Regex::new
is called at run-time to compile the regular expression:
use regex::Regex;
use lazy_static::lazy_static;
lazy_static!{
pub static ref FOO_REGEX: Regex = Regex::new(r"foo.*").unwrap();
}
Playground
(1) Quoting from this answer:
A literal is a value written as-is in the code:
true
,1
,"hello"
; the result of an expression [likeRegex::new
] cannot be a literal (by definition). The resulting types may look similar (or even be identical) but types are irrelevant here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With