travailleur/workflow/instance.rs
1//! Workflow instance type
2
3use serde::{Deserialize, Serialize};
4use serde_json::{Map, Value};
5use uuid::Uuid;
6
7use crate::workflow::definition::{Identifier, WorkflowDefinition};
8
9/// Workflow instance container.
10///
11/// TODO expand
12#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct WorkflowInstance {
14 /// Workflow instance ID. Unique among all workflow instances.
15 pub id: String,
16
17 /// Workflow identifier.
18 pub workflow_identifier: Identifier,
19
20 /// Name of current workflow state, or `None` if workflow has completed.
21 pub state: Option<String>,
22
23 /// Workflow data (a JSON object), passed between states.
24 ///
25 /// If [`state`](Self::state) is `None`, this is the final workflow output.
26 pub data: Map<String, Value>,
27
28 /// Whether workflow has terminated prematurely.
29 pub terminated: bool,
30}
31
32impl WorkflowInstance {
33 /// Generates a new workflow instance from a [`WorkflowDefinition`].
34 ///
35 /// The instance will have a new, randomly-generated [`id`], will start at the workflow's
36 /// [start state] with the provided workflow input (or an empty JSON object if no initial
37 /// input is provided).
38 ///
39 /// [`id`]: Self::id
40 /// [start state]: WorkflowDefinition::start_state_name
41 pub fn for_definition(
42 definition: &WorkflowDefinition,
43 input: Option<Map<String, Value>>,
44 ) -> Self {
45 Self {
46 id: Self::generate_id(),
47 workflow_identifier: definition.identifier.clone(),
48 state: definition.start_state_name().map(|name| name.into()),
49 data: input.unwrap_or_default(),
50 terminated: false,
51 }
52 }
53
54 /// Generates a new workflow instance for a workflow identified via its [`Identifier`].
55 ///
56 /// The instance will have a new, randomly-generated [`id`], will point to the given `state`
57 /// and contain the given `data` (or an empty JSON object if no data is provided).
58 ///
59 /// [`id`]: Self::id
60 pub fn for_workflow_identifier<I>(
61 identifier: I,
62 state: Option<String>,
63 data: Option<Map<String, Value>>,
64 ) -> Self
65 where
66 I: Into<Identifier>,
67 {
68 Self {
69 id: Self::generate_id(),
70 workflow_identifier: identifier.into(),
71 state,
72 data: data.unwrap_or_default(),
73 terminated: false,
74 }
75 }
76
77 fn generate_id() -> String {
78 Uuid::new_v4().into()
79 }
80}