use crate::saga_action_error::ActionError;
use crate::saga_exec::ActionContext;
use crate::ActionName;
use futures::future::BoxFuture;
use serde::de::DeserializeOwned;
use serde::Serialize;
use std::fmt::Debug;
use std::sync::Arc;
pub trait SagaType: Debug + 'static {
type ExecContextType: Debug + Send + Sync + 'static;
}
pub trait ActionData:
Debug + DeserializeOwned + Serialize + Send + Sync + 'static
{
}
impl<T: Debug + DeserializeOwned + Serialize + Send + Sync + 'static> ActionData
for T
{
}
pub type ActionResult = Result<Arc<serde_json::Value>, ActionError>;
pub type UndoResult = Result<(), anyhow::Error>;
pub trait Action<UserType: SagaType>: Debug + Send + Sync {
fn do_it(
&self,
sgctx: ActionContext<UserType>,
) -> BoxFuture<'_, ActionResult>;
fn undo_it(
&self,
sgctx: ActionContext<UserType>,
) -> BoxFuture<'_, UndoResult>;
fn name(&self) -> ActionName;
}
#[derive(Debug)]
pub struct ActionConstant {
value: Arc<serde_json::Value>,
}
impl ActionConstant {
pub fn new(value: Arc<serde_json::Value>) -> ActionConstant {
ActionConstant { value }
}
}
impl<UserType> Action<UserType> for ActionConstant
where
UserType: SagaType,
{
fn do_it(&self, _: ActionContext<UserType>) -> BoxFuture<'_, ActionResult> {
Box::pin(futures::future::ok(self.value.clone()))
}
fn undo_it(&self, _: ActionContext<UserType>) -> BoxFuture<'_, UndoResult> {
Box::pin(futures::future::ok(()))
}
fn name(&self) -> ActionName {
ActionName::new("ActionConstant")
}
}
#[derive(Debug)]
pub struct ActionInjectError {}
impl<UserType: SagaType> Action<UserType> for ActionInjectError {
fn do_it(&self, _: ActionContext<UserType>) -> BoxFuture<'_, ActionResult> {
Box::pin(futures::future::err(ActionError::InjectedError))
}
fn undo_it(&self, _: ActionContext<UserType>) -> BoxFuture<'_, UndoResult> {
unimplemented!();
}
fn name(&self) -> ActionName {
ActionName::new("InjectError")
}
}