diff --git a/src/event/mod.rs b/src/event/mod.rs index bb18cba..f53140c 100644 --- a/src/event/mod.rs +++ b/src/event/mod.rs @@ -1,6 +1,7 @@ use {Message, Channel, User}; use std::sync::Arc; +use std::collections::btree_set::BTreeSet; #[derive(Debug)] pub enum Event { @@ -18,36 +19,36 @@ pub struct Envelope { pub from: Option, pub event: Event, pub to: Vec, - pub tags: Vec + pub tags: BTreeSet } impl Envelope { pub fn new (event: Event) -> Envelope { - let mut tags: Vec = vec![]; + let mut tags: BTreeSet = BTreeSet::new(); match &event { &Event::Message { ref message } => { - tags.push(format!("user:{:}", message.author.name)); + tags.insert(format!("user:{:}", message.author.name)); match message.channel { Some(ref channel) => { - tags.push(format!("channel:{:}", channel.name)); + tags.insert(format!("channel:{:}", channel.name)); }, None => {} } }, &Event::SelfJoin { ref channel } => { - tags.push(format!("channel:{:}", channel.name)); + tags.insert(format!("channel:{:}", channel.name)); }, &Event::SelfQuit { ref channel } => { - tags.push(format!("channel:{:}", channel.name)); + tags.insert(format!("channel:{:}", channel.name)); }, &Event::UserJoin { ref channel, ref user } => { - tags.push(format!("channel:{:}", channel.name)); - tags.push(format!("user:{:}", user.name)); + tags.insert(format!("channel:{:}", channel.name)); + tags.insert(format!("user:{:}", user.name)); }, &Event::UserQuit { ref channel, ref user } => { - tags.push(format!("channel:{:}", channel.name)); - tags.push(format!("user:{:}", user.name)); + tags.insert(format!("channel:{:}", channel.name)); + tags.insert(format!("user:{:}", user.name)); } } diff --git a/src/lib.rs b/src/lib.rs index f75deed..074a544 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -101,23 +101,36 @@ impl Tenquestionmarks { let arc_envelope = Arc::new(envelope); for (key, sender) in &module_senders { let from_this = String::from(*key); - if Some(from_this.clone()) == arc_envelope.from { - debug!("Refusing to transmit event to its originator ({:?})", from_this); - continue; - } - else if !(arc_envelope.to.is_empty() || !arc_envelope.to.contains(&from_this)) { - debug!( - "Refusing to transmit envelope from {:?} to {:?} since it is not on the list of allowed recipients ({:?})", - arc_envelope.from, - from_this, - arc_envelope.to - ); - continue; - } + match self.modules.get::(&from_this) { + Some(module) => { + if Some(from_this.clone()) == arc_envelope.from { + debug!("Refusing to transmit event to its originator ({:?})", from_this); + continue; + } + else if !(arc_envelope.to.is_empty() || !arc_envelope.to.contains(&from_this)) { + debug!( + "Refusing to transmit envelope from {:?} to {:?} since it is not on the list of allowed recipients ({:?})", + arc_envelope.from, + from_this, + arc_envelope.to + ); + continue; + } + else if !module.can_handle_event(&arc_envelope) { + debug!( + "Refusing to transmit envelope from {:?} to {:?} since envelope was filtered out", + arc_envelope.from, + from_this + ); + continue; + } - match sender.send(arc_envelope.clone()) { - Err(err) => debug!("Failed to dispatch event to module \"{}\": {:?}", key, err), - Ok(_) => {} + match sender.send(arc_envelope.clone()) { + Err(err) => debug!("Failed to dispatch event to module \"{}\": {:?}", key, err), + Ok(_) => {} + } + }, + None => debug!("Failed to dispatch event to module \"{}\": No such module found!", key) } } }, diff --git a/src/modules/mod.rs b/src/modules/mod.rs index fd4ae3e..6de6d54 100644 --- a/src/modules/mod.rs +++ b/src/modules/mod.rs @@ -19,6 +19,8 @@ use transformable_channels::mpsc::ExtSender; use toml::Table; +use std::collections::btree_set::BTreeSet; + pub struct Module { event_loop: Box, module_type: String, @@ -29,6 +31,22 @@ impl Module { pub fn run (&self, sender: Box>, receiver: Receiver>) { self.event_loop.run(sender, receiver); } + + pub fn can_handle_event (&self, envelope: &Envelope) -> bool { + let filters: BTreeSet = self.config.get("filters") + .and_then(|value| value.as_slice()) + .map(|value| value.to_vec()) + .unwrap_or(vec![]) + .into_iter() + .map(|value| { String::from(value.as_str().unwrap()) }) + .collect(); + + if filters.is_empty() { + return true; + } + + filters.intersection(&envelope.tags).count() > 0 + } } pub trait EventLoop : Sync { diff --git a/tenquestionmarks.toml b/tenquestionmarks.toml index 825b061..b281719 100644 --- a/tenquestionmarks.toml +++ b/tenquestionmarks.toml @@ -74,3 +74,6 @@ end foo = "bar" [autolink] + +[logger] +filters = ["user:Dave"]