use std::collections::{HashMap, HashSet};
use super::node::{InternalItem, NodeId};
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ItemSearchState {
pub query: String,
pub(crate) query_lower: String,
pub visible_ids: HashSet<NodeId>,
pub match_count: usize,
}
pub(crate) fn walk_for_search_item<T>(
id: NodeId,
store: &HashMap<NodeId, InternalItem<T>>,
display_fn: &dyn Fn(&T) -> String,
query_lower: &str,
visible: &mut HashSet<NodeId>,
match_count: &mut usize,
) -> bool {
let Some(item) = store.get(&id) else {
return false;
};
let label_lower = display_fn(&item.data).to_ascii_lowercase();
let self_matches = label_lower.contains(query_lower);
if self_matches {
*match_count += 1;
}
let mut descendant_matches = false;
for &child_id in &item.children_ids {
if walk_for_search_item(
child_id,
store,
display_fn,
query_lower,
visible,
match_count,
) {
descendant_matches = true;
}
}
let has_visible = self_matches || descendant_matches;
if has_visible {
visible.insert(id);
}
has_visible
}