From 5f3336ca2a0905d24977dc4e7313bed04087209d Mon Sep 17 00:00:00 2001 From: Lennart Kloock Date: Sat, 15 Apr 2023 22:13:46 +0200 Subject: [PATCH] Add .editorconfig, README.md, TODO.md and configure cargo package --- .editorconfig | 16 ++++++ Cargo.toml | 7 +++ README.md | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++ TODO.md | 3 + 4 files changed, 179 insertions(+) create mode 100644 .editorconfig create mode 100644 README.md create mode 100644 TODO.md diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..5094adc --- /dev/null +++ b/.editorconfig @@ -0,0 +1,16 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = false +max_line_length = 120 +tab_width = 4 + +[*.rs] +max_line_length = 100 + +[{*.apinotes,*.yaml,*.yml,.clang-format,.clang-tidy,_clang-format}] +indent_size = 2 diff --git a/Cargo.toml b/Cargo.toml index c18fdc2..7b8e8e5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,13 @@ name = "i18n_langid_codegen" version = "0.1.0" edition = "2021" +license = "MIT" +authors = ["Lennart Kloock "] +description = "Function-like proc macro for internationalization" +repository = "https://github.com/lennartkloock/i18n_langid_codegen" +keywords = ["proc-macro", "i18n", "internationalization"] +categories = ["internationalization", "localization"] +readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..9f9239b --- /dev/null +++ b/README.md @@ -0,0 +1,153 @@ +# `i18n_langid_codegen` + +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). + +## 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 +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() + } +} +``` diff --git a/TODO.md b/TODO.md new file mode 100644 index 0000000..2ca17d1 --- /dev/null +++ b/TODO.md @@ -0,0 +1,3 @@ +# TODOs + +- Improve documentation and README file