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 ®EX
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}