#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum FetchState {
Idle,
Pending,
Receiving,
Done,
}
#[derive(Debug, thiserror::Error, PartialEq, Eq)]
pub enum FetchError {
#[error("invalid transition from {from:?} on event {event}")]
InvalidTransition {
from: FetchState,
event: String,
},
}
pub struct FetchStateMachine {
state: FetchState,
}
impl Default for FetchStateMachine {
fn default() -> Self {
Self::new()
}
}
impl FetchStateMachine {
pub fn new() -> Self {
Self { state: FetchState::Idle }
}
pub fn state(&self) -> FetchState {
self.state
}
pub fn on_fetch_sent(&mut self) -> Result<(), FetchError> {
if self.state == FetchState::Idle {
self.state = FetchState::Pending;
Ok(())
} else {
Err(FetchError::InvalidTransition {
from: self.state,
event: "on_fetch_sent".to_string(),
})
}
}
pub fn on_fetch_ok(&mut self) -> Result<(), FetchError> {
if self.state == FetchState::Pending {
self.state = FetchState::Receiving;
Ok(())
} else {
Err(FetchError::InvalidTransition {
from: self.state,
event: "on_fetch_ok".to_string(),
})
}
}
pub fn on_fetch_error(&mut self) -> Result<(), FetchError> {
if self.state == FetchState::Pending {
self.state = FetchState::Done;
Ok(())
} else {
Err(FetchError::InvalidTransition {
from: self.state,
event: "on_fetch_error".to_string(),
})
}
}
pub fn on_fetch_cancel(&mut self) -> Result<(), FetchError> {
if self.state == FetchState::Pending || self.state == FetchState::Receiving {
self.state = FetchState::Done;
Ok(())
} else {
Err(FetchError::InvalidTransition {
from: self.state,
event: "on_fetch_cancel".to_string(),
})
}
}
pub fn on_stream_fin(&mut self) -> Result<(), FetchError> {
if self.state == FetchState::Receiving {
self.state = FetchState::Done;
Ok(())
} else {
Err(FetchError::InvalidTransition {
from: self.state,
event: "on_stream_fin".to_string(),
})
}
}
pub fn on_stream_reset(&mut self) -> Result<(), FetchError> {
if self.state == FetchState::Receiving {
self.state = FetchState::Done;
Ok(())
} else {
Err(FetchError::InvalidTransition {
from: self.state,
event: "on_stream_reset".to_string(),
})
}
}
}