use std::sync::{Arc, atomic::{AtomicUsize, Ordering}};
#[derive(Debug, PartialEq)]
pub enum ServiceStatus {
Starting,
Started,
Stopping,
Stopped,
}
impl From<usize> for ServiceStatus {
fn from(raw_state: usize) -> Self {
match raw_state {
0x01 => ServiceStatus::Starting,
0x02 => ServiceStatus::Started,
0x04 => ServiceStatus::Stopping,
0x08 => ServiceStatus::Stopped,
_ => panic!("There is no `ServiceState` that corresponds to {}", raw_state),
}
}
}
impl From<ServiceStatus> for usize {
fn from(state: ServiceStatus) -> Self {
match state {
ServiceStatus::Starting => 0x01,
ServiceStatus::Started => 0x02,
ServiceStatus::Stopping => 0x04,
ServiceStatus::Stopped => 0x08,
}
}
}
#[derive(Debug, Clone)]
pub struct ServiceStatusFlag {
flag: Arc<AtomicUsize>,
}
impl ServiceStatusFlag {
pub fn new(status: ServiceStatus) -> Self {
ServiceStatusFlag {
flag: Arc::new(AtomicUsize::new(status.into())),
}
}
pub fn get_status(&self) -> ServiceStatus {
self.flag.load(Ordering::SeqCst).into()
}
pub fn set_status(&self, status: ServiceStatus) {
self.flag.store(status.into(), Ordering::SeqCst)
}
pub fn starting(&self) {
self.set_status(ServiceStatus::Starting)
}
pub fn started(&self) {
self.set_status(ServiceStatus::Started)
}
pub fn stopping(&self) {
self.set_status(ServiceStatus::Stopping)
}
pub fn stopped(&self) {
self.set_status(ServiceStatus::Stopped)
}
pub fn is_starting(&self) -> bool {
self.get_status() == ServiceStatus::Starting
}
pub fn is_started(&self) -> bool {
self.get_status() == ServiceStatus::Started
}
pub fn is_stopping(&self) -> bool {
self.get_status() == ServiceStatus::Stopping
}
pub fn is_stopped(&self) -> bool {
self.get_status() == ServiceStatus::Stopped
}
pub fn await_started(&self) {
while !self.is_started() {};
}
pub fn await_stopped(&self) {
while !self.is_stopped() {};
}
}
impl Default for ServiceStatusFlag {
fn default() -> Self {
ServiceStatusFlag::new(ServiceStatus::Stopped)
}
}