# `i18n_langid_codegen` Crates.io version Function-like proc macro for internationalization Generates structs and functions from a set of YAML files with support for the [`unic-langid` crate](https://crates.io/crates/unic-langid). Inspired by [`i18n_codegen` crate](https://crates.io/crates/i18n_codegen). > **Disclaimer** > > This is my first macro, could contain bugs. > Feel free to suggest improvements. ## How to use it? Your YAML files: ```yaml # locales/en.default.yml hello: Hello World! # locales/de.yml hello: Hallo Welt! ``` Your Rust code: ```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); } ``` ## Full Example ### Add dependencies ```shell cargo add unic_langid --features macros cargo add i18n_langid_codegen ``` ### Add macro call to your code ```rust mod i18n { i18n_langid_codegen::i18n!("locales"); } ``` ### Files Consider the following file tree. ``` ├── ... ├── Cargo.toml ├── locales │ ├── de.yml │ └── en.default.yml ├── src │ └── ... └── ... ``` Content of `locales/en.default.yml`: ```yaml hello: Hello World! login_form: email: Email password: Password button: Log In ``` Content of `locales/de.yml`: ```yaml 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. ### What the `i18n` macro generates ```rust #[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 { 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() } } ```