use std::{collections::HashMap, sync::Mutex}; use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator}; #[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; fn action(&self, entry: &Entry, action: Action); } #[derive(Default)] pub struct Roftl { sources: Vec>, entries: Vec, narrow_map: Mutex> } impl Roftl { pub fn add_source(mut self, source: Box) -> 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 source(mut self) -> Self { self.entries = self .sources .par_iter_mut() .flat_map_iter(|s| s.entries()) .collect(); println!("Entries {:?}", self.entries); self } pub fn narrow(&self, input: &str) -> Vec<&Entry> { let count = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0)); self.narrow_map.lock().unwrap().clear(); self.entries .par_iter() .enumerate() .filter(|(_idx, e)| e.name.starts_with(input)) .map(move |(idx, e)| { self.narrow_map.lock().unwrap().insert(count.load(std::sync::atomic::Ordering::Acquire), idx); count.fetch_add(1, std::sync::atomic::Ordering::Acquire); 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); } }