Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
110 additions
and
53 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,48 @@ | ||
use std::path::Path; | ||
use std::{ffi::OsString, path::PathBuf}; | ||
|
||
use crate::{IntoSystem, PathError, PathValidationError, RelativeSystemPathBuf}; | ||
use bstr::BStr; | ||
|
||
use crate::{not_relative_error, PathError, RelativeSystemPathBuf}; | ||
|
||
#[repr(transparent)] | ||
pub struct RelativeUnixPath { | ||
inner: Path, | ||
inner: BStr, | ||
} | ||
|
||
impl RelativeUnixPath { | ||
pub fn new<P: AsRef<Path>>(value: &P) -> Result<&Self, PathError> { | ||
pub fn new<P: AsRef<BStr>>(value: &P) -> Result<&Self, PathError> { | ||
let path = value.as_ref(); | ||
if path.is_absolute() { | ||
return Err(PathValidationError::NotRelative(path.to_owned()).into()); | ||
if path[0] == b'/' { | ||
return Err(not_relative_error(path).into()); | ||
} | ||
// copied from stdlib path.rs: relies on the representation of | ||
// RelativeUnixPath being just a Path, the same way Path relies on | ||
// just being an OsStr | ||
Ok(unsafe { &*(path as *const Path as *const Self) }) | ||
Ok(unsafe { &*(path as *const BStr as *const Self) }) | ||
} | ||
|
||
pub fn to_system_path(&self) -> Result<RelativeSystemPathBuf, PathError> { | ||
let system_path = self.inner.into_system()?; | ||
Ok(RelativeSystemPathBuf::new_unchecked(system_path)) | ||
#[cfg(unix)] | ||
{ | ||
// On unix, unix paths are already system paths. Copy the bytes | ||
// but skip validation. | ||
use std::os::unix::prelude::OsStringExt; | ||
let path = PathBuf::from(OsString::from_vec(self.inner.to_vec())); | ||
Ok(RelativeSystemPathBuf::new_unchecked(path)) | ||
} | ||
|
||
#[cfg(windows)] | ||
{ | ||
let system_path_bytes = self | ||
.inner | ||
.iter() | ||
.map(|byte| if *byte == b'/' { b'\\' } else { *byte }) | ||
.collect::<Vec<u8>>(); | ||
// Is this safe to do? We think we have utf8 bytes or bytes that roundtrip | ||
// through utf8 | ||
let system_path_string = unsafe { String::from_utf8_unchecked(system_path_bytes) }; | ||
let system_path_buf = PathBuf::from(system_path_string); | ||
Ok(RelativeSystemPathBuf::new_unchecked(system_path_buf)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters