use std::{fmt, future::Future, ops::Deref, pin::Pin, sync::Arc};
use process::Command;
use crate::envelope::Envelope;
#[derive(Clone, Debug)]
#[cfg_attr(
feature = "derive",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "kebab-case")
)]
pub struct WatchHook {
pub cmd: Option<Command>,
pub notify: Option<WatchNotifyConfig>,
#[cfg_attr(feature = "derive", serde(skip))]
pub callback: Option<WatchFn>,
}
impl Eq for WatchHook {
}
impl PartialEq for WatchHook {
fn eq(&self, other: &Self) -> bool {
self.cmd == other.cmd && self.notify == other.notify
}
}
#[derive(Clone)]
pub struct WatchFn(
#[allow(clippy::type_complexity)]
Arc<
dyn Fn(&Envelope) -> Pin<Box<dyn Future<Output = crate::Result<()>> + Send>> + Send + Sync,
>,
);
impl WatchFn {
pub fn new<F: Future<Output = crate::Result<()>> + Send + 'static>(
f: impl Fn(&Envelope) -> F + Send + Sync + 'static,
) -> Self {
Self(Arc::new(move |envelope| Box::pin(f(envelope))))
}
}
impl Default for WatchFn {
fn default() -> Self {
Self(Arc::new(|_| Box::pin(async { Ok(()) })))
}
}
impl Deref for WatchFn {
type Target = Arc<
dyn Fn(&Envelope) -> Pin<Box<dyn Future<Output = crate::Result<()>> + Send>> + Send + Sync,
>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl fmt::Debug for WatchFn {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "WatchFn()")
}
}
#[derive(Clone, Debug, Default, Eq, PartialEq)]
#[cfg_attr(
feature = "derive",
derive(serde::Serialize, serde::Deserialize),
serde(rename_all = "kebab-case")
)]
pub struct WatchNotifyConfig {
pub summary: String,
pub body: String,
}