Skip to content

Commit

Permalink
Merge branch 'master' into no-gettext
Browse files Browse the repository at this point in the history
  • Loading branch information
danigm committed Aug 17, 2018
2 parents fa6f800 + 6b0f498 commit c514bbe
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "gettext-rs"
description = "GNU Gettext FFI binding for Rust"
version = "0.4.0"
version = "0.4.1"
authors = ["Konstantin Salikhov <koka58@yandex.ru>"]
repository = "https://github.com/Koka/gettext-rs"
documentation = "http://koka.github.io/gettext-rs/gettextrs/"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ Usage:
println!("Translated: {}", gettext("Hello, world!"));
println!("Singular: {}", ngettext("One thing", "Multiple things", 1));
println!("Plural: {}", ngettext("One thing", "Multiple things", 2));
println!("With context: {}", pgettext("This is the context", "Hello, world!"));
println!("Plural with context: {}", npgettext("This is the context", "One thing", "Multiple things", 2));
```

Alternatively, you can initialize the locale and text domain using the `TextDomain` builder.
Expand Down
62 changes: 62 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,47 @@ pub fn bind_textdomain_codeset<T: Into<Vec<u8>>>(domain: T, codeset: T) -> Strin
}
}

static CONTEXT_SEPARATOR: u8 = b'\x04';

fn build_context_id(ctx: &Vec<u8>, s: &Vec<u8>) -> String {
let mut text: Vec<u8> = vec![];
text.extend(ctx.iter().cloned());
text.push(CONTEXT_SEPARATOR);
text.extend(s.iter().cloned());
CString::new(text).unwrap().to_string_lossy().into_owned()
}

/// Translate msgid to localized message from default domain (with context support)
pub fn pgettext<T: Into<Vec<u8>>>(ctx: T, s: T) -> String {
let msgid = s.into();
let text = build_context_id(&ctx.into(), &msgid);

let trans = gettext(text);
if trans.contains(CONTEXT_SEPARATOR as char) {
return gettext(msgid);
//return CString::new(msgid).unwrap().to_string_lossy().into_owned();
}

trans
}

/// Translate msgid to localized message from default domain (with plural support and context
/// support)
pub fn npgettext<T: Into<Vec<u8>>>(ctx: T, singular: T, plural: T, n: u32) -> String {
let ctx = ctx.into();
let singular_msgid = singular.into();
let plural_msgid = plural.into();
let singular_ctx = build_context_id(&ctx, &singular_msgid);
let plural_ctx = build_context_id(&ctx, &plural_msgid);

let trans = ngettext(singular_ctx, plural_ctx, n);
if trans.contains(CONTEXT_SEPARATOR as char) {
return ngettext(singular_msgid, plural_msgid, n);
}

trans
}

#[cfg(test)]
mod tests {
use super::*;
Expand All @@ -190,4 +231,25 @@ mod tests {
assert_eq!("Hello, world!", ngettext("Hello, world!", "Hello, worlds!", 1));
assert_eq!("Hello, worlds!", ngettext("Hello, world!", "Hello, worlds!", 2));
}

#[test]
fn context_test() {
setlocale(LocaleCategory::LcAll, "en_US.UTF-8");

bindtextdomain("hellorust", "/usr/local/share/locale");
textdomain("hellorust");

assert_eq!("Hello, world!", pgettext("context", "Hello, world!"));
}

#[test]
fn plural_context_test() {
setlocale(LocaleCategory::LcAll, "en_US.UTF-8");

bindtextdomain("hellorust", "/usr/local/share/locale");
textdomain("hellorust");

assert_eq!("Hello, world!", npgettext("context", "Hello, world!", "Hello, worlds!", 1));
assert_eq!("Hello, worlds!", npgettext("context", "Hello, world!", "Hello, worlds!", 2));
}
}

0 comments on commit c514bbe

Please sign in to comment.