[][src]Crate i18n_codegen

Internationalization library based on code generation.

By leveraging code generation we are able to prevent common bugs like typos in i18n keys, missing interpolations, or various mistakes between locales.

It requires a directory with one JSON file per locale. Here is an example with English and Danish translations:

// tests/doc_locales/en.json
{
    "hello_world": "Hello, World!",
    "greeting": "Hello {name}"
}

// tests/doc_locales/da.json
{
    "hello_world": "Hej, Verden!",
    "greeting": "Hej {name}"
}

And in Rust:

use i18n_codegen::i18n;

i18n!("tests/doc_locales");

fn main() {
    assert_eq!("Hello, World!", Locale::En.hello_world());
    assert_eq!("Hej, Verden!", Locale::Da.hello_world());

    assert_eq!("Hello Bob", Locale::En.greeting(Name("Bob")));
    assert_eq!("Hej Bob", Locale::Da.greeting(Name("Bob")));
}

What gets generated?

This is what gets generated for the example above:

// Locale enum with variant for each JSON file
#[derive(Copy, Clone, Debug)]
pub enum Locale {
    En,
    Da,
}

impl Locale {
    // Each string in the locale files becomes a method on `Locale`
    pub fn hello_world(self) -> String {
        match self {
            Locale::Da => format!("Hej, Verden!"),
            Locale::En => format!("Hello, World!"),
        }
    }

    // Placeholders in strings become arguments to the methods.
    // For strings with multiple placeholders they must be provided in
    // alphabetical order.
    pub fn greeting(self, name_: Name<'_>) -> String {
        match self {
            Locale::Da => format!("Hej {name}", name = name_.0),
            Locale::En => format!("Hello {name}", name = name_.0),
        }
    }
}

// A placeholder for strings such as `"Hello {name}"`.
pub struct Name<'a>(pub &'a str);

fn main() {
    assert_eq!("Hello, World!", Locale::En.hello_world());
    assert_eq!("Hej, Verden!", Locale::Da.hello_world());

    assert_eq!("Hello Bob", Locale::En.greeting(Name("Bob")));
    assert_eq!("Hej Bob", Locale::Da.greeting(Name("Bob")));
}

It expects all the JSON keys to be lowercase and will replace - and . with _.

You can set the environment variable I18N_CODE_GEN_DEBUG to 1 to have the generated code printed during compilation. For example: I18N_CODE_GEN_DEBUG=1 cargo build.

Customizing placeholders

By default it will assume you use { and } for placeholders such as "Hello {name}". That can be customized like so:

i18n!("tests/locales_with_different_placeholders", open: "%{", close: "}");

There is currently no support for escaping placeholders.

Macros

i18n

See root module for more info.