Update, improve Windows impl

This commit is contained in:
Michael Pfaff 2025-03-15 23:11:54 -04:00
commit d1e447bc57
2 changed files with 15 additions and 9 deletions

View file

@ -1,4 +1,5 @@
#![feature(maybe_uninit_uninit_array)]
#![feature(maybe_uninit_slice)]
#![feature(maybe_uninit_uninit_array_transpose)]
#[cfg(any(target_os = "macos", target_os = "ios"))]
#[path = "apple.rs"]

View file

@ -6,24 +6,29 @@ use std::os::windows::ffi::OsStringExt;
use windows::Win32::System::SystemServices::LOCALE_NAME_MAX_LENGTH;
use windows::Win32::System::WindowsProgramming::uaw_wcslen;
use windows_sys::Win32::Globalization::GetUserDefaultLocaleName;
use windows_sys::core::PWSTR;
pub fn get_preferred_locales() -> Vec<String> {
let mut locale_name_buf: [MaybeUninit<u16>; LOCALE_NAME_MAX_LENGTH as usize] =
MaybeUninit::uninit_array();
let locale_name: PWSTR = locale_name_buf.as_mut_ptr().cast();
MaybeUninit::uninit().transpose();
let buf_size =
unsafe { GetUserDefaultLocaleName(locale_name, LOCALE_NAME_MAX_LENGTH as c_int) };
let buf_size = unsafe {
GetUserDefaultLocaleName(
locale_name_buf.as_mut_ptr().cast(),
locale_name_buf.len() as c_int,
)
};
if buf_size == 0 {
// error occurred
return Vec::new();
}
let os_lang: OsString = OsString::from_wide(unsafe {
std::slice::from_raw_parts(locale_name, uaw_wcslen(locale_name))
});
// SAFETY: we have checked for errors and the Windows API promised to place a valid,
// null-terminated string in the buffer.
let len = unsafe { uaw_wcslen(locale_name_buf.as_mut_ptr().cast()) };
// SAFETY: `len` bytes have been initialized by the Windows API
let os_lang: OsString =
OsString::from_wide(unsafe { locale_name_buf[..len].assume_init_ref() });
os_lang
.into_string()