use anyhow::{anyhow, Context};
use crate::plugin::{AlumetPluginStart, Plugin};
use super::{phases::AlumetPreStart, AlumetPostStart, ConfigTable};
pub trait AlumetPlugin {
fn name() -> &'static str;
fn version() -> &'static str;
fn init(config: ConfigTable) -> anyhow::Result<Box<Self>>;
fn default_config() -> anyhow::Result<Option<ConfigTable>>;
fn start(&mut self, alumet: &mut AlumetPluginStart) -> anyhow::Result<()>;
fn stop(&mut self) -> anyhow::Result<()>;
fn pre_pipeline_start(&mut self, alumet: &mut AlumetPreStart) -> anyhow::Result<()> {
let _ = alumet; Ok(())
}
fn post_pipeline_start(&mut self, alumet: &mut AlumetPostStart) -> anyhow::Result<()> {
let _ = alumet; Ok(())
}
}
impl<P: AlumetPlugin> Plugin for P {
fn name(&self) -> &str {
P::name() as _
}
fn version(&self) -> &str {
P::version() as _
}
fn start(&mut self, alumet: &mut AlumetPluginStart) -> anyhow::Result<()> {
AlumetPlugin::start(self, alumet)
}
fn stop(&mut self) -> anyhow::Result<()> {
AlumetPlugin::stop(self)
}
fn pre_pipeline_start(&mut self, alumet: &mut AlumetPreStart) -> anyhow::Result<()> {
AlumetPlugin::pre_pipeline_start(self, alumet)
}
fn post_pipeline_start(&mut self, alumet: &mut AlumetPostStart) -> anyhow::Result<()> {
AlumetPlugin::post_pipeline_start(self, alumet)
}
}
pub fn deserialize_config<'de, T: serde::de::Deserialize<'de>>(config: ConfigTable) -> anyhow::Result<T> {
toml::Value::Table(config.0)
.try_into::<T>()
.with_context(|| format!("error when deserializing ConfigTable to {}", std::any::type_name::<T>()))
.context(InvalidConfig)
}
pub fn serialize_config<T: serde::ser::Serialize>(config: T) -> anyhow::Result<ConfigTable> {
let res = match toml::Value::try_from(config) {
Ok(toml::Value::Table(t)) => Ok(ConfigTable(t)),
Ok(wrong) => Err(anyhow!(
"{} did not get serialized to a toml Table but to a {}",
std::any::type_name::<T>(),
wrong.type_str()
)),
Err(e) => Err(anyhow!(
"error when serializing {} to ConfigTable: {e}",
std::any::type_name::<T>()
)),
};
res.context(InvalidConfig)
}
#[derive(Debug)]
pub struct InvalidConfig;
impl std::error::Error for InvalidConfig {}
impl std::fmt::Display for InvalidConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "invalid configuration")
}
}