mirror of
https://github.com/BurntSushi/ripgrep.git
synced 2025-05-19 09:40:22 -07:00
ignore: add sort_by_file_path builder method
This permits callers to sort entries by their full file path, which makes it easy to query for various file statistics. It would have been better to provide a comparator on DirEntry itself, similar to how walkdir does it, but this seems to require quite a bit of work to make the types work out, assuming we want to continue to use walkdir's sorting support (we do).
This commit is contained in:
parent
f9ce7a84a8
commit
510f15f4da
@ -453,12 +453,16 @@ pub struct WalkBuilder {
|
|||||||
max_filesize: Option<u64>,
|
max_filesize: Option<u64>,
|
||||||
follow_links: bool,
|
follow_links: bool,
|
||||||
same_file_system: bool,
|
same_file_system: bool,
|
||||||
sorter: Option<Arc<
|
sorter: Option<Sorter>,
|
||||||
Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static
|
|
||||||
>>,
|
|
||||||
threads: usize,
|
threads: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
enum Sorter {
|
||||||
|
ByName(Arc<Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static>),
|
||||||
|
ByPath(Arc<Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static>),
|
||||||
|
}
|
||||||
|
|
||||||
impl fmt::Debug for WalkBuilder {
|
impl fmt::Debug for WalkBuilder {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.debug_struct("WalkBuilder")
|
f.debug_struct("WalkBuilder")
|
||||||
@ -496,7 +500,7 @@ impl WalkBuilder {
|
|||||||
pub fn build(&self) -> Walk {
|
pub fn build(&self) -> Walk {
|
||||||
let follow_links = self.follow_links;
|
let follow_links = self.follow_links;
|
||||||
let max_depth = self.max_depth;
|
let max_depth = self.max_depth;
|
||||||
let cmp = self.sorter.clone();
|
let sorter = self.sorter.clone();
|
||||||
let its = self.paths.iter().map(move |p| {
|
let its = self.paths.iter().map(move |p| {
|
||||||
if p == Path::new("-") {
|
if p == Path::new("-") {
|
||||||
(p.to_path_buf(), None)
|
(p.to_path_buf(), None)
|
||||||
@ -507,12 +511,20 @@ impl WalkBuilder {
|
|||||||
if let Some(max_depth) = max_depth {
|
if let Some(max_depth) = max_depth {
|
||||||
wd = wd.max_depth(max_depth);
|
wd = wd.max_depth(max_depth);
|
||||||
}
|
}
|
||||||
if let Some(ref cmp) = cmp {
|
if let Some(ref sorter) = sorter {
|
||||||
let cmp = cmp.clone();
|
match sorter.clone() {
|
||||||
|
Sorter::ByName(cmp) => {
|
||||||
wd = wd.sort_by(move |a, b| {
|
wd = wd.sort_by(move |a, b| {
|
||||||
cmp(a.file_name(), b.file_name())
|
cmp(a.file_name(), b.file_name())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
Sorter::ByPath(cmp) => {
|
||||||
|
wd = wd.sort_by(move |a, b| {
|
||||||
|
cmp(a.path(), b.path())
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
(p.to_path_buf(), Some(WalkEventIter::from(wd)))
|
(p.to_path_buf(), Some(WalkEventIter::from(wd)))
|
||||||
}
|
}
|
||||||
}).collect::<Vec<_>>().into_iter();
|
}).collect::<Vec<_>>().into_iter();
|
||||||
@ -726,6 +738,30 @@ impl WalkBuilder {
|
|||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set a function for sorting directory entries by their path.
|
||||||
|
///
|
||||||
|
/// If a compare function is set, the resulting iterator will return all
|
||||||
|
/// paths in sorted order. The compare function will be called to compare
|
||||||
|
/// entries from the same directory.
|
||||||
|
///
|
||||||
|
/// This is like `sort_by_file_name`, except the comparator accepts
|
||||||
|
/// a `&Path` instead of the base file name, which permits it to sort by
|
||||||
|
/// more criteria.
|
||||||
|
///
|
||||||
|
/// This method will override any previous sorter set by this method or
|
||||||
|
/// by `sort_by_file_name`.
|
||||||
|
///
|
||||||
|
/// Note that this is not used in the parallel iterator.
|
||||||
|
pub fn sort_by_file_path<F>(
|
||||||
|
&mut self,
|
||||||
|
cmp: F,
|
||||||
|
) -> &mut WalkBuilder
|
||||||
|
where F: Fn(&Path, &Path) -> cmp::Ordering + Send + Sync + 'static
|
||||||
|
{
|
||||||
|
self.sorter = Some(Sorter::ByPath(Arc::new(cmp)));
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
/// Set a function for sorting directory entries by file name.
|
/// Set a function for sorting directory entries by file name.
|
||||||
///
|
///
|
||||||
/// If a compare function is set, the resulting iterator will return all
|
/// If a compare function is set, the resulting iterator will return all
|
||||||
@ -733,11 +769,14 @@ impl WalkBuilder {
|
|||||||
/// names from entries from the same directory using only the name of the
|
/// names from entries from the same directory using only the name of the
|
||||||
/// entry.
|
/// entry.
|
||||||
///
|
///
|
||||||
|
/// This method will override any previous sorter set by this method or
|
||||||
|
/// by `sort_by_file_path`.
|
||||||
|
///
|
||||||
/// Note that this is not used in the parallel iterator.
|
/// Note that this is not used in the parallel iterator.
|
||||||
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
|
pub fn sort_by_file_name<F>(&mut self, cmp: F) -> &mut WalkBuilder
|
||||||
where F: Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static
|
where F: Fn(&OsStr, &OsStr) -> cmp::Ordering + Send + Sync + 'static
|
||||||
{
|
{
|
||||||
self.sorter = Some(Arc::new(cmp));
|
self.sorter = Some(Sorter::ByName(Arc::new(cmp)));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user