use std::time::{Duration, SystemTime};
use dex_sdk::{
Attribute, AttributeIndex, AttributeMap, Context, Flow, HandlerError, HandlerResult,
PersistenceSchema, Step, StepDecision, StepList, Wait,
};
#[derive(Debug, PartialEq, serde::Deserialize, serde::Serialize)]
pub(crate) struct PersistenceModel {
pub(crate) value: i32,
}
pub(crate) struct PersistenceWorkflow {
pub(crate) initial: Attribute<String>,
pub(crate) data: Attribute<String>,
pub(crate) model: Attribute<PersistenceModel>,
pub(crate) data_map: AttributeMap<String>,
pub(crate) keyword: Attribute<String>,
pub(crate) integer: Attribute<i32>,
pub(crate) datetime: Attribute<SystemTime>,
start: PersistenceStep,
}
impl PersistenceWorkflow {
pub(crate) fn new() -> Self {
let data = Attribute::new("data-obj-1");
let model = Attribute::new("data-obj-2");
let data_map = AttributeMap::new("data-map");
let keyword = Attribute::new("CustomKeywordField").indexed(AttributeIndex::keyword());
let integer = Attribute::new("CustomIntField").indexed(AttributeIndex::int());
let datetime = Attribute::new("CustomDatetimeField").indexed(AttributeIndex::date_time());
Self {
initial: Attribute::new("data-obj-0"),
start: PersistenceStep {
data: data.clone(),
model: model.clone(),
data_map: data_map.clone(),
keyword: keyword.clone(),
integer: integer.clone(),
datetime: datetime.clone(),
},
data,
model,
data_map,
keyword,
integer,
datetime,
}
}
}
impl Flow for PersistenceWorkflow {
type StartInput = String;
fn steps(&self) -> StepList<'_, Self::StartInput> {
StepList::start(&self.start)
}
fn persistence(&self) -> PersistenceSchema {
PersistenceSchema::new()
.attribute(&self.initial)
.attribute(&self.data)
.attribute(&self.model)
.attribute_map(&self.data_map)
.attribute(&self.keyword)
.attribute(&self.integer)
.attribute(&self.datetime)
}
}
struct PersistenceStep {
data: Attribute<String>,
model: Attribute<PersistenceModel>,
data_map: AttributeMap<String>,
keyword: Attribute<String>,
integer: Attribute<i32>,
datetime: Attribute<SystemTime>,
}
impl Step for PersistenceStep {
type Input = String;
fn wait_for(&self, context: &mut Context, input: String) -> HandlerResult<Wait> {
self.data.set(context, input.clone())?;
self.data_map.set(context, "one", input.clone())?;
context.set_step_execution_local("local", input.clone())?;
context.record_event("written", input)?;
Ok(Wait::skip_immediately())
}
fn execute(&self, context: &mut Context, input: String) -> HandlerResult<StepDecision> {
let local: String = context.step_execution_local("local")?;
if local != input {
return Err(HandlerError::new("step execution local did not round trip"));
}
self.keyword.set(context, input)?;
self.integer.set(context, 1)?;
self.datetime.set(
context,
SystemTime::UNIX_EPOCH + Duration::from_secs(1_681_766_269),
)?;
self.model.set(context, PersistenceModel { value: 0 })?;
self.data_map.delete(context, "one")?;
Ok(StepDecision::graceful_complete(
self.data.get_required(context)?,
))
}
}