diff --git a/src/lib.rs b/src/lib.rs index 02623799..eeb9c4b8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -71,6 +71,7 @@ pub mod icon_theme; pub mod keyboard_nav; mod localize; +pub use localize::prepend_languages; #[cfg(all(target_env = "gnu", not(target_os = "windows")))] pub(crate) mod malloc; diff --git a/src/localize.rs b/src/localize.rs index 95a31655..0759100e 100644 --- a/src/localize.rs +++ b/src/localize.rs @@ -3,9 +3,10 @@ use i18n_embed::{ DefaultLocalizer, LanguageLoader, Localizer, fluent::{FluentLanguageLoader, fluent_language_loader}, + unic_langid::LanguageIdentifier }; use rust_embed::RustEmbed; -use std::sync::{LazyLock, OnceLock}; +use std::sync::{LazyLock, Mutex, MutexGuard, OnceLock, PoisonError}; #[derive(RustEmbed)] #[folder = "i18n/"] @@ -23,6 +24,15 @@ pub static LANGUAGE_LOADER: LazyLock = LazyLock::new(|| { static LOCALIZATION_INITIALIZED: OnceLock<()> = OnceLock::new(); +static LANGS_TO_PREPEND: LazyLock>> = LazyLock::new(|| Mutex::new(Vec::new())); + +pub type LanguagePrependingError = PoisonError>>; + +pub fn prepend_languages<'a>(langs: impl Into>) -> Result<(), LanguagePrependingError> { + *LANGS_TO_PREPEND.lock()? = langs.into().iter().filter_map(|lang| lang.parse::().ok()).collect(); + Ok(()) +} + #[macro_export] macro_rules! fl { ($message_id:literal) => {{ @@ -43,7 +53,8 @@ pub fn localizer() -> Box { pub fn localize() { LOCALIZATION_INITIALIZED.get_or_init(|| { let localizer = localizer(); - let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages(); + let mut requested_languages = LANGS_TO_PREPEND.lock().map(|mutex_guard| mutex_guard.clone()).unwrap_or_default(); + requested_languages.extend_from_slice(&i18n_embed::DesktopLanguageRequester::requested_languages()); if let Err(error) = localizer.select(&requested_languages) { eprintln!("Error while loading language for libcosmic {}", error); }