Optimize normalize_path: Avoid copy if possible

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-06-15 17:45:50 +10:00
parent 282805c3ac
commit 30b9a78520
No known key found for this signature in database
GPG key ID: 591C0B03040416D6
2 changed files with 24 additions and 5 deletions

View file

@ -49,7 +49,8 @@ impl TarEntriesVisitor for ManifestVisitor {
fn visit<R: Read>(&mut self, entries: Entries<'_, R>) -> Result<(), BinstallError> { fn visit<R: Read>(&mut self, entries: Entries<'_, R>) -> Result<(), BinstallError> {
for res in entries { for res in entries {
let mut entry = res?; let mut entry = res?;
let path = entry.path()?.normalize_path(); let path = entry.path()?;
let path = path.normalize_path();
let path = if let Ok(path) = path.strip_prefix(&self.manifest_dir_path) { let path = if let Ok(path) = path.strip_prefix(&self.manifest_dir_path) {
path path

View file

@ -1,16 +1,34 @@
//! Shamelessly taken from: //! Shamelessly adapted from:
//! https://github.com/rust-lang/cargo/blob/fede83ccf973457de319ba6fa0e36ead454d2e20/src/cargo/util/paths.rs#L61 //! https://github.com/rust-lang/cargo/blob/fede83ccf973457de319ba6fa0e36ead454d2e20/src/cargo/util/paths.rs#L61
use std::borrow::Cow;
use std::path::{Component, Path, PathBuf}; use std::path::{Component, Path, PathBuf};
pub trait PathExt { pub trait PathExt {
/// Similiar to `os.path.normpath`: It does not perform /// Similiar to `os.path.normpath`: It does not perform
/// any fs operation. /// any fs operation.
fn normalize_path(&self) -> PathBuf; fn normalize_path(&self) -> Cow<'_, Path>;
}
fn is_normalized(path: &Path) -> bool {
for component in path.components() {
match component {
Component::CurDir | Component::ParentDir => {
return false;
}
_ => continue,
}
}
true
} }
impl PathExt for Path { impl PathExt for Path {
fn normalize_path(&self) -> PathBuf { fn normalize_path(&self) -> Cow<'_, Path> {
if is_normalized(self) {
return Cow::Borrowed(self);
}
let mut components = self.components().peekable(); let mut components = self.components().peekable();
let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() { let mut ret = if let Some(c @ Component::Prefix(..)) = components.peek().cloned() {
components.next(); components.next();
@ -34,6 +52,6 @@ impl PathExt for Path {
} }
} }
} }
ret Cow::Owned(ret)
} }
} }