use std::collections::{BTreeMap, BTreeSet};
use crate::{ToolGroup, ToolGroupInfo};
pub(crate) fn collect_groups<'a>(
entries: impl Iterator<Item = (&'a String, Option<ToolGroupInfo>)>,
) -> Vec<ToolGroup> {
let mut grouped: BTreeMap<String, (ToolGroupInfo, Vec<String>)> = BTreeMap::new();
for (name, info) in entries {
if let Some(info) = info {
grouped
.entry(info.id.clone())
.or_insert_with(|| (info, Vec::new()))
.1
.push(name.clone());
}
}
grouped
.into_values()
.map(|(info, mut members)| {
members.sort();
ToolGroup::from_info(info, members)
})
.collect()
}
pub(crate) fn select_by_names<'a, V, T>(
set: &'a BTreeMap<String, V>,
names: Option<&[String]>,
project: impl Fn(&'a V) -> T,
) -> Vec<T> {
match names {
None => set.values().map(project).collect(),
Some(names) => {
let mut seen = BTreeSet::new();
names
.iter()
.filter_map(|name| {
let key = name.to_ascii_lowercase();
set.get(&key)
.and_then(|entry| seen.insert(key).then(|| project(entry)))
})
.collect()
}
}
}