tramli_plugins/resume/
mod.rs1use std::any::TypeId;
2use tramli::{CloneAny, FlowEngine, FlowError, FlowState};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum RichResumeStatus {
7 Transitioned,
8 AlreadyComplete,
9 NoApplicableTransition,
10 Rejected,
11 ExceptionRouted,
12}
13
14#[derive(Debug)]
16pub struct RichResumeResult {
17 pub status: RichResumeStatus,
18 pub error: Option<FlowError>,
19}
20
21pub struct RichResumeExecutor;
23
24impl RichResumeExecutor {
25 pub fn resume<S: FlowState>(
26 engine: &mut FlowEngine<S>,
27 flow_id: &str,
28 external_data: Vec<(TypeId, Box<dyn CloneAny>)>,
29 previous_state: S,
30 ) -> RichResumeResult {
31 match engine.resume_and_execute(flow_id, external_data) {
32 Ok(()) => {
33 let flow = engine.store.get(flow_id);
34 match flow {
35 Some(f) => {
36 if f.is_completed() && f.current_state() == previous_state {
37 RichResumeResult { status: RichResumeStatus::AlreadyComplete, error: None }
38 } else if f.current_state() == previous_state && !f.is_completed() {
39 RichResumeResult { status: RichResumeStatus::Rejected, error: None }
40 } else {
41 RichResumeResult { status: RichResumeStatus::Transitioned, error: None }
42 }
43 }
44 None => RichResumeResult { status: RichResumeStatus::NoApplicableTransition, error: None },
45 }
46 }
47 Err(e) => {
48 let status = match e.code {
49 "FLOW_ALREADY_COMPLETED" => RichResumeStatus::AlreadyComplete,
50 "FLOW_NOT_FOUND" => RichResumeStatus::NoApplicableTransition,
51 "INVALID_TRANSITION" => RichResumeStatus::NoApplicableTransition,
52 _ => RichResumeStatus::ExceptionRouted,
53 };
54 RichResumeResult { status, error: Some(e) }
55 }
56 }
57 }
58}