use crate::{
cancellation::{CancellationFlag, Outcome},
spelled_path::{SpelledPath, WikiDirectory},
};
use ignore::{WalkBuilder, overrides::OverrideBuilder};
use std::path::Path;
pub fn wiki_tree_walker(wiki_directory: &Path) -> WalkBuilder {
let mut overrides = OverrideBuilder::new(wiki_directory);
overrides
.add("!.git/")
.expect("The static .git override should be valid.")
.add("!.hg/")
.expect("The static .hg override should be valid.");
let overrides = overrides
.build()
.expect("The static overrides should compile.");
let mut walker_builder = WalkBuilder::new(wiki_directory);
walker_builder
.current_dir(wiki_directory)
.follow_links(true)
.hidden(false)
.parents(false)
.require_git(false)
.overrides(overrides);
walker_builder
}
#[derive(Debug, Eq, PartialEq)]
pub enum Visibility {
Visible,
Empty,
Ignored,
}
pub fn visibility(
wiki_directory: &WikiDirectory,
target: &SpelledPath,
cancellation: &CancellationFlag,
) -> Outcome<Visibility> {
let mut walker_builder = wiki_tree_walker(wiki_directory.path());
walker_builder.filter_entry({
let wiki_directory = wiki_directory.clone();
let target = target.clone();
move |entry| {
let path = wiki_directory.entry_path(entry);
target.starts_with(&path) || path.starts_with(&target)
}
});
let mut reached = false;
for entry in walker_builder.build().flatten() {
if cancellation.is_cancelled() {
return Outcome::Cancelled;
}
let path = wiki_directory.entry_path(&entry);
if path == *target {
reached = true;
}
if path.starts_with(target)
&& entry
.file_type()
.expect("Only standard input lacks a file type.")
.is_file()
{
return Outcome::Completed(Visibility::Visible);
}
}
Outcome::Completed(if reached {
Visibility::Empty
} else {
Visibility::Ignored
})
}