use rayon::iter::{IntoParallelRefIterator, ParallelIterator}; #[derive(Clone)] pub struct Entry { pub name: String, pub description: String, pub source: *const dyn Source, pub id: u32 } unsafe impl Sync for Entry {} unsafe impl Send for Entry {} #[derive(Debug)] pub enum Action { Primary, } pub trait Source: Send + Sync { fn name(&self) -> &str; fn entries(&self) -> Vec; fn action(&self, entry: &Entry, action: Action); } pub struct Roftl { sources: Vec>, entries: Vec, } impl Roftl { pub fn new() -> Roftl { Roftl { sources: vec![], entries: vec![], } } pub fn add_source(&mut self, source: Box) -> &mut Roftl { self.sources.push(source); self } pub fn source(&mut self) { self.entries = self .sources .par_iter() .flat_map_iter(|s| s.entries()) .collect(); } pub fn narrow(&self, input: &str) -> Vec<&Entry> { self.entries.par_iter() .filter(|e| e.name.starts_with(input)) .collect() } pub fn action(&self, entry: &Entry, action: Action) { unsafe { Source::action(&*entry.source, entry, action); } } }