use super::*;
#[derive(Clone, Copy, PartialEq)]
pub(crate) enum FilterMode {
All,
Manual,
Auto,
Flatpak,
}
impl FilterMode {
pub(crate) fn matches(self, world: &World, name: &str) -> bool {
let is_flatpak = world
.packages
.get(name)
.map(|p| p.source == crate::model::Source::Flatpak)
.unwrap_or(false);
match self {
FilterMode::All => true,
FilterMode::Manual => world.is_manual(name) && !is_flatpak,
FilterMode::Auto => !world.is_manual(name) && !is_flatpak,
FilterMode::Flatpak => is_flatpak,
}
}
pub(crate) fn next(self) -> Self {
match self {
FilterMode::All => FilterMode::Manual,
FilterMode::Manual => FilterMode::Auto,
FilterMode::Auto => FilterMode::Flatpak,
FilterMode::Flatpak => FilterMode::All,
}
}
pub(crate) fn label(self) -> &'static str {
match self {
FilterMode::All => "all",
FilterMode::Manual => "manual [M]",
FilterMode::Auto => "auto [A]",
FilterMode::Flatpak => "flatpak [F]",
}
}
}
impl App {
pub(crate) fn filtered(&mut self) -> Vec<String> {
let (query, base) = {
let base: Vec<String> = self
.base_list()
.iter()
.filter(|n| self.filter.matches(&self.world, n))
.cloned()
.collect();
(self.stack.last().unwrap().query.clone(), base)
};
if query.is_empty() {
return base;
}
let pattern = Pattern::parse(&query, CaseMatching::Ignore, Normalization::Smart);
let world = &self.world;
let matcher = &mut self.matcher;
let mut buf = Vec::new();
let mut scored: Vec<(u32, String)> = base
.into_iter()
.filter_map(|name| {
let haystack = match world.packages.get(&name) {
Some(p) => {
let mut h = name.clone();
if !p.description.is_empty() {
h.push(' ');
h.push_str(&p.description);
}
if let Some(d) = &p.details {
h.push(' ');
h.push_str(d);
}
h
}
None => name.clone(),
};
let utf32 = Utf32Str::new(&haystack, &mut buf);
pattern.score(utf32, matcher).map(|score| (score, name))
})
.collect();
scored.sort_by(|a, b| b.0.cmp(&a.0));
scored.into_iter().map(|(_, name)| name).collect()
}
}