Skip to main content

windows_erg/utils/
strings.rs

1use windows::core::PWSTR;
2
3/// Encode UTF-8 text into UTF-16 code units without a trailing NUL.
4pub fn to_utf16(value: &str) -> Vec<u16> {
5    value.encode_utf16().collect()
6}
7
8/// Encode UTF-8 text into UTF-16 code units with a trailing NUL terminator.
9pub fn to_utf16_nul(value: &str) -> Vec<u16> {
10    value.encode_utf16().chain(std::iter::once(0)).collect()
11}
12
13/// Fill a caller-provided UTF-16 buffer with text plus a trailing NUL terminator.
14pub fn to_utf16_nul_in(value: &str, out_buffer: &mut Vec<u16>) {
15    out_buffer.clear();
16    out_buffer.extend(value.encode_utf16());
17    out_buffer.push(0);
18}
19
20/// Convert a NUL-terminated `PWSTR` into `String`.
21///
22/// Returns `None` if the pointer is null or the string is empty.
23pub fn pwstr_to_string(value: PWSTR) -> Option<String> {
24    let ptr = value.0;
25    if ptr.is_null() {
26        return None;
27    }
28
29    let mut len = 0usize;
30    unsafe {
31        while *ptr.add(len) != 0 {
32            len += 1;
33        }
34
35        if len == 0 {
36            return None;
37        }
38
39        let slice = std::slice::from_raw_parts(ptr, len);
40        Some(String::from_utf16_lossy(slice))
41    }
42}
43
44/// Convert a `PWSTR` with an explicit UTF-16 code-unit length into `String`.
45pub fn pwstr_to_string_len(value: PWSTR, len: usize) -> String {
46    if value.is_null() || len == 0 {
47        return String::new();
48    }
49
50    let slice = unsafe { std::slice::from_raw_parts(value.0, len) };
51    String::from_utf16_lossy(slice)
52}