created_at2016-02-02 08:25:52.447508
updated_at2021-04-25 08:26:45.434091
descriptionSafe bindings for gettext
Alexander Batischev (Minoru)




Safe bindings for gettext. Please see documentation for details.


This crate depends on gettext-sys, which compiles GNU gettext on platforms that don't have a native gettext implementation. GNU gettext is licensed under LGPL, and is linked statically, which means you have to abide by LGPL. If you don't want or can't do that, there are two ways out:

  1. if you use glibc or musl libc, enable gettext-system feature (see below);
  2. dynamically link to GNU gettext library you obtained by some other means, like a package manager. For details, see environment variables in gettext-sys documentation.


(If you know how to use gettext and just want a gist of this crate's API, skip to the next section).

To internationalize your program with gettext, you have to do four things:

  1. wrap translatable strings into calls to appropriate gettext functions;
  2. use tools to extract those strings into a so-called "PO template file";
  3. translate the strings in the template, getting a so-called "message catalog" as a result;
  4. compile the message catalog from the plain-text, human-readable PO format to the binary MO format, and install them into a well-known location like /usr/local/share/locale.

This crate only covers the first step, the markup. To extract messages, use xtr (cargo install xtr). To translate, you can use desktop tools like Poedit, sites like Crowdin, or any text editor. To compile from PO to MO, use msgfmt tool from gettext-tools. The way you install files highly depend on your distribution method, so it's not covered here either.

The best resource on gettext is GNU gettext manual. This crate has the same API, so you should have an easy time transferring the advice from that manual to this crate. In a pitch, you can also glance at the manpages for C functions which this crate wraps.

Complete API example

use gettextrs::*;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Specify the name of the .mo file to use.
    // 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!"));
        "Plural with context: {}",
        npgettext("This is the context", "One thing", "Multiple things", 2));



  • gettext-system: if enabled, asks the crate to use the gettext implementation that's part of glibc or musl libc. This only works on:

    • Linux with glibc or musl libc;

    • Windows + GNU (e.g. MSYS2) with gettext-devel installed e.g. using:

      pacman --noconfirm -S base-devel mingw-w64-x86_64-gcc libxml2-devel tar

    If none of those conditions hold, the crate will proceed to building and statically linking its own copy of GNU gettext!

    This enables gettext-system feature of the underlying gettext-sys crate.

Environment variables

This crate doesn't use any. See also the documentation for the underlying gettext-sys crate.

Commit count: 180

cargo fmt