diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 35ebce8..acf00e1 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -10,6 +10,7 @@ pub mod cthulhu; pub mod management; pub mod misc; pub mod parser; +pub mod rooms; pub mod variables; /// A custom error type specifically related to parsing command text. diff --git a/src/commands/parser.rs b/src/commands/parser.rs index 879bd0a..83b0882 100644 --- a/src/commands/parser.rs +++ b/src/commands/parser.rs @@ -9,6 +9,7 @@ use crate::commands::{ cthulhu::{CthAdvanceRoll, CthRoll}, management::{CheckCommand, LinkCommand, RegisterCommand, UnlinkCommand, UnregisterCommand}, misc::HelpCommand, + rooms::ListRoomsCommand, variables::{ DeleteVariableCommand, GetAllVariablesCommand, GetVariableCommand, SetVariableCommand, }, @@ -89,6 +90,7 @@ pub fn parse_command(input: &str) -> Result, BotError> { "unlink" => convert_to!(UnlinkCommand, cmd_input), "check" => convert_to!(CheckCommand, cmd_input), "unregister" => convert_to!(UnregisterCommand, cmd_input), + "rooms" => convert_to!(ListRoomsCommand, cmd_input), _ => Err(CommandParsingError::UnrecognizedCommand(cmd).into()), }, //All other errors passed up. diff --git a/src/commands/rooms.rs b/src/commands/rooms.rs new file mode 100644 index 0000000..ccbb09a --- /dev/null +++ b/src/commands/rooms.rs @@ -0,0 +1,54 @@ +use super::{Command, Execution, ExecutionResult}; +use crate::context::Context; +use crate::error::BotError; +use async_trait::async_trait; +use futures::stream::{self, StreamExt, TryStreamExt}; +use matrix_sdk::identifiers::UserId; +use std::convert::TryFrom; + +pub struct ListRoomsCommand; + +impl From for Box { + fn from(cmd: ListRoomsCommand) -> Self { + Box::new(cmd) + } +} + +impl TryFrom<&str> for ListRoomsCommand { + type Error = BotError; + + fn try_from(input: &str) -> Result { + Ok(ListRoomsCommand) + } +} + +#[async_trait] +impl Command for ListRoomsCommand { + fn name(&self) -> &'static str { + "list rooms command" + } + + fn is_secure(&self) -> bool { + true + } + + async fn execute(&self, ctx: &Context<'_>) -> ExecutionResult { + let user_id = UserId::try_from(ctx.username)?; + let rooms_for_user = crate::matrix::get_rooms_for_user(ctx.matrix_client, &user_id).await?; + + let rooms_for_user: Vec = stream::iter(rooms_for_user) + .filter_map(|room| async move { + Some( + room.display_name() + .await + .map(|room_name| (room.room_id().to_string(), room_name)), + ) + }) + .map_ok(|(room_id, room_name)| format!("[{}] {}", room_id, room_name)) + .try_collect() + .await?; + + let html = format!("{}", rooms_for_user.join("\n")); + Execution::success(html) + } +}