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

Is this broken with Gettext? #92

Closed ctrlcctrlv closed 2 years ago

ctrlcctrlv commented 2 years ago
pub extern crate tr;
extern crate i18n_embed;
extern crate rust_embed;
extern crate gettext;

use self::i18n_embed::{DesktopLanguageRequester, gettext::{
    gettext_language_loader
}};
use self::rust_embed::{RustEmbed};
use self::gettext::Catalog;

#[derive(RustEmbed)]
#[folder = "i18n/mo"]
struct Localizations;

use std::borrow::Borrow;

use i18n::gettext::i18n_embed::LanguageLoader;

pub fn i18n_init() {
    let language_loader = gettext_language_loader!();
    let requested_languages = DesktopLanguageRequester::requested_languages();
    eprintln!("{:?}", requested_languages);
    let _result = i18n_embed::select(
        &language_loader, &Localizations, &requested_languages);
    if let Some(mut f) = language_loader.language_file(&requested_languages[0], &Localizations).1 {
        tr::set_translator!(Catalog::parse(&f.to_mut()[..]).unwrap());
    };
}

Returns

$ LANGUAGE=ja LC_ALL=ja_JP.UTF-8 target/release/tripcode -h
[LanguageIdentifier { language: Language(Some("ja")), script: None, region: Some(Region("JP")), variants: None }]
Usage: tripcode [options] [--] [passwords]

Options:
    -t, --type {4[chan]|2[ch]|s[c]}
                        specify the type of tripcodes. defaults to `4chan`
    -f, --filter        read passwords from standard input
    -h, --help          print this help message and exit
    -p, --password      print passwords along with tripcodes

No clue what else I can do.

ctrlcctrlv commented 2 years ago

This library is very difficult to use but I figured it out.

$ LANGUAGE=ja_JP.UTF-8 LC_ALL=ja_JP.UTF-8 target/debug/tripcode -h
使用法: tripcode [設定] [--] [トリップキー (パスワード)]

設定一覧
    -t, --type {4[chan]|2[ch]|s[c]}
                        トリップコードの種類を設定。初期値は `4chan`
    -f, --filter        標準入力からパスワードを読み取る
    -h, --help          この文を表示し、終了
    -p, --password      トリップキーとトリップコードを標準出力する

bin/src/i18n/gettext.rs

pub extern crate tr;
pub extern crate i18n_embed;

use rust_embed::{RustEmbed};

#[derive(Debug, RustEmbed)]
#[folder = "i18n/mo"]
pub struct Localizations;

#[macro_export]
macro_rules! i18n_init {
    () => {
        let requested_languages = $crate::i18n_embed::DesktopLanguageRequester::requested_languages();
        let language_loader = $crate::i18n_embed::gettext::gettext_language_loader!();
        let _result = $crate::i18n_embed::select(
            &language_loader, &$crate::i18n::Localizations, &requested_languages);
    }
}

bin/src/i18n/mod.rs

#[cfg(feature = "i18n")]
#[macro_use]
mod gettext;
#[cfg(not(feature = "i18n"))]
#[macro_use]
mod gettext {
    #[macro_export]
    macro_rules! tr {
        ($($arg:expr),*) => ($($arg),*);
    }
    #[macro_export]
    macro_rules! i18n_init {
        () => {}
    }
}

pub use self::gettext::*;
#[cfg(feature = "i18n")]
pub use self::gettext::tr::tr;

bin/src/main.rs

#[cfg(feature = "i18n")]
use i18n_embed;

mod i18n;
#[cfg(feature = "i18n")]
use i18n::tr; // otherwise, i18n null mod puts a noop tr!() into crate root
…

fn main() {
    i18n_init!();
…

To be charitable it seems like its developers included gettext only to be able to interact with C libraries that use it already, not for new projects wanting to use it from Rust but allow it to be disabled. Thus you have to hack quite a bit, it sets the module wrong when you do not.