use super::types::{CommandTypes, TelegramCommand};
use crate::{
client::Context,
model::{Message, MessageContent, MessageEntity, Update, UpdateContent},
};
use log::{debug, warn};
pub struct Framework {
commands: Vec<TelegramCommand>,
bot_name: String,
}
impl Framework {
pub fn new(bot_name: &str) -> Self {
Self {
commands: Vec::new(),
bot_name: bot_name.to_owned(),
}
}
fn match_command(&self, message: &Message, name: &str) -> bool {
if let MessageContent::Text { entities, content } = &message.content {
for entity in entities {
if let MessageEntity::BotCommand(ref t) = entity {
let t = t.get_text(content);
return t == format!("/{}", name)
|| t == format!("/{}@{}", name, &self.bot_name);
}
}
}
false
}
#[allow(clippy::needless_pass_by_value)]
fn fire_message_commands(&self, context: Context, message: Message) {
for command in &self.commands {
match command.command.clone() {
CommandTypes::Default(c) if self.match_command(&message, command.options.name) => {
let ctx = context.clone();
let msg = message.clone();
let command_name = command.options.name;
debug!("calling command {}", &command_name);
tokio::spawn(async move {
let res = c(ctx, msg).await;
if res.is_err() {
warn!(
"command {} returned error: {}",
&command_name,
res.unwrap_err().0
);
}
});
},
CommandTypes::Default(_) => (),
}
}
}
pub fn add_command(&mut self, command: &TelegramCommand) {
self.commands.push(command.clone());
}
pub fn get_commands(&self) -> &Vec<TelegramCommand> {
&self.commands
}
pub fn fire_commands(&self, context: Context, update: Update) {
if let UpdateContent::Message(c) = update.content {
self.fire_message_commands(context, c);
}
}
}