use fluent_langneg::NegotiationStrategy;
pub use fluent_embed_derive::localize;
pub use fixed_decimal::{Decimal, FloatPrecision};
pub use icu_locale::{self, langid, LanguageIdentifier};
pub use icu_plurals::{self, PluralRuleType, PluralRules, PluralRulesOptions};
pub use jiff::Timestamp;
pub mod decimal;
pub mod string;
pub mod time;
#[derive(thiserror::Error, Debug)]
pub enum LocalizationError {
#[error("invalid locale selected")]
InvalidLocale,
#[error("unable to write localized output")]
IO(#[from] std::io::Error),
#[error("unable to retrieve system locales")]
RetrievalError(env_preferences::LocaleError),
}
pub trait Localize<W: std::io::Write> {
const CANONICAL_LOCALE: LanguageIdentifier;
fn available_locales(&self) -> Vec<LanguageIdentifier>;
fn message_for_locale(
&self,
writer: &mut W,
locale: &LanguageIdentifier,
) -> Result<(), LocalizationError>;
fn old_locale_version(
new_locales: Vec<icu_locale_core::LanguageIdentifier>,
) -> Vec<icu_locid::LanguageIdentifier> {
new_locales
.into_iter()
.map(|icu_langid| icu_langid.to_string())
.map(|icu_langid| icu_locid::LanguageIdentifier::try_from_bytes(icu_langid.as_bytes()))
.map(Result::unwrap)
.collect::<_>()
}
fn localize(&self, writer: &mut W) -> Result<(), LocalizationError> {
let system_locales = env_preferences::get_locales_lossy()
.map_err(|error| LocalizationError::RetrievalError(error))?;
let system_langids = system_locales
.into_iter()
.map(|icu_locale| icu_locale.id)
.collect::<Vec<icu_locale_core::LanguageIdentifier>>();
let requested_locales = Self::old_locale_version(system_langids);
let available_locales = Self::old_locale_version(self.available_locales());
let canonical_locale = icu_locid::LanguageIdentifier::try_from_bytes(
Self::CANONICAL_LOCALE.to_string().as_bytes(),
)
.unwrap();
let selected_locale = fluent_langneg::negotiate_languages(
&requested_locales,
&available_locales,
Some(&canonical_locale),
NegotiationStrategy::Matching,
);
self.message_for_locale(
writer,
&LanguageIdentifier::try_from_str(&selected_locale[0].to_string()).unwrap(),
)
}
}