longbridgeapp / rust-i18n

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

support _rust_i18n_translate in extractor #52

Closed PingPongun closed 12 months ago

PingPongun commented 1 year ago

Currently, extractor supports only extracting from t!(...) placed directly in text. However sometimes it is more convenient to not place t!() calls directly in text, but rather use some macros, that would expand to/generate t!() calls. This requires either i18n understand & be able to expand macros or using some other tool that would expand macros prior i18n (i.e. cargo-expand). The problem is that cargo-expand expands all macros also t!() to _rust_i18n_translate() call (which are not recognized by extractor). This PR enables extracting also from _rust_i18n_translate() calls.

huacnlee commented 1 year ago

_rust_i18n_translate is an internal method, so I named it with started with _.

By this reason, we don't need to handle this, because this not a right way.

PingPongun commented 1 year ago

OK. Could you maybe give me a hint how to make this crate work effortlessly with enum's in right way? Let's assume I have enum/what I have currently:

#[derive(AsI18NStr)]
pub enum TabName {
    Mods = 0,
    Downloads,
    Settings,
    About,
}

where I intend macro #[derive(AsI18NStr)] to expand to sth like this:

impl TabName{
  pub fn to_i18n_string(&self) -> String {
            match *self {
                TabName::Mods => t!( "TabName.Mods" ),
                TabName::Downloads=> t!( "TabName.Downloads" ),
                TabName::Settings=> t!( "TabName.Settings" ),
                TabName::About=> t!( "TabName.About" ),
            }
        }
}

so when I have enum value I can simply display translated text:

let tab = TabName::About;
println!("{}", tab.to_i18n_string() )

But problem is that rust-i18n does not find t!() that is "hidden" beyond macro (as in first code snippet). My solution was to use cargo-expand, and call rust-i18n over expanded file:

cargo expand | out-file translate/expanded.rs -encoding utf8
cargo i18n ./translate

but cargo-expand also expands t!() macro so in expanded.rs I get:

impl TabName {
        pub fn to_i18n_string(&self) -> String {
            match *self {
                TabName::Mods => {
                    crate::_rust_i18n_translate(
                        rust_i18n::locale().as_str(),
                        "menu.TabName.Mods",
                    )
                }
[...]

Which is not recognized by rust-i18n (until this PR). I don't have another idea how to achieve i18n working with enum's without adding many code to each enum type.