-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
1 parent
ff4ae8f
commit 2093c1f
Showing
10 changed files
with
188 additions
and
86 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#[cfg(not(windows))] | ||
use std::os::unix::fs::symlink as symlink_file; | ||
#[cfg(windows)] | ||
use std::os::windows::fs::symlink_file; | ||
use std::{borrow::Cow, fmt, fs, fs::Metadata, io, path::Path}; | ||
|
||
use path_slash::PathExt; | ||
|
||
use crate::{ | ||
AbsoluteSystemPathBuf, AnchoredSystemPathBuf, IntoSystem, PathError, PathValidationError, | ||
RelativeSystemPathBuf, RelativeUnixPath, | ||
}; | ||
|
||
pub struct AbsoluteSystemPath(Path); | ||
|
||
impl ToOwned for AbsoluteSystemPath { | ||
type Owned = AbsoluteSystemPathBuf; | ||
|
||
fn to_owned(&self) -> Self::Owned { | ||
AbsoluteSystemPathBuf(self.0.to_owned()) | ||
} | ||
} | ||
|
||
impl fmt::Display for AbsoluteSystemPath { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
self.0.display().fmt(f) | ||
} | ||
} | ||
|
||
impl AsRef<Path> for AbsoluteSystemPath { | ||
fn as_ref(&self) -> &Path { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl AbsoluteSystemPath { | ||
pub fn new<P: AsRef<Path>>(value: &P) -> Result<Cow<Self>, PathError> { | ||
let path = value.as_ref(); | ||
if path.is_relative() { | ||
return Err(PathValidationError::NotAbsolute(path.to_owned()).into()); | ||
} | ||
|
||
let system_path = path.to_slash().ok_or_else(|| { | ||
PathError::PathValidationError(PathValidationError::InvalidUnicode(path.to_owned())) | ||
})?; | ||
|
||
// copied from stdlib path.rs: relies on the representation of | ||
// AbsoluteSystemPath being just a Path, the same way Path relies on | ||
// just being an OsStr | ||
match system_path { | ||
Cow::Owned(path) => Ok(Cow::Owned(AbsoluteSystemPathBuf::new(path)?)), | ||
Cow::Borrowed(path) => { | ||
let path = Path::new(path); | ||
let absolute_system_path = unsafe { &*(path as *const Path as *const Self) }; | ||
Ok(Cow::Borrowed(absolute_system_path)) | ||
} | ||
} | ||
} | ||
|
||
pub fn symlink_metadata(&self) -> Result<Metadata, PathError> { | ||
Ok(fs::symlink_metadata(&self.0)?) | ||
} | ||
|
||
pub fn as_path(&self) -> &Path { | ||
&self.0 | ||
} | ||
|
||
pub fn read_link(&self) -> Result<AbsoluteSystemPathBuf, PathError> { | ||
let path = fs::read_link(&self.0)?; | ||
Ok(AbsoluteSystemPathBuf::new(path)?) | ||
} | ||
|
||
pub fn join_relative(&self, path: &RelativeSystemPathBuf) -> AbsoluteSystemPathBuf { | ||
let path = self.0.join(path.as_path()); | ||
AbsoluteSystemPathBuf(path) | ||
} | ||
|
||
pub fn join_unix_path( | ||
&self, | ||
unix_path: &RelativeUnixPath, | ||
) -> Result<AbsoluteSystemPathBuf, PathError> { | ||
let tail = unix_path.to_system_path()?; | ||
Ok(AbsoluteSystemPathBuf(self.0.join(tail.as_path()))) | ||
} | ||
|
||
pub fn anchor(&self, path: &AbsoluteSystemPath) -> Result<AnchoredSystemPathBuf, PathError> { | ||
AnchoredSystemPathBuf::new(self, path) | ||
} | ||
|
||
pub fn ensure_dir(&self) -> Result<(), io::Error> { | ||
if let Some(parent) = self.0.parent() { | ||
fs::create_dir_all(parent) | ||
} else { | ||
Ok(()) | ||
} | ||
} | ||
|
||
pub fn symlink_to_file<P: AsRef<Path>>(&self, to: P) -> Result<(), PathError> { | ||
let system_path = to.as_ref(); | ||
let system_path = system_path.into_system()?; | ||
symlink_file(&system_path, &self.0)?; | ||
Ok(()) | ||
} | ||
|
||
pub fn resolve(&self, path: &AnchoredSystemPathBuf) -> AbsoluteSystemPathBuf { | ||
let path = self.0.join(path.as_path()); | ||
AbsoluteSystemPathBuf(path) | ||
} | ||
} |
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
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
Oops, something went wrong.