Armin Friedl
35f01cafe3
- Move to unstable winit since 0.25.0 does not handle transparency correctly on X11 - Matcher trait to enable different matching algorithms - Find correct visualtype for cairo xcb surface: Visualtype was more or less taken randomly which only worked by chance. Now find visualtype that corresponds to visualid of the winit window which should be the correct one.
103 lines
2.7 KiB
Rust
103 lines
2.7 KiB
Rust
use std::{collections::HashMap, sync::{Arc, Mutex, atomic::{AtomicUsize, Ordering}}};
|
|
|
|
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
|
|
|
|
use super::matcher::PrefixMatcher;
|
|
|
|
pub type SourceRef = Box<dyn Source>;
|
|
pub type MatcherRef = Box<dyn Matcher>;
|
|
|
|
#[derive(Clone, Debug)]
|
|
pub struct Entry {
|
|
pub source: &'static str,
|
|
pub name: String,
|
|
pub description: String,
|
|
pub identifier: u64,
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
pub enum Action {
|
|
Primary,
|
|
}
|
|
|
|
pub trait Source: Send + Sync {
|
|
fn name(&self) -> &'static str;
|
|
fn entries(&mut self) -> Vec<Entry>;
|
|
fn action(&self, entry: &Entry, action: Action);
|
|
}
|
|
|
|
pub trait Matcher: Send + Sync {
|
|
fn try_match(&self, haystack: &str, needle: &str) -> Option<(f64, Vec<usize>)>;
|
|
}
|
|
|
|
pub struct Roftl {
|
|
sources: Vec<SourceRef>,
|
|
matcher: MatcherRef,
|
|
entries: Vec<Entry>,
|
|
narrow_map: Mutex<HashMap<usize, usize>>
|
|
}
|
|
|
|
impl Roftl {
|
|
pub fn new() -> Self {
|
|
Roftl {
|
|
sources: vec![],
|
|
matcher: PrefixMatcher::new(),
|
|
entries: vec![],
|
|
narrow_map: Mutex::default()
|
|
}
|
|
}
|
|
|
|
pub fn add_source(mut self, source: SourceRef) -> Self {
|
|
if self.sources.par_iter().any(|s| s.name().eq(source.name())) {
|
|
panic! {"Source with name '{}' already exists", source.name()}
|
|
}
|
|
|
|
self.sources.push(source);
|
|
self
|
|
}
|
|
|
|
pub fn with_matcher(mut self, matcher: MatcherRef) -> Self {
|
|
self.matcher = matcher;
|
|
self
|
|
}
|
|
|
|
pub fn source(&mut self) {
|
|
self.entries = self
|
|
.sources
|
|
.par_iter_mut()
|
|
.flat_map(|s| s.entries())
|
|
.collect();
|
|
|
|
println!("Entries {:?}", self.entries);
|
|
}
|
|
|
|
pub fn narrow(&self, input: &str) -> Vec<&Entry> {
|
|
let count = Arc::new(AtomicUsize::new(0));
|
|
self.narrow_map.lock().unwrap().clear();
|
|
|
|
self.entries
|
|
.par_iter()
|
|
.enumerate()
|
|
.filter(|(_idx, e)| self.matcher.try_match(&e.name, input).is_some())
|
|
.map(move |(idx, e)| {
|
|
self.narrow_map.lock().unwrap().insert(count.fetch_add(1, Ordering::Relaxed), idx);
|
|
e
|
|
})
|
|
.collect()
|
|
}
|
|
|
|
pub fn action(&self, entry_id: i32, action: Action) {
|
|
println!("NarrowMap {:?}", self.narrow_map.lock().unwrap());
|
|
|
|
let real_id = *self.narrow_map.lock().unwrap().get(&((entry_id-1) as usize)).unwrap();
|
|
let entry = self.entries.get(real_id).unwrap();
|
|
|
|
let source = self
|
|
.sources
|
|
.iter()
|
|
.find(|&s| s.name().eq(entry.source))
|
|
.unwrap();
|
|
|
|
source.action(entry, action);
|
|
}
|
|
}
|