mod peek;
mod roulette;
use super::Roulette;
use frankenstein::{
client_reqwest::Bot,
types::{BotCommand, Message},
};
use peek::PeekCommand;
use roulette::RouletteCommand;
use tokio::sync::Mutex;
pub trait Command {
const TRIGGER: &'static str;
const HELP: &'static str;
async fn execute(bot: &Bot, msg: Message, roulette: &Mutex<Roulette>) -> Option<String>;
}
#[non_exhaustive]
pub enum Commands {
Peek,
Roulette,
}
impl Commands {
pub fn parse(text: Option<&String>, username: &str) -> Option<Commands> {
let Some(text) = text else {
return None;
};
let text = text.trim();
let (command, _arg) = text.split_once(' ').unwrap_or((text, ""));
let slash = command.starts_with('/');
if !slash {
return None;
}
let command = &command[1..];
let (command, mention) = command.split_once('@').unwrap_or((command, ""));
if !mention.is_empty() && mention != username {
return None;
}
match command {
PeekCommand::TRIGGER => Some(Commands::Peek),
RouletteCommand::TRIGGER => Some(Commands::Roulette),
_ => None,
}
}
pub async fn execute(
&self,
bot: &Bot,
msg: Message,
roulette: &Mutex<Roulette>,
) -> Option<String> {
match self {
Self::Peek => PeekCommand::execute(bot, msg, roulette).await,
Self::Roulette => RouletteCommand::execute(bot, msg, roulette).await,
}
}
pub fn list() -> Vec<BotCommand> {
vec![
BotCommand {
command: PeekCommand::TRIGGER.to_string(),
description: PeekCommand::HELP.to_string(),
},
BotCommand {
command: RouletteCommand::TRIGGER.to_string(),
description: RouletteCommand::HELP.to_string(),
},
]
}
}