pub mod consts;
mod shims;
use std::fmt;
use serde::{Deserialize, Serialize};
pub use shims::*;
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
pub enum SearchFilter {
None,
URLRegex(String),
}
#[macro_export]
macro_rules! register_plugin {
($t:ty) => {
thread_local! {
static STATE: std::cell::RefCell<$t> = std::cell::RefCell::new(Default::default());
}
fn main() {
STATE.with(|state| {
state.borrow_mut().load();
});
}
#[no_mangle]
pub fn update() {
STATE.with(|state| {
let event = $crate::object_from_stdin::<PluginEvent>();
if let Ok(event) = event {
state.borrow_mut().update(event);
}
})
}
#[no_mangle]
pub fn search_filter() {
STATE.with(|state| {
let filters = state.borrow_mut().search_filter();
let _ = object_to_stdout(&filters);
})
}
};
}
pub trait SpyglassPlugin {
fn load(&mut self);
fn update(&mut self, event: PluginEvent);
fn search_filter(&mut self) -> Vec<SearchFilter> {
vec![SearchFilter::None]
}
}
#[derive(Clone, Deserialize, Serialize)]
pub enum PluginSubscription {
CheckUpdateInterval,
WatchDirectory {
path: String,
recurse: bool,
},
}
impl fmt::Display for PluginSubscription {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
PluginSubscription::CheckUpdateInterval => {
write!(f, "<CheckUpdateInterval>")
}
PluginSubscription::WatchDirectory { path, recurse } => write!(
f,
"<WatchDirectory {} - {}>",
path,
if *recurse {
"recursive"
} else {
"non-recursive"
}
),
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
pub enum PluginEvent {
IntervalUpdate,
FileCreated(String),
FileUpdated(String),
FileDeleted(String),
}
#[derive(Deserialize, Serialize)]
pub enum PluginCommandRequest {
DeleteDoc { url: String },
Enqueue { urls: Vec<String> },
ListDir { path: String },
Subscribe(PluginSubscription),
SqliteQuery { path: String, query: String },
SyncFile { dst: String, src: String },
}
#[derive(Deserialize, Serialize)]
pub struct ListDirEntry {
pub path: String,
pub is_file: bool,
pub is_dir: bool,
}