pub use crate::i18n::LanguageInfo;
const EXTRA_LANGUAGE_CODES: &[&str] = &["it", "nl"];
#[must_use]
pub fn get_languages() -> Vec<LanguageInfo> {
let mut languages: Vec<_> = crate::i18n::get_supported_languages()
.into_iter()
.map(|code| crate::i18n::get_language_info(&code))
.collect();
languages.extend(
EXTRA_LANGUAGE_CODES
.iter()
.map(|code| get_language_info(code)),
);
languages.sort_unstable_by(|left, right| left.code.cmp(&right.code));
languages
}
#[must_use]
pub fn get_language_info(code: &str) -> LanguageInfo {
let normalized = code.trim().to_ascii_lowercase();
extra_language_info(&normalized).unwrap_or_else(|| crate::i18n::get_language_info(&normalized))
}
fn extra_language_info(code: &str) -> Option<LanguageInfo> {
match code {
"it" => Some(LanguageInfo {
code: String::from("it"),
name: String::from("Italian"),
name_local: String::from("Italiano"),
bidi: false,
}),
"nl" => Some(LanguageInfo {
code: String::from("nl"),
name: String::from("Dutch"),
name_local: String::from("Nederlands"),
bidi: false,
}),
_ => None,
}
}
#[cfg(test)]
mod tests {
use super::{get_language_info, get_languages};
#[test]
fn get_languages_includes_at_least_ten_entries() {
let languages = get_languages();
assert!(languages.len() >= 10);
assert!(languages.iter().any(|language| language.code == "en-us"));
assert!(languages.iter().any(|language| language.code == "it"));
}
#[test]
fn get_language_info_reuses_core_language_metadata() {
let language = get_language_info("fr");
assert_eq!(language.code, "fr");
assert_eq!(language.name, "French");
assert_eq!(language.name_local, "Français");
}
#[test]
fn get_language_info_supports_extra_languages() {
let language = get_language_info("IT");
assert_eq!(language.code, "it");
assert_eq!(language.name, "Italian");
assert_eq!(language.name_local, "Italiano");
}
#[test]
fn get_language_info_normalizes_unknown_codes() {
let language = get_language_info("EO");
assert_eq!(language.code, "eo");
assert_eq!(language.name, "eo");
assert_eq!(language.name_local, "eo");
assert!(!language.bidi);
}
}