regex_macro/
lib.rs

1//! This crate contains a little macro to generate a lazy
2//! [`Regex`](../regex/struct.Regex.html) and remove some boilerplate when
3//! compiling regex expressions.
4//!
5//! # Usage
6//!
7//! Since it is an anti-pattern to compile the same regular expression in a loop
8//! this means for most regex expressions you need to store them in a
9//! [`LazyLock`] in a static. But this can get a bit tiresome with many regex
10//! expressions. This crate provides a [`regex!`] macro that will store the
11//! compiled regex in a global static and return a reference to it.
12//!
13//! [`LazyLock`]: std::sync::LazyLock
14//!
15//! ### Before
16//!
17//! ```
18//! use std::sync::LazyLock;
19//! use regex::Regex;
20//!
21//! // only compiled once, by storing in a static
22//! static HEX_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
23//!    Regex::new("[0-9a-f]+").expect("invalid regex")
24//! });
25//!
26//! # let my_iter = vec!["deadbeaf", "1234"];
27//! for item in my_iter {
28//!     if HEX_PATTERN.is_match(item) {
29//!        // frobnicate
30//!     }
31//! }
32//! ```
33//!
34//! ### After
35//!
36//! ```
37//! use regex_macro::regex;
38//!
39//! # let my_iter = vec!["deadbeaf", "1234"];
40//! for item in my_iter {
41//!     // this is still only compiled once!
42//!     if regex!("[0-9a-f]+").is_match(item) {
43//!        // frobnicate
44//!     }
45//! }
46//! ```
47//!
48//! Isn't that much nicer?
49//!
50
51use std::sync::LazyLock;
52
53#[doc(hidden)]
54pub use regex::Regex;
55
56/// Convenient type alias for a lazy regex.
57pub type LazyRegex = LazyLock<Regex>;
58
59/// Returns a lazy regex.
60///
61/// # Examples
62///
63/// ```
64/// use regex_macro::{LazyRegex, lazy_regex};
65///
66/// static RE: LazyRegex = lazy_regex!("[0-9a-f]+");
67/// ```
68#[macro_export]
69macro_rules! lazy_regex {
70    ($re:expr $(,)?) => {{
71        $crate::LazyRegex::new(|| $crate::Regex::new($re).expect("invalid regex"))
72    }};
73}
74
75/// Creates a static regex and returns a reference to it.
76///
77/// See the [crate level documentation][crate] for more information.
78#[macro_export]
79macro_rules! regex {
80    ($re:expr $(,)?) => {{
81        static RE: $crate::LazyRegex = $crate::lazy_regex!($re);
82        &RE
83    }};
84}
85
86#[cfg(test)]
87mod tests {
88    use super::*;
89
90    #[test]
91    fn regex() {
92        let hex = regex!("[0-9a-f]+");
93        assert!(hex.is_match("1234deadbeef"));
94    }
95}