diff --git a/src/events.rs b/src/events.rs index a062b2c..0036a1f 100644 --- a/src/events.rs +++ b/src/events.rs @@ -128,22 +128,33 @@ impl Irc { let mut context = self.context.write().await; if !context.systems.contains_key(&sys_name) { - for line in context.run_default_system(prefix, &arguments).await { - context.privmsg(channel, &line) + let resp = context.run_default_system(prefix, &arguments).await; + + let Response::Data(data) = resp else { + return; + }; + + for (idx, line) in data.data.iter().enumerate() { + if idx == 0 && data.highlight { + context.privmsg(channel, &format!("{}: {}", prefix.nick, line)) + } else { + context.privmsg(channel, &line) + } } return; } let response = context.run_system(prefix, &arguments, &sys_name).await; - - let lines = match response { - Response::Lines(lines) => lines, - Response::InvalidArgument => context.run_invalid_system(prefix, &arguments).await, - _ => return, + let Response::Data(data) = response else { + return; }; - for line in lines { - context.privmsg(channel, &line) + for (idx, line) in data.data.iter().enumerate() { + if idx == 0 && data.highlight { + context.privmsg(channel, &format!("{}: {}", prefix.nick, line)) + } else { + context.privmsg(channel, &line) + } } } } diff --git a/src/lib.rs b/src/lib.rs index a6e4a3e..834c6d7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -271,7 +271,7 @@ impl Context { pub async fn run_system<'a>( &mut self, prefix: &'a IrcPrefix<'a>, - arguments: &'a[&'a str], + arguments: &'a [&'a str], name: &str, ) -> Response { let system = self.systems.get_mut(name).unwrap(); @@ -281,44 +281,36 @@ impl Context { pub async fn run_default_system<'a>( &mut self, prefix: &'a IrcPrefix<'a>, - arguments: &'a[&'a str], - ) -> Vec { - if self.default_system.is_none() { - return vec![]; + arguments: &'a [&'a str], + ) -> Response { + if self.invalid_system.is_none() { + return Response::Empty; } - if let Response::Lines(lines) = self.default_system.as_mut().unwrap().run( + self.default_system.as_mut().unwrap().run( prefix, arguments, &mut *self.factory.write().await, - ) { - lines - } else { - return vec![]; - } + ) } pub async fn run_invalid_system<'a>( &mut self, prefix: &'a IrcPrefix<'a>, - arguments: &'a[&'a str], - ) -> Vec { + arguments: &'a [&'a str], + ) -> Response { if self.invalid_system.is_none() { - return vec![]; + return Response::Empty; } - if let Response::Lines(lines) = self.invalid_system.as_mut().unwrap().run( + self.invalid_system.as_mut().unwrap().run( prefix, arguments, &mut *self.factory.write().await, - ) { - lines - } else { - return vec![]; - } + ) } - pub async fn run_interval_tasks(&mut self, tx: mpsc::Sender>) { + pub async fn run_interval_tasks(&mut self, tx: mpsc::Sender) { for (task_duration, mut task) in std::mem::take(&mut self.interval_tasks) { let fact = self.factory.clone(); let task_tx = tx.clone(); @@ -334,11 +326,7 @@ impl Context { &[], &mut *fact.write().await, ); - match resp { - Response::Lines(lines) => task_tx.send(lines).await.unwrap(), - Response::Empty => continue, - Response::InvalidArgument => continue, - } + task_tx.send(resp).await.unwrap(); } }); } @@ -554,7 +542,7 @@ impl Irc { pub async fn run(&mut self) -> std::io::Result<()> { self.connect().await?; info!("Ready!"); - let (tx, mut rx) = mpsc::channel::>(512); + let (tx, mut rx) = mpsc::channel::(512); { let mut context = self.context.write().await; context.register(); @@ -586,11 +574,15 @@ impl Irc { } } -async fn handle_rx(rx: &mut mpsc::Receiver>, arc_context: &RwLock) { - while let Some(data) = rx.recv().await { +async fn handle_rx(rx: &mut mpsc::Receiver, arc_context: &RwLock) { + while let Some(response) = rx.recv().await { let mut context = arc_context.write().await; - for line in data { + let Response::Data(data) = response else { + continue; + }; + + for line in data.data { context.privmsg_all(&line); } } diff --git a/src/system.rs b/src/system.rs index 16ea33a..ffe3513 100644 --- a/src/system.rs +++ b/src/system.rs @@ -125,17 +125,59 @@ pub(crate) trait SystemParam { } } -#[derive(Clone)] +#[derive(Debug)] +pub struct ResponseData { + pub(crate) highlight: bool, + pub(crate) data: Vec, +} + +impl Default for ResponseData { + fn default() -> Self { + Self { + highlight: true, + data: Default::default(), + } + } +} + +#[derive(Debug)] pub enum Response { - Lines(Vec), + Data(ResponseData), Empty, InvalidArgument, } +impl Into for ResponseData { + fn into(self) -> Response { + Response::Data(self) + } +} + pub trait IntoResponse { fn response(self) -> Response; } +impl IntoResponse for ResponseData { + fn response(self) -> Response { + self.into() + } +} + +impl IntoResponse for (bool, T) { + fn response(self) -> Response { + let resp = self.1.response(); + + match resp { + Response::Data(data) => ResponseData { + highlight: self.0, + data: data.data, + } + .into(), + _ => resp, + } + } +} + impl IntoResponse for () { fn response(self) -> Response { Response::Empty @@ -144,19 +186,31 @@ impl IntoResponse for () { impl IntoResponse for String { fn response(self) -> Response { - Response::Lines(vec![self]) + ResponseData { + data: vec![self], + ..Default::default() + } + .into() } } impl IntoResponse for &str { fn response(self) -> Response { - Response::Lines(vec![self.to_owned()]) + ResponseData { + data: vec![self.to_owned()], + ..Default::default() + } + .into() } } impl IntoResponse for Msg { fn response(self) -> Response { - Response::Lines(vec![self.to_string()]) + ResponseData { + data: vec![self.to_string()], + ..Default::default() + } + .into() } } @@ -187,7 +241,11 @@ where impl IntoResponse for Vec { fn response(self) -> Response { - Response::Lines(self.iter().map(|elem| elem.to_string()).collect::>()) + ResponseData { + data: self.iter().map(|elem| elem.to_string()).collect::>(), + ..Default::default() + } + .into() } } @@ -195,7 +253,11 @@ macro_rules! impl_into_response_for_primitives { ($param:ident) => { impl IntoResponse for $param { fn response(self) -> Response { - Response::Lines(vec![self.to_string()]) + ResponseData { + data: vec![self.to_string()], + ..Default::default() + } + .into() } } };