From 7027290697ae1238326d41030e325b6c210a83fe Mon Sep 17 00:00:00 2001 From: Nick Groenen Date: Sun, 13 Dec 2020 23:15:13 +0100 Subject: [PATCH] Allow custom filter function to be passed with WalkOptions --- src/lib.rs | 2 +- src/walker.rs | 29 ++++++++++++++++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index f409ded..ca90ff9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -180,7 +180,7 @@ impl<'a> Exporter<'a> { }); } - let vault = vault_contents(self.root.as_path(), self.walk_options)?; + let vault = vault_contents(self.root.as_path(), self.walk_options.clone())?; vault.clone().into_par_iter().try_for_each(|file| { let relative_path = file .strip_prefix(&self.root.clone()) diff --git a/src/walker.rs b/src/walker.rs index 77bae4f..efbbae8 100644 --- a/src/walker.rs +++ b/src/walker.rs @@ -1,15 +1,28 @@ use crate::{ExportError, WalkDirError}; -use ignore::{Walk, WalkBuilder}; +use ignore::{DirEntry, Walk, WalkBuilder}; use snafu::ResultExt; +use std::fmt; use std::path::{Path, PathBuf}; type Result = std::result::Result; +type FilterFn = dyn Fn(&DirEntry) -> bool + Send + Sync + 'static; -#[derive(Debug, Clone, Copy)] +#[derive(Clone)] pub struct WalkOptions<'a> { pub ignore_filename: &'a str, pub ignore_hidden: bool, pub honor_gitignore: bool, + pub filter_fn: Option>, +} + +impl<'a> fmt::Debug for WalkOptions<'a> { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("WalkOptions") + .field("ignore_filename", &self.ignore_filename) + .field("ignore_hidden", &self.ignore_hidden) + .field("honor_gitignore", &self.honor_gitignore) + .finish() + } } impl<'a> WalkOptions<'a> { @@ -18,11 +31,13 @@ impl<'a> WalkOptions<'a> { ignore_filename: ".export-ignore", ignore_hidden: true, honor_gitignore: true, + filter_fn: None, } } fn build_walker(self, path: &Path) -> Walk { - WalkBuilder::new(path) + let mut walker = WalkBuilder::new(path); + walker .standard_filters(false) .parents(true) .hidden(self.ignore_hidden) @@ -30,8 +45,12 @@ impl<'a> WalkOptions<'a> { .require_git(true) .git_ignore(self.honor_gitignore) .git_global(self.honor_gitignore) - .git_exclude(self.honor_gitignore) - .build() + .git_exclude(self.honor_gitignore); + + if let Some(filter) = self.filter_fn { + walker.filter_entry(filter); + } + walker.build() } }