use std::sync::OnceLock;
use crate::i18n::Idioma;
static IDIOMA_GLOBAL: OnceLock<Idioma> = OnceLock::new();
pub fn resolver_idioma(forcar: Option<&str>) -> Idioma {
if let Some(codigo) = forcar {
if let Some(idioma) = codigo_para_idioma(codigo) {
return idioma;
}
}
if let Ok(env_lang) = std::env::var("SSH_CLI_LANG") {
if let Some(idioma) = codigo_para_idioma(&env_lang) {
return idioma;
}
}
if let Some(locale) = sys_locale::get_locale() {
if let Some(idioma) = codigo_para_idioma(&locale) {
return idioma;
}
}
Idioma::English
}
pub fn definir_idioma(idioma: Idioma) {
let _ = IDIOMA_GLOBAL.set(idioma);
}
pub fn idioma_atual() -> Idioma {
IDIOMA_GLOBAL.get().copied().unwrap_or(Idioma::English)
}
fn codigo_para_idioma(codigo: &str) -> Option<Idioma> {
let normalizado = codigo.to_lowercase();
match normalizado.as_str() {
"pt" | "pt-br" | "pt_br" => Some(Idioma::Portugues),
"en" | "en-us" | "en_us" => Some(Idioma::English),
outro => {
if outro.starts_with("pt") {
Some(Idioma::Portugues)
} else if outro.starts_with("en") {
Some(Idioma::English)
} else {
None
}
}
}
}
#[cfg(test)]
mod testes {
use super::*;
#[test]
fn codigo_pt_retorna_portugues() {
assert_eq!(codigo_para_idioma("pt"), Some(Idioma::Portugues));
}
#[test]
fn codigo_pt_br_retorna_portugues() {
assert_eq!(codigo_para_idioma("pt-BR"), Some(Idioma::Portugues));
}
#[test]
fn codigo_pt_br_underscore_retorna_portugues() {
assert_eq!(codigo_para_idioma("pt_BR"), Some(Idioma::Portugues));
}
#[test]
fn codigo_en_retorna_english() {
assert_eq!(codigo_para_idioma("en"), Some(Idioma::English));
}
#[test]
fn codigo_en_us_retorna_english() {
assert_eq!(codigo_para_idioma("en-US"), Some(Idioma::English));
}
#[test]
fn codigo_en_gb_retorna_english_por_prefixo() {
assert_eq!(codigo_para_idioma("en-GB"), Some(Idioma::English));
}
#[test]
fn codigo_desconhecido_retorna_none() {
assert_eq!(codigo_para_idioma("fr-FR"), None);
}
#[test]
fn codigo_vazio_retorna_none() {
assert_eq!(codigo_para_idioma(""), None);
}
#[test]
fn codigo_maiusculo_normalizado() {
assert_eq!(codigo_para_idioma("PT"), Some(Idioma::Portugues));
assert_eq!(codigo_para_idioma("EN"), Some(Idioma::English));
}
#[test]
fn resolver_com_forcar_pt_retorna_portugues() {
let resultado = resolver_idioma(Some("pt-BR"));
assert_eq!(resultado, Idioma::Portugues);
}
#[test]
fn resolver_com_forcar_en_retorna_english() {
let resultado = resolver_idioma(Some("en-US"));
assert_eq!(resultado, Idioma::English);
}
#[test]
fn resolver_com_forcar_invalido_usa_camadas_seguintes() {
std::env::remove_var("SSH_CLI_LANG");
let resultado = resolver_idioma(Some("xx-YY"));
assert!(
resultado == Idioma::English || resultado == Idioma::Portugues,
"resolver_idioma deve retornar idioma válido mesmo com código inválido"
);
}
#[test]
fn resolver_sem_forcar_retorna_idioma_valido() {
std::env::remove_var("SSH_CLI_LANG");
let resultado = resolver_idioma(None);
assert!(
resultado == Idioma::English || resultado == Idioma::Portugues,
"resolver_idioma deve retornar idioma válido"
);
}
#[test]
fn idioma_atual_retorna_fallback_english_antes_de_definir() {
let resultado = idioma_atual();
assert!(
resultado == Idioma::English || resultado == Idioma::Portugues,
"idioma_atual deve retornar idioma válido"
);
}
}