use std::{
any::Any,
fmt,
sync::{Arc, RwLock},
};
use crate::{error::BoxDynError, worker::context::WorkerContext};
pub type EventHandlerBuilder =
Arc<RwLock<Option<Box<dyn Fn(&WorkerContext, &Event) + Send + Sync>>>>;
pub type EventListener = Arc<RawEventListener>;
pub(crate) type RawEventListener = Box<dyn Fn(&WorkerContext, &Event) + Send + Sync>;
#[non_exhaustive]
pub enum Event {
Start,
HeartBeat,
Custom(Box<dyn Any + 'static + Send + Sync>),
Success(Box<dyn Any + 'static + Send + Sync>),
Error(Arc<BoxDynError>),
Stop,
Exit,
}
impl std::fmt::Debug for Event {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Start => f.write_str("Start"),
Self::HeartBeat => f.write_str("HeartBeat"),
Self::Custom(_) => f.write_str("Custom(..)"),
Self::Success(_) => f.write_str("Success(..)"),
Self::Error(error) => f.debug_tuple("Error").field(error).finish(),
Self::Stop => f.write_str("Stop"),
Self::Exit => f.write_str("Exit"),
}
}
}
impl fmt::Display for Event {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let event_description = match &self {
Self::Start => "worker started".to_owned(),
Self::Custom(_) => "custom event".to_owned(),
Self::Error(err) => format!("worker encountered an error: {err}"),
Self::Stop => "worker stopped".to_owned(),
Self::HeartBeat => "worker heartbeat".to_owned(),
Self::Success(_) => "worker completed task successfully".to_owned(),
Self::Exit => "worker exited".to_owned(),
};
write!(f, "{event_description}")
}
}
impl Event {
#[must_use]
pub fn as_error(&self) -> Option<Arc<BoxDynError>> {
match self {
Self::Error(err) => Some(err.clone()),
_ => None,
}
}
#[must_use]
pub fn custom<T: 'static + Send + Sync>(data: T) -> Self {
Self::Custom(Box::new(data))
}
}