educative.io

Rust - Why dont work the output on windows?

Hello,
build a hello world with gettext-ng
so that show the output dependent on LANG Variable

but this did not work on Windows… why ?

The *.mo files are in the same diretory

de_DE.UTF-8.mo
en_US.UTF-8.mo
fr_FR.UTF-8.mo

Linux

$ export RUST_BACKTRACE=full

$ ./hello_world
Filename: en_US.UTF-8.mo
Hello World!

Windows

C:\Users\admin\Desktop\hello_world>set RUST_BACKTRACE=full

C:\Users\admin\Desktop\hello_world>hello_world.exe
thread ‘main’ panicked at ‘called Result::unwrap() on an Err value: NotPresent’, src/main.rs:4:43
stack backtrace:
0: 0x7ff78c054ee2 -
1: 0x7ff78c017d6b -
2: 0x7ff78c031957 -
3: 0x7ff78c05842d -
4: 0x7ff78c0581ca -
5: 0x7ff78c058974 -
6: 0x7ff78c05859e -
7: 0x7ff78c0584f9 -
8: 0x7ff78c0584e4 -
9: 0x7ff78c016ce5 -
10: 0x7ff78c0184d3 -
11: 0x7ff78c0158d4 -
12: 0x7ff78c0116d0 -
13: 0x7ff78c015d03 -
14: 0x7ff78c0113ae -
15: 0x7ff78c0114e6 -
16: 0x7ffdaf707034 -
17: 0x7ffdb0b426a1 -

cargo new hello_world
cd hello_world
cargo add gettext-ng

cargo.toml

[profile.release]
opt-level = ‘z’ # Optimize for size
lto = true # Enable link-time optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations
panic = ‘abort’ # Abort on panic
strip = true # Strip symbols from binary*

vi src/main.rs

use std::fs::File;
use gettext_ng::Catalog;
fn main() {
let lang_code = std::env::var(“LANG”).unwrap();
let filename = format!("{}.mo", lang_code);
let f = File::open(filename).expect(“could not open the catalog”);
let catalog = Catalog::parse(f).expect(“could not parse the catalog”);

// Will print out the French translation
// if it is found in the parsed file
// or "Name" otherwise.
println!("{}", catalog.gettext("Name"));

}

vi en_US.UTF-8.po

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2023-09-08 21:39+0200\n"
"Last-Translator: developer <developer@w541>\n"
"Language-Team: English\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Name"
msgstr "Hello World!"

vi de_DE.UTF-8.po

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2023-09-08 21:46+0200\n"
"Last-Translator: developer <developer@w541>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Name"
msgstr "Hallo Welt!"

vi fr_FR.UTF-8.po

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2023-09-08 21:34+0200\n"
"Last-Translator: developer <developer@w541>\n"
"Language-Team: French <traduc@traduc.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "Name"
msgstr "Bonjour le monde!"

msgfmt en_US.UTF-8.po -o en_US.UTF-8.mo
msgfmt de_DE.UTF-8.po -o de_DE.UTF-8.mo
msgfmt fr_FR.UTF-8.po -o fr_FR.UTF-8.mo

cargo run

export LANG=de_DE.UTF-8

cargo run

export LANG=fr_FR.UTF-8

cargo run

build for windows

cargo build --target x86_64-pc-windows-gnu --release

build for linux

cargo build --release

Hi @DS2k5 !!
The issue might be related to the way Windows handles environment variables or file paths differently than Linux.

Here are a few things to consider when running your Rust application on Windows:

  1. Environment Variables:

    • Windows uses a different syntax for environment variables. Instead of export LANG=de_DE.UTF-8, you should use set LANG=de_DE.UTF-8. So, your commands should look like this on Windows:
      set LANG=de_DE.UTF-8
      cargo run
      
  2. File Paths:

    • Windows uses backslashes \ as path separators, while Linux uses forward slashes /. Make sure your file paths in the code are constructed correctly for Windows. You may need to replace forward slashes with backslashes when creating file paths.
    • Additionally, Windows file systems are case-insensitive but case-preserving. Ensure that the file names and paths match the case of the actual files on disk.
  3. Encoding:

    • Windows uses a different character encoding for text files by default (e.g., ANSI or UTF-16LE) compared to Linux (UTF-8). Ensure that your .po and .mo files are saved in UTF-8 encoding to be compatible with your Rust code.
  4. Command Line:

    • When building your Rust project for Windows, you may need to use the appropriate target specification, such as x86_64-pc-windows-msvc, if you’re using the MSVC toolchain, or x86_64-pc-windows-gnu, if you’re using the GNU toolchain. Make sure the correct target is specified in your Cargo.toml.
  5. Debugging:

    • If you encounter issues specific to Windows, consider adding debugging output to your code to inspect the values of environment variables, file paths, and any error messages. This can help pinpoint the problem.

Once you’ve made these adjustments and ensured that your file paths, encoding, and environment variables are set correctly for Windows, your Rust internationalization (i18n) application should work on both Linux and Windows.
Happy Learning :blush:

thanks @Javeria_Tariq

here is my solution

cargo new multilaguage
cd multilaguage
cargo add gettext-ng
cargo add sys_locale
cargo add current_platform

vi Cargo.toml

add this lines

[profile.release]
opt-level = 'z'     # Optimize for size
lto = true          # Enable link-time optimization
codegen-units = 1   # Reduce number of codegen units to increase optimizations
panic = 'abort'     # Abort on panic
strip = true        # Strip symbols from binary*

vi src/main.rs

use std::fs::File;
use sys_locale::get_locale;
use gettext_ng::Catalog;
use std::path::Path;
use current_platform::{CURRENT_PLATFORM, COMPILED_ON};

fn main() {
    let current_locale = get_locale().unwrap_or_else(|| String::from("en-US"));
    let filename = format!("{}.mo", current_locale);

    let file_path = format!("{current_locale}.mo");
    let path = Path::new(&file_path);
    if path.exists() {
        println!("LanguageFile: {file_path} exists!");

        let f = File::open(filename).expect("could not open the catalog");
        let catalog = Catalog::parse(f).expect("could not parse the catalog");

        println!("Program was compiled on {} {}", CURRENT_PLATFORM,COMPILED_ON);
        println!("The locale is {}", current_locale);
        println!("");
        println!("{}", catalog.gettext("Name"));
        println!("");


    } else {
        println!("File: {file_path} does not exist! Program abort");
    }

}

vi en-US.po

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2023-09-08 21:39+0200\n"
"Last-Translator: developer <developer@w541>\n"
"Language-Team: English\n"
"Language: en_US\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Name"
msgstr "Hello World!"

vi de-DE.po

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2023-09-08 21:46+0200\n"
"Last-Translator: developer <developer@w541>\n"
"Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
"Language: de\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
msgid "Name"
msgstr "Hallo Welt!"

vi fr-FR.po

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"PO-Revision-Date: 2023-09-08 21:34+0200\n"
"Last-Translator: developer <developer@w541>\n"
"Language-Team: French <traduc@traduc.org>\n"
"Language: fr\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=ASCII\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
msgid "Name"
msgstr "Bonjour le monde!"

msgfmt en-US.po -o en-US.mo
msgfmt de-DE.po -o de-DE.mo
msgfmt fr-FR.po -o fr-FR.mo

cargo run

export LANG=de_DE.UTF-8

cargo run

export LANG=fr_FR.UTF-8

cargo run

rustup target add x86_64-pc-windows-gnu

cargo build --target x86_64-pc-windows-gnu --release

cargo build --release

1 Like