1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
use crate::{domain_from_module, I18nAssets, I18nEmbedError, LanguageLoader};
pub use i18n_embed_impl::gettext_language_loader;
use parking_lot::RwLock;
use unic_langid::LanguageIdentifier;
#[derive(Debug)]
pub struct GettextLanguageLoader {
current_language: RwLock<LanguageIdentifier>,
module: &'static str,
fallback_language: LanguageIdentifier,
}
impl GettextLanguageLoader {
pub fn new(module: &'static str, fallback_language: unic_langid::LanguageIdentifier) -> Self {
Self {
current_language: RwLock::new(fallback_language.clone()),
module,
fallback_language,
}
}
fn load_src_language(&self) {
let catalog = gettext_system::Catalog::empty();
tr::internal::set_translator(self.module, catalog);
*(self.current_language.write()) = self.fallback_language().clone();
}
}
impl LanguageLoader for GettextLanguageLoader {
fn fallback_language(&self) -> &LanguageIdentifier {
&self.fallback_language
}
fn domain(&self) -> &'static str {
domain_from_module(self.module)
}
fn language_file_name(&self) -> String {
format!("{}.mo", self.domain())
}
fn current_language(&self) -> LanguageIdentifier {
self.current_language.read().clone()
}
fn load_languages(
&self,
i18n_assets: &dyn I18nAssets,
language_ids: &[&unic_langid::LanguageIdentifier],
) -> Result<(), I18nEmbedError> {
let language_id = *language_ids
.get(0)
.ok_or(I18nEmbedError::RequestedLanguagesEmpty)?;
if language_id == self.fallback_language() {
self.load_src_language();
return Ok(());
}
let (_path, file) = match self.language_file(&language_id, i18n_assets) {
(path, Some(f)) => (path, f),
(path, None) => {
log::error!(
target:"i18n_embed::gettext",
"{} Setting current_language to fallback locale: \"{}\".",
I18nEmbedError::LanguageNotAvailable(path, language_id.clone()),
self.fallback_language);
self.load_src_language();
return Ok(());
}
};
let catalog = gettext_system::Catalog::parse(&*file).expect("could not parse the catalog");
tr::internal::set_translator(self.module, catalog);
*(self.current_language.write()) = language_id.clone();
Ok(())
}
}