acick_util/
macros.rs

1/// Create and cache Regex object
2#[macro_export]
3macro_rules! regex {
4    ($expr:expr) => {{
5        static REGEX: ::once_cell::sync::Lazy<::regex::Regex> =
6            ::once_cell::sync::Lazy::new(|| ::regex::Regex::new($expr).unwrap());
7        &REGEX
8    }};
9    ($expr:expr,) => {
10        regex!($expr)
11    };
12}
13
14#[macro_export]
15macro_rules! select {
16    ($selectors:literal) => {{
17        static SELECTOR: ::once_cell::sync::Lazy<::scraper::selector::Selector> =
18            ::once_cell::sync::Lazy::new(|| {
19                ::scraper::selector::Selector::parse($selectors).unwrap()
20            });
21        &SELECTOR
22    }};
23    ($selectors:literal,) => {
24        selector!($selectors)
25    };
26}
27
28/// Check if an expression matches a refutable pattern.
29///
30/// Syntax: `matches!(` *expression* ` => ` *pattern* `)`
31///
32/// Return a boolean, true if the expression matches the pattern, false otherwise.
33///
34/// # Examples
35///
36/// ```
37/// #[macro_use]
38/// extern crate acick_util;
39///
40/// pub enum Foo<T> {
41///     A,
42///     B(T),
43/// }
44///
45/// impl<T> Foo<T> {
46///     pub fn is_a(&self) -> bool {
47///         matches!(*self => Foo::A)
48///     }
49///
50///     pub fn is_b(&self) -> bool {
51///         matches!(*self => Foo::B(_))
52///     }
53/// }
54///
55/// # fn main() { }
56/// ```
57#[macro_export]
58macro_rules! matches {
59    ($expression:expr => $pattern:pat) => {
60        match $expression {
61            $pattern => true,
62            _ => false,
63        }
64    };
65}
66
67/// Assert that an expression matches a refutable pattern.
68///
69/// Syntax: `assert_matches!(` *expression* ` => ` *pattern* `)`
70///
71/// Panic with a message that shows the expression if it does not match the
72/// pattern.
73///
74/// # Examples
75///
76/// ```
77/// #[macro_use]
78/// extern crate acick_util;
79///
80/// fn main() {
81///     let data = [1, 2, 3];
82///     assert_matches!(data.get(1) => Some(_));
83/// }
84/// ```
85#[macro_export]
86macro_rules! assert_matches {
87    ($expression:expr => $pattern:pat) => {
88        match $expression {
89            $pattern => (),
90            ref e => panic!(
91                "assertion failed: `{:?}` does not match `{}`",
92                e,
93                stringify!($pattern)
94            ),
95        }
96    };
97}
98
99#[cfg(test)]
100mod tests {
101    #[test]
102    fn test_regex() {
103        // check multiple regex! calls creates only one instance and caches it
104        let regs: Vec<_> = (0..2).map(|_| regex!(r"\A(hello)+\z")).collect();
105        assert_eq!(regs[0] as *const _, regs[1] as *const _);
106    }
107
108    #[test]
109    fn test_select() {
110        // check multiple select! calls creates only one instance and caches it
111        let selects: Vec<_> = (0..2).map(|_| select!("div a")).collect();
112        assert_eq!(selects[0] as *const _, selects[1] as *const _);
113    }
114}