From 3b2633c880a53288587157a0dc290fcd16e8a8b1 Mon Sep 17 00:00:00 2001 From: StNicolay Date: Sun, 4 Jun 2023 18:46:59 +0300 Subject: [PATCH] Split up get_account_name into 2 states: get_new_name and get_existing_name --- Cargo.lock | 12 ++-- src/commands/add_account.rs | 9 +-- src/commands/delete.rs | 9 ++- src/commands/get_account.rs | 9 ++- src/lib.rs | 3 +- src/state/generic.rs | 3 +- src/state/get_account_name.rs | 110 --------------------------------- src/state/get_existing_name.rs | 84 +++++++++++++++++++++++++ src/state/get_new_name.rs | 49 +++++++++++++++ src/state/get_password.rs | 2 +- src/state/mod.rs | 9 ++- 11 files changed, 161 insertions(+), 138 deletions(-) delete mode 100644 src/state/get_account_name.rs create mode 100644 src/state/get_existing_name.rs create mode 100644 src/state/get_new_name.rs diff --git a/Cargo.lock b/Cargo.lock index f0b8844..55a167d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -42,9 +42,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67fc08ce920c31afb70f013dcce1bfc3a3195de6a228474e45e1f145b36f8d04" +checksum = "43f6cb1bf222025340178f382c426f13757b2960e89779dfcb319c32542a5a41" dependencies = [ "memchr", ] @@ -1093,9 +1093,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.144" +version = "0.2.145" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b00cc1c228a6782d0f076e7b232802e0c5689d41bb5df366f2a6b6621cfdfe1" +checksum = "fc86cde3ff845662b8f4ef6cb50ea0e20c524eb3d29ae048287e06a1b3fa6a81" [[package]] name = "libm" @@ -1268,9 +1268,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.2" +version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9670a07f94779e00908f3e686eab508878ebb390ba6e604d3a284c00e8d0487b" +checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" [[package]] name = "opaque-debug" diff --git a/src/commands/add_account.rs b/src/commands/add_account.rs index 20abc25..dc10d3b 100644 --- a/src/commands/add_account.rs +++ b/src/commands/add_account.rs @@ -1,6 +1,6 @@ use crate::{ - errors::NoUserInfo, markups::deletion_markup, models::DecryptedAccount, state::NameCheckKind, - Handler, MainDialogue, State, + errors::NoUserInfo, markups::deletion_markup, models::DecryptedAccount, Handler, MainDialogue, + State, }; use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; @@ -101,10 +101,7 @@ pub async fn add_account( ) -> crate::Result<()> { let previous = bot.send_message(msg.chat.id, "Send account name").await?; dialogue - .update(State::GetAccountName( - Handler::new(get_account_name, previous), - NameCheckKind::NewAccountName, - )) + .update(State::GetNewName(Handler::new(get_account_name, previous))) .await?; Ok(()) } diff --git a/src/commands/delete.rs b/src/commands/delete.rs index 8912158..0267b36 100644 --- a/src/commands/delete.rs +++ b/src/commands/delete.rs @@ -1,7 +1,6 @@ use crate::{ errors::NoUserInfo, markups::{self, deletion_markup}, - state::NameCheckKind, Handler, MainDialogue, State, }; use entity::prelude::*; @@ -60,10 +59,10 @@ pub async fn delete( .reply_markup(markup) .await?; dialogue - .update(State::GetAccountName( - Handler::new(get_account_name, previous), - NameCheckKind::MustExist, - )) + .update(State::GetExistingName(Handler::new( + get_account_name, + previous, + ))) .await?; Ok(()) } diff --git a/src/commands/get_account.rs b/src/commands/get_account.rs index 2431cf4..01c8218 100644 --- a/src/commands/get_account.rs +++ b/src/commands/get_account.rs @@ -1,7 +1,6 @@ use crate::{ errors::NoUserInfo, markups::{self, deletion_markup}, - state::NameCheckKind, Handler, MainDialogue, State, }; use cryptography::prelude::*; @@ -75,10 +74,10 @@ pub async fn get_account( .reply_markup(markup) .await?; dialogue - .update(State::GetAccountName( - Handler::new(get_account_name, previous), - NameCheckKind::MustExist, - )) + .update(State::GetExistingName(Handler::new( + get_account_name, + previous, + ))) .await?; Ok(()) } diff --git a/src/lib.rs b/src/lib.rs index 70adbca..3e9bd0a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -47,7 +47,8 @@ pub fn get_dispatcher( let message_handler = Update::filter_message() .map_async(utils::delete_message) .enter_dialogue::, State>() - .branch(case![State::GetAccountName(next, check)].endpoint(state::get_account_name)) + .branch(case![State::GetExistingName(next)].endpoint(state::get_existing_name)) + .branch(case![State::GetNewName(next)].endpoint(state::get_new_name)) .branch(case![State::GetMasterPass(next)].endpoint(state::get_master_pass)) .branch(case![State::GetLogin(next)].endpoint(state::get_login)) .branch(case![State::GetPassword(next)].endpoint(state::get_password)) diff --git a/src/state/generic.rs b/src/state/generic.rs index ebd062c..7489ef1 100644 --- a/src/state/generic.rs +++ b/src/state/generic.rs @@ -27,7 +27,8 @@ where let text = match msg.text() { Some(text) => text.trim_end(), None => { - bot.send_message(msg.chat.id, no_text_message).await?; + let msg = bot.send_message(msg.chat.id, no_text_message).await?; + handler.previous = Some(msg); return Ok(()); } }; diff --git a/src/state/get_account_name.rs b/src/state/get_account_name.rs deleted file mode 100644 index 23e7d1c..0000000 --- a/src/state/get_account_name.rs +++ /dev/null @@ -1,110 +0,0 @@ -use crate::{ - errors::{HandlerUsed, NoUserInfo}, - markups::{account_markup, deletion_markup}, - utils::{delete_optional, validate_field}, - MainDialogue, -}; -use entity::prelude::*; -use sea_orm::DatabaseConnection; -use teloxide::{adaptors::Throttle, prelude::*}; - -/// Specifies the kind of checks to be run during the account name validation -#[derive(Clone, Copy)] -pub enum NameCheckKind { - NewAccountName, - MustExist, -} - -/// Validates the account name -#[inline] -async fn check_name( - bot: &Throttle, - msg: &Message, - db: &DatabaseConnection, - name: &str, - check_kind: NameCheckKind, - user_id: u64, -) -> crate::Result> { - match check_kind { - NameCheckKind::MustExist => { - if !Account::exists(user_id, name, db).await? { - let msg = bot - .send_message(msg.chat.id, "Account doesn't exists. Try again") - .reply_markup(account_markup(user_id, db).await?) - .await?; - return Ok(Some(msg)); - } - } - NameCheckKind::NewAccountName => { - if Account::exists(user_id, name, db).await? { - let msg = bot - .send_message(msg.chat.id, "Account already exists") - .await?; - return Ok(Some(msg)); - } - if !validate_field(name) { - let msg = bot - .send_message(msg.chat.id, "Invalid account name. Try again") - .await?; - return Ok(Some(msg)); - } - } - } - Ok(None) -} - -/// Function to handle GetAccountName state -pub async fn get_account_name( - bot: Throttle, - msg: Message, - db: DatabaseConnection, - dialogue: MainDialogue, - (next, check_kind): (super::PackagedHandler, NameCheckKind), -) -> crate::Result<()> { - let user_id = msg.from().ok_or(NoUserInfo)?.id.0; - let mut handler = next.lock().await; - delete_optional(&bot, handler.previous.as_ref()).await; - - let text = match msg.text() { - Some(text) => text.trim_end(), - None => { - let mut send = bot.send_message( - msg.chat.id, - "Couldn't get the text of the message. Send the name again", - ); - if let NameCheckKind::MustExist = check_kind { - send = send.reply_markup(account_markup(user_id, &db).await?) - } - send.await?; - 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_name(&bot, &msg, &db, text, check_kind, user_id).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(()) -} diff --git a/src/state/get_existing_name.rs b/src/state/get_existing_name.rs new file mode 100644 index 0000000..34f0371 --- /dev/null +++ b/src/state/get_existing_name.rs @@ -0,0 +1,84 @@ +use crate::{ + errors::{HandlerUsed, NoUserInfo}, + markups::{account_markup, deletion_markup}, + utils::delete_optional, + MainDialogue, +}; +use entity::prelude::*; +use sea_orm::DatabaseConnection; +use teloxide::{adaptors::Throttle, prelude::*}; + +/// Checks that the account with that name exists +#[inline] +async fn check_name( + bot: &Throttle, + msg: &Message, + db: &DatabaseConnection, + name: &str, + user_id: u64, +) -> crate::Result> { + if !Account::exists(user_id, name, db).await? { + let msg = bot + .send_message(msg.chat.id, "Account doesn't exists. Try again") + .reply_markup(account_markup(user_id, db).await?) + .await?; + return Ok(Some(msg)); + } + Ok(None) +} + +/// Function to handle GetExistingName state +pub async fn get_existing_name( + bot: Throttle, + msg: Message, + db: DatabaseConnection, + dialogue: MainDialogue, + next: super::PackagedHandler, +) -> crate::Result<()> { + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; + let mut handler = next.lock().await; + delete_optional(&bot, handler.previous.as_ref()).await; + + let text = match msg.text() { + Some(text) => text.trim_end(), + None => { + let msg = bot + .send_message( + msg.chat.id, + "Couldn't get the text of the message. Send the name again", + ) + .reply_markup(account_markup(user_id, &db).await?) + .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_name(&bot, &msg, &db, text, user_id).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(()) +} diff --git a/src/state/get_new_name.rs b/src/state/get_new_name.rs new file mode 100644 index 0000000..5dacf62 --- /dev/null +++ b/src/state/get_new_name.rs @@ -0,0 +1,49 @@ +use crate::{errors::NoUserInfo, utils::validate_field, MainDialogue}; +use entity::prelude::*; +use sea_orm::prelude::*; +use teloxide::{adaptors::Throttle, prelude::*}; + +/// Validates a new account +#[inline] +async fn check_new_account_name( + bot: &Throttle, + msg: &Message, + db: &DatabaseConnection, + name: &str, +) -> crate::Result> { + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; + if Account::exists(user_id, name, db).await? { + let msg = bot + .send_message(msg.chat.id, "Account already exists") + .await?; + return Ok(Some(msg)); + } + if !validate_field(name) { + let msg = bot + .send_message(msg.chat.id, "Invalid account name. Try again") + .await?; + return Ok(Some(msg)); + } + + Ok(None) +} + +/// Handles GetNewName state +pub async fn get_new_name( + bot: Throttle, + msg: Message, + db: DatabaseConnection, + dialogue: MainDialogue, + next: super::PackagedHandler, +) -> crate::Result<()> { + super::generic::generic( + bot, + msg, + db, + dialogue, + |bot, msg, db, name| Box::pin(check_new_account_name(bot, msg, db, name)), + "Couldn't get the text of the message. Send the name of the new account again", + next, + ) + .await +} diff --git a/src/state/get_password.rs b/src/state/get_password.rs index 4ce8db7..87770d4 100644 --- a/src/state/get_password.rs +++ b/src/state/get_password.rs @@ -28,7 +28,7 @@ pub async fn get_password( Ok(None) }) }, - "Couldn't get the text of the message. Send the master password again", + "Couldn't get the text of the message. Send the password again", next, ) .await diff --git a/src/state/mod.rs b/src/state/mod.rs index da7c24b..354e2e0 100644 --- a/src/state/mod.rs +++ b/src/state/mod.rs @@ -1,16 +1,18 @@ //! This module consists of endpoints to handle the state mod generic; -mod get_account_name; +mod get_existing_name; mod get_login; mod get_master_pass; +mod get_new_name; mod get_password; mod get_user; mod handler; -pub use get_account_name::{get_account_name, NameCheckKind}; +pub use get_existing_name::get_existing_name; pub use get_login::get_login; pub use get_master_pass::get_master_pass; +pub use get_new_name::get_new_name; pub use get_password::get_password; pub use get_user::get_user; pub use handler::{Handler, PackagedHandler}; @@ -22,7 +24,8 @@ use teloxide::{dispatching::dialogue::InMemStorage, prelude::*}; pub enum State { #[default] Start, - GetAccountName(PackagedHandler, NameCheckKind), + GetExistingName(PackagedHandler), + GetNewName(PackagedHandler), GetMasterPass(PackagedHandler), GetLogin(PackagedHandler), GetPassword(PackagedHandler),