pub mod content;
pub mod path;
use std::collections::{HashMap, HashSet};
use std::ops::Range;
use uuid::Uuid;
use crate::model::file::File;
pub use content::ContentSearcher;
pub use path::PathSearcher;
#[derive(Debug, Clone, Default)]
pub struct SearchResult {
pub id: Uuid,
pub filename: String,
pub parent_path: String,
pub is_folder: bool,
pub path_indices: Vec<u32>,
pub path_matches: Vec<ContentMatch>,
pub content_matches: Vec<ContentMatch>,
}
#[derive(Debug, Clone)]
pub enum SearchFilter {
Path(String),
}
#[derive(Debug, Clone)]
pub struct ContentMatch {
pub range: Range<usize>,
pub exact: bool,
}
use crate::Lb;
impl Lb {
pub async fn path_searcher(&self) -> PathSearcher {
PathSearcher::new(self).await
}
}
pub(crate) fn build_descendants(files: &[File]) -> HashMap<Uuid, Vec<Uuid>> {
let parent_of: HashMap<Uuid, Uuid> = files.iter().map(|f| (f.id, f.parent)).collect();
let mut descendants: HashMap<Uuid, Vec<Uuid>> = HashMap::new();
for f in files {
let mut node = f.id;
while let Some(&parent) = parent_of.get(&node) {
if parent == node {
break; }
descendants.entry(parent).or_default().push(f.id);
node = parent;
}
}
descendants
}
pub(crate) fn resolve_filter(
filter: Option<SearchFilter>, path_to_id: &HashMap<String, Uuid>,
descendants: &HashMap<Uuid, Vec<Uuid>>,
) -> Option<HashSet<Uuid>> {
filter.map(|SearchFilter::Path(path)| {
path_to_id
.get(&path)
.and_then(|id| descendants.get(id))
.map(|ids| ids.iter().copied().collect())
.unwrap_or_default()
})
}