use crate::prelude::*; use futures::{future::BoxFuture, TryFutureExt}; use std::{mem, sync::Arc}; use teloxide::{ requests::HasPayload, types::{InlineKeyboardMarkup, MessageId, ParseMode}, RequestError, }; use tokio::{sync::Mutex, try_join}; #[derive(Clone, Copy)] pub struct MessageIds(pub ChatId, pub MessageId); impl MessageIds { // Tries to delete the message while ignoring API errors #[inline] pub async fn delete(self, bot: &Throttle) -> crate::Result<()> { match bot.delete_message(self.0, self.1).await { Ok(_) | Err(RequestError::Api(_)) => Ok(()), Err(err) => Err(err.into()), } } /// Tries to alter the message or sends a new one #[inline] pub async fn alter_message( &mut self, bot: &Throttle, text: impl Into + Send, markup: impl Into> + Send, parse_mode: impl Into> + Send, ) -> 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 send = { let mut send_request = bot.send_message(self.0, mem::take(&mut edit.text)); let payload = send_request.payload_mut(); payload.parse_mode = edit.parse_mode; payload.reply_markup = edit.reply_markup.take().map(Into::into); send_request.send().map_err(Into::into) }; let msg = try_join!(self.delete(bot), 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, Pool, MainDialogue, MessageIds, T, ) -> BoxFuture<'static, crate::Result<()>> + Send, >; pub struct Handler { pub func: Option>, pub previous: MessageIds, } pub type Packaged = 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, Pool, 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)) } }