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}