fluent-templates icon indicating copy to clipboard operation
fluent-templates copied to clipboard

Compile time i18n macro

Open XAMPPRocky opened this issue 1 year ago • 5 comments

Discussed in https://github.com/XAMPPRocky/fluent-templates/discussions/52

Originally posted by patefacio September 5, 2023 For compile-time support is it possible to get a compile error when compiling if the lookup fails? I tried cargo-i18n with i18n-embed and in that setup a mispelling will trigger a compile error. My issue with that setup was I could not figure out how to make it work in wasm. This project works just fine in wasm but the forced breakage at compile time would be great.

assert_eq!("Hello World!", LOCALES.lookup(&US_ENGLISH, "hello-world-ooops"));

Thank you for question! I think this should be possible if implemented as procedural macro. I don't have much time to work on this at the moment, but I'd be happy to review a PR for it. We already have a macro crate, so what would work would be to add a new macro similar to the existing one, but that uses the ArcLoader to load localisations into the macro itself, and then provides a panic message when it's not found using a separate lookup macro.

XAMPPRocky avatar Sep 07 '23 08:09 XAMPPRocky

My issue with that setup was I could not figure out how to make it work in wasm.

There is no special treatment needed for fluent-templates targetting wasm, see leptos-fluent.

mondeja avatar Mar 07 '24 14:03 mondeja

I've just started using Fluent in a project, and thought of a similar way to get compile-time checking. If we generate helper functions for every message, we can also check the variables (and get autocomplete, maybe?).

For example:

# This .ftl file
issue-control-conflict-summary =
    Control Input '{ $input-name }' on Processing Object '{ $po-display-name }' has conflicting inputs
issue-control-conflict-details =
    Driving a Control Input with more than one signal can cause fighting.

would generate

mod tr {
    use std::collections::HashMap;

    use fluent::FluentValue;
    use fluent_templates::Loader;
    use unic_langid::LanguageIdentifier;

    pub fn issue_control_conflict_summary(
        lang: &LanguageIdentifier,
        input_name: FluentValue<'_>,
        po_display_name: FluentValue<'_>,
    ) -> Option<String> {
        let mut args = HashMap::with_capacity(2);
        args.insert("input-name", input_name);
        args.insert("po-display-name", po_display_name);

        super::LOCALES.try_lookup_with_args(lang, "issue-control-conflict-summary", &args)
    }

    pub fn issue_control_conflict_details(lang: &LanguageIdentifier) -> Option<String> {
        super::LOCALES.try_lookup(lang, "issue-control-conflict-details")
    }
}

I presume somebody has thought of this before, but has anybody implemented it?

joshchngs avatar Mar 20 '24 11:03 joshchngs