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(())
}
}