| 1 | use std::collections::BTreeMap; |
| 2 | use std::vec::Vec; |
| 3 | use crate::message::MatchRule; |
| 4 | use crate::Message; |
| 5 | use crate::channel::Token; |
| 6 | |
| 7 | pub struct Filters<F> { |
| 8 | list: BTreeMap<Token, (MatchRule<'static>, F)>, |
| 9 | nextid: Token, |
| 10 | } |
| 11 | |
| 12 | |
| 13 | impl<F> Default for Filters<F> { |
| 14 | fn default() -> Self { Filters { |
| 15 | list: BTreeMap::new(), |
| 16 | nextid: Token(1), |
| 17 | }} |
| 18 | } |
| 19 | |
| 20 | impl<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 | |