1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
mod gettext_raw {
use std::os::raw::{c_char, c_int};
extern {
pub fn gettext(s: *const c_char) -> *const c_char;
pub fn bindtextdomain(domain : *const c_char, dir : *const c_char) -> *const c_char;
pub fn textdomain(domain : *const c_char) -> *const c_char;
pub fn setlocale(category: c_int, locale: *const c_char) -> *const c_char;
}
}
mod gettext {
use gettext_raw;
use std::ffi::CString;
use std::ffi::CStr;
pub enum LocaleCategory {
LC_CTYPE = 0,
LC_NUMERIC = 1,
LC_TIME = 2,
LC_COLLATE = 3,
LC_MONETARY = 4,
LC_MESSAGES = 5,
LC_ALL = 6,
LC_PAPER = 7,
LC_NAME = 8,
LC_ADDRESS = 9,
LC_TELEPHONE = 10,
LC_MEASUREMENT = 11,
LC_IDENTIFICATION = 12
}
pub fn gettext<T: Into<Vec<u8>>>(s:T) -> String {
unsafe {
CStr::from_ptr(gettext_raw::gettext(CString::new(s).unwrap().as_ptr())).to_string_lossy().into_owned()
}
}
pub fn textdomain<T: Into<Vec<u8>>>(domain:T) -> String {
unsafe {
CStr::from_ptr(gettext_raw::textdomain(CString::new(domain).unwrap().as_ptr())).to_string_lossy().into_owned()
}
}
pub fn bindtextdomain<T: Into<Vec<u8>>>(domian:T, dir:T) -> String {
unsafe {
CStr::from_ptr(gettext_raw::bindtextdomain(CString::new(domian).unwrap().as_ptr(), CString::new(dir).unwrap().as_ptr())).to_string_lossy().into_owned()
}
}
pub fn setlocale<T: Into<Vec<u8>>>(category: LocaleCategory, locale:T) -> String {
unsafe {
CStr::from_ptr(gettext_raw::setlocale(category as i32, CString::new(locale).unwrap().as_ptr())).to_string_lossy().into_owned()
}
}
}
pub use gettext::*;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn smoke_test() {
setlocale(LocaleCategory::LC_ALL, "en_US.UTF-8");
bindtextdomain("hellorust", "/usr/local/share/locale");
textdomain("hellorust");
assert_eq!("Hello, world!", gettext("Hello, world!"));
}
}