Skip to main content

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​

FeatureHardcoded Translation StringsFerrox i18n Engine
MaintainabilityString changes require recompiling backend Rust services.Catalogs loaded dynamically from JSON / Fluent assets.
PluralizationComplex if count == 1 branching scattered in code.Standard Unicode CLDR pluralization rule engine.
PerformanceHigh 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.