use topcoat::{
context::{Cx, try_app_context},
l10n::{Locale, accept_language, locale, negotiate, try_locale},
};
use super::Catalog;
pub(crate) static ENGLISH: Locale = locale!("en");
const MAX_ACCEPTED: usize = 16;
pub(crate) fn entered(cx: &Cx, catalog: &Catalog) -> Cx {
let offered = catalog.locales();
let locale = match offered {
[only] => only,
_ => {
negotiate(accept_language(cx).iter().take(MAX_ACCEPTED), offered).unwrap_or(&offered[0])
}
};
cx.with(locale.clone())
}
pub(crate) fn addressed_to(cx: &Cx, locale: Option<&Locale>) -> Cx {
let matched = locale
.zip(catalog(cx))
.and_then(|(locale, catalog)| negotiate([locale], catalog.locales()));
match matched {
Some(matched) => cx.with(matched.clone()),
None => cx.clone(),
}
}
pub(crate) fn catalog_and_locale(cx: &Cx) -> (&Catalog, &Locale) {
match catalog(cx) {
Some(catalog) => (catalog, try_locale(cx).unwrap_or(&catalog.locales()[0])),
None => (Catalog::english(), &ENGLISH),
}
}
fn catalog(cx: &Cx) -> Option<&Catalog> {
(try_app_context::<CatalogSource>(cx)?.0)(cx)
}
pub(crate) struct CatalogSource(pub(crate) for<'a> fn(&'a Cx) -> Option<&'a Catalog>);