regex_map/bytes.rs
1pub struct RegexMap<V> {
2 set: regex::bytes::RegexSet,
3 values: Vec<V>,
4}
5
6impl<V> RegexMap<V> {
7 /// Create a new `RegexMap` from iterator over (expression, value) pairs, where the expression is `&str`-like.
8 ///
9 /// ```
10 /// use regex_map::bytes::RegexMap;
11 ///
12 /// let map = RegexMap::new([
13 /// ("foo", 1),
14 /// ("bar", 2),
15 /// ("foobar", 3),
16 /// ("^foo$", 4),
17 /// ("^bar$", 5),
18 /// ("^foobar$", 6),
19 /// ]);
20 ///
21 /// assert_eq!(map.get(b"foo").cloned().collect::<Vec<_>>(), vec![1, 4]);
22 /// assert_eq!(map.get(b"bar").cloned().collect::<Vec<_>>(), vec![2, 5], );
23 /// assert_eq!(map.get(b"foobar").cloned().collect::<Vec<_>>(), vec![1, 2, 3, 6]);
24 /// assert_eq!(map.get(b"XXX foo XXX").cloned().collect::<Vec<_>>(), vec![1]);
25 /// assert_eq!(map.get(b"XXX bar XXX").cloned().collect::<Vec<_>>(), vec![2]);
26 /// ```
27 pub fn new<I, S>(items: I) -> Self
28 where
29 I: IntoIterator<Item = (S, V)>,
30 S: AsRef<str>,
31 {
32 let mut exprs = Vec::new();
33 let mut values = Vec::new();
34 for (expr, value) in items {
35 exprs.push(expr);
36 values.push(value);
37 }
38
39 let set = regex::bytes::RegexSet::new(exprs).unwrap();
40 RegexMap { set, values }
41 }
42
43 /// Get an iterator over all values whose regular expression matches the given key.
44 ///
45 /// To get first matching value, use can use `.next()` on the returned iterator:
46 ///
47 /// ```
48 /// use regex_map::bytes::RegexMap;
49 ///
50 /// let map = RegexMap::new([
51 /// ("foo", 1),
52 /// ("bar", 2),
53 /// ]);
54 ///
55 /// assert_eq!(map.get(b"foo").next(), Some(&1));
56 /// ```
57 pub fn get(&self, key: &[u8]) -> impl Iterator<Item = &V> {
58 self.set
59 .matches(key)
60 .into_iter()
61 .map(move |i| &self.values[i])
62 }
63
64 /// Check if the given key matches any of the regular expressions.
65 pub fn contains_key(&self, key: &[u8]) -> bool {
66 self.set.is_match(key)
67 }
68}