gavel 0.1.0

A matrix moderation bot
Documentation
use std::fmt::Write;

use clap::Subcommand;
use color_eyre::Result;
use matrix_sdk::{
    room::Joined,
    ruma::{
        events::room::message::{OriginalRoomMessageEvent, RoomMessageEventContent},
        OwnedRoomOrAliasId,
    },
};

use crate::{
    bot::Gavel,
    utils::{resolve_room, room_link},
};

/// Configure the rooms under protection by the bot
#[allow(clippy::module_name_repetitions)]
#[derive(Subcommand, Debug)]
pub enum ConfigureProtectedRooms {
    /// Add a protected room.
    ///
    /// The bot will join the room and synchronize it with the configured policy
    /// lists.
    Add {
        /// The room ID or alias of the room to protect.
        room: OwnedRoomOrAliasId,
    },
    /// Remove a protected room.
    Remove {
        /// The room ID or alias of the room to unprotect.
        room: OwnedRoomOrAliasId,
    },
    /// Show the rooms currently under protection.
    List,
}

impl ConfigureProtectedRooms {
    pub async fn run(
        self,
        bot: &Gavel,
        _ev: &OriginalRoomMessageEvent,
        room: &Joined,
    ) -> Result<()> {
        match self {
            ConfigureProtectedRooms::Add { room } => {
                bot.client().join_room_by_id_or_alias(&room, &[]).await?;
                bot.protected_rooms.add(&room).await?;
            }
            ConfigureProtectedRooms::Remove { room } => {
                let room_id = resolve_room(bot.client(), &room).await?;

                bot.protected_rooms.remove((&*room_id).into()).await?;

                if let Some(room) = bot.client().get_joined_room(&room_id) {
                    room.leave().await?;
                }
            }
            ConfigureProtectedRooms::List => {
                let message = bot.protected_rooms.with_rooms(|rooms| {
                    if rooms.is_empty() {
                        "No protected rooms".to_string()
                    } else {
                        let mut message = String::new();

                        writeln!(message, "**{} protected rooms:**", rooms.len()).unwrap();
                        writeln!(message).unwrap();

                        for room in rooms {
                            writeln!(
                                message,
                                "* {}",
                                room_link(bot.client(), (**room).into(), true),
                            )
                            .unwrap();
                        }

                        message
                    }
                });

                room.send(RoomMessageEventContent::notice_markdown(message), None)
                    .await?;
            }
        }

        Ok(())
    }
}