# `i18n-runtime`** ๐
---
# ๐ i18n-runtime
Effortless, fast, and type-safe **internationalization (i18n)** for Rust apps.
Supports both **runtime JSON loading** and **compile-time PHF maps** (when used with [i18n-gen](https://crates.io/crates/i18n-gen)).
---
## โจ Features
- โ
**Runtime JSON mode** โ load translations directly from `locales/*.json`
- โก **Compile-time PHF mode** โ use generated Rust maps for O(1) lookups
- ๐ **Fallback logic** โ handles tags like `en-IN-BR โ en-IN โ en`
- ๐ **Type-safe keys** โ auto-generated `MessageKey` enum
- ๐ **Zero-cost lookups** โ powered by [`phf`](https://crates.io/crates/phf)
---
## ๐ฆ Installation
Add to your `Cargo.toml`:
```toml
[dependencies]
i18n-runtime = "0.1"
# Only required if you use generated PHF mode
phf = "0.11"
````
---
## ๐ Quick Start
### Runtime JSON mode
1. Define `messages.schema.json`:
```json
{
"keys": ["welcome", "login_success", "login_failed"]
}
```
2. Add a locale file `locales/en.json`:
```json
{
"welcome": "Welcome!",
"login_success": "You have logged in successfully.",
"login_failed": "Login failed. Please try again."
}
```
3. Use it in code:
```rust
use i18n_runtime::{I18n, Locale};
fn main() -> anyhow::Result<()> {
let i18n = I18n::from_json_dir("./locales", "en")?;
let tags = ["en", "hi-IN", "fr"];
for tag in &tags {
let loc = Locale::new(tag);
let msg = i18n.get_owned(&loc, "welcome").unwrap_or("<missing>".into());
println!("{:<6} => {}", tag, msg);
}
Ok(())
}
```
Output:
```
en => Welcome!
hi-IN => เคธเฅเคตเคพเคเคค เคนเฅ!
fr => Welcome!
```
---
### Generated PHF mode
1. Install [i18n-gen](https://crates.io/crates/i18n-gen):
```bash
cargo install i18n-gen
```
2. Run the generator:
```bash
i18n-gen ./ ./src/generated_i18n
```
This creates:
```
src/generated_i18n/generated_keys.rs # MessageKey enum
src/generated_i18n/locales/EN.rs # en.json โ phf::Map
src/generated_i18n/locales/HI_IN.rs # hi-IN.json โ phf::Map
src/generated_i18n/mod.rs # registry
```
3. Use in code:
```rust
// include generated files
include!("generated_i18n/generated_keys.rs");
mod generated_i18n { include!("generated_i18n/mod.rs"); }
use i18n_runtime::{I18n, Locale};
fn main() {
let registry = generated_i18n::get_generated_registry();
let i18n = I18n::from_generated_registry(registry, "en");
let msg = i18n
.get_by_str_key(&Locale::new("hi-IN"), MessageKey::Welcome.as_str())
.unwrap();
println!("{}", msg); // เคธเฅเคตเคพเคเคค เคนเฅ!
}
```
---
## ๐ Fallback Logic
`en-IN-BR` โ `en-IN` โ `en` โ fallback locale.
---
## ๐งฉ Ecosystem
* [**i18n-runtime**](https://crates.io/crates/i18n-runtime) โ runtime API (this crate)
* [**i18n-gen**](https://crates.io/crates/i18n-gen) โ generator CLI for compile-time PHF maps
---
## ๐ License
MIT
---