Enabled clippy warnings and fixed them

This commit is contained in:
StNicolay 2023-11-16 21:51:46 +03:00
parent f0116b3207
commit 6ae745fcd4
Signed by: StNicolay
GPG Key ID: 9693D04DCD962B0D
21 changed files with 129 additions and 163 deletions

8
Cargo.lock generated
View File

@ -1909,9 +1909,9 @@ dependencies = [
[[package]] [[package]]
name = "rustls" name = "rustls"
version = "0.21.8" version = "0.21.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c" checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
dependencies = [ dependencies = [
"log", "log",
"ring", "ring",
@ -3336,6 +3336,6 @@ dependencies = [
[[package]] [[package]]
name = "zeroize" name = "zeroize"
version = "1.6.1" version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12a3946ecfc929b583800f4629b6c25b88ac6e92a40ea5670f77112a85d40a8b" checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"

View File

@ -12,7 +12,7 @@ bitflags::bitflags! {
const SPECIAL_CHARACTER = 0b1000; const SPECIAL_CHARACTER = 0b1000;
} }
#[derive(PartialEq, Eq)] #[derive(PartialEq, Eq, Clone, Copy)]
pub struct PasswordValidity: u8 { pub struct PasswordValidity: u8 {
const NO_LOWERCASE = 0b00001; const NO_LOWERCASE = 0b00001;
const NO_UPPERCASE = 0b00010; const NO_UPPERCASE = 0b00010;

View File

@ -9,7 +9,7 @@ use teloxide::types::CallbackQuery;
type NameHash = Vec<u8>; type NameHash = Vec<u8>;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AlterableField { pub enum AlterableField {
Name, Name,
Login, Login,
@ -38,37 +38,36 @@ impl FromStr for CallbackCommand {
type Err = crate::errors::InvalidCommand; type Err = crate::errors::InvalidCommand;
fn from_str(s: &str) -> Result<Self, Self::Err> { fn from_str(s: &str) -> Result<Self, Self::Err> {
use AlterableField::*;
use CallbackCommand::*;
match s { match s {
"delete_message" => return Ok(DeleteMessage), "delete_message" => return Ok(Self::DeleteMessage),
"get_menu" => return Ok(GetMenu), "get_menu" => return Ok(Self::GetMenu),
_ => (), _ => (),
}; };
let mut substrings = s.split(' '); let mut substrings = s.split(' ');
let (command, name) = match (substrings.next(), substrings.next(), substrings.next()) { let (Some(command), Some(name), None) =
(Some(command), Some(name), None) => (command, name), (substrings.next(), substrings.next(), substrings.next())
_ => return Err(InvalidCommand::InvalidParams), else {
return Err(InvalidCommand::InvalidParams);
}; };
let name_hash = B64_ENGINE.decode(name)?; let name_hash = B64_ENGINE.decode(name)?;
if name_hash.len() != 32 { if name_hash.len() != 32 {
return Err(InvalidCommand::InvalidOutputLength); return Err(InvalidCommand::InvalidOutputLength);
} }
match command { match command {
"get" => Ok(Get(name_hash)), "get" => Ok(Self::Get(name_hash)),
"decrypt" => Ok(Decrypt(name_hash)), "decrypt" => Ok(Self::Decrypt(name_hash)),
"hide" => Ok(Hide(name_hash)), "hide" => Ok(Self::Hide(name_hash)),
"an" => Ok(Alter(name_hash, Name)), "an" => Ok(Self::Alter(name_hash, AlterableField::Name)),
"al" => Ok(Alter(name_hash, Login)), "al" => Ok(Self::Alter(name_hash, AlterableField::Login)),
"ap" => Ok(Alter(name_hash, Pass)), "ap" => Ok(Self::Alter(name_hash, AlterableField::Pass)),
"delete0" => Ok(DeleteAccount { "delete0" => Ok(Self::DeleteAccount {
name: name_hash, name: name_hash,
is_command: false, is_command: false,
}), }),
"delete1" => Ok(DeleteAccount { "delete1" => Ok(Self::DeleteAccount {
name: name_hash, name: name_hash,
is_command: true, is_command: true,
}), }),

View File

@ -1,4 +1,4 @@
use super::AlterableField::{self, *}; use super::AlterableField::{self, Login, Name, Pass};
use crate::{change_state, prelude::*}; use crate::{change_state, prelude::*};
use account::ActiveModel; use account::ActiveModel;
use futures::TryFutureExt; use futures::TryFutureExt;
@ -14,7 +14,7 @@ async fn update_account(
field_value: String, field_value: String,
master_pass: String, master_pass: String,
) -> crate::Result<()> { ) -> crate::Result<()> {
if let Name = field { if field == Name {
Account::update_name(user_id, name, field_value, db).await?; Account::update_name(user_id, name, field_value, db).await?;
return Ok(()); return Ok(());
@ -37,7 +37,7 @@ async fn update_account(
match field { match field {
Login => model.enc_login = Set(field_value), Login => model.enc_login = Set(field_value),
Pass => model.enc_password = Set(field_value), Pass => model.enc_password = Set(field_value),
_ => unreachable!(), Name => unreachable!(),
} }
model.update(db).await?; model.update(db).await?;
@ -87,18 +87,15 @@ pub async fn alter(
let user_id = q.from.id.0; let user_id = q.from.id.0;
let mut ids: MessageIds = q.message.as_ref().unwrap().into(); let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let name = match name_from_hash(&db, user_id, &hash).await? { let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
Some(name) => name, try_join!(
None => { bot.send_message(ids.0, "Account wasn't found")
try_join!( .reply_markup(deletion_markup())
bot.send_message(ids.0, "Account wasn't found") .send(),
.reply_markup(deletion_markup()) bot.answer_callback_query(q.id).send()
.send(), )?;
bot.answer_callback_query(q.id).send()
)?;
return Ok(()); return Ok(());
}
}; };
let text = match field { let text = match field {

View File

@ -16,14 +16,11 @@ async fn get_master_pass(
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let account = match Account::get(user_id, &name, &db).await? { let Some(account) = Account::get(user_id, &name, &db).await? else {
Some(account) => account, bot.send_message(msg.chat.id, "Account not found")
None => { .reply_markup(deletion_markup())
bot.send_message(msg.chat.id, "Account not found") .await?;
.reply_markup(deletion_markup()) return Ok(());
.await?;
return Ok(());
}
}; };
let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??; let (login, password) = spawn_blocking(move || account.decrypt(&master_pass)).await??;
@ -50,18 +47,15 @@ pub async fn decrypt(
let mut ids: MessageIds = q.message.as_ref().unwrap().into(); let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let user_id = q.from.id.0; let user_id = q.from.id.0;
let name = match name_from_hash(&db, user_id, &hash).await? { let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
Some(name) => name, try_join!(
None => { bot.send_message(ids.0, "Account wasn't found")
try_join!( .reply_markup(deletion_markup())
bot.send_message(ids.0, "Account wasn't found") .send(),
.reply_markup(deletion_markup()) bot.answer_callback_query(q.id).send()
.send(), )?;
bot.answer_callback_query(q.id).send()
)?;
return Ok(()); return Ok(());
}
}; };
ids.alter_message(&bot, "Send master password", None, None) ids.alter_message(&bot, "Send master password", None, None)

View File

@ -40,18 +40,15 @@ pub async fn delete(
let mut ids: MessageIds = q.message.as_ref().unwrap().into(); let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let user_id = q.from.id.0; let user_id = q.from.id.0;
let name = match name_from_hash(&db, user_id, &hash).await? { let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
Some(name) => name, try_join!(
None => { bot.send_message(ids.0, "Account wasn't found")
try_join!( .reply_markup(deletion_markup())
bot.send_message(ids.0, "Account wasn't found") .send(),
.reply_markup(deletion_markup()) bot.answer_callback_query(q.id).send()
.send(), )?;
bot.answer_callback_query(q.id).send()
)?;
return Ok(()); return Ok(());
}
}; };
let response = async { let response = async {
@ -59,10 +56,10 @@ pub async fn delete(
Once you send the master password the account is unrecoverable"; Once you send the master password the account is unrecoverable";
if is_command { if is_command {
ids.alter_message(&bot, TEXT, None, None).await? ids.alter_message(&bot, TEXT, None, None).await?;
} else { } else {
let msg = bot.send_message(ids.0, TEXT).await?; let msg = bot.send_message(ids.0, TEXT).await?;
ids = MessageIds::from(&msg) ids = MessageIds::from(&msg);
}; };
Ok::<_, crate::Error>(()) Ok::<_, crate::Error>(())

View File

@ -12,17 +12,14 @@ pub async fn get(
let user_id = q.from.id.0; let user_id = q.from.id.0;
let mut ids: MessageIds = q.message.as_ref().unwrap().into(); let mut ids: MessageIds = q.message.as_ref().unwrap().into();
let name = match name_from_hash(&db, user_id, &hash).await? { let Some(name) = name_from_hash(&db, user_id, &hash).await? else {
Some(name) => name, try_join!(
None => { bot.send_message(ids.0, "Account wasn't found")
try_join!( .reply_markup(deletion_markup())
bot.send_message(ids.0, "Account wasn't found") .send(),
.reply_markup(deletion_markup()) bot.answer_callback_query(q.id).send()
.send(), )?;
bot.answer_callback_query(q.id).send() return Ok(());
)?;
return Ok(());
}
}; };
let text = format!("Name:\n`{name}`\nLogin:\n\\*\\*\\*\nPassword:\n\\*\\*\\*"); let text = format!("Name:\n`{name}`\nLogin:\n\\*\\*\\*\nPassword:\n\\*\\*\\*");

View File

@ -13,7 +13,7 @@ type PasswordArray = [ArrayString<PASSWORD_LENGTH>; AMOUNT_OF_PASSWORDS];
const BUFFER_LENGTH: usize = const BUFFER_LENGTH: usize =
MESSAGE_HEADER.len() + (PASSWORD_LENGTH + PASSWORD_PADDING_LENGTH) * AMOUNT_OF_PASSWORDS; MESSAGE_HEADER.len() + (PASSWORD_LENGTH + PASSWORD_PADDING_LENGTH) * AMOUNT_OF_PASSWORDS;
/// Handles /gen_password command by generating 10 copyable passwords and sending them to the user /// Handles /`gen_password` command by generating 10 copyable passwords and sending them to the user
#[inline] #[inline]
pub async fn gen_password(bot: Throttle<Bot>, msg: Message) -> crate::Result<()> { pub async fn gen_password(bot: Throttle<Bot>, msg: Message) -> crate::Result<()> {
let mut message: ArrayString<BUFFER_LENGTH> = MESSAGE_HEADER.try_into().unwrap(); let mut message: ArrayString<BUFFER_LENGTH> = MESSAGE_HEADER.try_into().unwrap();

View File

@ -3,7 +3,7 @@ use futures::future;
use std::fmt::Write; use std::fmt::Write;
use teloxide::types::ParseMode; use teloxide::types::ParseMode;
/// Handles /get_accounts command by sending the list of copyable account names to the user /// Handles /`get_accounts` command by sending the list of copyable account names to the user
#[inline] #[inline]
pub async fn get_accounts( pub async fn get_accounts(
bot: Throttle<Bot>, bot: Throttle<Bot>,

View File

@ -66,7 +66,7 @@ async fn get_master_pass(
Ok(()) Ok(())
} }
/// Handles /set_master_pass command /// Handles /`set_master_pass` command
#[inline] #[inline]
pub async fn set_master_pass( pub async fn set_master_pass(
bot: Throttle<Bot>, bot: Throttle<Bot>,

View File

@ -2,37 +2,38 @@ use crate::prelude::*;
use teloxide::{dispatching::DpHandlerDescription, dptree::Handler}; use teloxide::{dispatching::DpHandlerDescription, dptree::Handler};
#[inline] #[inline]
#[allow(clippy::needless_pass_by_value)]
fn has_no_user_info(msg: Message) -> bool { fn has_no_user_info(msg: Message) -> bool {
msg.from().is_none() msg.from().is_none()
} }
#[inline] #[inline]
#[allow(clippy::significant_drop_tightening)]
async fn notify_about_no_user_info( async fn notify_about_no_user_info(
bot: Throttle<Bot>, bot: Throttle<Bot>,
msg: Message, msg: Message,
state: State, state: State,
) -> crate::Result<()> { ) -> crate::Result<()> {
use State::*;
const TEXT: &str = "Invalid message. Couldn't get the user information. Send the message again"; const TEXT: &str = "Invalid message. Couldn't get the user information. Send the message again";
match state { match state {
Start => { State::Start => {
bot.send_message(msg.chat.id, TEXT) bot.send_message(msg.chat.id, TEXT)
.reply_markup(deletion_markup()) .reply_markup(deletion_markup())
.await?; .await?;
} }
GetNewName(handler) State::GetNewName(handler)
| GetMasterPass(handler) | State::GetMasterPass(handler)
| GetNewMasterPass(handler) | State::GetNewMasterPass(handler)
| GetLogin(handler) | State::GetLogin(handler)
| GetPassword(handler) => { | State::GetPassword(handler) => {
let mut handler = handler.lock().await; let mut handler = handler.lock().await;
handler handler
.previous .previous
.alter_message(&bot, TEXT, None, None) .alter_message(&bot, TEXT, None, None)
.await?; .await?;
} }
GetUser(handler) => { State::GetUser(handler) => {
let mut handler = handler.lock().await; let mut handler = handler.lock().await;
handler handler
.previous .previous

View File

@ -1,3 +1,6 @@
#![warn(clippy::pedantic, clippy::all, clippy::nursery)]
#![allow(clippy::single_match_else)]
mod callbacks; mod callbacks;
mod commands; mod commands;
mod default; mod default;
@ -36,7 +39,7 @@ fn get_dispatcher(
.branch(case![Command::GenPassword].endpoint(commands::gen_password)) .branch(case![Command::GenPassword].endpoint(commands::gen_password))
.branch(case![Command::Cancel].endpoint(commands::cancel)) .branch(case![Command::Cancel].endpoint(commands::cancel))
// This branch filters out the users that don't have a master password set // This branch filters out the users that don't have a master password set
.branch(master_password_check::get_handler::<Message>()) .branch(master_password_check::get_handler())
.branch(case![Command::Menu].endpoint(commands::menu)) .branch(case![Command::Menu].endpoint(commands::menu))
.branch(case![Command::AddAccount].endpoint(commands::add_account)) .branch(case![Command::AddAccount].endpoint(commands::add_account))
.branch(case![Command::GetAccount].endpoint(commands::get_account)) .branch(case![Command::GetAccount].endpoint(commands::get_account))
@ -62,7 +65,7 @@ fn get_dispatcher(
let callback_handler = Update::filter_callback_query() let callback_handler = Update::filter_callback_query()
.filter_map(CallbackCommand::from_query) .filter_map(CallbackCommand::from_query)
.branch(case![CallbackCommand::DeleteMessage].endpoint(callbacks::delete_message)) .branch(case![CallbackCommand::DeleteMessage].endpoint(callbacks::delete_message))
.branch(master_password_check::get_handler::<CallbackQuery>()) .branch(master_password_check::get_handler())
.branch(case![CallbackCommand::GetMenu].endpoint(callbacks::get_menu)) .branch(case![CallbackCommand::GetMenu].endpoint(callbacks::get_menu))
.branch(case![CallbackCommand::Get(hash)].endpoint(callbacks::get)) .branch(case![CallbackCommand::Get(hash)].endpoint(callbacks::get))
.branch(case![CallbackCommand::Decrypt(hash)].endpoint(callbacks::decrypt)) .branch(case![CallbackCommand::Decrypt(hash)].endpoint(callbacks::decrypt))

View File

@ -27,7 +27,7 @@ pub fn menu_markup_sync(
#[inline] #[inline]
pub async fn menu_markup( pub async fn menu_markup(
command: impl Into<String>, command: impl Into<String> + Send,
user_id: u64, user_id: u64,
db: &DatabaseConnection, db: &DatabaseConnection,
) -> crate::Result<InlineKeyboardMarkup> { ) -> crate::Result<InlineKeyboardMarkup> {

View File

@ -3,39 +3,19 @@ use std::sync::Arc;
use teloxide::{ use teloxide::{
dispatching::{dialogue::GetChatId, DpHandlerDescription}, dispatching::{dialogue::GetChatId, DpHandlerDescription},
dptree::Handler, dptree::Handler,
types::User,
}; };
pub trait GetUserInfo: GetChatId + Clone + Send + Sync + 'static { type DynError = Arc<dyn std::error::Error + Send + Sync>;
fn user(&self) -> Option<&User>;
}
impl GetUserInfo for Message { /// Filters out the messages from users without master passwords
fn user(&self) -> Option<&User> {
self.from()
}
}
impl GetUserInfo for CallbackQuery {
fn user(&self) -> Option<&User> {
Some(&self.from)
}
}
/// A wierd filter that checks for the existance of a master password.
/// ///
/// # Returns /// # Returns
/// ///
/// Returns None if account exists, Some(None) if there's an account and Some(Some(String)) if an error occures. /// Returns None if account exists, Some(None) if there's an account and Some(Some(String)) if an error occures.
/// The String represents the error that occured /// The String represents the error that occured
#[inline] #[inline]
async fn master_pass_exists<T: GetUserInfo>( async fn master_pass_exists(update: Update, db: DatabaseConnection) -> Option<Option<DynError>> {
msg: T, let user_id = match update.user() {
db: DatabaseConnection,
) -> Option<Option<Arc<dyn std::error::Error + Send + Sync>>> {
msg.chat_id()?;
let user_id = match msg.user() {
Some(user) => user.id.0, Some(user) => user.id.0,
None => return Some(Some(Arc::new(NoUserInfo))), None => return Some(Some(Arc::new(NoUserInfo))),
}; };
@ -47,16 +27,16 @@ async fn master_pass_exists<T: GetUserInfo>(
} }
#[inline] #[inline]
async fn notify_about_no_master_pass<T: GetChatId>( async fn notify_about_no_master_pass(
bot: Throttle<Bot>, bot: Throttle<Bot>,
result: Option<Arc<dyn std::error::Error + Send + Sync>>, result: Option<DynError>,
msg: T, update: Update,
) -> crate::Result<()> { ) -> crate::Result<()> {
if let Some(error) = result { if let Some(error) = result {
return Err(error.into()); return Err(error.into());
} }
bot.send_message( bot.send_message(
msg.chat_id().unwrap(), update.chat_id().unwrap(),
"No master password set. Use /set_master_pass to set it", "No master password set. Use /set_master_pass to set it",
) )
.reply_markup(deletion_markup()) .reply_markup(deletion_markup())
@ -66,7 +46,6 @@ async fn notify_about_no_master_pass<T: GetChatId>(
/// Gets a handler that filters out the messages of users that don't have a master password set /// Gets a handler that filters out the messages of users that don't have a master password set
#[inline] #[inline]
pub fn get_handler<T: GetUserInfo>( pub fn get_handler() -> Handler<'static, DependencyMap, crate::Result<()>, DpHandlerDescription> {
) -> Handler<'static, DependencyMap, crate::Result<()>, DpHandlerDescription> { dptree::filter_map_async(master_pass_exists).endpoint(notify_about_no_master_pass)
dptree::filter_map_async(master_pass_exists::<T>).endpoint(notify_about_no_master_pass::<T>)
} }

View File

@ -11,7 +11,7 @@ pub struct DecryptedAccount {
} }
impl DecryptedAccount { impl DecryptedAccount {
/// Constructs DecryptedAccount by decrypting the provided account /// Constructs `DecryptedAccount` by decrypting the provided account
#[inline] #[inline]
pub fn from_account(account: account::Model, master_pass: &str) -> crate::Result<Self> { pub fn from_account(account: account::Model, master_pass: &str) -> crate::Result<Self> {
let (login, password) = account.decrypt(master_pass)?; let (login, password) = account.decrypt(master_pass)?;
@ -22,7 +22,7 @@ impl DecryptedAccount {
}) })
} }
/// Constructs ActiveModel with eath field Set by encrypting `self` /// Constructs `ActiveModel` with eath field Set by encrypting `self`
#[inline] #[inline]
pub fn into_account( pub fn into_account(
self, self,

View File

@ -1,15 +1,14 @@
pub(crate) use crate::{ pub use crate::{
commands::Command, commands::Command,
errors::*, errors::*,
first_handler, handler, first_handler, handler,
markups::*, markups::*,
models::*, models::*,
state::State, state::{Handler, MainDialogue, MessageIds, PackagedHandler, State},
state::{Handler, MainDialogue, MessageIds, PackagedHandler},
utils::*, utils::*,
}; };
pub(crate) use cryptography::prelude::*; pub use cryptography::prelude::*;
pub(crate) use entity::prelude::*; pub use entity::prelude::*;
pub(crate) use futures::{StreamExt, TryStreamExt}; pub use futures::{StreamExt, TryStreamExt};
pub(crate) use sea_orm::prelude::*; pub use sea_orm::prelude::*;
pub(crate) use teloxide::{adaptors::Throttle, prelude::*}; pub use teloxide::{adaptors::Throttle, prelude::*};

View File

@ -3,7 +3,7 @@
mod generic; mod generic;
mod handler; mod handler;
pub use handler::{Handler, MessageIds, PackagedHandler}; pub use handler::{Handler, MessageIds, Packaged as PackagedHandler};
crate::export_handlers!( crate::export_handlers!(
get_login, get_login,

View File

@ -9,17 +9,18 @@ pub async fn generic<F>(
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
check: F, check: F,
no_text_message: impl Into<String>, no_text_message: impl Into<String> + Send,
next: PackagedHandler<String>, handler: PackagedHandler<String>,
) -> crate::Result<()> ) -> crate::Result<()>
where where
for<'a> F: FnOnce( for<'a> F: FnOnce(
&'a Message, &'a Message,
&'a DatabaseConnection, &'a DatabaseConnection,
&'a str, &'a str,
) -> BoxFuture<'a, crate::Result<Option<String>>>, ) -> BoxFuture<'a, crate::Result<Option<String>>>
+ Send,
{ {
let mut handler = next.lock().await; let mut handler = handler.lock().await;
if handler.func.is_none() { if handler.func.is_none() {
let _ = dialogue.exit().await; let _ = dialogue.exit().await;
return Err(HandlerUsed.into()); return Err(HandlerUsed.into());

View File

@ -10,19 +10,19 @@ fn process_validity(validity: PasswordValidity) -> Result<(), String> {
let mut error_text = "Your master password is invalid:\n".to_owned(); let mut error_text = "Your master password is invalid:\n".to_owned();
if validity.contains(PasswordValidity::NO_LOWERCASE) { if validity.contains(PasswordValidity::NO_LOWERCASE) {
error_text.push_str("\n* It doesn't have any lowercase characters") error_text.push_str("\n* It doesn't have any lowercase characters");
} }
if validity.contains(PasswordValidity::NO_UPPERCASE) { if validity.contains(PasswordValidity::NO_UPPERCASE) {
error_text.push_str("\n* It doesn't have any uppercase characters") error_text.push_str("\n* It doesn't have any uppercase characters");
} }
if validity.contains(PasswordValidity::NO_NUMBER) { if validity.contains(PasswordValidity::NO_NUMBER) {
error_text.push_str("\n* It doesn't have any numbers") error_text.push_str("\n* It doesn't have any numbers");
} }
if validity.contains(PasswordValidity::NO_SPECIAL_CHARACTER) { if validity.contains(PasswordValidity::NO_SPECIAL_CHARACTER) {
error_text.push_str("\n* It doesn't have any special characters") error_text.push_str("\n* It doesn't have any special characters");
} }
if validity.contains(PasswordValidity::TOO_SHORT) { if validity.contains(PasswordValidity::TOO_SHORT) {
error_text.push_str("\n* It is shorter than 8 characters") error_text.push_str("\n* It is shorter than 8 characters");
} }
error_text.push_str("\n\nModify your password and send it again"); error_text.push_str("\n\nModify your password and send it again");

View File

@ -10,9 +10,8 @@ use trim_in_place::TrimInPlace;
#[inline] #[inline]
fn validate_document(document: Option<&Document>) -> Result<&Document, &'static str> { fn validate_document(document: Option<&Document>) -> Result<&Document, &'static str> {
let document = match document { let Some(document) = document else {
Some(document) => document, return Err("You didn't send a file. Try again");
None => return Err("You didn't send a file. Try again"),
}; };
if document.file.size > 1024 * 1024 * 200 { if document.file.size > 1024 * 1024 * 200 {
@ -70,7 +69,7 @@ fn process_accounts(
duplicates.push(account.name.as_str()); duplicates.push(account.name.as_str());
} }
if exists { if exists {
existing.push(account.name.as_str()) existing.push(account.name.as_str());
} }
// If it already exists or if it is a duplicate there's no need to check the account's validity // If it already exists or if it is a duplicate there's no need to check the account's validity
if !duplicate && !exists && !account.validate() { if !duplicate && !exists && !account.validate() {
@ -91,7 +90,7 @@ fn process_accounts(
error_text, error_text,
"\n\nDuplicate names:\n{:?}", "\n\nDuplicate names:\n{:?}",
duplicates.into_iter().format("\n") duplicates.into_iter().format("\n")
)? )?;
} }
if !existing.is_empty() { if !existing.is_empty() {
@ -99,7 +98,7 @@ fn process_accounts(
error_text, error_text,
"\n\nAccounts with these names already exist in the database:\n{:?}", "\n\nAccounts with these names already exist in the database:\n{:?}",
existing.into_iter().format("\n") existing.into_iter().format("\n")
)? )?;
} }
if !invalid.is_empty() { if !invalid.is_empty() {
@ -107,7 +106,7 @@ fn process_accounts(
error_text, error_text,
"\n\nInvalid account fields:\n{:?}", "\n\nInvalid account fields:\n{:?}",
invalid.into_iter().format("\n") invalid.into_iter().format("\n")
)? )?;
} }
error_text.push_str("\n\nFix these problems and send the file again"); error_text.push_str("\n\nFix these problems and send the file again");
@ -128,23 +127,23 @@ fn user_from_vec(
} }
} }
/// Function to handle GetUser state. It doesn't actually validate anything /// Function to handle `GetUser` state. It doesn't actually validate anything
pub async fn get_user( pub async fn get_user(
bot: Throttle<Bot>, bot: Throttle<Bot>,
msg: Message, msg: Message,
db: DatabaseConnection, db: DatabaseConnection,
dialogue: MainDialogue, dialogue: MainDialogue,
next: PackagedHandler<User>, handler: PackagedHandler<User>,
) -> crate::Result<()> { ) -> crate::Result<()> {
let user_id = msg.from().ok_or(NoUserInfo)?.id.0; let user_id = msg.from().ok_or(NoUserInfo)?.id.0;
let mut handler = next.lock().await; let mut handler = handler.lock().await;
if handler.func.is_none() { if handler.func.is_none() {
let _ = dialogue.exit().await; let _ = dialogue.exit().await;
return Err(HandlerUsed.into()); return Err(HandlerUsed.into());
} }
if let Some("/cancel") = msg.text().map(str::trim) { if msg.text().map(str::trim) == Some("/cancel") {
dialogue.exit().await?; dialogue.exit().await?;
handler handler
.previous .previous

View File

@ -26,9 +26,9 @@ impl MessageIds {
pub async fn alter_message( pub async fn alter_message(
&mut self, &mut self,
bot: &Throttle<Bot>, bot: &Throttle<Bot>,
text: impl Into<String>, text: impl Into<String> + Send,
markup: impl Into<Option<InlineKeyboardMarkup>>, markup: impl Into<Option<InlineKeyboardMarkup>> + Send,
parse_mode: impl Into<Option<ParseMode>>, parse_mode: impl Into<Option<ParseMode>> + Send,
) -> crate::Result<()> { ) -> crate::Result<()> {
let mut edit = bot.edit_message_text(self.0, self.1, text); let mut edit = bot.edit_message_text(self.0, self.1, text);
edit.parse_mode = parse_mode.into(); edit.parse_mode = parse_mode.into();
@ -76,10 +76,10 @@ pub struct Handler<T: ?Sized> {
pub previous: MessageIds, pub previous: MessageIds,
} }
pub type PackagedHandler<T> = Arc<Mutex<Handler<T>>>; pub type Packaged<T> = Arc<Mutex<Handler<T>>>;
impl<T> Handler<T> { impl<T> Handler<T> {
/// Convinience method to convert a simple async function and a previous message into PackagedHandler /// Convinience method to convert a simple async function and a previous message into `PackagedHandler`
#[inline] #[inline]
pub fn new<H>(f: H, previous: impl Into<MessageIds>) -> PackagedHandler<T> pub fn new<H>(f: H, previous: impl Into<MessageIds>) -> PackagedHandler<T>
where where