diff options
| author | Chris Denton <chris@chrisdenton.dev> | 2025-04-11 16:15:34 +0000 |
|---|---|---|
| committer | Chris Denton <chris@chrisdenton.dev> | 2025-04-11 18:02:03 +0000 |
| commit | b613e9781a773232f81af9f61a8c8ac34b04873a (patch) | |
| tree | 928795829efa5ecb8426dce0c784f11b9af98540 /library/std/src/sys/path/windows.rs | |
| parent | 2205455d444f5f9da3a52e50f43c0306480218fb (diff) | |
| download | rust-b613e9781a773232f81af9f61a8c8ac34b04873a.tar.gz rust-b613e9781a773232f81af9f61a8c8ac34b04873a.zip | |
Use with_native_path for Windows
Also add a WCStr type
Diffstat (limited to 'library/std/src/sys/path/windows.rs')
| -rw-r--r-- | library/std/src/sys/path/windows.rs | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/library/std/src/sys/path/windows.rs b/library/std/src/sys/path/windows.rs index 6547ed9aa5f..e0e003f6a81 100644 --- a/library/std/src/sys/path/windows.rs +++ b/library/std/src/sys/path/windows.rs @@ -10,6 +10,40 @@ mod tests; pub const MAIN_SEP_STR: &str = "\\"; pub const MAIN_SEP: char = '\\'; +/// A null terminated wide string. +#[repr(transparent)] +pub struct WCStr([u16]); + +impl WCStr { + /// Convert a slice to a WCStr without checks. + /// + /// Though it is memory safe, the slice should also not contain interior nulls + /// as this may lead to unwanted truncation. + /// + /// # Safety + /// + /// The slice must end in a null. + pub unsafe fn from_wchars_with_null_unchecked(s: &[u16]) -> &Self { + unsafe { &*(s as *const [u16] as *const Self) } + } + + pub fn as_ptr(&self) -> *const u16 { + self.0.as_ptr() + } + + pub fn count_bytes(&self) -> usize { + self.0.len() + } +} + +#[inline] +pub fn with_native_path<T>(path: &Path, f: &dyn Fn(&WCStr) -> io::Result<T>) -> io::Result<T> { + let path = maybe_verbatim(path)?; + // SAFETY: maybe_verbatim returns null-terminated strings + let path = unsafe { WCStr::from_wchars_with_null_unchecked(&path) }; + f(path) +} + #[inline] pub fn is_sep_byte(b: u8) -> bool { b == b'/' || b == b'\\' |
