use crate::SagaId;
use crate::SagaName;
use crate::SagaNodeEvent;
use anyhow::Context;
use async_trait::async_trait;
use schemars::JsonSchema;
use serde::Deserialize;
use serde::Serialize;
use std::convert::TryFrom;
use std::fmt;
#[async_trait]
pub trait SecStore: fmt::Debug + Send + Sync {
async fn saga_create(
&self,
create_params: SagaCreateParams,
) -> Result<(), anyhow::Error>;
async fn record_event(&self, event: SagaNodeEvent);
async fn saga_update(&self, id: SagaId, update: SagaCachedState);
}
#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)]
pub struct SagaCreateParams {
pub id: SagaId,
pub name: SagaName,
pub dag: serde_json::Value,
pub state: SagaCachedState,
}
#[derive(
Clone, Copy, Debug, Eq, PartialEq, Serialize, Deserialize, JsonSchema,
)]
#[serde(rename_all = "snake_case")]
pub enum SagaCachedState {
Running,
Unwinding,
Done,
}
impl fmt::Display for SagaCachedState {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", <&str>::from(self))
}
}
impl TryFrom<&str> for SagaCachedState {
type Error = anyhow::Error;
fn try_from(value: &str) -> Result<Self, Self::Error> {
let json = serde_json::to_string(value).unwrap();
serde_json::from_str(&json).context("parsing saga state")
}
}
impl<'a> From<&'a SagaCachedState> for &'a str {
fn from(s: &'a SagaCachedState) -> &'a str {
match s {
SagaCachedState::Running => "running",
SagaCachedState::Unwinding => "unwinding",
SagaCachedState::Done => "done",
}
}
}
#[derive(Debug)]
pub struct InMemorySecStore {}
impl InMemorySecStore {
pub fn new() -> InMemorySecStore {
InMemorySecStore {}
}
}
#[async_trait]
impl SecStore for InMemorySecStore {
async fn saga_create(
&self,
_create_params: SagaCreateParams,
) -> Result<(), anyhow::Error> {
Ok(())
}
async fn record_event(&self, _event: SagaNodeEvent) {
}
async fn saga_update(&self, _id: SagaId, _update: SagaCachedState) {
}
}