diff --git a/Cargo.lock b/Cargo.lock index bb1b9dc..a7e6eb2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1303,9 +1303,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.142" +version = "0.2.143" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317" +checksum = "edc207893e85c5d6be840e969b496b53d94cec8be2d501b214f50daa97fa8024" [[package]] name = "libm" @@ -1582,6 +1582,7 @@ dependencies = [ "serde_json", "sha2", "teloxide", + "thiserror", "tokio", ] @@ -2705,9 +2706,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.20" +version = "0.3.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0cbfecb4d19b5ea75bb31ad904eb5b9fa13f21079c3b92017ebdf4999a5890" +checksum = "8f3403384eaacbca9923fa06940178ac13e4edb725486d70e8e15881d0c836cc" dependencies = [ "itoa", "serde", @@ -2717,15 +2718,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" +checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.8" +version = "0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd80a657e71da814b8e5d60d3374fc6d35045062245d80224748ae522dd76f36" +checksum = "372950940a5f07bf38dbe211d7283c9e6d7327df53794992d293e534c733d09b" dependencies = [ "time-core", ] diff --git a/Cargo.toml b/Cargo.toml index 037ffe0..93755dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,4 +28,5 @@ serde = "1.0.160" serde_json = "1.0.96" sha2 = "0.10.6" teloxide = { version = "0.12.2", features = ["macros", "ctrlc_handler", "rustls", "throttle"], default-features = false } +thiserror = "1.0.40" tokio = { version = "1.27.0", features = ["macros", "rt-multi-thread"] } diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..3b34c3f --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,11 @@ +#[derive(thiserror::Error, Debug)] +#[error("No user info found")] +pub struct NoUserInfo; + +#[derive(thiserror::Error, Debug)] +#[error("Message text not found")] +pub struct NoMessageText; + +#[derive(thiserror::Error, Debug)] +#[error("Handler was already used")] +pub struct HandlerUsed; diff --git a/src/handlers/commands/add_account.rs b/src/handlers/commands/add_account.rs index a15d052..253deb2 100644 --- a/src/handlers/commands/add_account.rs +++ b/src/handlers/commands/add_account.rs @@ -1,4 +1,5 @@ use crate::entity::{account, prelude::Account}; +use crate::errors::NoUserInfo; use crate::handlers::{utils::package_handler, MainDialogue, State}; use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; @@ -16,7 +17,7 @@ async fn get_master_pass( master_pass: String, ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; dialogue.exit().await?; let account = spawn_blocking(move || { account::ActiveModel::from_unencrypted(user_id, name, &login, &password, &master_pass) @@ -91,7 +92,7 @@ async fn get_account_name( name: String, ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; if Account::exists(user_id, &name, &db).await? { bot.send_message(msg.chat.id, "Account alreay exists") .await?; diff --git a/src/handlers/commands/delete.rs b/src/handlers/commands/delete.rs index 4dff7a3..0ebc39d 100644 --- a/src/handlers/commands/delete.rs +++ b/src/handlers/commands/delete.rs @@ -1,5 +1,6 @@ use crate::{ entity::prelude::Account, + errors::NoUserInfo, handlers::{markups, utils::package_handler, MainDialogue, State}, }; use sea_orm::prelude::*; @@ -15,7 +16,7 @@ async fn get_master_pass( ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; dialogue.exit().await?; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; Account::delete_by_id((user_id, name)).exec(&db).await?; bot.send_message(msg.chat.id, "The account is successfully deleted") .await?; @@ -31,7 +32,7 @@ async fn get_account_name( name: String, ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; if !Account::exists(user_id, &name, &db).await? { bot.send_message(msg.chat.id, "Account doesn't exists") .await?; @@ -56,7 +57,8 @@ pub async fn delete( dialogue: MainDialogue, db: DatabaseConnection, ) -> crate::Result<()> { - let markup = markups::account_markup(msg.from().unwrap().id.0, &db).await?; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; + let markup = markups::account_markup(user_id, &db).await?; let previous = bot .send_message(msg.chat.id, "Send account name") .reply_markup(markup) diff --git a/src/handlers/commands/delete_all.rs b/src/handlers/commands/delete_all.rs index aa6e3b7..cc81e56 100644 --- a/src/handlers/commands/delete_all.rs +++ b/src/handlers/commands/delete_all.rs @@ -1,5 +1,6 @@ use crate::{ entity::{account, prelude::*}, + errors::NoUserInfo, handlers::{utils::package_handler, MainDialogue, State}, }; use sea_orm::prelude::*; @@ -14,7 +15,7 @@ async fn get_master_pass( ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; dialogue.exit().await?; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; Account::delete_many() .filter(account::Column::UserId.eq(user_id)) .exec(&db) diff --git a/src/handlers/commands/export.rs b/src/handlers/commands/export.rs index 4da9b0e..86c3bc4 100644 --- a/src/handlers/commands/export.rs +++ b/src/handlers/commands/export.rs @@ -1,5 +1,6 @@ use crate::{ entity::prelude::Account, + errors::NoUserInfo, handlers::{utils::package_handler, MainDialogue, State}, models::{DecryptedAccount, User}, }; @@ -20,7 +21,7 @@ async fn get_master_pass( ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; let master_pass: Arc = master_pass.into(); - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let accounts = Arc::new(Mutex::new(Vec::new())); Account::get_all(user_id, &db) .await? diff --git a/src/handlers/commands/get_account.rs b/src/handlers/commands/get_account.rs index 5568833..db553f6 100644 --- a/src/handlers/commands/get_account.rs +++ b/src/handlers/commands/get_account.rs @@ -1,5 +1,6 @@ use crate::{ entity::{account, prelude::Account}, + errors::NoUserInfo, handlers::{markups, utils::package_handler, MainDialogue, State}, }; use sea_orm::prelude::*; @@ -17,7 +18,7 @@ async fn get_master_pass( ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; dialogue.exit().await?; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let account = Account::find() .filter(account::Column::UserId.eq(user_id)) .filter(account::Column::Name.eq(&name)) @@ -41,7 +42,7 @@ async fn get_account_name( name: String, ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; if !Account::exists(user_id, &name, &db).await? { bot.send_message(msg.chat.id, "Account doesn't exists") .await?; @@ -66,7 +67,8 @@ pub async fn get_account( dialogue: MainDialogue, db: DatabaseConnection, ) -> crate::Result<()> { - let markup = markups::account_markup(msg.from().unwrap().id.0, &db).await?; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; + let markup = markups::account_markup(user_id, &db).await?; let previous = bot .send_message(msg.chat.id, "Send account name") .reply_markup(markup) diff --git a/src/handlers/commands/get_accounts.rs b/src/handlers/commands/get_accounts.rs index 17204b5..d8f286d 100644 --- a/src/handlers/commands/get_accounts.rs +++ b/src/handlers/commands/get_accounts.rs @@ -1,4 +1,4 @@ -use crate::entity::prelude::Account; +use crate::{entity::prelude::Account, errors::NoUserInfo}; use futures::TryStreamExt; use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode}; @@ -8,7 +8,7 @@ pub async fn get_accounts( msg: Message, db: DatabaseConnection, ) -> crate::Result<()> { - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let mut account_names = Account::get_names(user_id, &db, true).await?; let mut result = match account_names.try_next().await? { Some(name) => format!("Accounts:\n`{name}`"), diff --git a/src/handlers/commands/import.rs b/src/handlers/commands/import.rs index 40756df..2b42b72 100644 --- a/src/handlers/commands/import.rs +++ b/src/handlers/commands/import.rs @@ -1,4 +1,5 @@ use crate::{ + errors::NoUserInfo, handlers::{utils::package_handler, MainDialogue, State}, models::{DecryptedAccount, User}, }; @@ -20,7 +21,7 @@ async fn get_master_pass( accounts: Vec, ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let master_pass: Arc = master_pass.into(); let failed = Arc::new(Mutex::new(Vec::new())); stream::iter(accounts) diff --git a/src/handlers/commands/set_master_pass.rs b/src/handlers/commands/set_master_pass.rs index 308b0c6..016536d 100644 --- a/src/handlers/commands/set_master_pass.rs +++ b/src/handlers/commands/set_master_pass.rs @@ -1,5 +1,6 @@ use crate::{ entity::{master_pass, prelude::*}, + errors::NoUserInfo, handlers::{utils::package_handler, MainDialogue, State}, }; use sea_orm::prelude::*; @@ -16,7 +17,7 @@ async fn get_master_pass( ) -> crate::Result<()> { let _ = bot.delete_message(previous.chat.id, previous.id).await; dialogue.exit().await?; - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let model = task::spawn_blocking(move || { master_pass::ActiveModel::from_unencrypted(user_id, &master_password) }) @@ -32,7 +33,7 @@ pub async fn set_master_pass( dialogue: MainDialogue, db: DatabaseConnection, ) -> crate::Result<()> { - let user_id = msg.from().unwrap().id.0; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; if MasterPass::exists(user_id, &db).await? { bot.send_message(msg.chat.id, "Master password already exists") .await?; diff --git a/src/handlers/state/generic.rs b/src/handlers/state/generic.rs index 85b4145..23f196b 100644 --- a/src/handlers/state/generic.rs +++ b/src/handlers/state/generic.rs @@ -1,7 +1,7 @@ use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; -use crate::PinnedFuture; +use crate::{errors::HandlerUsed, PinnedFuture}; pub async fn generic( bot: Throttle, @@ -37,5 +37,5 @@ where return Err(err); } }; - next.lock().await.take().unwrap()(bot, msg, db, dialogue, text).await + next.lock().await.take().ok_or(HandlerUsed)?(bot, msg, db, dialogue, text).await } diff --git a/src/handlers/state/get_account_name.rs b/src/handlers/state/get_account_name.rs index 379d6e2..64d7ec6 100644 --- a/src/handlers/state/get_account_name.rs +++ b/src/handlers/state/get_account_name.rs @@ -1,7 +1,10 @@ use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; -use crate::handlers::{MainDialogue, PackagedHandler}; +use crate::{ + errors::NoMessageText, + handlers::{MainDialogue, PackagedHandler}, +}; pub async fn get_account_name( bot: Throttle, @@ -10,7 +13,7 @@ pub async fn get_account_name( dialogue: MainDialogue, next: PackagedHandler, ) -> crate::Result<()> { - let text = msg.text().unwrap().trim().to_owned(); + let text = msg.text().ok_or(NoMessageText)?.trim().to_owned(); super::generic::generic( bot, text, diff --git a/src/handlers/state/get_document.rs b/src/handlers/state/get_document.rs index 07c8665..622513b 100644 --- a/src/handlers/state/get_document.rs +++ b/src/handlers/state/get_document.rs @@ -1,4 +1,7 @@ -use crate::handlers::{MainDialogue, PackagedHandler}; +use crate::{ + errors::HandlerUsed, + handlers::{MainDialogue, PackagedHandler}, +}; use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; @@ -9,5 +12,5 @@ pub async fn get_document( dialogue: MainDialogue, next: PackagedHandler<()>, ) -> crate::Result<()> { - next.lock().await.take().unwrap()(bot, msg, db, dialogue, ()).await + next.lock().await.take().ok_or(HandlerUsed)?(bot, msg, db, dialogue, ()).await } diff --git a/src/handlers/state/get_login.rs b/src/handlers/state/get_login.rs index 4090247..2af1b86 100644 --- a/src/handlers/state/get_login.rs +++ b/src/handlers/state/get_login.rs @@ -1,7 +1,10 @@ use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; -use crate::handlers::{MainDialogue, PackagedHandler}; +use crate::{ + errors::NoMessageText, + handlers::{MainDialogue, PackagedHandler}, +}; pub async fn get_login( bot: Throttle, @@ -10,7 +13,7 @@ pub async fn get_login( dialogue: MainDialogue, next: PackagedHandler, ) -> crate::Result<()> { - let text = msg.text().unwrap().trim().to_owned(); + let text = msg.text().ok_or(NoMessageText)?.trim().to_owned(); super::generic::generic( bot, text, diff --git a/src/handlers/state/get_master_pass.rs b/src/handlers/state/get_master_pass.rs index 02362c3..c4c93d8 100644 --- a/src/handlers/state/get_master_pass.rs +++ b/src/handlers/state/get_master_pass.rs @@ -1,5 +1,6 @@ use crate::{ entity::prelude::MasterPass, + errors::{NoMessageText, NoUserInfo}, handlers::{MainDialogue, PackagedHandler}, }; use sea_orm::prelude::*; @@ -12,8 +13,8 @@ pub async fn check_master_pass<'a>( db: &'a DatabaseConnection, master_pass: &'a str, ) -> crate::Result { - let result = - MasterPass::verify_master_pass(msg.from().unwrap().id.0, master_pass.to_owned(), db).await; + let user_id = msg.from().ok_or(NoUserInfo)?.id.0; + let result = MasterPass::verify_master_pass(user_id, master_pass.to_owned(), db).await; match result { Ok(Some(true)) => Ok(true), Ok(Some(false)) => { @@ -37,7 +38,7 @@ pub async fn get_master_pass( dialogue: MainDialogue, next: PackagedHandler, ) -> crate::Result<()> { - let text = msg.text().unwrap().trim().to_owned(); + let text = msg.text().ok_or(NoMessageText)?.trim().to_owned(); super::generic::generic( bot, text, diff --git a/src/handlers/state/get_password.rs b/src/handlers/state/get_password.rs index c6f234e..1d1155e 100644 --- a/src/handlers/state/get_password.rs +++ b/src/handlers/state/get_password.rs @@ -1,7 +1,10 @@ use sea_orm::prelude::*; use teloxide::{adaptors::Throttle, prelude::*}; -use crate::handlers::{MainDialogue, PackagedHandler}; +use crate::{ + errors::NoMessageText, + handlers::{MainDialogue, PackagedHandler}, +}; pub async fn get_password( bot: Throttle, @@ -10,7 +13,7 @@ pub async fn get_password( dialogue: MainDialogue, next: PackagedHandler, ) -> crate::Result<()> { - let text = msg.text().unwrap().trim().to_owned(); + let text = msg.text().ok_or(NoMessageText)?.trim().to_owned(); super::generic::generic( bot, text, diff --git a/src/main.rs b/src/main.rs index f88b544..f438549 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ mod entity; +mod errors; mod handlers; mod models; @@ -16,8 +17,8 @@ async fn main() -> Result<()> { let _ = dotenv(); pretty_env_logger::init(); - let token = env::var("TOKEN").unwrap(); - let database_url = env::var("DATABASE_URL").unwrap(); + let token = env::var("TOKEN").expect("expected TOKEN in the enviroment"); + let database_url = env::var("DATABASE_URL").expect("expected DATABASE_URL in the enviroment"); let db = Database::connect(database_url).await?; Migrator::up(&db, None).await?; get_dispatcher(token, db).dispatch().await;