use crate::prelude::*; use futures::future::BoxFuture; use std::{mem, sync::Arc}; use teloxide::{ requests::HasPayload, types::{InlineKeyboardMarkup, MessageId, ParseMode}, RequestError, }; use tokio::{join, sync::Mutex}; #[derive(Clone, Copy)] pub struct MessageIds(pub ChatId, pub MessageId); impl MessageIds { #[inline] pub async fn delete(self, bot: &Throttle) { let _ = bot.delete_message(self.0, self.1).await; } /// Tries to alter the message or sends a new one /// /// # Returns /// /// Returns true if the message was edited successfully. Returns false otherwise #[inline] pub async fn alter_message( &mut self, bot: &Throttle, text: impl Into, markup: impl Into>, parse_mode: impl Into>, ) -> crate::Result<()> { let mut edit = bot.edit_message_text(self.0, self.1, text); edit.parse_mode = parse_mode.into(); edit.reply_markup = markup.into(); match edit.send_ref().await { Ok(_) => return Ok(()), Err(RequestError::Api(_)) => (), Err(err) => return Err(err.into()), }; let mut send = bot.send_message(self.0, mem::take(&mut edit.text)); let payload = send.payload_mut(); payload.parse_mode = edit.parse_mode; payload.reply_markup = mem::take(&mut edit.reply_markup).map(Into::into); let msg = join!(self.delete(bot), send.send()).1?; *self = Self::from(&msg); Ok(()) } } impl From<&Message> for MessageIds { #[inline] fn from(value: &Message) -> Self { Self(value.chat.id, value.id) } } type DynHanlder = Box< dyn FnOnce( Throttle, Message, DatabaseConnection, MainDialogue, MessageIds, T, ) -> BoxFuture<'static, crate::Result<()>> + Send, >; pub struct Handler { pub func: Option>, pub previous: MessageIds, } pub type PackagedHandler = Arc>>; impl Handler { /// Convinience method to convert a simple async function and a previous message into PackagedHandler #[inline] pub fn new(f: H, previous: impl Into) -> PackagedHandler where H: FnOnce( Throttle, Message, DatabaseConnection, MainDialogue, MessageIds, T, ) -> BoxFuture<'static, crate::Result<()>> + Send + 'static, { let handler = Self { func: Some(Box::new(f)), previous: previous.into(), }; Arc::new(Mutex::new(handler)) } }