1 个不稳定版本
新版本 0.1.0 | 2024年8月14日 |
---|
#129 在 国际化(i18n)
120 每月下载量
在 easy-imgui-filechooser 中使用
30KB
709 行
include-po
一个crate,用于将gettext信息目录(PO文件)直接包含到您的Rust程序中,作为可编译的Rust模块。
与tr
crate一起使用。
如果您想使用不同的翻译引擎,只需提交一个问题或pull request,我会尽力而为。
阅读文档以获取详细信息。
lib.rs
:
这个crate包含解析PO文件(gettext信息目录)并在Rust中使用它们的函数。
主要用途
推荐的使用方法是使用它来构建一个包含翻译的Rust模块。
首先将您的PO文件构建到项目根目录下的locales
目录中。
然后在这个crate中将其作为[build-dependencies]
,并将tr
作为一个常规依赖项:在您的Cargo.toml
[dev-dependencies]
include-po = "0.1"
[dependencies]
tr = { version = "0.1.10", default-features = false }
编写一个build.rs
脚本
fn main() {
let output_dir = std::env::var("OUT_DIR").unwrap();
let out = std::path::PathBuf::from(&output_dir).join("locale/translators.rs");
include_po::generate_locales_from_dir("locales", out).unwrap();
}
并在您的main.rs
或lib.rs
中
include!(concat!(env!("OUT_DIR"), "/locale/translators.rs"));
这就对了!现在您可以通过调用translators::set_locale("es");
来切换到西班牙语!
如果您正在编写一个lib crate,按照惯例,您应该在根命名空间中有一个公共函数
fn set_locale(locale: &str) {
translators::set_locale(locale);
}
这样您就可以链式调用多个可翻译库的locale。
其他函数
如果您喜欢自己进行翻译,您也可以使用这个crate来解析PO文件并获取消息。但请注意,目前消息将不会被转义,即一个"将是一个'\n'等等。
为什么是PO而不是MO?
大多数基于gettext的解决方案都从MO文件中读取信息目录,而不是从PO中。一个MO文件是一个编译后的信息目录。原始gettext使用MO文件的原因是为了优化启动时间:当gettext
库想要使用一个MO时,它只需定位文件,打开它并对其进行内存映射。它所做的解析非常少,因为一切都是为了从该内存映射中使用而设计的。它甚至包含一个预计算的哈希表!
在Rust中,我觉得没有必要将MO文件与可执行文件分开分发。有些人尝试使用include_bytes!
,然后将二进制数据解析到BTreeMap
中……但这最初就违背了MO存在的目的。
如果你打算将消息目录嵌入到可执行文件中,你不妨将其完全作为代码包含:消息目录再次是内存映射的(就像大多数可执行代码一样),并且运行时无需解析。但如果你打算在构建时解析目录并将其转换为Rust,为什么读MO而不是更简单且节省编译步骤的PO呢?
但是,关于哈希表,你可能想知道……好吧,目前这个crate正在为每个源PO文件构建一个巨大的match字符串
。这似乎足够好了,但如果需要,我们可以透明地将其升级到一个更聪明的算法。我的希望是,编译器生成的代码会比这个crate的需求更快地变得更好。
依赖项
~1.1–1.8MB
~37K SLoC