diff --git a/src/main.rs b/src/main.rs index 607249d6448c8dd17b8d661721d288534db89942..d48e70cf41caf2909fda31da4755683caf87d1ea 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,25 +5,23 @@ mod config; mod matrix; mod utils; -use log::{error, info}; +use crate::cmd::Cmd; use matrix_sdk; -use std::{env, process::abort}; +use std::env; #[tokio::main] async fn main() -> matrix_sdk::Result<()> { config::setup_logging(); config::check_argument_or_abort(true); - let config_file = env::args().last().unwrap(); - info!("Using config file: {}", config_file); - return match config::from_file(&config_file) { - Ok(config) => matrix::connect_and_handle(config).await, - Err(e) => { - error!( - "Failed to read config file '{}' with error: {}", - config_file, e - ); - abort(); - } - }; + let basic_cmds = vec![ + Cmd::new_simple(format!("ping"), 0, |_x| true), + Cmd::new_echo(format!("bot_name"), 0, |_x| format!("toto")), + ]; + + matrix::Bot::new(env::args().last().unwrap()) + .connect().await? + .add_package(format!("basic"), basic_cmds) + .listen() + .await } diff --git a/src/matrix.rs b/src/matrix.rs index 48b7abca801cd4b077797707b8068fc00ec55202..7a6e9378df7753b987eb1ade482cd821362a3ccf 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1,4 +1,9 @@ -use crate::{cmd::package::CmdPackage, cmd::Cmd, config::Config, return_if}; +use crate::{ + cmd::package::CmdPackage, + cmd::Cmd, + config::{from_file as config_from_file, Config}, + return_if, +}; use futures::future::join_all; use log::{error, info, warn}; use matrix_sdk::{ @@ -158,48 +163,128 @@ macro_rules! register_handler_if_enabled { }}; } -pub async fn connect_and_handle(config: Config) -> Result<()> { - // TODO: Refactor - let pkg_commands_vec = vec![ - Cmd::new_simple(format!("ping"), 0, Arc::new(|_x| true)), - Cmd::new_echo(format!("bot_name"), 0, Arc::new(move |_x| format!("toto"))), - ]; - let pkg = match config.section("basic") { - Some(section) => CmdPackage::from_config(§ion, pkg_commands_vec), - None => { - abort(); +pub struct Bot { + config: Config, + client: Option<Client>, +} + +impl Bot { + pub fn new(config_file: String) -> Bot { + match config_from_file(&config_file) { + Err(e) => { + error!( + "Failed to read config file '{}' with error: {}", + config_file, e + ); + abort(); + } + Ok(config) => { + info!("Using config file: {}", config_file); + Bot { + config: config, + client: None, + } + } } - }; - GLOBAL_PKG.lock().unwrap().push(pkg); - - let alice = UserId::try_from(config.user_name)?; - let client = Client::new(config.homeserver_url)?; - - client - .login( - alice.localpart(), - config.user_password.as_str(), - None, - Some(config.display_name.as_str()), - ) - .await?; - info!("Logged as: {}", alice); - - client.sync_once(SyncSettings::default()).await?; - startup_and_log_rooms(&client).await; - register_handler_if_enabled!( - client, - config.handle_state_member, - on_state_member, - "state member" - ); - - client.register_event_handler(on_msg_room_event).await; - client.register_event_handler(on_msg_room_reaction).await; - - info!("Entering sync loop"); - let token = client.sync_token().await.unwrap(); - let settings = SyncSettings::default().token(token); - client.sync(settings).await; - Ok(()) + } + + pub async fn connect(&mut self) -> Result<&mut Self> { + let alice = UserId::try_from(self.config.user_name.clone())?; + let client = Client::new(self.config.homeserver_url.clone())?; + + client + .login( + alice.localpart(), + self.config.user_password.as_str(), + None, + Some(self.config.display_name.as_str()), + ) + .await?; + + info!("Logged as: {}", alice); + + client.sync_once(SyncSettings::default()).await?; + startup_and_log_rooms(&client).await; + register_handler_if_enabled!( + client, + self.config.handle_state_member, + on_state_member, + "state member" + ); + + client.register_event_handler(on_msg_room_event).await; + client.register_event_handler(on_msg_room_reaction).await; + + self.client = Some(client); + return Ok(self); + } + + pub async fn listen(&self) -> Result<()> { + match &self.client { + None => abort(), + Some(client) => { + info!("Entering sync loop"); + let token = client.sync_token().await.unwrap(); + client.sync(SyncSettings::default().token(token)).await; + Ok(()) + } + } + } + + pub fn add_package(&self, name: String, cmds: Vec<Cmd>) -> &Self { + let pkg = match self.config.section("basic") { + Some(section) => CmdPackage::from_config(§ion, cmds), + None => { + abort(); + } + }; + GLOBAL_PKG.lock().unwrap().push(pkg); + &self + } + + pub async fn connect_and_handle(config: Config) -> Result<()> { + // TODO: Refactor + let pkg_commands_vec = vec![ + Cmd::new_simple(format!("ping"), 0, Arc::new(|_x| true)), + Cmd::new_echo(format!("bot_name"), 0, Arc::new(move |_x| format!("toto"))), + ]; + let pkg = match config.section("basic") { + Some(section) => CmdPackage::from_config(§ion, pkg_commands_vec), + None => { + abort(); + } + }; + GLOBAL_PKG.lock().unwrap().push(pkg); + + let alice = UserId::try_from(config.user_name)?; + let client = Client::new(config.homeserver_url)?; + + client + .login( + alice.localpart(), + config.user_password.as_str(), + None, + Some(config.display_name.as_str()), + ) + .await?; + info!("Logged as: {}", alice); + + client.sync_once(SyncSettings::default()).await?; + startup_and_log_rooms(&client).await; + register_handler_if_enabled!( + client, + config.handle_state_member, + on_state_member, + "state member" + ); + + client.register_event_handler(on_msg_room_event).await; + client.register_event_handler(on_msg_room_reaction).await; + + info!("Entering sync loop"); + let token = client.sync_token().await.unwrap(); + let settings = SyncSettings::default().token(token); + client.sync(settings).await; + Ok(()) + } }