use super::loader::LocaleStore;
use serde_json::Value;
pub fn do_translate(
store: &LocaleStore,
locale: &str,
default: &str,
key: &str,
args: &[(&str, String)],
) -> String {
let raw = lookup_str(store, locale, key)
.or_else(|| {
if locale != default {
lookup_str(store, default, key)
} else {
None
}
})
.unwrap_or_else(|| key.to_string());
interpolate(&raw, args)
}
pub fn do_translate_plural(
store: &LocaleStore,
locale: &str,
default: &str,
key: &str,
count: u64,
args: &[(&str, String)],
) -> String {
let form = if count == 1 { "one" } else { "other" };
let raw = lookup_plural(store, locale, key, form)
.or_else(|| {
if locale != default {
lookup_plural(store, default, key, form)
} else {
None
}
})
.or_else(|| lookup_str(store, locale, key))
.or_else(|| {
if locale != default {
lookup_str(store, default, key)
} else {
None
}
})
.unwrap_or_else(|| key.to_string());
let mut all_args: Vec<(&str, String)> = args.to_vec();
if !args.iter().any(|(k, _)| *k == "count") {
all_args.push(("count", count.to_string()));
}
interpolate(&raw, &all_args)
}
fn lookup_str(store: &LocaleStore, locale: &str, key: &str) -> Option<String> {
store
.get(locale)?
.get(key)
.and_then(|v| v.as_str())
.map(String::from)
}
fn lookup_plural(store: &LocaleStore, locale: &str, key: &str, form: &str) -> Option<String> {
let guard = store.get(locale)?;
let obj = guard.get(key)?.as_object()?;
obj.get(form)
.or_else(|| obj.get("other"))
.and_then(|v| v.as_str())
.map(String::from)
}
pub fn interpolate(template: &str, args: &[(&str, String)]) -> String {
let mut result = template.to_string();
for (key, val) in args {
result = result.replace(&format!("{{{key}}}"), val);
}
result
}
#[allow(dead_code)]
pub fn value_as_str(v: &Value) -> Option<&str> {
v.as_str()
}