use std::path::PathBuf;
use globset::{GlobBuilder, GlobSetBuilder};
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FileKind {
File,
Directory,
Symlink,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum EntryOrigin {
Primary,
Recovered,
}
#[derive(Debug, Clone)]
pub struct FileEntry {
pub rel_path: String,
pub abs_path: PathBuf,
pub kind: FileKind,
pub origin: EntryOrigin,
}
#[derive(Debug, Clone)]
pub struct FileTree {
pub root: PathBuf,
pub entries: Vec<FileEntry>,
}
impl FileTree {
#[must_use]
pub fn entry(&self, rel_path: &str) -> Option<&FileEntry> {
self.entries
.binary_search_by(|e| e.rel_path.as_str().cmp(rel_path))
.ok()
.and_then(|i| self.entries.get(i))
}
#[must_use]
pub fn entries_with_origin(&self, origin: EntryOrigin) -> Vec<&FileEntry> {
self.entries.iter().filter(|e| e.origin == origin).collect()
}
pub fn glob(
&self,
pattern: &str,
case_sensitive: bool,
) -> Result<Vec<&FileEntry>, globset::Error> {
let glob = GlobBuilder::new(pattern)
.case_insensitive(!case_sensitive)
.literal_separator(false)
.build()?;
let mut builder = GlobSetBuilder::new();
let _ = builder.add(glob);
let set = builder.build()?;
Ok(self
.entries
.iter()
.filter(|e| set.is_match(&e.rel_path))
.collect())
}
}