#fluent #localization #generate-static

fluent-static-codegen

自动从 Fluent 消息文件生成 Rust 函数,以简化 Rust 应用程序中的本地化

12 个版本 (4 个破坏性更新)

新版本 0.5.0 2024 年 8 月 19 日
0.4.1 2024 年 8 月 16 日
0.3.2 2024 年 8 月 8 日
0.2.4 2024 年 6 月 6 日
0.1.0 2024 年 5 月 24 日

#189 in 国际化(i18n)

Download history 212/week @ 2024-05-20 181/week @ 2024-05-27 392/week @ 2024-06-03 18/week @ 2024-06-10 605/week @ 2024-08-05 216/week @ 2024-08-12

每月 821 次下载

MIT 许可证

66KB
1.5K SLoC

fluent-static-codegen

fluent-static 库的一部分,负责从 Fluent 资源生成 Rust 代码。

该项目大量依赖 fluent-rs 来解析和处理 Fluent 资源。

用法

Fluent 资源

代码生成器要求 Fluent 资源遵守命名约定:<l10n_root>/<language_id>/<bundle_name>

Cargo 依赖项

fluent-static-codegen 添加到项目的 build-dependencies 部分

[build-dependencies]
fluent-static-codegen = "*"

构建脚本

fluent-static-codegen 需要 Cargo Build Script 才能运行。


use fluent_static_codegen::{generate, FunctionPerMessageCodeGenerator};
use std::{env, fs, path::Path};

pub fn main() {
    generate!("./l10n/", FunctionPerMessageCodeGenerator::new("en-US"), "l10n");
}
  

代码生成

生成的代码命名约定

  • 将 Fluent 消息名称转换为 Rust snake_cased 标识符
    • my-message -> my_message
    • msgTest -> msg_test
    • msg1 -> msg_1
  • 也将 Fluent 消息变量映射到 snake_cased 标识符
  • 将 Fluent 消息属性映射到 <message_name>_<attribute_name>
    • my-button.title -> my_button_title

将 Fluent 消息映射到函数

fluent_static_codegen::FunctionPerMessageCodeGenerator 为每个 message_bundle 生成模块并将消息映射到函数

pub mod <bundle_name> {
    use fluent_static::fluent_bundle::{FluentValue, FluentError};
    use fluent_static::Message;

    pub fn <fluent_message_no_args>(language_id: impl AsRef<str>) -> Message {
    }

    pub fn <fluent_message_with_args>(language_id: impl AsRef<str>, var1: impl Into<FluentValue>>, ...) -> Result<Message, FluentError> {
    }
}

将 Fluent 消息映射到方法

fluent_static_codegen::FunctionPerMessageCodeGenerator 为每个 message_bundle 生成结构体,并将消息映射到该结构体的公共方法。

pub mod <bundle_name>
    use fluent_static::fluent_bundle::{FluentValue, FluentError};
    use fluent_static::Message;

    pub struct <BundleName>Bundle {
    }

    impl <BundleName>Bundle {
        pub fn all_languages() -> &'static [&'static str] {
        }

        pub fn current_language(&self) -> &LanguageSpec {
        }

        pub fn <fluent_message_no_args>(&self) -> Message {
        }

        pub fn <fluent_message_some_args>(&self, name: impl Into<FluentValue>, ...) -> Result<Message, FluentError> {
        }
    }
}  

设置 FluentBundle 选项

    let generator = FunctionPerMessageCodeGenerator::new_with_options(
        "en",
        FluentBundleOptions {
            use_isolating: false,
            transform_fn: Some("crate::util::fluent_value_transformer".to_string()),
            format_fn: Some("crate::util::fluent_formatter".to_string()),
        },
    );
    generate!("./l10n/", generator, "l10n");

编译时验证

以下条件在编译时进行验证,以确保 bundle_name 中的每个消息都正确定义

  1. 消息必须在所有受支持的语言中定义。
  2. 所有消息实例必须共享相同的一组变量(如果有变量存在)。
  3. 消息属性必须在所有语言中保持一致。

如果这些条件中的任何一个不满足,将引发编译时错误,确保不同语言实现之间的一致性和正确性。

贡献

欢迎贡献!请随时通过问题跟踪器提交拉取请求、报告错误和提出功能建议。

许可协议

本项目采用 MIT 许可协议。您可以根据许可协议条件自由使用、修改和分发。


依赖项

~3.5MB
~68K SLoC