use std::cell::RefCell;
use std::cmp::Ordering;
use std::collections::HashMap;
use icu_collator::options::CollatorOptions;
use icu_collator::{Collator, CollatorBorrowed};
day_reactive::tls_slots! {
collate;
static COLLATORS: RefCell<HashMap<String, Option<CollatorBorrowed<'static>>>> =
RefCell::new(HashMap::new());
}
fn with_collator<R>(locale: &str, f: impl FnOnce(Option<&CollatorBorrowed<'static>>) -> R) -> R {
COLLATORS.with(|c| {
let mut map = c.borrow_mut();
let entry = map.entry(locale.to_string()).or_insert_with(|| {
let parsed: icu_locale_core::Locale = locale.parse().ok()?;
Collator::try_new((&parsed).into(), CollatorOptions::default()).ok()
});
f(entry.as_ref())
})
}
pub fn compare_in(locale: &str, a: &str, b: &str) -> Ordering {
with_collator(locale, |c| match c {
Some(c) => c.compare(a, b),
None => a.cmp(b),
})
}
pub fn compare(a: &str, b: &str) -> Ordering {
let locale = crate::locale().get();
compare_in(&locale, a, b)
}
pub fn sort_localized<T: AsRef<str>>(items: &mut [T]) {
let locale = crate::locale().get();
with_collator(&locale, |c| match c {
Some(c) => items.sort_by(|a, b| c.compare(a.as_ref(), b.as_ref())),
None => items.sort_by(|a, b| a.as_ref().cmp(b.as_ref())),
});
}