Skip to main content

luaur_cli_lib/functions/
from_utf_8.rs

1use alloc::vec::Vec;
2
3// `fromUtf8` lives inside `#ifdef _WIN32` in FileUtils.cpp — it converts a UTF-8
4// path to the UTF-16 `wstring` the Win32 wide-char APIs require. The
5// `MultiByteToWideChar` symbol only exists on Windows, so the implementation is
6// gated; on POSIX no caller reaches it (all callers are themselves Win32-only).
7
8#[cfg(windows)]
9pub fn from_utf_8(path: &str) -> Vec<u16> {
10    use core::ffi::c_int;
11    use luaur_common::macros::luau_assert::LUAU_ASSERT;
12
13    #[allow(non_upper_case_globals)]
14    const CP_UTF8: u32 = 65001;
15
16    extern "system" {
17        fn MultiByteToWideChar(
18            code_page: u32,
19            dw_flags: u32,
20            lp_multi_byte_str: *const core::ffi::c_char,
21            cb_multi_byte: c_int,
22            lp_wide_char_str: *mut u16,
23            cch_wide_char: c_int,
24        ) -> c_int;
25    }
26
27    let path_bytes = path.as_bytes();
28    let path_ptr = path_bytes.as_ptr() as *const core::ffi::c_char;
29    let path_len = path_bytes.len() as c_int;
30
31    let result =
32        unsafe { MultiByteToWideChar(CP_UTF8, 0, path_ptr, path_len, core::ptr::null_mut(), 0) };
33    LUAU_ASSERT!(result > 0);
34
35    let mut buf = vec![0u16; result as usize];
36    unsafe {
37        MultiByteToWideChar(CP_UTF8, 0, path_ptr, path_len, buf.as_mut_ptr(), result);
38    }
39
40    buf
41}
42
43#[cfg(not(windows))]
44pub fn from_utf_8(path: &str) -> Vec<u16> {
45    // POSIX builds never invoke the Win32 wide-path conversion.
46    let _ = path;
47    Vec::new()
48}