use std::sync::atomic::{AtomicU8, Ordering};
#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Ord, PartialOrd)]
pub enum ServiceClass {
#[default]
Idle,
Warm,
Audible,
}
impl From<ServiceClass> for u8 {
fn from(class: ServiceClass) -> Self {
match class {
ServiceClass::Idle => 0,
ServiceClass::Warm => 1,
ServiceClass::Audible => 2,
}
}
}
impl From<u8> for ServiceClass {
fn from(value: u8) -> Self {
match value {
2 => Self::Audible,
1 => Self::Warm,
_ => Self::Idle,
}
}
}
pub(crate) struct AtomicServiceClass(AtomicU8);
impl AtomicServiceClass {
pub(crate) fn new(class: ServiceClass) -> Self {
Self(AtomicU8::new(class.into()))
}
pub(crate) fn load(&self) -> ServiceClass {
self.0.load(Ordering::Relaxed).into()
}
pub(crate) fn store(&self, class: ServiceClass) {
self.0.store(class.into(), Ordering::Relaxed);
}
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub(crate) enum TickResult {
Progress,
Waiting,
Backpressured,
Done,
}
pub(crate) trait Node: Send + 'static {
fn on_cancel(&mut self) {}
fn service_class(&self) -> ServiceClass {
ServiceClass::Audible
}
fn tick(&mut self) -> TickResult;
}
impl Node for Box<dyn Node> {
fn on_cancel(&mut self) {
(**self).on_cancel();
}
fn service_class(&self) -> ServiceClass {
(**self).service_class()
}
fn tick(&mut self) -> TickResult {
(**self).tick()
}
}
#[cfg(test)]
mod tests {
use kithara_test_utils::kithara;
use super::*;
#[kithara::test]
fn service_class_ordering() {
assert!(ServiceClass::Idle < ServiceClass::Warm);
assert!(ServiceClass::Warm < ServiceClass::Audible);
}
#[kithara::test]
fn service_class_default_is_idle() {
assert_eq!(ServiceClass::default(), ServiceClass::Idle);
}
}