diff --git a/src/events.rs b/src/events.rs index 73eb88e..245bd66 100644 --- a/src/events.rs +++ b/src/events.rs @@ -64,15 +64,12 @@ impl Irc { channel: &str, message: &str, ) { - let context = self.context.read().await; + let config = self.context.read().await.config.clone(); - if channel == &context.config.nick { - if message.ends_with(&format!( - "\x02{}\x02 isn't registered.", - context.config.nick - )) { - let nickserv_pass = context.config.nickserv_pass.as_ref().unwrap().to_string(); - let nickserv_email = context.config.nickserv_email.as_ref().unwrap().to_string(); + if channel == &config.nick { + if message.ends_with(&format!("\x02{}\x02 isn't registered.", config.nick)) { + let nickserv_pass = config.nickserv_pass.as_ref().unwrap().to_string(); + let nickserv_email = config.nickserv_email.as_ref().unwrap().to_string(); info!("Registering to nickserv now."); let mut context = self.context.write().await; context.privmsg( @@ -106,13 +103,14 @@ impl Irc { channel: &str, message: &str, ) { + let mut elements; let sys_name; { let context = self.context.read().await; if !message.starts_with(&context.config.cmdkey) { return; } - let mut elements = message.split_whitespace(); + elements = message.split_whitespace(); sys_name = elements.next().unwrap()[1..].to_owned(); if context.is_owner(prefix) && sys_name == "raw" { @@ -130,7 +128,9 @@ impl Irc { if !context.systems.contains_key(&sys_name) { return; } - let response = context.run_system(prefix, &sys_name).await; + let response = context + .run_system(prefix, elements.collect(), &sys_name) + .await; if response.0.is_none() { return; diff --git a/src/lib.rs b/src/lib.rs index 16c65fc..b5297ec 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -139,13 +139,13 @@ impl<'a> From<&'a str> for IrcMessage<'a> { } } -#[derive(Serialize, Deserialize)] +#[derive(Clone, Serialize, Deserialize)] pub struct IrcConfig { host: String, port: u16, ssl: bool, - channels: HashSet, nick: String, + channels: HashSet, user: String, real: String, nickserv_pass: Option, @@ -295,9 +295,14 @@ impl Context { self } - pub async fn run_system<'a>(&mut self, prefix: &'a IrcPrefix<'a>, name: &str) -> Response { + pub async fn run_system<'a>( + &mut self, + prefix: &'a IrcPrefix<'a>, + arguments: Vec<&'a str>, + name: &str, + ) -> Response { let system = self.systems.get_mut(name).unwrap(); - system.run(prefix, &mut *self.factory.write().await) + system.run(prefix, &arguments, &mut *self.factory.write().await) } pub async fn run_interval_tasks(&mut self, tx: mpsc::Sender>) { @@ -313,6 +318,7 @@ impl Context { user: None, host: None, }, + &[], &mut *fact.write().await, ); if resp.0.is_none() { diff --git a/src/system.rs b/src/system.rs index f7d0e2d..d5b4fd1 100644 --- a/src/system.rs +++ b/src/system.rs @@ -8,7 +8,7 @@ pub struct FunctionSystem { } pub trait System { - fn run(&mut self, prefix: &IrcPrefix, factory: &mut Factory) -> Response; + fn run(&mut self, prefix: &IrcPrefix, arguments: &[&str], factory: &mut Factory) -> Response; } pub trait IntoSystem { @@ -29,7 +29,7 @@ macro_rules! impl_system { FnMut( $($params),* ) -> R + FnMut( $(<$params as SystemParam>::Item<'b>),* ) -> R { - fn run(&mut self, prefix: &IrcPrefix, factory: &mut Factory) -> Response { + fn run(&mut self, prefix: &IrcPrefix, arguments: &[&str], factory: &mut Factory) -> Response { fn call_inner<'a, R: IntoResponse, $($params),*>( mut f: impl FnMut($($params),*) -> R, $($params: $params),* @@ -38,7 +38,7 @@ macro_rules! impl_system { } $( - let $params = $params::retrieve(prefix, &factory); + let $params = $params::retrieve(prefix, arguments, &factory); )* call_inner(&mut self.f, $($params),*) @@ -74,18 +74,26 @@ impl_system!(T1); impl_system!(T1, T2); impl_system!(T1, T2, T3); impl_system!(T1, T2, T3, T4); +impl_system!(T1, T2, T3, T4, T5); +impl_system!(T1, T2, T3, T4, T5, T6); +impl_system!(T1, T2, T3, T4, T5, T6, T7); +impl_system!(T1, T2, T3, T4, T5, T6, T7, T8); impl_into_system!(); impl_into_system!(T1); impl_into_system!(T1, T2); impl_into_system!(T1, T2, T3); impl_into_system!(T1, T2, T3, T4); +impl_into_system!(T1, T2, T3, T4, T5); +impl_into_system!(T1, T2, T3, T4, T5, T6); +impl_into_system!(T1, T2, T3, T4, T5, T6, T7); +impl_into_system!(T1, T2, T3, T4, T5, T6, T7, T8); pub(crate) type StoredSystem = Box System + Send + Sync>; pub(crate) trait SystemParam { type Item<'new>; - fn retrieve<'r>(prefix: &'r IrcPrefix, factory: &'r Factory) -> Self::Item<'r>; + fn retrieve<'r>(prefix: &'r IrcPrefix, arguments: &'r[&'r str], factory: &'r Factory) -> Self::Item<'r>; } #[derive(Clone)] @@ -119,6 +127,31 @@ impl IntoResponse for Msg { } } +impl IntoResponse for Result +where + O: IntoResponse, + E: IntoResponse, +{ + fn response(self) -> Response { + match self { + Ok(o) => o.response(), + Err(e) => e.response(), + } + } +} + +impl IntoResponse for Option +where + S: IntoResponse, +{ + fn response(self) -> Response { + match self { + Some(s) => s.response(), + None => Response(None), + } + } +} + impl IntoResponse for Vec { fn response(self) -> Response { Response(Some( diff --git a/src/system_params.rs b/src/system_params.rs index a292223..4ad0962 100644 --- a/src/system_params.rs +++ b/src/system_params.rs @@ -28,7 +28,11 @@ impl<'a, T: 'static> AsRef for Res<'a, T> { impl<'res, T: 'static> SystemParam for Res<'res, T> { type Item<'new> = Res<'new, T>; - fn retrieve<'r>(_prefix: &'r IrcPrefix, factory: &'r Factory) -> Self::Item<'r> { + fn retrieve<'r>( + _prefix: &'r IrcPrefix, + _arguments: &'r [&'r str], + factory: &'r Factory, + ) -> Self::Item<'r> { Res { value: &factory .resources @@ -73,7 +77,11 @@ impl<'a, T: 'static> AsMut for ResMut<'a, T> { impl<'res, T: 'static> SystemParam for ResMut<'res, T> { type Item<'new> = ResMut<'new, T>; - fn retrieve<'r>(_prefix: &'r IrcPrefix, factory: &'r Factory) -> Self::Item<'r> { + fn retrieve<'r>( + _prefix: &'r IrcPrefix, + _arguments: &'r [&'r str], + factory: &'r Factory, + ) -> Self::Item<'r> { let const_ptr = &factory.resources as *const HashMap>; let mut_ptr = const_ptr as *mut HashMap>; let res_mut = unsafe { &mut *mut_ptr }; @@ -91,7 +99,33 @@ impl<'res, T: 'static> SystemParam for ResMut<'res, T> { impl<'a> SystemParam for IrcPrefix<'a> { type Item<'new> = IrcPrefix<'new>; - fn retrieve<'r>(prefix: &'r IrcPrefix, _factory: &'r Factory) -> Self::Item<'r> { + fn retrieve<'r>( + prefix: &'r IrcPrefix, + _arguments: &'r [&'r str], + _factory: &'r Factory, + ) -> Self::Item<'r> { prefix.clone() } } + +pub struct Arguments<'a>(&'a [&'a str]); + +impl<'a> Deref for Arguments<'a> { + type Target = &'a [&'a str]; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl<'a> SystemParam for Arguments<'a> { + type Item<'new> = Arguments<'new>; + + fn retrieve<'r>( + _prefix: &'r IrcPrefix, + arguments: &'r [&'r str], + _factory: &'r Factory, + ) -> Self::Item<'r> { + Arguments(arguments) + } +}