batbox_i18n/
lib.rs

1//! Internationalization
2//!
3//! Use `batbox_i18n::gen!(mod mod_name: "path/to.toml")`
4//!
5//! Example toml file:
6//!
7//! ```toml
8//! [en]
9//! hello = "Hello"
10//! world = "World"
11//!
12//! [ru]
13//! hello = "Привет"
14//! world = "Мир"
15//! ```
16//!
17//! Generated code with `batbox_i18n::gen!(mod i18n: "hello_world.toml")`:
18//!
19//! ```ignore
20//! mod i18n {
21//!     struct Locale {
22//!         ..
23//!     }
24//!
25//!     fn get(locale: &str) -> Option<&'static Locale> { .. }
26//!     fn get_or_en(locale: &str) -> &'static Locale { .. }
27//!
28//!     impl Locale {
29//!         pub fn hello(&self) -> &str { .. }
30//!         pub fn world(&self) -> &str { .. }
31//!     }
32//! }
33//! ```
34#![warn(missing_docs)]
35
36pub use batbox_i18n_macro::gen;
37
38/// Detect user's locale
39///
40/// If detection failed, defaults to "en"
41pub fn detect_locale() -> &'static str {
42    static CELL: once_cell::sync::Lazy<String> = once_cell::sync::Lazy::new(|| {
43        #[cfg(target_arch = "wasm32")]
44        let locale = web_sys::window().unwrap().navigator().language();
45        #[cfg(not(target_arch = "wasm32"))]
46        let locale = unsafe {
47            let locale = libc::setlocale(
48                libc::LC_COLLATE,
49                std::ffi::CStr::from_bytes_with_nul_unchecked(b"\0").as_ptr(),
50            );
51            if locale.is_null() {
52                None
53            } else {
54                std::ffi::CStr::from_ptr(locale)
55                    .to_str()
56                    .ok()
57                    .map(|s| s.to_owned())
58            }
59        };
60        log::trace!("Detected locale: {:?}", locale);
61        let mut locale = match locale {
62            Some(locale) => locale,
63            None => String::from("en"),
64        };
65        if locale.len() > 2 {
66            locale.truncate(2);
67        }
68        let locale = locale.to_lowercase();
69        log::trace!("Using locale: {:?}", locale);
70        locale
71    });
72    CELL.as_str()
73}