1use std::collections::BTreeMap;
2use std::vec::Vec;
3use crate::message::MatchRule;
4use crate::Message;
5use crate::channel::Token;
6
7pub struct Filters<F> {
8 list: BTreeMap<Token, (MatchRule<'static>, F)>,
9 nextid: Token,
10}
11
12
13impl<F> Default for Filters<F> {
14 fn default() -> Self { Filters {
15 list: BTreeMap::new(),
16 nextid: Token(1),
17 }}
18}
19
20impl<F> Filters<F> {
21 pub fn add(&mut self, m: MatchRule<'static>, f: F) -> Token {
22 let id = self.nextid;
23 self.nextid.0 += 1;
24 self.list.insert(id, (m, f));
25 id
26 }
27
28 pub fn insert(&mut self, (t, m, f): (Token, MatchRule<'static>, F)) {
29 self.list.insert(t, (m, f));
30 }
31
32 pub fn remove(&mut self, id: Token) -> Option<(MatchRule<'static>, F)> {
33 self.list.remove(&id)
34 }
35
36 /// Removes and returns the first filter which matches the given message.
37 pub fn remove_first_matching(&mut self, msg: &Message) -> Option<(Token, MatchRule<'static>, F)> {
38 if let Some(k) = self.list.iter_mut().find_map(|(k, v)| if v.0.matches(&msg) { Some(*k) } else { None }) {
39 let v = self.list.remove(&k).unwrap();
40 Some((k, v.0, v.1))
41 } else {
42 None
43 }
44 }
45
46 /// Removes and returns all filters which match the given message.
47 pub fn remove_all_matching(&mut self, msg: &Message) -> Vec<(Token, MatchRule<'static>, F)> {
48 let matching: Vec<_> = self.list.iter().filter_map(|(k, v)| if v.0.matches(&msg) { Some(*k) } else { None }).collect();
49 matching
50 .into_iter()
51 .map(|k| {
52 let v = self.list.remove(&k).unwrap();
53 (k, v.0, v.1)
54 })
55 .collect()
56 }
57}
58