Added NoUserInfo, NoMessageText and HandlerUsed error types to decrease the amount of unwraps

This commit is contained in:
StNicolay 2023-05-06 20:20:33 +03:00
parent c1e1b9c0c1
commit 71940762ff
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
18 changed files with 74 additions and 38 deletions

17
Cargo.lock generated
View File

@ -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",
]

View File

@ -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"] }

11
src/errors.rs Normal file
View File

@ -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;

View File

@ -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?;

View File

@ -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)

View File

@ -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)

View File

@ -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<str> = 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?

View File

@ -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)

View File

@ -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}`"),

View File

@ -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<DecryptedAccount>,
) -> 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<str> = master_pass.into();
let failed = Arc::new(Mutex::new(Vec::new()));
stream::iter(accounts)

View File

@ -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?;

View File

@ -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<F>(
bot: Throttle<Bot>,
@ -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
}

View File

@ -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<Bot>,
@ -10,7 +13,7 @@ pub async fn get_account_name(
dialogue: MainDialogue,
next: PackagedHandler<String>,
) -> 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,

View File

@ -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
}

View File

@ -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<Bot>,
@ -10,7 +13,7 @@ pub async fn get_login(
dialogue: MainDialogue,
next: PackagedHandler<String>,
) -> 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,

View File

@ -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<bool> {
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<String>,
) -> 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,

View File

@ -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<Bot>,
@ -10,7 +13,7 @@ pub async fn get_password(
dialogue: MainDialogue,
next: PackagedHandler<String>,
) -> 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,

View File

@ -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;