> Enter regex macros! While it is presently slower, and requires a Rust nightly, it has the very appealing property that if your regex is not a correct expression, your program won’t compile!
It looks like `regex!` is the only thing preventing your project from compiling on stable Rust, right? FWIW, the Clippy lint tool will check your `Regex::new` calls at compile time for you (assuming it's a string literal, which it is in your case).
Also, I'd recommend not using `*` as a version constraint in your `Cargo.toml`. You do have a `Cargo.lock` so it's not as bad, but with better version constraints, you'll be able to run `cargo update` and get semver compatible updates.
Both good suggestions for improvement, Andrew. I saw the performance notes, and admit I was a little torn. Quite simply, the regex! macro was interesting for the reason stated, and I left it in there for the purpose of showcasing something (a little bit) unique in Rust.
Regarding the asterisk for versioning in Cargo.toml, I also agree. When quickly putting things together, I usually start with it just to see if the default version pulled works. The great utility of Cargo.lock, effectively storing the working versions of all the crates, allows scraping the versions out of there at any time, and putting them into the .toml.
I hope you noticed the extensive links in the post, as one of the goals was to bring more people into the Rust ecosystem. The Spyglass utility does work quite well. None of us claimed it has reached a state of absolute perfection, so your comments are appreciated (and pull requests will be as well)!
Is there any fundamental reason that compile-time regular expressions couldn't be just as fast as Regex::new? They could use the same regex implementation.
One approach is to turn regex! into something like lazy_static! but with syntax checking. Since this just reuses Regex::new, I wouldn't call these "compile time regexps."
Another approach is to re-implement everything that has gone into Regex::new, but in a way that works at compile time.
Another approach is to operate more like Ragel and try to get better performance, but this will need to be compensated somehow to provide the full suite of the regex API.
(1) isn't that interesting since lazy_static! and Clippy already serve that role. That latter two approaches require a lot of work that will only be available on nightly for the foreseeable future. (And it's not even clear to me how much faster (3) could even be.)
To be clear, it's not just slower, it's much slower. See the benchmark comparison here: https://gist.github.com/b0f6a17744dd1df60752b6e8ced47afd <-- That's why the `regex!` macro isn't even in the docs any more.
It looks like `regex!` is the only thing preventing your project from compiling on stable Rust, right? FWIW, the Clippy lint tool will check your `Regex::new` calls at compile time for you (assuming it's a string literal, which it is in your case).
Also, I'd recommend not using `*` as a version constraint in your `Cargo.toml`. You do have a `Cargo.lock` so it's not as bad, but with better version constraints, you'll be able to run `cargo update` and get semver compatible updates.