iTools Localization
🌍 iTools Localization 是 iTools 项目的国际化支持模块,提供完整的国际化功能,包括翻译管理、语言切换和参数化翻译。
特性
- ✨ 支持多语言翻译
- ✨ 参数化翻译
- ✨ 复数形式支持
- ✨ 性别形式支持
- ✨ 语言自动检测和切换
- ✨ 翻译缓存机制
- ✨ 错误处理和回退机制
- ✨ 支持 Fluent 格式
- ✨ 支持 JSON、TOML、YAML 格式(通过特性开关)
安装
在 Cargo.toml 文件中添加依赖:
[]
= {
path = "path/to/itools-localization",
= ["json", "toml", "yaml"] # 可选特性
}
API 参考
核心类型
I18nError
国际化错误类型,包含以下变体:
FileRead- 文件读取错误ParseError- 解析错误UnsupportedFormat- 不支持的文件格式FeatureNotEnabled- 特性未启用TranslationNotFound- 翻译未找到
TranslationProvider
翻译提供者 trait,定义了翻译功能的核心接口:
SimpleTranslator
简单内存翻译提供者,适用于小型应用或测试:
方法:
new(current_locale: &str, default_locale: &str) -> Self- 创建新的简单翻译提供者add_translations(&mut self, locale: &str, translations: HashMap<String, String>)- 添加翻译
OakFluentTranslator
Oak Fluent 翻译提供者,支持 Fluent 格式的翻译文件:
方法:
new(current_locale: &str, default_locale: &str) -> Self- 创建新的 Oak Fluent 翻译提供者add_translations_from_file(&mut self, locale: &str, file_path: &Path) -> Result<(), I18nError>- 从文件加载翻译add_simple_translations(&mut self, locale: &str, translations: HashMap<String, String>) -> Result<(), I18nError>- 添加简单翻译add_translations_from_string(&mut self, locale: &str, ftl_content: &str) -> Result<(), I18nError>- 从字符串加载翻译
I18nContext
国际化上下文,提供翻译功能的高级接口:
方法:
new(translator: Box<dyn TranslationProvider + Send + Sync>) -> Self- 创建新的国际化上下文with_cache_capacity(translator: Box<dyn TranslationProvider + Send + Sync>, capacity: usize) -> Self- 创建带有自定义缓存容量的国际化上下文t(&mut self, key: &str) -> String- 翻译一个键t_with_args(&mut self, key: &str, args: Option<&HashMap<String, String>>) -> String- 翻译带参数的键t_batch(&mut self, keys: &[(String, Option<HashMap<String, String>>)]) -> Vec<String>- 批量翻译get_locale(&self) -> &str- 获取当前语言set_locale(&mut self, locale: &str)- 设置当前语言clear_cache(&mut self)- 清除翻译缓存cache_size(&self) -> usize- 获取缓存大小
全局函数
t(key: &str) -> String- 获取翻译t_with_args(key: &str, args: &[(&str, &str)]) -> String- 获取带参数的翻译set_locale(locale: &str)- 设置当前语言get_locale() -> String- 获取当前语言
使用示例
基本使用
use ;
// 基本翻译
let hello = t;
// 带参数的翻译
let greeting = t_with_args;
语言切换
use ;
// 设置语言
set_locale;
// 获取当前语言
let current_locale = get_locale;
自定义翻译提供者
use ;
use HashMap;
// 创建简单翻译提供者
let mut translator = new;
// 添加翻译
let mut en_translations = new;
en_translations.insert;
translator.add_translations;
// 添加中文翻译
let mut zh_translations = new;
zh_translations.insert;
translator.add_translations;
// 创建国际化上下文
let mut context = new;
// 使用翻译
let hello = context.t;
// 切换语言
context.set_locale;
let hello_zh = context.t;
使用 Fluent 格式
use ;
use Path;
// 创建 Fluent 翻译提供者
let mut translator = new;
// 从文件加载翻译
let path = new;
translator.add_translations_from_file.unwrap;
// 从字符串加载翻译
let ftl_content = r#"
messages.hello = Hello world!
messages.greeting = Hello, {name}!
messages.apples =
{ $count ->
[one] There is one apple
*[other] There are {count} apples
}
"#;
translator.add_translations_from_string.unwrap;
// 创建国际化上下文
let mut context = new;
// 使用翻译
let hello = context.t;
let greeting = context.t_with_args;
let apples = context.t_with_args;
使用 JSON 格式
use ;
use Path;
// 创建 Fluent 翻译提供者
let mut translator = new;
// 从 JSON 文件加载翻译(需要启用 json 特性)
let path = new;
translator.add_translations_from_file.unwrap;
// 创建国际化上下文
let mut context = new;
// 使用翻译
let hello = context.t;
使用 TOML 格式
use ;
use Path;
// 创建 Fluent 翻译提供者
let mut translator = new;
// 从 TOML 文件加载翻译(需要启用 toml 特性)
let path = new;
translator.add_translations_from_file.unwrap;
// 创建国际化上下文
let mut context = new;
// 使用翻译
let hello = context.t;
使用 YAML 格式
use ;
use Path;
// 创建 Fluent 翻译提供者
let mut translator = new;
// 从 YAML 文件加载翻译(需要启用 yaml 特性)
let path = new;
translator.add_translations_from_file.unwrap;
// 创建国际化上下文
let mut context = new;
// 使用翻译
let hello = context.t;
批量翻译
use ;
use HashMap;
// 创建翻译提供者并添加翻译
let mut translator = new;
let ftl_content = r#"
messages.hello = Hello world!
messages.greeting = Hello, {name}!
messages.bye = Goodbye!
"#;
translator.add_translations_from_string.unwrap;
// 创建国际化上下文
let mut context = new;
// 批量翻译
let mut args = new;
args.insert;
let translations = context.t_batch;
for translation in translations
最佳实践
翻译文件组织
-
推荐结构:
locales/ ├── en.ftl # 英文翻译 ├── zh-CN.ftl # 中文简体翻译 ├── fr.ftl # 法语翻译 └── es.ftl # 西班牙语翻译 -
命名约定:
- 翻译键使用点分隔的命名空间格式(如
messages.hello) - 语言代码使用标准格式(如
en,zh-CN) - 翻译文件使用对应语言代码作为文件名
- 翻译键使用点分隔的命名空间格式(如
性能优化
-
使用缓存:
- 默认缓存容量为 1000,可以根据应用规模调整
- 语言切换时会自动清除缓存
-
资源预加载:
- 应用启动时预加载所有翻译资源
- 避免运行时动态加载翻译文件
-
懒加载:
- 对于大型应用,可以考虑按需加载翻译资源
- 仅加载当前语言和默认语言的翻译
错误处理
-
回退机制:
- 当翻译未找到时,会回退到默认语言
- 当默认语言也没有翻译时,会回退到键本身
-
错误日志:
- 翻译错误会记录到调试日志中
- 不会影响应用正常运行
国际化最佳实践
-
文本提取:
- 使用工具自动提取代码中的文本
- 确保所有用户可见的文本都经过翻译
-
文化适配:
- 考虑不同文化的习惯和偏好
- 避免硬编码日期、时间和数字格式
-
复数形式:
- 使用 Fluent 的复数形式支持
- 不同语言的复数规则可能不同
-
性别形式:
- 使用 Fluent 的性别形式支持
- 考虑不同语言的性别语法差异
常见问题
翻译不显示
-
检查翻译文件:
- 确保翻译文件存在且格式正确
- 确保翻译键与代码中使用的键一致
-
检查语言设置:
- 确保设置了正确的语言代码
- 确保翻译文件包含对应语言的翻译
-
检查特性开关:
- 如果使用 JSON、TOML 或 YAML 格式,确保启用了对应的特性
语言切换不生效
-
检查语言代码:
- 确保使用了正确的语言代码格式
- 确保翻译文件使用了相同的语言代码
-
检查环境变量:
- 全局实例会尝试读取
LANG环境变量 - 可以通过
set_locale函数覆盖环境变量设置
- 全局实例会尝试读取
-
检查缓存:
- 语言切换时会自动清除缓存
- 如果手动管理缓存,确保在语言切换后清除缓存
性能问题
-
检查缓存容量:
- 对于大型应用,考虑增加缓存容量
- 对于小型应用,使用默认缓存容量即可
-
检查翻译文件大小:
- 避免在单个翻译文件中包含过多翻译
- 考虑按模块拆分翻译文件
-
检查加载方式:
- 预加载翻译资源,避免运行时动态加载
- 仅加载必要的语言翻译
示例项目结构
my-app/
├── src/
│ ├── main.rs
│ └── i18n.rs
├── locales/
│ ├── en.ftl
│ ├── zh-CN.ftl
│ └── fr.ftl
└── Cargo.toml
i18n.rs 示例
use ;
use Path;
main.rs 示例
use init_i18n;
use ;
许可证
MIT