1use crate::jsep::JsepNode;
2use rkyv::{Archive, Deserialize, Serialize};
3use std::sync::Arc;
4
5#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
6#[archive(compare(PartialEq))]
7#[archive_attr(derive(Debug))]
8pub struct StartEventDef {
9 pub outgoing: Arc<[i32]>,
10}
11
12#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
13#[archive(compare(PartialEq))]
14#[archive_attr(derive(Debug))]
15pub struct EndEventDef {
16 pub incoming: Arc<[i32]>,
17}
18
19#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
20#[archive(compare(PartialEq))]
21#[archive_attr(derive(Debug))]
22pub struct UserTaskDef {
23 pub incoming: Arc<[i32]>,
24 pub outgoing: Arc<[i32]>,
25}
26
27#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
28#[archive(compare(PartialEq))]
29#[archive_attr(derive(Debug))]
30pub struct ExclusiveGatewayDef {
31 pub incoming: Arc<[i32]>,
32 pub outgoing: Arc<[i32]>,
33 pub default: i32,
34}
35
36#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
37#[archive(compare(PartialEq))]
38#[archive_attr(derive(Debug))]
39pub enum TaskDef {
40 StartEvent(StartEventDef),
41 EndEvent(EndEventDef),
42 UserTask(UserTaskDef),
43 ExclusiveGateway(ExclusiveGatewayDef),
44}
45
46#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
47#[archive(compare(PartialEq))]
48#[archive_attr(derive(Debug))]
49pub struct Task {
50 pub id: i32,
51 pub def: TaskDef,
52}
53
54impl Task {
55 pub fn is_user_task(&self) -> bool {
56 match &self.def {
57 TaskDef::UserTask(_) => true,
58 _ => false,
59 }
60 }
61}
62
63#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
64#[archive(compare(PartialEq))]
65#[archive_attr(derive(Debug))]
66pub enum ConditionExpression {
67 Jsep(JsepNode),
68}
69
70#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
71#[archive(compare(PartialEq))]
72#[archive_attr(derive(Debug))]
73pub struct Flow {
74 pub id: i32,
75 pub source_ref: i32,
76 pub target_ref: i32,
77 pub condition_expression: Option<ConditionExpression>,
78}
79
80#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
81#[archive(compare(PartialEq))]
82#[archive_attr(derive(Debug))]
83pub struct WorkflowProperties {
84 pub autostart: bool,
85}
86
87#[derive(Archive, Deserialize, Serialize, Debug, PartialEq)]
88#[archive(
89 bound(
90 serialize = "__S: rkyv::ser::ScratchSpace + rkyv::ser::SharedSerializeRegistry + rkyv::ser::Serializer",
91 deserialize = "__D: rkyv::de::SharedDeserializeRegistry"
92 ),
93 compare(PartialEq)
94)]
95#[archive_attr(derive(Debug))]
96pub struct WorkflowDefinition {
97 pub version: Arc<str>,
98 pub id: Arc<str>,
99 pub start_event: i32,
100 #[omit_bounds]
101 pub parent: Option<Arc<WorkflowDefinition>>,
102 pub flows: Arc<[Flow]>,
103 pub flow_ids: Arc<[Arc<str>]>,
104 pub tasks: Arc<[Task]>,
105 pub task_ids: Arc<[Arc<str>]>,
106 #[omit_bounds]
107 pub children: Option<Arc<[WorkflowDefinition]>>,
108 pub options: Option<WorkflowProperties>,
109}
110
111impl WorkflowDefinition {
112 pub fn root_start_event(&self) -> i32 {
113 if let Some(parent) = self.parent.as_ref() {
114 parent.root_start_event()
115 } else {
116 self.start_event
117 }
118 }
119
120 pub fn format_id(&self, id: &str) -> String {
121 format!("{}_{id}", self.id.as_ref())
122 }
123
124 pub fn user_tasks(&self) -> Vec<i32> {
125 self.tasks
126 .iter()
127 .enumerate()
128 .filter_map(|(idx, task)| {
129 if task.is_user_task() {
130 Some(idx as i32)
131 } else {
132 None
133 }
134 })
135 .collect()
136 }
137}