-
Notifications
You must be signed in to change notification settings - Fork 97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
An idea to leverage the type and macro system #36
Comments
I like the idea that we'd have compile-time checks for string errors. I wonder if you could extend your ideas here for a couple of things: For one, we'll need named arguments for fluent. So, instead of passing in "Thomas", we need to pass in {"name":"Thomas"} in some sort. Looking at examples/external_arguments.rs in this repo, I wonder if there's rustanian syntax sugar to make that easier on the eye. Being able to catch errors between the message and the arguments at compile time would be awesome. The next challenge I'd like to put out is language switching. Could you pass a commandline argumet to your code to select a particular language? ./foopy -lang=nl vs ./foopy -lang=en ? And then we'll want language fallback at runtime. If a Dutch string doesn't exist, try the English one. We've learned the hard way that getting all strings in all languages isn't realistic, and that users prefer partial translation to all-English. |
For the named arguments maybe we can use something like As for the language switching my first though was something like an enum As for a fallback language I would against it. I've had to deal with partially translated applications and there more annoying to work with then properly translated all English applications. But I agree that in big applications it might be hard to translate everything. The easiest solution I can think of right now would be copying over the English (or fallback language) into the translate (in the case Dutch) one. |
That would require us to annotate each string with the language it's in in order to use the correct Plural Rules, DateTimeFormat, NumberFormat etc. It would also make MessageContext's basically multilingual after such merge. Fluent made a design decision to rather go for lazy fallback chains, and I think we should try to apply it to Rust if possible. |
As far as I understand it, the stringly-typed API allows us to think of I like the ideas here for improving the experience of Rust developers. In particular, the
|
Given that Macros 1.2 is now stablized, I have a slightly different proposal based on module attributes as proc macros. This will be like: #[translate_module(path = "/translate/files")]
mod whatever_code; Ideally it should be crate global, but that's currently not possible (rust-lang/rust#41430). |
I only just spotted this today, I recently implemented a similar idea in this crate: https://crates.io/crates/i18n-embed-fl for anyone interested. |
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:
(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 thetranslate
macro, which has the following API:It takes a
Language
item (will get back to that), a message (just likeMessageContext.get_message
now) and optional arguments used to format the message (likeMessageContext.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:
And the message in an array or a hash map, for each language:
We can check at compile time if the index/hash and message exists and if not fail the compilation. The
Language
item provided totranslate
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:
Looking forward to a reply, although I don't expect it very soon it got quite long.
The text was updated successfully, but these errors were encountered: