longbridgeapp / rust-i18n

A better and simply I18n crate for Rust.
MIT License
321 stars 32 forks source link

Now only the first time is i18n #87

Closed yk0n9 closed 3 months ago

yk0n9 commented 3 months ago

my code:

rust_i18n::i18n!("locales");

fn main() {
    rust_i18n::set_locale("zh-CN");
    for _ in 0..5 {
        show_message(t!("ok"), t!("hello"));
        thread::sleep(Duration::from_secs(1));
    }
}

fn show_message(title: impl AsRef<str>, message: impl AsRef<str>) {
    rfd::MessageDialog::new()
        .set_title(title.as_ref())
        .set_description(message.as_ref())
        .show();
}

zh-CN.yaml

ok: "好的"
hello: "你好 世界"

en-US.yaml

ok: "OK"
hello: "Hello World"

first time image second time image

It can be found that even the first call will not be fully i18n The second or subsequent calls will never find the yaml content

yk0n9 commented 3 months ago

windows 11 rustc 1.80.1 rust-i18n 3.1.1

KKRainbow commented 3 months ago

this issue is casued by following path:

  1. I18nConfig has a default value "en" on default_locale
  2. lib.rs: load_metadata will use this default value when init Args. which make Args::default_locale always be Some("xxx")
  3. when default_locale is Some(x), the rust_i18n::i18n! macro always call rust_i18n::set_locale(#default_locale); during init _RUST_I18N_BACKEND.
  4. _RUST_I18N_BACKEND is lazily inited until the first call of t!() macro, and overwrite original value set by rust_i18n::set_locale.

for a workaround, just call t!() before set_locale.

for bugfix, i think when init default_locale, should check if set_locale is already called.