use std::{convert::TryInto, ptr::null_mut};
use winapi::um::{stringapiset::MultiByteToWideChar, winnls::CP_UTF8};
pub fn str_to_c_wstr(s: &str) -> Option<Box<[u16]>> {
if s.len() == 0 {
Some(Box::new([0]))
} else {
unsafe {
let in_len = s.len().try_into().ok()?;
let num_wchars =
MultiByteToWideChar(CP_UTF8, 0, s.as_ptr() as *const i8, in_len, null_mut(), 0);
if num_wchars == 0 {
return None;
}
let len: usize = num_wchars.try_into().ok()?;
let len = len.checked_add(1)?;
let mut out = Vec::<u16>::with_capacity(len);
let out_num_wchars = MultiByteToWideChar(
CP_UTF8,
0,
s.as_ptr() as *const i8,
in_len,
out.as_mut_ptr(),
num_wchars,
);
if out_num_wchars != num_wchars {
return None;
}
out.as_mut_ptr().offset(len as isize - 1).write(0); out.set_len(len);
Some(out.into())
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use wchar::wch_c;
#[test]
fn test_str_to_c_wstr() {
assert_eq!(*str_to_c_wstr("").unwrap(), *wch_c!(""));
assert_eq!(*str_to_c_wstr("книга").unwrap(), *wch_c!("книга"));
assert_eq!(*str_to_c_wstr("🦄✨").unwrap(), *wch_c!("🦄✨"));
}
}