Function-like proc macro for internationalization
Generates structs and functions from a set of YAML files with support for
the unic-langid
crate.
Inspired by i18n_codegen
crate.
Disclaimer
This is my first macro, could contain bugs. Feel free to suggest improvements.
Your YAML files:
# locales/en.default.yml
hello: Hello World!
# locales/de.yml
hello: Hallo Welt!
Your Rust code:
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");
}
Consider the following file tree.
├── ...
├── Cargo.toml
├── locales
│ ├── de.yml
│ └── en.default.yml
├── src
│ └── ...
└── ...
Content of locales/en.default.yml
:
hello: Hello World!
login_form:
email: Email
password: Password
button: Log In
Content of locales/de.yml
:
hello: Hallo Welt!
login_form:
password: Passwort
button: Anmelden
Note that login_form.email
is not included in the German translation. In this case the value from the file ending
in .default.yml
is used.
#[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()
}
}