Internacionalização (i18n) em Rust: gettext-rs e fluent-rs
Internacionalização (i18n) é um aspecto chave do desenvolvimento de aplicações modernas, permitindo adaptar o software para usuários de diferentes países e culturas. No ecossistema Rust, existem várias bibliotecas poderosas para implementar i18n. Neste artigo, veremos duas das mais populares: gettext-rs (abordagem clássica baseada em gettext) e fluent-rs (sistema moderno de localização da Mozilla).
1. Biblioteca gettext-rs
gettext-rs é um wrapper Rust para o sistema clássico GNU gettext. É ideal para projetos que já usam gettext ou para quem prefere soluções testadas pelo tempo.
Instalação e configuração
Adicione a dependência no Cargo.toml:
[dependencies]gettext-rs = "0.7"gettext-sys = "0.21"Exemplo básico de uso
use gettextrs::*;
fn main() { // Define o locale e o domínio de tradução setlocale(LocaleCategory::LcAll, "pt_BR.UTF-8"); bindtextdomain("myapp", "/usr/share/locale").unwrap(); textdomain("myapp").unwrap();
// Usa a tradução let greeting = gettext("Hello, world!"); println!("{}", greeting);
// Formas plurais let items = 5; let message = ngettext("{} item", "{} items", items); println!("{}", message.replace("{}", &items.to_string()));}Trabalhando com contexto
Para diferenciar strings iguais em contextos diferentes, use pgettext:
let menu_item = pgettext("menu", "File");let dialog_title = pgettext("dialog", "File");2. Biblioteca fluent-rs
fluent-rs é um sistema de localização moderno, flexível e poderoso, desenvolvido pela Mozilla. Suporta construções gramaticais complexas, formas plurais e traduções contextuais.
Instalação
[dependencies]fluent = "0.16"fluent-bundle = "0.15"fluent-resmgr = "0.5"fluent-langneg = "0.4"unic-langid = "0.9"Criação de arquivos de tradução (FTL)
Fluent usa seu próprio formato de arquivo .ftl. Exemplo para português (pt.ftl):
hello-world = Olá, mundo!greeting = Olá, {$name}!items-count = { $count -> [one] {$count} item [many] {$count} itens *[other] {$count} itens}Exemplo de uso do fluent-rs
use fluent_bundle::{FluentBundle, FluentResource};use unic_langid::langid;use std::fs;
fn main() { // Carrega o arquivo de tradução let ftl_string = fs::read_to_string("locales/pt.ftl") .expect("Falha ao ler o arquivo de localização"); let resource = FluentResource::try_new(ftl_string) .expect("Erro ao analisar FTL");
// Cria o bundle para português let lang_pt = langid!("pt"); let mut bundle = FluentBundle::new(&[lang_pt]); bundle.add_resource(&resource).unwrap();
// Obtém a tradução com parâmetros let mut errors = vec![]; let msg = bundle.get_message("greeting").unwrap(); let mut args = fluent_bundle::FluentArgs::new(); args.set("name", "João"); let pattern = msg.value().unwrap(); let value = bundle.format_pattern(pattern, Some(&args), &mut errors); println!("{}", value);
// Formas plurais let msg = bundle.get_message("items-count").unwrap(); let mut args = fluent_bundle::FluentArgs::new(); args.set("count", 3); let pattern = msg.value().unwrap(); let value = bundle.format_pattern(pattern, Some(&args), &mut errors); println!("{}", value);}3. Comparação entre gettext-rs e fluent-rs
- gettext-rs:
-
Também na biblioteca
Processamento JSON em Java: bibliotecas e exemplos práticos
Migrações de banco de dados em Kotlin: Visão geral de ferramentas e abordagens
Lombok para Java: guia completo com exemplos
BenchmarkDotNet para C# (.NET): guia completo com exemplos
Rate Limiting em Go: guia para limitar a velocidade de requisições
Recommendations
-