Most likely a more robust version of the custom implementation, might be put behind a feature so users can select the right implementation for their use-case.
WBI5HFOBBUMDSGKY2RX3YA6N7YDCJEP23JNEJ7PG5VZXHLYIRJRQC
HCGVXOF7P3KKS2IMGVJWI2POVOZQFPXH26YVBJZRSOYSUM4CHUBQC
SHNZZSZGIBTTD4IV5SMW5BIN5DORUWQVTVTNB5RMRD5CTFNOMJ6AC
UKFEFT6LSI4K7X6UHQFZYD52DILKXMZMYSO2UYS2FCHNPXIF4BEQC
YNEOCYMGMSHQGCL5TOIGWDDKHE4BZ5M7FGY5I6B2V6JO6ZRCLETAC
T6JEWQJ7KI4SQFGIZNRKCWD5DEUVTIPEWXU7AX6WM7IU4DBSQZRQC
LIH6JCXY5GMYQPU5L6HY2NOMJDMEW54THPKJ6YXI62Y2SVXFIAXQC
// TODO: this is wasteful but avoids dealing with lifetimes for now
supported.into_iter().cloned().collect()
// TODO: properly handle this case
if let [single_locale] = supported[..] {
// TODO: this is wasteful but avoids dealing with lifetimes for now
single_locale.to_owned()
} else {
todo!("Multiple locales returned, which is not yet handled. Got: {supported:#?}");
}
use std::ffi::CStr;
const NUL_BYTE: &[u8] = b"\0";
macro_rules! repr_lc {
($($variant:ident),+) => {
#[derive(Clone, Copy, Debug)]
#[allow(non_camel_case_types)] // Required for parity with C enum
pub enum LocaleCategory {
$($variant,)*
}
impl TryFrom<i32> for LocaleCategory {
type Error = ();
pub enum LocaleCategory {
CType,
Collate,
Messages,
Monetary,
Numeric,
Time,
Address,
Identification,
Measurement,
Name,
Paper,
Telephone,
}
fn try_from(value: i32) -> Result<Self, Self::Error> {
match value {
$(libc::$variant => Ok(Self::$variant),)*
_ => Err(())
}
}
}
impl Into<i32> for LocaleCategory {
fn into(self) -> i32 {
match self {
$(Self::$variant => libc::$variant,)*
}
}
}
impl LocaleCategory {
fn as_str(&self) -> &str {
match self {
Self::CType => "LC_CTYPE",
Self::Collate => "LC_COLLATE",
Self::Messages => "LC_MESSAGES",
Self::Monetary => "LC_MONETARY",
Self::Numeric => "LC_NUMERIC",
Self::Time => "LC_TIME",
Self::Address => "LC_ADDRESS",
Self::Identification => "LC_IDENTIFICATION",
Self::Measurement => "LC_MEASUREMENT",
Self::Name => "LC_NAME",
Self::Paper => "LC_PAPER",
Self::Telephone => "LC_TELEPHONE",
impl LocaleCategory {
fn as_str(&self) -> &str {
match self {
$(Self::$variant => stringify!($variant),)*
}
}
// TODO: handle and document safety invariants
fn get_locale_libc(category: i32) -> String {
let empty_cstr = CStr::from_bytes_with_nul(NUL_BYTE).unwrap();
let locale_string_pointer = unsafe { libc::setlocale(category, empty_cstr.as_ptr()) };
let locale_c_str = unsafe { CStr::from_ptr(locale_string_pointer) };
locale_c_str.to_str().unwrap().to_string()
}
impl LocaleCategory {