use std::future::Future;
use std::pin::Pin;
use super::controller::PostingContext;
pub type BoxFuture<'a, T> = Pin<Box<dyn Future<Output = T> + Send + 'a>>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum StepOutcome {
Completed,
Skipped
}
#[derive(Debug, thiserror::Error)]
#[error("{message}")]
pub struct PostingError {
pub message: String
}
impl PostingError {
pub fn new(message: impl Into<String>) -> Self {
Self { message: message.into() }
}
}
impl From<anyhow::Error> for PostingError {
fn from(err: anyhow::Error) -> Self {
Self { message: err.to_string() }
}
}
impl From<String> for PostingError {
fn from(message: String) -> Self {
Self { message }
}
}
impl From<&str> for PostingError {
fn from(message: &str) -> Self {
Self { message: message.to_string() }
}
}
pub trait PostingStep<T>: Send {
fn name(&self) -> &str;
fn execute<'a>(
&'a mut self,
ctx: &'a mut PostingContext<T>
) -> BoxFuture<'a, Result<StepOutcome, PostingError>>;
fn undo<'a>(
&'a mut self,
ctx: &'a mut PostingContext<T>
) -> BoxFuture<'a, Result<(), PostingError>>;
}
pub type BoxPostingStep<T> = Box<dyn PostingStep<T>>;