#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PublishState {
Idle,
Publishing,
Active,
Done,
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum PublishError {
#[error("invalid transition from {from:?} on event {event}")]
InvalidTransition {
from: PublishState,
event: String,
},
}
pub struct PublishStateMachine {
state: PublishState,
}
impl Default for PublishStateMachine {
fn default() -> Self {
Self::new()
}
}
impl PublishStateMachine {
pub fn new() -> Self {
Self { state: PublishState::Idle }
}
pub fn state(&self) -> PublishState {
self.state
}
pub fn on_publish_sent(&mut self) -> Result<(), PublishError> {
if self.state == PublishState::Idle {
self.state = PublishState::Publishing;
Ok(())
} else {
Err(PublishError::InvalidTransition {
from: self.state,
event: "on_publish_sent".to_string(),
})
}
}
pub fn on_publish_ok(&mut self) -> Result<(), PublishError> {
if self.state == PublishState::Publishing {
self.state = PublishState::Active;
Ok(())
} else {
Err(PublishError::InvalidTransition {
from: self.state,
event: "on_publish_ok".to_string(),
})
}
}
pub fn on_publish_error(&mut self) -> Result<(), PublishError> {
if self.state == PublishState::Publishing {
self.state = PublishState::Done;
Ok(())
} else {
Err(PublishError::InvalidTransition {
from: self.state,
event: "on_publish_error".to_string(),
})
}
}
pub fn on_publish_done_sent(&mut self) -> Result<(), PublishError> {
if self.state == PublishState::Active {
self.state = PublishState::Done;
Ok(())
} else {
Err(PublishError::InvalidTransition {
from: self.state,
event: "on_publish_done_sent".to_string(),
})
}
}
}