kellpossible / cargo-i18n

A Rust Cargo sub-command and libraries to extract and build localization resources to embed in your application/library
MIT License
121 stars 25 forks source link

Builtins `NUMBER()` not working #107

Closed Weasy666 closed 1 year ago

Weasy666 commented 1 year ago

Hello! I really like how easy to use the fluent system is with your i18n-embed-fl crate. But i ran into an issue and am not sure if i am doing something wrong. I want to use a localization string like flight-time = Flight time: {NUMBER($time, maximumFractionDigits: 1)} h with the below minimal example:

use i18n_embed::{
    fluent::{fluent_language_loader, FluentLanguageLoader},
    LanguageLoader
};
use i18n_embed_fl::fl;
use rust_embed::RustEmbed;
use unic_langid::LanguageIdentifier;

#[derive(RustEmbed)]
#[folder = "assets/locales"]
struct Localizations;

pub struct FluentLocales {
    pub loader: FluentLanguageLoader,
}

impl FluentLocales {
    pub fn new() -> FluentLocales {
        let loader: FluentLanguageLoader = fluent_language_loader!();
        loader.load_available_languages(&Localizations).unwrap();
        println!("Found locales: {:?}", loader.available_languages(&Localizations).unwrap());

        let locales = FluentLocales { loader };

        //INFO: does somehow not work, so we are setting the lang manually
        let requested_languages = i18n_embed::DesktopLanguageRequester::requested_languages();
        println!("System langs: {:?}", requested_languages);
        locales.select_langs(&vec!["de-DE".parse().unwrap(), "en-US".parse().unwrap()]);

        locales
    }

    pub fn select_lang(&self, lang: LanguageIdentifier) {
        self.select_langs(&vec![lang]);
    }

    pub fn select_langs(&self, langs: &[LanguageIdentifier]) {
        i18n_embed::select(&self.loader, &Localizations, langs).unwrap();
    }
}

fn main() {
    let locales = FluentLocales::new();
    let flight_time = fl!(&locales.loader, "flight-time", time=0.3512);

    println!("{}", flight_time);
}

I'd expect to get a printed message that looks like Flight time: 0.4 h, but instead it prints Flight time: {NUMBER()}⁩ h and also logs this error:

i18n_embed::fluent: Failed to format a message for language "de-DE" and id "flight-time".
Errors
[ResolverError(Reference(Function { id: "NUMBER" }))].

Am i doing something wrong, or are builtins not supported right now?

kellpossible commented 1 year ago

@Weasy666 I haven't used the built-in functions before, perhaps this is related to https://github.com/projectfluent/fluent-rs/issues/313 ?

Perhaps built-in functions aren't available in fluent-rs yet, I wonder?

It looks like it should be possible to specify our own using https://docs.rs/fluent/latest/fluent/bundle/struct.FluentBundle.html#method.add_function

kellpossible commented 1 year ago

Perhaps they were never implemented as per https://github.com/projectfluent/fluent-rs/issues/19#issuecomment-466160940

Weasy666 commented 1 year ago

Oh...looks like you are right. That's a shame, but then that's not exactly a problem or bug of this crate. Should we just close the issue then?

kellpossible commented 1 year ago

@Weasy666 no worries! Yeah I guess we'll close this for now, it really would be nice to have. I think it should be possible to implement something similar yourself using with_bundles_mut()