2021-10-03 21:07:19 +00:00
|
|
|
use std::{collections::HashMap, sync::Mutex};
|
2021-09-12 14:33:52 +00:00
|
|
|
|
2021-10-03 21:07:19 +00:00
|
|
|
use rayon::iter::{IndexedParallelIterator, IntoParallelRefIterator, IntoParallelRefMutIterator, ParallelIterator};
|
|
|
|
|
|
|
|
#[derive(Clone, Debug)]
|
2021-09-12 14:33:52 +00:00
|
|
|
pub struct Entry {
|
2021-10-03 21:07:19 +00:00
|
|
|
pub source: &'static str,
|
2021-09-12 14:33:52 +00:00
|
|
|
pub name: String,
|
|
|
|
pub description: String,
|
2021-10-03 21:07:19 +00:00
|
|
|
pub identifier: u64,
|
2021-09-12 14:33:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Action {
|
|
|
|
Primary,
|
|
|
|
}
|
|
|
|
|
|
|
|
pub trait Source: Send + Sync {
|
2021-10-03 21:07:19 +00:00
|
|
|
fn name(&self) -> &'static str;
|
|
|
|
fn entries(&mut self) -> Vec<Entry>;
|
2021-09-12 14:33:52 +00:00
|
|
|
fn action(&self, entry: &Entry, action: Action);
|
|
|
|
}
|
|
|
|
|
2021-10-03 21:07:19 +00:00
|
|
|
#[derive(Default)]
|
2021-09-12 14:33:52 +00:00
|
|
|
pub struct Roftl {
|
|
|
|
sources: Vec<Box<dyn Source>>,
|
|
|
|
entries: Vec<Entry>,
|
2021-10-03 21:07:19 +00:00
|
|
|
narrow_map: Mutex<HashMap<usize, usize>>
|
2021-09-12 14:33:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Roftl {
|
2021-10-03 21:07:19 +00:00
|
|
|
pub fn add_source(mut self, source: Box<dyn Source>) -> Self {
|
|
|
|
if self.sources.par_iter().any(|s| s.name().eq(source.name())) {
|
|
|
|
panic! {"Source with name '{}' already exists", source.name()}
|
2021-09-12 14:33:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
self.sources.push(source);
|
|
|
|
self
|
|
|
|
}
|
|
|
|
|
2021-10-03 21:07:19 +00:00
|
|
|
pub fn source(mut self) -> Self {
|
2021-09-12 14:33:52 +00:00
|
|
|
self.entries = self
|
|
|
|
.sources
|
2021-10-03 21:07:19 +00:00
|
|
|
.par_iter_mut()
|
2021-09-12 14:33:52 +00:00
|
|
|
.flat_map_iter(|s| s.entries())
|
|
|
|
.collect();
|
2021-10-03 21:07:19 +00:00
|
|
|
|
|
|
|
println!("Entries {:?}", self.entries);
|
|
|
|
self
|
2021-09-12 14:33:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn narrow(&self, input: &str) -> Vec<&Entry> {
|
2021-10-03 21:07:19 +00:00
|
|
|
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
|
|
|
|
})
|
2021-09-12 14:33:52 +00:00
|
|
|
.collect()
|
|
|
|
}
|
|
|
|
|
2021-10-03 21:07:19 +00:00
|
|
|
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);
|
2021-09-12 14:33:52 +00:00
|
|
|
}
|
|
|
|
}
|