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}