#![allow(unused_variables)]
#![allow(dead_code)]
use crate::config::RouteConfig;
use crate::server::server::AppState;
use humphrey::http::{Request, Response};
use humphrey::stream::Stream;
use std::any::Any;
use std::collections::HashMap;
use std::fmt::Debug;
use std::sync::Arc;
pub trait Plugin: Any + Send + Sync + Debug {
fn name(&self) -> &'static str;
fn on_load(
&mut self,
config: &HashMap<String, String>,
state: Arc<AppState>,
) -> PluginLoadResult<(), &'static str> {
PluginLoadResult::Ok(())
}
fn on_request(
&self,
request: &mut Request,
state: Arc<AppState>,
route: &RouteConfig,
) -> Option<Response> {
None
}
fn on_websocket_request(
&self,
request: &mut Request,
stream: Stream,
state: Arc<AppState>,
route: Option<&RouteConfig>,
) -> Option<Stream> {
Some(stream)
}
fn on_response(&self, response: &mut Response, state: Arc<AppState>, route: &RouteConfig) {}
fn on_unload(&mut self) {}
}
#[macro_export]
macro_rules! declare_plugin {
($plugin_type:ty, $constructor:path) => {
#[no_mangle]
pub extern "C" fn _plugin_init() -> *mut dyn Plugin {
let constructor: fn() -> $plugin_type = $constructor;
let object = constructor();
let boxed: Box<dyn Plugin> = Box::new(object);
Box::into_raw(boxed)
}
};
}
#[must_use = "this `PluginLoadResult` may be a `NonFatal` or `Fatal` variant, which should be handled"]
pub enum PluginLoadResult<T, E> {
Ok(T),
NonFatal(E),
Fatal(E),
}
impl<T, E> PluginLoadResult<T, E> {
pub const fn is_ok(&self) -> bool {
matches!(self, Self::Ok(_))
}
pub const fn is_err(&self) -> bool {
!self.is_ok()
}
pub const fn is_fatal(&self) -> bool {
matches!(self, Self::Fatal(_))
}
pub fn map<U, F: FnOnce(T) -> U>(self, op: F) -> PluginLoadResult<U, E> {
match self {
Self::Ok(value) => PluginLoadResult::Ok(op(value)),
Self::NonFatal(e) => PluginLoadResult::NonFatal(e),
Self::Fatal(e) => PluginLoadResult::Fatal(e),
}
}
}
impl<T, E> PluginLoadResult<T, E>
where
E: Debug,
{
pub fn unwrap(self) -> T {
match self {
Self::Ok(value) => value,
Self::NonFatal(e) => panic!("Unwrap called on non-fatal error: {:?}", e),
Self::Fatal(e) => panic!("Unwrap called on fatal error: {:?}", e),
}
}
}