Skip to content

An idea to leverage the type and macro system #36

Open
@Thomasdezeeuw

Description

@Thomasdezeeuw

This is an idea that I had that leverages the Rust type system and macro system, rather then using stringly-typed arguments (well sort of). It's inspired by Diesel.

First the client that the user has to write:

translate_module!("/path/to/translation/files");

translate!(English, "hello-world");
translate!(Dutch, "intro", "Thomas");

(I know it's still looks stringly-typed, but under the hood it isn't).

The translate_module will create a new module based on the provided directory. The only (public) API this will define is the translate macro, which has the following API:

macro_rules! translate {
    ($lang:tt, $msg:expr, $($arg:tt)*) => { ... };
}

It takes a Language item (will get back to that), a message (just like MessageContext.get_message now) and optional arguments used to format the message (like MessageContext.format).

Now to use Rust's type system. First we'll start off by generating an index or hash for each available translation message, something like:

const _TRANSLATE_HELLO_WORLD: usize = 0;
const _TRANSLATE_INTO: usize = 1;

And the message in an array or a hash map, for each language:

// This could also be hash maps or something.
_TRANSLATIONS_ENGLISH: [&'static str; 2] = ["Hello, world!", "Welcome, { $name }."];
_TRANSLATIONS_DUTCH: [&'static str; 2] = ["Hallo, wereld!", "Welkom, { $name }."];

We can check at compile time if the index/hash and message exists and if not fail the compilation. The Language item provided to translate will define what array/hash map to used, e.g. _TRANSLATIONS_DUTCH for Dutch.

Next for the formatting we'll have a single function inside ether the fluent crate or the generated module, to which the translation string and the other provided arguments to format the message gets passed. Something like this:

// translate!(English, "hello-world") translates into:
translate(_TRANSLATIONS_ENGLISH[_TRANSLATE_HELLO_WORLD])
// translate!(Dutch, "intro", "Thomas")
translate(_TRANSLATIONS_DUTCH[_TRANSLATE_INTO], "Thomas")

Looking forward to a reply, although I don't expect it very soon it got quite long.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementhelp wantedWe need help making decisions or writing PRs for this.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions