Internacionalización (i18n) en Rust: mejores bibliotecas y prácticas

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Internacionalización (i18n) en Rust: resumen de bibliotecas y herramientas

\n\n

La internacionalización (abreviada i18n — por las 18 letras entre la 'i' y la 'n') es el proceso de diseñar una aplicación para que pueda adaptarse a diferentes idiomas y estándares regionales sin modificar el código fuente. En el ecosistema de Rust existen varias bibliotecas maduras para implementar i18n. En este artículo veremos tres enfoques principales: el clásico gettext, el orientado a macros rust-i18n y el moderno fluent-rs de Mozilla.

\n\n

1. Biblioteca gettext (crate gettext-rs)

\n

gettext es el estándar de facto de localización Unix. El envoltorio de Rust gettext-rs proporciona acceso completo a las funciones de GNU gettext.

\n\n

Instalación

\n
[dependencies]\ngettext-rs = "0.7"
\n\n

Ejemplo de uso

\n
use gettextrs::*;\nuse std::env;\n\nfn main() {\n    // Establecer locale y dominio\n    setlocale(LocaleCategory::LcAll, "ru_RU.UTF-8");\n    bindtextdomain("myapp", "/usr/share/locale").unwrap();\n    textdomain("myapp");\n\n    // Traducción de cadena\n    println!("{}", gettext("Hello, world!"));\n    \n    // Pluralización (número plural)\n    let n = 5;\n    println!("{}", ngettext("{} apple", "{} apples", n, n));\n}
\n\n

Ventajas: madurez, soporte de pluralización, traducciones contextuales (pgettext), integración con Poedit y Transifex.
\nDesventajas: requiere instalación de gettext del sistema, soporte imperfecto de Unicode en Windows.

\n\n

2. Biblioteca rust-i18n

\n

Implementación pura en Rust sin dependencias externas. Utiliza archivos YAML para almacenar traducciones y macros para extraer cadenas.

\n\n

Instalación

\n
[dependencies]\nrust-i18n = "3.0"
\n\n

Estructura del proyecto

\n
locales/\n├── en.yml\n└── ru.yml
\n\n

Ejemplo de locales/ru.yml:

\n
hello: "¡Hola, mundo!"\napples: \n  zero: "No hay manzanas"\n  one: "{} manzana"\n  few: "{} manzanas"\n  many: "{} manzanas"
\n\n

Uso en código

\n
use rust_i18n::t;\n\nrust_i18n::i18n!("locales");\n\nfn main() {\n    // Traducción simple\n    println!("{}", t!("hello"));\n\n    // Pluralización con reglas rusas\n    let n = 3;\n    println!("{}", t!("apples", count = n, n));\n}
\n\n

Ventajas: simplicidad, detección automática de locale, soporte de placeholders y pluralización para idiomas complejos (ruso, árabe).
\nDesventajas: menos flexible que gettext, sin soporte de contextos.

\n\n

3. Biblioteca fluent-rs

\n

Desarrollada por Mozilla para Firefox. Utiliza su propia sintaxis FTL (Fluent Translation List).

\n\n

Instalación

\n
[dependencies]\nfluent = "0.16"\nfluent-bundle = "0.15"\nfluent-resmgr = "0.4"
\n\n

Ejemplo de archivo FTL (locales/ru/main.ftl)

\n
hello = ¡Hola, mundo!\napples = \n    { $count ->\n        [0] No hay manzanas\n        [one] { $count } manzana\n        [few] { $count } manzanas\n       *[many] { $count } manzanas\n    }
\n\n

Uso en Rust

\n
use fluent_bundle::{FluentBundle, FluentResource};\nuse fluent_resmgr::ResourceManager;\nuse unic_langid::langid;\n\nfn main() {\n    let langid = langid!("ru");\n    let res_mgr = ResourceManager::new("./locales/".into());\n    \n    let mut bundle = FluentBundle::new(&[langid]);\n    let ftl_string = res_mgr.load("ru/main.ftl").unwrap();\n    let resource = FluentResource::try_new(ftl_string).unwrap();\n    bundle.add_resource(resource).unwrap();\n\n    let mut errors = vec![];\n    let msg = bundle.format_pattern(\n        bundle.get_message("hello").unwrap().value().unwrap(),\n        None,\n        &mut errors\n    );\n    println!("{}", msg);\n\n    // Pluralización\n    let mut args = fluent_bundle::FluentArgs::new();\n                    

Recommendations