diff --git a/src/bot.rs b/src/bot.rs index 683691e..3db22c6 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -3,7 +3,7 @@ use crate::ExecutorConnection; use async_trait::async_trait; use fancy_regex::{Captures, Regex}; use std::collections::HashMap; -use tokio::sync::Mutex; +use tokio::sync::{Mutex, mpsc}; fn dissect<'a>(prefixes: &[String], str: &'a str) -> Option<(&'a str, Option<&'a str>)> { for prefix in prefixes { @@ -108,8 +108,8 @@ impl anyhow::Result<()>> Bot { Ok(()) } - pub async fn handle_message(&self, origin: &str, author: &str, content: &str) { - if let Err(e) = self.handle_message_inner(origin, author, content).await { + pub async fn handle_message(&self, origin: String, author: String, content: String, _cancel_handle: mpsc::Sender<()>) { + if let Err(e) = self.handle_message_inner(&origin, &author, &content).await { let _err = (self.sendmsg)(origin.into(), format!("Error: {}", e)); } } diff --git a/src/main.rs b/src/main.rs index 4e5c7bc..f2dfe33 100644 --- a/src/main.rs +++ b/src/main.rs @@ -22,7 +22,7 @@ use irc::client::{Client, ClientStream}; use irc::proto::{ChannelExt, Command, Prefix}; use rspotify::Credentials; use tokio::select; -use tokio::sync::broadcast; +use tokio::sync::{broadcast, mpsc}; use tokio::sync::mpsc::unbounded_channel; use tracing::Level; @@ -185,23 +185,30 @@ async fn main() -> anyhow::Result<()> { Ok(()) } -async fn message_loop anyhow::Result<()>>( +async fn message_loop( mut stream: ClientStream, bot: Bot, -) -> anyhow::Result<()> { +) -> anyhow::Result<()> where SF: Fn(String, String) -> anyhow::Result<()> + Send + Sync + 'static { + let bot = Arc::new(bot); + let (cancelled_send, mut cancelled_recv) = mpsc::channel::<()>(1); while let Some(message) = stream.next().await.transpose()? { - if let Command::PRIVMSG(ref origin, content) = message.command { + if let Command::PRIVMSG(origin, content) = message.command { if origin.is_channel_name() { - if let Some(author) = message.prefix.as_ref().and_then(|p| match p { - Prefix::Nickname(name, _, _) => Some(&name[..]), + if let Some(author) = message.prefix.and_then(|p| match p { + Prefix::Nickname(name, _, _) => Some(name), Prefix::ServerName(_) => None, }) { - bot.handle_message(origin, author, &content).await; + let bot = bot.clone(); + let cancelled_send = cancelled_send.clone(); + tokio::spawn(async move { + bot.handle_message(origin, author, content, cancelled_send).await; + }); } else { tracing::warn!("Couldn't get the author for a message"); } } } } + let _ = cancelled_recv.recv().await; Ok(()) }