Internationalization (i18n) in Rust: Overview of Libraries and Tools
Internationalization (abbreviated as i18n — 18 letters between 'i' and 'n') is the process of designing an application so it can be adapted to various languages and regional standards without modifying the source code. In the Rust ecosystem, there are several mature libraries for implementing i18n. In this article, we will look at three main approaches: the classic gettext, the macro-oriented rust-i18n, and the modern fluent-rs from Mozilla.
1. The gettext Library (crate gettext-rs)
gettext is the de facto standard for Unix localization. The Rust wrapper gettext-rs provides full access to GNU gettext functions.
Installation
[dependencies]gettext-rs = "0.7"Usage Example
use gettextrs::*;use std::env;
fn main() { // Set locale and domain setlocale(LocaleCategory::LcAll, "ru_RU.UTF-8"); bindtextdomain("myapp", "/usr/share/locale").unwrap(); textdomain("myapp");
// String translation println!("{}", gettext("Hello, world!")); // Pluralization let n = 5; println!("{}", ngettext("{} apple", "{} apples", n, n));}Pros: maturity, support for pluralization, contextual translations (pgettext), integration with Poedit and Transifex.
Cons: requires system gettext installation, imperfect Unicode support on Windows.
2. The rust-i18n Library
A pure Rust implementation with no external dependencies. Uses YAML files for storing translations and macros for extracting strings.
Installation
[dependencies]rust-i18n = "3.0"Project Structure
locales/├── en.yml└── ru.ymlExample locales/ru.yml:
hello: "Hello, world!"apples: zero: "No apples" one: "{} apple" few: "{} apples" many: "{} apples"Usage in Code
use rust_i18n::t;
rust_i18n::i18n!("locales");
fn main() { // Simple translation println!("{}", t!("hello"));
// Pluralization considering Russian rules let n = 3; println!("{}", t!("apples", count = n, n));}Pros: simplicity, automatic locale detection, support for placeholders and pluralization for complex languages (Russian, Arabic).
Cons: less flexible than gettext, no context support.
3. The fluent-rs Library
Developed by Mozilla for Firefox. Uses its own FTL (Fluent Translation List) syntax.
Installation
[dependencies]fluent = "0.16"fluent-bundle = "0.15"fluent-resmgr = "0.4"Example FTL File (locales/ru/main.ftl)
hello = Hello, world!apples = { $count -> [0] No apples [one] { $count } apple [few] { $count } apples *[many] { $count } apples }Usage in Rust
use fluent_bundle::{FluentBundle, FluentResource};use fluent_resmgr::ResourceManager;use unic_langid::langid;
fn main() { let langid = langid!("ru"); let res_mgr = ResourceManager::new("./locales/".into()); let mut bundle = FluentBundle::new(&[langid]); let ftl_string = res_mgr.load("ru/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);
// Pluralization let mut args = fluent_bundle::FluentArgs::new(); Also in library
CLI framework for Swift: creating console utilities on iOS/macOS
PHP Task Scheduler: cron-like tasks without crond
HTTP client for Java: overview of top libraries (Java 11, Apache, OkHttp, Retrofit)