| 1 | //! A library to safely and easily obtain the current locale on the system or for an application. |
| 2 | //! |
| 3 | //! This library currently supports the following platforms: |
| 4 | //! - Android |
| 5 | //! - iOS (and derivatives such as watchOS, tvOS, and visionOS) |
| 6 | //! - macOS |
| 7 | //! - Linux, BSD, and other UNIX variations |
| 8 | //! - WebAssembly on the web (via the `js` feature) |
| 9 | //! - Windows |
| 10 | #![cfg_attr (any(not(unix), target_vendor = "apple" , target_os = "android" ), no_std)] |
| 11 | extern crate alloc; |
| 12 | use alloc::string::String; |
| 13 | |
| 14 | #[cfg (target_os = "android" )] |
| 15 | mod android; |
| 16 | #[cfg (target_os = "android" )] |
| 17 | use android as provider; |
| 18 | |
| 19 | #[cfg (target_vendor = "apple" )] |
| 20 | mod apple; |
| 21 | #[cfg (target_vendor = "apple" )] |
| 22 | use apple as provider; |
| 23 | |
| 24 | #[cfg (all(unix, not(any(target_vendor = "apple" , target_os = "android" ))))] |
| 25 | mod unix; |
| 26 | #[cfg (all(unix, not(any(target_vendor = "apple" , target_os = "android" ))))] |
| 27 | use unix as provider; |
| 28 | |
| 29 | #[cfg (all(target_family = "wasm" , feature = "js" , not(unix)))] |
| 30 | mod wasm; |
| 31 | #[cfg (all(target_family = "wasm" , feature = "js" , not(unix)))] |
| 32 | use wasm as provider; |
| 33 | |
| 34 | #[cfg (windows)] |
| 35 | mod windows; |
| 36 | #[cfg (windows)] |
| 37 | use windows as provider; |
| 38 | |
| 39 | #[cfg (not(any(unix, all(target_family = "wasm" , feature = "js" , not(unix)), windows)))] |
| 40 | mod provider { |
| 41 | pub fn get() -> impl Iterator<Item = alloc::string::String> { |
| 42 | core::iter::empty() |
| 43 | } |
| 44 | } |
| 45 | |
| 46 | /// Returns the most preferred locale for the system or application. |
| 47 | /// |
| 48 | /// This is equivalent to `get_locales().next()` (the first entry). |
| 49 | /// |
| 50 | /// # Returns |
| 51 | /// |
| 52 | /// Returns [`Some(String)`] with a BCP 47 language tag inside. |
| 53 | /// If the locale couldn't be obtained, [`None`] is returned instead. |
| 54 | /// |
| 55 | /// # Example |
| 56 | /// |
| 57 | /// ```no_run |
| 58 | /// use sys_locale::get_locale; |
| 59 | /// |
| 60 | /// let current_locale = get_locale().unwrap_or_else(|| String::from("en-US" )); |
| 61 | /// |
| 62 | /// println!("The locale is {}" , current_locale); |
| 63 | /// ``` |
| 64 | pub fn get_locale() -> Option<String> { |
| 65 | get_locales().next() |
| 66 | } |
| 67 | |
| 68 | /// Returns the preferred locales for the system or application, in descending order of preference. |
| 69 | /// |
| 70 | /// # Returns |
| 71 | /// |
| 72 | /// Returns an [`Iterator`] with any number of BCP 47 language tags inside. |
| 73 | /// If no locale preferences could be obtained, the iterator will be empty. |
| 74 | /// |
| 75 | /// # Example |
| 76 | /// |
| 77 | /// ```no_run |
| 78 | /// use sys_locale::get_locales; |
| 79 | /// |
| 80 | /// let mut locales = get_locales(); |
| 81 | /// |
| 82 | /// println!("The most preferred locale is {}" , locales.next().unwrap_or("en-US" .to_string())); |
| 83 | /// println!("The least preferred locale is {}" , locales.last().unwrap_or("en-US" .to_string())); |
| 84 | /// ``` |
| 85 | pub fn get_locales() -> impl Iterator<Item = String> { |
| 86 | provider::get() |
| 87 | } |
| 88 | |
| 89 | #[cfg (test)] |
| 90 | mod tests { |
| 91 | use super::{get_locale, get_locales}; |
| 92 | extern crate std; |
| 93 | |
| 94 | #[cfg (all(target_family = "wasm" , feature = "js" , not(unix)))] |
| 95 | use wasm_bindgen_test::wasm_bindgen_test as test; |
| 96 | #[cfg (all(target_family = "wasm" , feature = "js" , not(unix)))] |
| 97 | wasm_bindgen_test::wasm_bindgen_test_configure!(run_in_browser); |
| 98 | |
| 99 | #[test ] |
| 100 | fn can_obtain_locale() { |
| 101 | assert!(get_locale().is_some(), "no locales were returned" ); |
| 102 | let locales = get_locales(); |
| 103 | for (i, locale) in locales.enumerate() { |
| 104 | assert!(!locale.is_empty(), "locale string {} was empty" , i); |
| 105 | assert!( |
| 106 | !locale.ends_with(' \0' ), |
| 107 | "locale {} contained trailing NUL" , |
| 108 | i |
| 109 | ); |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | |