#proc-macro #localization

i18n_langid_codegen

类似函数的国际化 proc 宏

2 个版本

0.1.1 2023年4月16日
0.1.0 2023年4月15日

#164 in 国际化 (i18n)

每月 35 次下载

MIT 许可证

13KB
200

i18n_langid_codegen

Crates.io version

类似函数的国际化 proc 宏

从一组 YAML 文件生成结构和函数,支持 unic-langid crate

i18n_codegen crate 启发。

免责声明

这是我的第一个宏,可能包含错误。欢迎提出改进意见。

如何使用它?

您的 YAML 文件

# locales/en.default.yml
hello: Hello World!

# locales/de.yml
hello: Hallo Welt!

您的 Rust 代码

mod i18n {
    i18n_langid_codegen::i18n!("locales");
}

fn main() {
    // Get single key
    assert_eq!("Hello World!", i18n::I18n::en().hello);
    assert_eq!("Hallo Welt!", i18n::I18n::de().hello);
    
    // Get the right struct instance by language identifier
    let id = unic_langid::langid!("de");
    let de = I18n::from_lang_id(id).unwrap_or_default();
    assert_eq!("Hallo Welt!", de.hello);
}

完整示例

添加依赖项

cargo add unic_langid --features macros
cargo add i18n_langid_codegen

将宏调用添加到您的代码中

mod i18n {
    i18n_langid_codegen::i18n!("locales");
}

文件

考虑以下文件结构。

├── ...
├── Cargo.toml
├── locales
│   ├── de.yml
│   └── en.default.yml
├── src
│   └── ...
└── ...

locales/en.default.yml 的内容

hello: Hello World!
login_form:
    email: Email
    password: Password
    button: Log In

locales/de.yml 的内容

hello: Hallo Welt!
login_form:
    password: Passwort
    button: Anmelden

注意,login_form.email 未包含在德语翻译中。在这种情况下,使用以 .default.yml 结尾的文件中的值。

i18n 宏生成的代码

#[derive(Debug)]
pub struct I18n {
    pub lang_id: unic_langid::LanguageIdentifier,
    pub hello: &'static str,
    pub login_form: LoginForm,
}

#[derive(Debug)]
pub struct LoginForm {
    pub email: &'static str,
    pub password: &'static str,
    pub button: &'static str,
}

impl I18n {
    pub fn from_lang_id(
        lang_id: &unic_langid::LanguageIdentifier,
    ) -> Option<Self> {
        match lang_id.to_string().as_str() {
            "en" => Some(Self::en()),
            "de" => Some(Self::de()),
            _ => None,
        }
    }

    pub fn en() -> Self {
        Self {
            lang_id: unic_langid::LanguageIdentifier::from_str("en").unwrap(),
            hello: "Hello World!",
            login_form: LoginForm {
                email: "Email",
                password: "Password",
                button: "Log In",
            },
        }
    }

    pub fn de() -> Self {
        Self {
            lang_id: unic_langid::LanguageIdentifier::from_str("de").unwrap(),
            hello: "Hallo Welt!",
            login_form: LoginForm {
                email: "Email",
                password: "Passwort",
                button: "Anmelden",
            },
        }
    }
}

impl Default for I18n {
    fn default() -> Self {
        Self::en()
    }
}

依赖项

~4MB
~80K SLoC