1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
# static-l10n
Procedural macros for `static-l10n`.
## Macros
- `main!()` initializes the language state with the default language.
- `lang!("xx")` switches the current language.
- `l10n!("key")` returns a localized string for `key`.
- `f16n!("fmt: {}", arg)` returns a localized formatted string.
- `l10n_print!("key")` prints a localized string.
- `l10n_println!("key")` prints a localized string with newline.
- `l10n_eprint!("key")` prints a localized string to stderr.
- `l10n_eprintln!("key")` prints a localized string to stderr with newline.
- `l10n_write!(writer, "key")` writes a localized string to a writer.
- `l10n_writeln!(writer, "key")` writes a localized string to a writer with newline.
- `l10n_panic!("key")` panics with a localized string.
- `l10n_args!("key")` returns `std::fmt::Arguments` for formatting APIs.
- `l10n_assert!(cond, "key")` asserts a condition with a localized message.
- `l10n_assert_eq!(left, right, "key")` asserts equality with a localized message.
- `l10n_assert_ne!(left, right, "key")` asserts inequality with a localized message.
- `l10n_debug_assert!(cond, "key")` debug-asserts a condition with a localized message.
- `l10n_debug_assert_eq!(left, right, "key")` debug-asserts equality with a localized message.
- `l10n_debug_assert_ne!(left, right, "key")` debug-asserts inequality with a localized message.
- `f16n_print!("fmt: {}", arg)` prints a localized formatted string.
- `f16n_println!("fmt: {}", arg)` prints a localized formatted string with newline.
- `f16n_eprint!("fmt: {}", arg)` prints a localized formatted string to stderr.
- `f16n_eprintln!("fmt: {}", arg)` prints a localized formatted string to stderr with newline.
- `f16n_write!(writer, "fmt: {}", arg)` writes a localized formatted string to a writer.
- `f16n_writeln!(writer, "fmt: {}", arg)` writes a localized formatted string to a writer with newline.
- `f16n_panic!("fmt: {}", arg)` panics with a localized formatted string.
- `f16n_args!("fmt: {}", arg)` returns `std::fmt::Arguments` for formatting APIs.
- `f16n_assert!(cond, "fmt: {}", arg)` asserts a condition with a localized formatted message.
- `f16n_assert_eq!(left, right, "fmt: {}", arg)` asserts equality with a localized formatted message.
- `f16n_assert_ne!(left, right, "fmt: {}", arg)` asserts inequality with a localized formatted message.
- `f16n_debug_assert!(cond, "fmt: {}", arg)` debug-asserts a condition with a localized formatted message.
- `f16n_debug_assert_eq!(left, right, "fmt: {}", arg)` debug-asserts equality with a localized formatted message.
- `f16n_debug_assert_ne!(left, right, "fmt: {}", arg)` debug-asserts inequality with a localized formatted message.
- `debug_print_metadata!()` prints resolved metadata and loaded translations at compile time.
## Usage
Add metadata to your crate `Cargo.toml` (this is read at compile time):
```toml
[package.metadata.static-l10n]
path = "i18n"
base = "en"
langs = ["en", { name = "zh", fallback = "en" }]
```
Create translation files under the `path` directory. Each file is TOML and can contain multiple keys:
```toml
["Hello, world!"]
en = "Hello, world!"
zh = "你好,世界!"
["Hello, {}!"]
en = "Hello, {}!"
zh = "你好,{}!"
```
You can split keys across multiple files and nested folders under `path`. Duplicate keys for the same language will cause a compile-time panic.
Then use the macros in your crate:
```rust
static_l10n::main!();
static_l10n::lang!("zh");
let msg = static_l10n::l10n!("hello");
let formatted = static_l10n::f16n!("count: {}", 3);
static_l10n::l10n_println!("hello");
static_l10n::f16n_println!("count: {}", 3);
```
## How It Works
- `main!()` defines a global mutex holding the current language. Call it once at crate root.
- `lang!("xx")` switches the current language for subsequent lookups.
- `l10n!` looks up a string key and returns a `&'static str` literal from the translations table.
- `f16n!` looks up a format string and returns a `String` built with `format!`.
- `*_args!` returns `std::fmt::Arguments` for zero-allocation formatting (use with `write!`, `format!`, etc.).
## Common Patterns
Print to stdout or stderr:
```rust
static_l10n::l10n_print!("Hello, world!");
static_l10n::l10n_eprintln!("Hello, world!");
static_l10n::f16n_println!("Hello, {}!", "Rust");
```
Write into a buffer or writer:
```rust
let mut buf = String::new();
static_l10n::l10n_write!(&mut buf, "Hello, world!");
static_l10n::f16n_writeln!(&mut buf, "Hello, {}!", "Rust");
```
Use `*_args!` with formatting APIs:
```rust
use std::fmt::Write;
let mut buf = String::new();
let args = static_l10n::f16n_args!("Hello, {}!", "Rust");
let _ = write!(&mut buf, "{}", args);
```
Localized assertions:
```rust
static_l10n::l10n_assert!(1 + 1 == 2, "Hello, world!");
static_l10n::f16n_assert_eq!(2 + 2, 4, "Hello, {}!", "Rust");
static_l10n::l10n_debug_assert_ne!(3, 4, "Hello, world!");
```
Localized panic:
```rust
static_l10n::l10n_panic!("Hello, world!");
static_l10n::f16n_panic!("Hello, {}!", "Rust");
```
## Notes
- All translations are loaded at compile time from `path`.
- Missing keys per language produce a compile-time error.
- `debug_print_metadata!()` can help inspect loaded metadata and translations during compilation.
|