pub const LANGUAGE_OPTIONS: &[(&str, &str)] = &[
("en", "English"),
("fr", "Français"),
("es", "Español"),
("pt", "Português"),
("it", "Italiano"),
("de", "Deutsch"),
("nl", "Nederlands"),
("sv", "Svenska"),
("fi", "Suomi"),
("pl", "Polski"),
("cs", "Čeština"),
("sk", "Slovenčina"),
("tr", "Türkçe"),
("ru", "Русский"),
("ar", "العربية"),
("hi", "हिन्दी"),
("bn", "বাংলা"),
("zh", "中文"),
("zh_tw", "繁體中文"),
("ja", "日本語"),
("ko", "한국어"),
("id", "Bahasa Indonesia"),
("ur", "اردو"),
("sw", "Kiswahili"),
("vi", "Tiếng Việt"),
("th", "ไทย"),
];
pub fn detect_system_language() -> usize {
let lang_raw = detect_system_language_string();
match_language_code(&lang_raw)
}
fn detect_system_language_string() -> String {
if let Ok(lang) = std::env::var("LANG")
.or_else(|_| std::env::var("LC_ALL"))
.or_else(|_| std::env::var("LC_MESSAGES"))
{
if !lang.is_empty() && lang != "C" && lang != "POSIX" {
return lang.to_lowercase();
}
}
#[cfg(target_os = "macos")]
{
if let Ok(output) = std::process::Command::new("defaults")
.args(["read", "-g", "AppleLocale"])
.output()
{
if output.status.success() {
let locale = String::from_utf8_lossy(&output.stdout)
.trim()
.to_lowercase();
if !locale.is_empty() {
return locale;
}
}
}
}
#[cfg(target_os = "windows")]
{
if let Ok(output) = std::process::Command::new("powershell")
.args([
"-NoProfile",
"-Command",
"(Get-Culture).TwoLetterISOLanguageName",
])
.output()
{
if output.status.success() {
let lang = String::from_utf8_lossy(&output.stdout)
.trim()
.to_lowercase();
if !lang.is_empty() {
return lang;
}
}
}
}
String::new()
}
fn match_language_code(raw: &str) -> usize {
let normalized = raw.replace('-', "_");
if normalized.starts_with("zh_tw") {
return LANGUAGE_OPTIONS
.iter()
.position(|(c, _)| *c == "zh_tw")
.unwrap_or(0);
}
let code = normalized.get(..2).unwrap_or("");
LANGUAGE_OPTIONS
.iter()
.position(|(c, _)| *c == code)
.unwrap_or(0)
}
pub fn set_locale(lang: &str) {
rust_i18n::set_locale(lang);
}