Improved readability of gen_password.rs by intoducing the bitflags
This commit is contained in:
@ -1,26 +1,38 @@
|
||||
use crate::handlers::markups::deletion_markup;
|
||||
use arrayvec::{ArrayString, ArrayVec};
|
||||
use rand::{rngs::OsRng, seq::SliceRandom};
|
||||
use std::str::from_utf8_unchecked;
|
||||
use std::{fmt::Write, str::from_utf8_unchecked};
|
||||
use teloxide::{adaptors::Throttle, prelude::*, types::ParseMode};
|
||||
use tokio::task::spawn_blocking;
|
||||
|
||||
const CHARS: &[u8] = br##"!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[]^_abcdefghijklmnopqrstuvwxyz{|}~"##;
|
||||
|
||||
bitflags::bitflags! {
|
||||
#[derive(PartialEq)]
|
||||
struct PasswordFlags: u8 {
|
||||
const LOWERCASE = 0b0001;
|
||||
const UPPERCASE = 0b0010;
|
||||
const NUMBER = 0b0100;
|
||||
const SPECIAL_CHARACTER = 0b1000;
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true if the generated master password is valid.
|
||||
/// It checks that it has at least one lowercase, one lowercase and one punctuation char
|
||||
#[inline]
|
||||
fn check_generated_password(password: &[u8]) -> bool {
|
||||
let mut flags: u8 = 0;
|
||||
let mut flags = PasswordFlags::empty();
|
||||
for &byte in password {
|
||||
match byte {
|
||||
b'a'..=b'z' => flags |= 0b1,
|
||||
b'A'..=b'Z' => flags |= 0b10,
|
||||
b'0'..=b'9' => flags |= 0b100,
|
||||
b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~' => flags |= 0b1000,
|
||||
b'a'..=b'z' => flags |= PasswordFlags::LOWERCASE,
|
||||
b'A'..=b'Z' => flags |= PasswordFlags::UPPERCASE,
|
||||
b'0'..=b'9' => flags |= PasswordFlags::NUMBER,
|
||||
b'!'..=b'/' | b':'..=b'@' | b'['..=b'`' | b'{'..=b'~' => {
|
||||
flags |= PasswordFlags::SPECIAL_CHARACTER
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
if flags == 0b1111 {
|
||||
if flags == PasswordFlags::all() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -29,17 +41,15 @@ fn check_generated_password(password: &[u8]) -> bool {
|
||||
|
||||
/// Continuously generates the password until it passes the checks
|
||||
#[inline]
|
||||
fn generate_passwords() -> [ArrayString<34>; 10] {
|
||||
fn generate_passwords() -> [ArrayString<32>; 10] {
|
||||
let mut passwords = ArrayVec::new_const();
|
||||
while !passwords.is_full() {
|
||||
let password: ArrayVec<u8, 32> = (0..32)
|
||||
.map(|_| *CHARS.choose(&mut OsRng).unwrap())
|
||||
.collect();
|
||||
if check_generated_password(&password) {
|
||||
let mut string = ArrayString::<34>::new_const();
|
||||
string.push('`');
|
||||
let mut string = ArrayString::<32>::new_const();
|
||||
unsafe { string.push_str(from_utf8_unchecked(&password)) };
|
||||
string.push('`');
|
||||
passwords.push(string)
|
||||
}
|
||||
}
|
||||
@ -51,8 +61,7 @@ pub async fn gen_password(bot: Throttle<Bot>, msg: Message) -> crate::Result<()>
|
||||
let mut message: ArrayString<{ 10 + 35 * 10 }> = "Passwords:".try_into().unwrap();
|
||||
let passwords = spawn_blocking(generate_passwords).await?;
|
||||
for password in passwords {
|
||||
message.push('\n');
|
||||
message.push_str(&password)
|
||||
write!(message, "\n`{password}`").unwrap();
|
||||
}
|
||||
bot.send_message(msg.chat.id, message.as_str())
|
||||
.parse_mode(ParseMode::MarkdownV2)
|
||||
|
Reference in New Issue
Block a user