Internacionalização (i18n) em Rust: melhores bibliotecas e práticas

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Internacionalização (i18n) em Rust: visão geral das bibliotecas e ferramentas

Internacionalização (abreviada como i18n — 18 letras entre 'i' e 'n') é o processo de projetar um aplicativo para que ele possa ser adaptado a diferentes idiomas e padrões regionais sem alterar o código-fonte. No ecossistema Rust, existem várias bibliotecas maduras para implementar i18n. Neste artigo, vamos explorar três abordagens principais: a clássica gettext, a orientada a macros rust-i18n e a moderna fluent-rs da Mozilla.

1. Biblioteca gettext (crate gettext-rs)

gettext é o padrão de facto para localização em Unix. O wrapper Rust gettext-rs oferece acesso completo às funções do GNU gettext.

Instalação

[dependencies]
gettext-rs = "0.7"

Exemplo de uso

use gettextrs::*;
use std::env;

fn main() {
    // Define o locale e o domínio
    setlocale(LocaleCategory::LcAll, "pt_BR.UTF-8");
    bindtextdomain("myapp", "/usr/share/locale").unwrap();
    textdomain("myapp");

    // Tradução de string
    println!("{}", gettext("Hello, world!"));
    
    // Pluralização
    let n = 5;
    println!("{}", ngettext("{} apple", "{} apples", n, n));
}

Vantagens: maturidade, suporte a pluralização, traduções contextuais (pgettext), integração com Poedit e Transifex.
Desvantagens: requer instalação do gettext no sistema, suporte imperfeito a Unicode no Windows.

2. Biblioteca rust-i18n

Implementação puramente em Rust, sem dependências externas. Usa arquivos YAML para armazenar traduções e macros para extrair strings.

Instalação

[dependencies]
rust-i18n = "3.0"

Estrutura do projeto

locales/
├── en.yml
└── pt-BR.yml

Exemplo de locales/pt-BR.yml:

hello: "Olá, mundo!"
apples: 
  zero: "Nenhuma maçã"
  one: "{} maçã"
  many: "{} maçãs"

Uso no código

use rust_i18n::t;

rust_i18n::i18n!("locales");

fn main() {
    // Tradução simples
    println!("{}", t!("hello"));

    // Pluralização com regras do português
    let n = 3;
    println!("{}", t!("apples", count = n, n));
}

Vantagens: simplicidade, detecção automática de locale, suporte a placeholders e pluralização para idiomas complexos (português, árabe).
Desvantagens: menos flexível que gettext, sem suporte a contextos.

3. Biblioteca fluent-rs

Desenvolvida pela Mozilla para o Firefox. Usa a sintaxe própria FTL (Fluent Translation List).

Instalação

[dependencies]
fluent = "0.16"
fluent-bundle = "0.15"
fluent-resmgr = "0.4"

Exemplo de arquivo FTL (locales/pt-BR/main.ftl)

hello = Olá, mundo!
apples = 
    { $count ->
        [0] Nenhuma maçã
        [one] { $count } maçã
       *[many] { $count } maçãs
    }

Uso em Rust

use fluent_bundle::{FluentBundle, FluentResource};
use fluent_resmgr::ResourceManager;
use unic_langid::langid;

fn main() {
    let langid = langid!("pt-BR");
    let res_mgr = ResourceManager::new("./locales/".into());
    
    let mut bundle = FluentBundle::new(&[langid]);
    let ftl_string = res_mgr.load("pt-BR/main.ftl").unwrap();
    let resource = FluentResource::try_new(ftl_string).unwrap();
    bundle.add_resource(resource).unwrap();

    let mut errors = vec![];
    let msg = bundle.format_pattern(
        bundle.get_message("hello").unwrap().value().unwrap(),
        None,
        &mut errors
    );
    println!("{}", msg);

    // Pluralização
    let mut args = fluent_bundle::FluentArgs::new();
    args.set("count", 3);
    let                    

Recommendations