wfrs_model/
model.rs

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}