diff --git a/src/lib.rs b/src/lib.rs index 8428a9a..9222daa 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -72,6 +72,7 @@ doctest!("../README.md"); use std::cmp; use std::cmp::Ordering; use std::error::Error; +use std::ffi::OsStr; use std::fmt; use std::fs; use std::fs::DirEntry; @@ -199,13 +200,13 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Result PathBuf { + fn to_scope(p: &Path) -> Box { // FIXME handle volume relative paths here - p.to_path_buf() + p.into() } #[cfg(not(windows))] - fn to_scope(p: &Path) -> PathBuf { - p.to_path_buf() + fn to_scope(p: &Path) -> Box { + p.into() } // make sure that the pattern is valid first, else early return with error @@ -242,7 +243,7 @@ pub fn glob_with(pattern: &str, options: MatchOptions) -> Result, is_directory: bool, + file_name: Option>, } impl PathWrapper { - fn from_dir_entry(path: PathBuf, e: DirEntry) -> Self { + fn from_dir_entry(path: Box, file_name: Option>, e: DirEntry) -> Self { let is_directory = e .file_type() .ok() @@ -347,15 +349,24 @@ impl PathWrapper { }) .or_else(|| fs::metadata(&path).map(|m| m.is_dir()).ok()) .unwrap_or(false); - Self { path, is_directory } + Self { + path, + is_directory, + file_name, + } } - fn from_path(path: PathBuf) -> Self { + fn from_path(path: Box) -> Self { let is_directory = fs::metadata(&path).map(|m| m.is_dir()).unwrap_or(false); - Self { path, is_directory } + let file_name = path.file_name().map(Box::from); + Self { + path, + is_directory, + file_name, + } } fn into_path(self) -> PathBuf { - self.path + self.path.into_path_buf() } } @@ -917,7 +928,7 @@ fn fill_todo( } else { path.join(&s) }; - let next_path = PathWrapper::from_path(next_path); + let next_path = PathWrapper::from_path(next_path.into_boxed_path()); if (special && is_dir) || (!special && (fs::metadata(&next_path).is_ok() @@ -930,12 +941,16 @@ fn fill_todo( let dirs = fs::read_dir(path).and_then(|d| { d.map(|e| { e.map(|e| { - let path = if curdir { - PathBuf::from(e.path().file_name().unwrap()) + let (path, file_name) = if curdir { + let path = e.path(); + let file_name = path.file_name().unwrap(); + (Box::from(file_name.as_ref()), Some(Box::from(file_name))) } else { - e.path() + let path = e.path().into_boxed_path(); + let file_name = path.file_name().map(Box::from); + (path, file_name) }; - PathWrapper::from_dir_entry(path, e) + PathWrapper::from_dir_entry(path, file_name, e) }) }) .collect::, _>>() @@ -946,7 +961,7 @@ fn fill_todo( children .retain(|x| !x.file_name().unwrap().to_str().unwrap().starts_with('.')); } - children.sort_by(|p1, p2| p2.file_name().cmp(&p1.file_name())); + children.sort_by(|p1, p2| p2.file_name.cmp(&p1.file_name)); todo.extend(children.into_iter().map(|x| Ok((x, idx)))); // Matching the special directory entries . and .. that @@ -957,7 +972,10 @@ fn fill_todo( if !pattern.tokens.is_empty() && pattern.tokens[0] == Char('.') { for &special in &[".", ".."] { if pattern.matches_with(special, options) { - add(todo, PathWrapper::from_path(path.join(special))); + add( + todo, + PathWrapper::from_path(path.join(special).into_boxed_path()), + ); } } }