Avoid to use an hash map in translations
This commit is contained in:
parent
03ebbb74fa
commit
91ab379718
10 changed files with 334 additions and 237 deletions
|
|
@ -1,15 +1,16 @@
|
|||
use std::{fs::File, sync::LazyLock};
|
||||
|
||||
use ron::de::from_reader;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::Deserialize;
|
||||
use strum::EnumCount;
|
||||
use strum_macros::EnumCount;
|
||||
use tracing::{event, Level};
|
||||
|
||||
use crate::consts;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Hash, Deserialize, Clone)]
|
||||
#[derive(Debug, Clone, EnumCount, Deserialize)]
|
||||
pub enum Sentence {
|
||||
MainTitle,
|
||||
MainTitle = 0,
|
||||
CreateNewRecipe,
|
||||
UnpublishedRecipes,
|
||||
UntitledRecipe,
|
||||
|
|
@ -107,6 +108,8 @@ pub enum Sentence {
|
|||
RecipeIngredientComment,
|
||||
}
|
||||
|
||||
const DEFAULT_LANGUAGE_CODE: &str = "en";
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Tr {
|
||||
lang: &'static Language,
|
||||
|
|
@ -114,61 +117,48 @@ pub struct Tr {
|
|||
|
||||
impl Tr {
|
||||
pub fn new(code: &str) -> Self {
|
||||
for lang in TRANSLATIONS.iter() {
|
||||
if lang.code == code {
|
||||
return Self { lang };
|
||||
}
|
||||
Self {
|
||||
lang: get_language_translation(code),
|
||||
}
|
||||
|
||||
event!(
|
||||
Level::WARN,
|
||||
"Unable to find translation for language {}",
|
||||
code
|
||||
);
|
||||
|
||||
Tr::new("en")
|
||||
}
|
||||
|
||||
pub fn t(&self, sentence: Sentence) -> String {
|
||||
match self.lang.translation.get(&sentence) {
|
||||
Some(str) => str.clone(),
|
||||
None => format!(
|
||||
"Translation missing, lang: {}/{}, element: {:?}",
|
||||
self.lang.name, self.lang.code, sentence
|
||||
),
|
||||
}
|
||||
//&'static str {
|
||||
self.lang.get(sentence).to_string()
|
||||
// match self.lang.translation.get(&sentence) {
|
||||
// Some(str) => str.clone(),
|
||||
// None => format!(
|
||||
// "Translation missing, lang: {}/{}, element: {:?}",
|
||||
// self.lang.name, self.lang.code, sentence
|
||||
// ),
|
||||
// }
|
||||
}
|
||||
|
||||
pub fn tp(&self, sentence: Sentence, params: &[Box<dyn ToString + Send>]) -> String {
|
||||
match self.lang.translation.get(&sentence) {
|
||||
Some(str) => {
|
||||
let mut result = str.clone();
|
||||
for p in params {
|
||||
result = result.replacen("{}", &p.to_string(), 1);
|
||||
}
|
||||
result
|
||||
}
|
||||
None => format!(
|
||||
"Translation missing, lang: {}/{}, element: {:?}",
|
||||
self.lang.name, self.lang.code, sentence
|
||||
),
|
||||
// match self.lang.translation.get(&sentence) {
|
||||
// Some(str) => {
|
||||
// let mut result = str.clone();
|
||||
// for p in params {
|
||||
// result = result.replacen("{}", &p.to_string(), 1);
|
||||
// }
|
||||
// result
|
||||
// }
|
||||
// None => format!(
|
||||
// "Translation missing, lang: {}/{}, element: {:?}",
|
||||
// self.lang.name, self.lang.code, sentence
|
||||
// ),
|
||||
// }
|
||||
let text = self.lang.get(sentence);
|
||||
let mut result = text.to_string();
|
||||
for p in params {
|
||||
result = result.replacen("{}", &p.to_string(), 1);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn current_lang_code(&self) -> &str {
|
||||
&self.lang.code
|
||||
}
|
||||
|
||||
pub fn available_languages() -> Vec<(&'static str, &'static str)> {
|
||||
TRANSLATIONS
|
||||
.iter()
|
||||
.map(|tr| (tr.code.as_ref(), tr.name.as_ref()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn available_codes() -> Vec<&'static str> {
|
||||
TRANSLATIONS.iter().map(|tr| tr.code.as_ref()).collect()
|
||||
}
|
||||
}
|
||||
|
||||
// #[macro_export]
|
||||
|
|
@ -185,22 +175,98 @@ impl Tr {
|
|||
// };
|
||||
// }
|
||||
|
||||
#[derive(Debug, Deserialize, Clone)]
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct StoredLanguage {
|
||||
code: String,
|
||||
name: String,
|
||||
translation: Vec<(Sentence, String)>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Language {
|
||||
code: String,
|
||||
name: String,
|
||||
translation: FxHashMap<Sentence, String>,
|
||||
translation: Vec<String>,
|
||||
}
|
||||
|
||||
impl Language {
|
||||
pub fn from_stored_language(stored_language: StoredLanguage) -> Self {
|
||||
println!("!!!!!!!!!!!! {:?}", &stored_language.code);
|
||||
Self {
|
||||
code: stored_language.code,
|
||||
name: stored_language.name,
|
||||
translation: {
|
||||
let mut translation = vec![String::new(); Sentence::COUNT];
|
||||
for (sentence, text) in stored_language.translation {
|
||||
translation[sentence as usize] = text;
|
||||
}
|
||||
translation
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&'static self, sentence: Sentence) -> &'static str {
|
||||
let text: &str = self
|
||||
.translation
|
||||
.get(sentence.clone() as usize)
|
||||
.unwrap()
|
||||
.as_ref();
|
||||
if text.is_empty() && self.code != DEFAULT_LANGUAGE_CODE {
|
||||
return get_language_translation(DEFAULT_LANGUAGE_CODE).get(sentence);
|
||||
}
|
||||
text
|
||||
}
|
||||
}
|
||||
|
||||
pub fn available_languages() -> Vec<(&'static str, &'static str)> {
|
||||
TRANSLATIONS
|
||||
.iter()
|
||||
.map(|tr| (tr.code.as_ref(), tr.name.as_ref()))
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn available_codes() -> Vec<&'static str> {
|
||||
TRANSLATIONS.iter().map(|tr| tr.code.as_ref()).collect()
|
||||
}
|
||||
|
||||
fn get_language_translation(code: &str) -> &'static Language {
|
||||
for lang in TRANSLATIONS.iter() {
|
||||
if lang.code == code {
|
||||
return lang;
|
||||
}
|
||||
}
|
||||
|
||||
event!(
|
||||
Level::WARN,
|
||||
"Unable to find translation for language {}",
|
||||
code
|
||||
);
|
||||
|
||||
if code != DEFAULT_LANGUAGE_CODE {
|
||||
get_language_translation(DEFAULT_LANGUAGE_CODE)
|
||||
} else {
|
||||
// 'DEFAULT_LANGUAGE_CODE' must exist.
|
||||
panic!("Unable to find language {}", code);
|
||||
}
|
||||
}
|
||||
|
||||
static TRANSLATIONS: LazyLock<Vec<Language>> =
|
||||
LazyLock::new(|| match File::open(consts::TRANSLATION_FILE) {
|
||||
Ok(file) => from_reader(file).unwrap_or_else(|error| {
|
||||
panic!(
|
||||
"Failed to read translation file {}: {}",
|
||||
consts::TRANSLATION_FILE,
|
||||
error
|
||||
)
|
||||
}),
|
||||
Ok(file) => {
|
||||
let stored_languages: Vec<StoredLanguage> = from_reader(file).unwrap_or_else(|error| {
|
||||
{
|
||||
panic!(
|
||||
"Failed to read translation file {}: {}",
|
||||
consts::TRANSLATION_FILE,
|
||||
error
|
||||
)
|
||||
}
|
||||
});
|
||||
stored_languages
|
||||
.into_iter()
|
||||
.map(Language::from_stored_language)
|
||||
.collect()
|
||||
}
|
||||
Err(error) => {
|
||||
panic!(
|
||||
"Failed to open translation file {}: {}",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue