pass_manager/src/locales.rs

167 lines
5.1 KiB
Rust
Raw Normal View History

2024-04-16 13:02:48 +00:00
use crate::prelude::*;
use anyhow::Result;
use entity::locale::LocaleType;
use log::error;
use std::future::Future;
use std::sync::OnceLock;
static LOCALES: OnceLock<LocaleStore> = OnceLock::new();
pub struct LocaleStore {
eng: Locale,
ru: Locale,
}
impl LocaleStore {
pub fn init() -> Result<()> {
let ru = serde_yaml::from_slice(include_bytes!("../locales/ru.yaml"))?;
let eng = serde_yaml::from_slice(include_bytes!("../locales/eng.yaml"))?;
assert!(
LOCALES.set(Self { eng, ru }).is_ok(),
"Locales are already intialized"
);
Ok(())
}
}
#[derive(serde::Deserialize)]
pub struct Locale {
pub master_password_is_not_set: Box<str>,
pub hide_button: Box<str>,
pub change_name_button: Box<str>,
pub change_login_button: Box<str>,
pub change_password_button: Box<str>,
pub delete_account_button: Box<str>,
pub couldnt_get_user_info_send_again: Box<str>,
pub unknown_command_use_help: Box<str>,
pub help_command: Box<str>,
pub no_file_send: Box<str>,
pub file_too_large: Box<str>,
pub couldnt_get_file_name: Box<str>,
pub following_accounts_have_problems: Box<str>,
pub duplicate_names: Box<str>,
pub accounts_already_in_db: Box<str>,
pub invalid_fields: Box<str>,
pub fix_that_and_send_again: Box<str>,
pub error_downloading_file: Box<str>,
pub error_getting_account_names: Box<str>,
pub error_parsing_json_file: Box<str>,
pub successfully_canceled: Box<str>,
pub invalid_password: Box<str>,
pub couldnt_get_message_text: Box<str>,
pub invalid_file_name: Box<str>,
pub account_already_exists: Box<str>,
pub master_password_too_weak: Box<str>,
pub no_lowercase: Box<str>,
pub no_uppercase: Box<str>,
pub no_numbers: Box<str>,
pub master_pass_too_short: Box<str>,
pub change_master_password_and_send_again: Box<str>,
pub wrong_master_password: Box<str>,
pub invalid_login: Box<str>,
pub start_command: Box<str>,
pub master_password_dont_match: Box<str>,
pub success: Box<str>,
pub send_master_password_again: Box<str>,
pub master_password_is_set: Box<str>,
pub send_new_master_password: Box<str>,
pub no_accounts_found: Box<str>,
pub choose_account: Box<str>,
pub couldnt_create_following_accounts: Box<str>,
pub send_master_password: Box<str>,
pub something_went_wrong: Box<str>,
pub nothing_to_cancel: Box<str>,
pub send_account_name: Box<str>,
pub send_login: Box<str>,
pub error_deleting_message: Box<str>,
pub account_not_found: Box<str>,
pub send_new_name: Box<str>,
pub send_new_login: Box<str>,
pub send_new_password: Box<str>,
pub success_choose_account_to_view: Box<str>,
pub send_json_file: Box<str>,
pub send_master_pass_to_delete_everything: Box<str>,
pub everything_was_deleted: Box<str>,
pub send_password: Box<str>,
pub send_master_pass_to_delete_account: Box<str>,
pub no_special_characters: Box<str>,
pub invalid_name: Box<str>,
pub decrypt_button: Box<str>,
pub delete_message_button: Box<str>,
pub menu_button: Box<str>,
pub choose_language: Box<str>,
word_name: Box<str>,
word_login: Box<str>,
word_password: Box<str>,
}
impl Locale {
pub async fn from_update(update: Update, db: Pool) -> &'static Self {
let locale_type = LocaleType::locale_for_update(&update, &db).await;
locale_type.get_locale()
}
pub fn show_account(&self, name: &str, login: &str, password: &str) -> String {
format!(
"{}:\n`{name}`\n{}:\n`{login}`\n{}:\n`{password}`",
self.word_name, self.word_login, self.word_password
)
}
pub fn show_hidden_account(&self, name: &str) -> String {
format!(
"{}:\n`{name}`\n{}:\n\\*\\*\\*\n{}:\n\\*\\*\\*",
self.word_name, self.word_login, self.word_password
)
}
}
pub type LocaleRef = &'static Locale;
pub trait LocaleTypeExt: Sized {
fn locale_for_update(update: &Update, db: &Pool) -> impl Future<Output = Self> + Send;
fn from_language_code(code: &str) -> Option<Self>;
fn get_locale(self) -> &'static Locale;
}
impl LocaleTypeExt for LocaleType {
async fn locale_for_update(update: &Update, db: &Pool) -> Self {
let Some(from) = update.user() else {
return Self::default();
};
match Self::get_from_db(from.id.0, db).await {
Ok(Some(locale)) => return locale,
Ok(None) => (),
Err(err) => error!("{err}"),
}
from.language_code
.as_deref()
.and_then(Self::from_language_code)
.unwrap_or_default()
}
fn from_language_code(code: &str) -> Option<Self> {
match code {
"ru" => Some(Self::Ru),
"en" => Some(Self::Eng),
_ => None,
}
}
fn get_locale(self) -> &'static Locale {
let Some(store) = LOCALES.get() else {
panic!("Locales are not initialized")
};
match self {
Self::Eng => &store.eng,
Self::Ru => &store.ru,
}
}
}