Crate gettextrs

source
Expand description

§Safe Rust bindings for gettext.

Usage:

use gettextrs::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Specify the name of the .mo file to use.
    textdomain("hellorust")?;
    // Ask gettext for UTF-8 strings. THIS CRATE CAN'T HANDLE NON-UTF-8 DATA!
    bind_textdomain_codeset("hellorust", "UTF-8")?;

    // You could also use `TextDomain` builder which calls `textdomain` and
    // other functions for you:
    //
    // TextDomain::new("hellorust").init()?;

    // `gettext()` simultaneously marks a string for translation and translates
    // it at runtime.
    println!("Translated: {}", gettext("Hello, world!"));

    // gettext supports plurals, i.e. you can have different messages depending
    // on the number of items the message mentions. This even works for
    // languages that have more than one plural form, like Russian or Czech.
    println!("Singular: {}", ngettext("One thing", "Multiple things", 1));
    println!("Plural: {}", ngettext("One thing", "Multiple things", 2));

    // gettext de-duplicates strings, i.e. the same string used multiple times
    // will have a single entry in the PO and MO files. However, the same words
    // might have different meaning depending on the context. To distinguish
    // between different contexts, gettext accepts an additional string:
    println!("With context: {}", pgettext("This is the context", "Hello, world!"));
    println!(
        "Plural with context: {}",
        npgettext("This is the context", "One thing", "Multiple things", 2));

    Ok(())
}

§UTF-8 is required

By default, gettext converts results to the locale’s codeset. Rust, on the other hand, always encodes strings to UTF-8. The best way to bridge this gap is to ask gettext to convert strings to UTF-8:

bind_textdomain_codeset("hellorust", "UTF-8")?;

…or using TextDomain builder:

TextDomain::new("hellorust")
    .codeset("UTF-8") // Optional, the builder does this by default
    .init()?;

This crate doesn’t do this for you because the encoding is a global setting; changing it can affect other gettext calls in your program, like calls in C or C++ parts of your binary.

If you don’t do this, calls to gettext() and other functions might panic when they encounter something that isn’t UTF-8. They can also garble data as they interpret the other encoding as UTF-8.

Another thing you could do is change the locale, e.g. setlocale(LocaleCategory::LcAll, "fr_FR.UTF-8"), but that would also hard-code the language, defeating the purpose of gettext: if you know the language in advance, you could just write all your strings in that language and be done with that.

Modules§

  • Query gettext configuration.

Structs§

Enums§

Functions§

  • Set encoding of translated messages.
  • Specify the directory that contains MO files for the given domain.
  • Translate msgid to localized message from the specified domain using custom locale category.
  • Translate msgid to localized message from the specified domain using custom locale category (with plural support).
  • Translate msgid to localized message from the specified domain.
  • Translate msgid to localized message from the specified domain (with plural support).
  • Translate msgid to localized message from the default domain.
  • Translate msgid to localized message from the default domain (with plural support).
  • Translate msgid to localized message from the default domain (with plural support and context support).
  • Translate msgid to localized message from the default domain (with context support).
  • Set current locale.
  • Switch to the specific text domain.