Internationalization (i18n), Localized Formatting & Translation Catalogs
The ferrox-i18n crate delivers multi-language translation, fallback catalog resolution, pluralization rules, dynamic parameter interpolation, and currency/date formatting for Rust backend APIs and WebAssembly frontend applications.
1. What It Is & Architectural Purpose
Global applications require serving localized response payloads, error messages, and email templates based on client locale headers (Accept-Language: fr-FR, en-US). Hardcoding English error strings directly in backend code breaks internationalization standards.
ferrox-i18n abstracts translation catalogs into a fast, zero-allocation memory lookup engine (supporting Fluent and JSON translation formats). It resolves locale strings with automatic fallback rules (fr-FR -> fr -> en).
┌────────────────────────────────────────────────────────────────────────┐
│ ferrox-i18n Engine │
├──────────────────────────────────┬─────────────────────────────────────┤
│ Accept-Language Header Parser │ Translation Catalog Resolver │
│ (Locale Fallback Resolution) │ (Fluent / JSON Translation Maps) │
└────────────────┬─────────────────┴──────────────────┬──────────────────┘
│ Parameter Interpolation
▼
┌────────────────────────────────────────────────────────────────────────┐
│ Localized Response Payload │
└────────────────────────────────────────────────────────────────────────┘
2. What It Does & Key Capabilities
- Locale Fallback Resolution: Automatically falls back gracefully when specific locale keys are missing.
- Dynamic Parameter Interpolation: Interpolates named parameters (e.g.,
"Welcome {name}") safely without string format vulnerabilities. - Pluralization Rules: Evaluates locale-specific plural forms (e.g., zero, one, few, many, other).
- Currency & Date Localization: Formats numbers, currencies, and dates per ISO locale standards.
3. How It Works Under the Hood
Locale Resolution & Interpolation Sequence
sequenceDiagram
autonumber
participant Client as HTTP Client
participant Controller as Ferrox Router
participant I18n as ferrox-i18n Resolver
participant Catalog as Fluent Translation Catalog
Client->>Controller: GET /api/welcome (Header Accept-Language: "es-MX, es;q=0.9")
Controller->>I18n: translate("es-MX", "user.welcome", { name: "Maria" })
I18n->>Catalog: Lookup key "user.welcome" in es-MX catalog
alt Found in es-MX
Catalog-->>I18n: Return "¡Bienvenida {name}!"
else Fallback to es
Catalog-->>I18n: Return "¡Bienvenido {name}!"
end
I18n->>I18n: Interpolate { name => "Maria" }
I18n-->>Controller: "¡Bienvenida Maria!"
Controller-->>Client: 200 OK JSON Response
4. Why It Was Designed This Way
| Feature | Hardcoded Translation Strings | Ferrox i18n Engine |
|---|---|---|
| Maintainability | String changes require recompiling backend Rust services. | Catalogs loaded dynamically from JSON / Fluent assets. |
| Pluralization | Complex if count == 1 branching scattered in code. | Standard Unicode CLDR pluralization rule engine. |
| Performance | High string allocation overhead on every API hit. | Zero-allocation lookup maps using compiled Fluent ASTs. |
5. Practical Usage Guide & Extended Code Examples
5.1 Resolving Localized Messages
use ferrox_i18n::{I18nEngine, Locale};
pub fn generate_localized_error(locale_str: &str, user_name: &str) -> String {
let i18n = I18nEngine::global();
let locale = Locale::parse(locale_str).unwrap_or(Locale::EN_US);
i18n.translate(locale, "error.user_not_found", &[("name", user_name)])
.unwrap_or_else(|| "User not found".to_string())
}
6. Anti-Patterns: How NOT to Use It
[!CAUTION] Anti-Pattern 1: Concatenating Localized String Snippets Avoid string concatenation like
translate("hello") + " " + user_name. Different languages have varying word orders. Always use named parameter templates (translate("hello_user", &[("name", user_name)])).
7. Pro-Tips & Best Practices
[!TIP] Pro-Tip 1: Compile-Time Key Validation Use procedural macros (
t!("error.not_found")) to catch missing translation catalog keys during Rust build compilation.