use crate::prelude::*; use futures::future::BoxFuture; /// A generic state handler. It checks for "/cancel" messages and runs the provided validation function #[inline] pub async fn generic( bot: Throttle, msg: Message, db: DatabaseConnection, dialogue: MainDialogue, check: F, no_text_message: impl Into, next: PackagedHandler, ) -> crate::Result<()> where for<'a> F: FnOnce( &'a Throttle, &'a Message, &'a DatabaseConnection, &'a str, ) -> BoxFuture<'a, crate::Result>>, { let mut handler = next.lock().await; delete_optional(&bot, handler.previous.as_ref()).await; let text = match msg.text() { Some(text) => text.trim(), None => { let msg = bot.send_message(msg.chat.id, no_text_message).await?; handler.previous = Some(msg); return Ok(()); } }; if text == "/cancel" { dialogue.exit().await?; bot.send_message(msg.chat.id, "Successfully cancelled") .reply_markup(deletion_markup()) .await?; return Ok(()); } if handler.func.is_none() { let _ = dialogue.exit().await; return Err(HandlerUsed.into()); } if let Some(failure_message) = check(&bot, &msg, &db, text).await? { handler.previous = Some(failure_message); return Ok(()); } let func = handler.func.take().unwrap(); drop(handler); let text = text.to_owned(); if let Err(err) = func(bot, msg, db, dialogue.clone(), text).await { let _ = dialogue.exit().await; return Err(err); } Ok(()) }