use super::{RunStatus, WorkflowRecord};
use crate::base::{ProgramId, WorkflowIx};
use crate::function::CallInfo;
use std::fmt;
use std::ops::{BitOr, BitOrAssign};
use std::time::Duration;
pub trait Observer: Send + Sync + 'static {
fn interest(&self) -> Interest {
Interest::WORKFLOWS | Interest::TASKS
}
fn on(&self, event: &Event<'_>);
}
#[derive(Clone, Copy, PartialEq, Eq, Hash)]
pub struct Interest(u8);
impl Interest {
pub const NONE: Self = Self(0);
pub const WORKFLOWS: Self = Self(1);
pub const TASKS: Self = Self(1 << 1);
pub const TIMINGS: Self = Self(1 << 2);
pub const ALL: Self = Self::WORKFLOWS.union(Self::TASKS).union(Self::TIMINGS);
const NAMES: [(Self, &'static str); 3] = [
(Self::WORKFLOWS, "WORKFLOWS"),
(Self::TASKS, "TASKS"),
(Self::TIMINGS, "TIMINGS"),
];
#[must_use]
pub const fn union(self, other: Self) -> Self {
Self(self.0 | other.0)
}
#[must_use]
pub const fn contains(self, other: Self) -> bool {
self.0 & other.0 == other.0
}
#[must_use]
pub const fn is_empty(self) -> bool {
self.0 == 0
}
}
impl BitOr for Interest {
type Output = Self;
fn bitor(self, other: Self) -> Self {
self.union(other)
}
}
impl BitOrAssign for Interest {
fn bitor_assign(&mut self, other: Self) {
*self = self.union(other);
}
}
impl fmt::Debug for Interest {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Interest(")?;
if self.is_empty() {
f.write_str("NONE")?;
}
let set = Self::NAMES.iter().filter(|(flag, _)| self.contains(*flag));
for (i, (_, name)) in set.enumerate() {
if i > 0 {
f.write_str(" | ")?;
}
f.write_str(name)?;
}
f.write_str(")")
}
}
#[derive(Debug)]
#[non_exhaustive]
pub enum Event<'a> {
#[non_exhaustive]
RunStarted {
program: ProgramId,
message_id: &'a str,
channel: Option<&'a str>,
considered: usize,
},
#[non_exhaustive]
WorkflowStarted {
workflow: WorkflowIx,
id: &'a str,
},
#[non_exhaustive]
TaskFinished {
info: &'a CallInfo<'a>,
status: Option<u16>,
elapsed: Option<Duration>,
},
#[non_exhaustive]
WorkflowFinished {
record: &'a WorkflowRecord<'a>,
elapsed: Option<Duration>,
},
#[non_exhaustive]
RunFinished {
message_id: &'a str,
status: &'a RunStatus,
errors: usize,
elapsed: Option<Duration>,
},
}