-
Notifications
You must be signed in to change notification settings - Fork 13.3k
Use with_native_path
for Windows
#139683
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use with_native_path
for Windows
#139683
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Btw, the convention in It’s not worth bumping this out of the queue, but something to possibly keep in mind for your next PR in the series. |
||
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> { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (Curiosity) why do these use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That was the optimisation made in #121101. I've not personally looked into the trade-offs though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Binary size, see #121101. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah thanks, I didn't realize this existed before #138832 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Jinxed 😄. It might be possible to improve things by splitting the string validation and copying to a separate, non-generic function but keep the stack allocation and inner function call in the generic part. Maybe I'll pursue that once this PR is merged... |
||
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'\\' | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to double check, this has the oposite logic to the other
cfg
'sThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's intentional. Because this is the one case where we can't (yet) simply pass through a native path to the Windows function but we can for Unix. And fortunately if I get the logic wrong here it'll be a loud error due to the signatures not matching.