1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
use crate::common::{Job, StartParameter, Step};
use crate::SchemaVersion;
use chrono::NaiveDateTime;
use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct WorkflowInstance {
  /// Creation date of this Workflow
  pub created_at: NaiveDateTime,
  /// The Id of this Workflow
  pub id: u32,
  /// The Identifier of the workflow, used to reference it
  pub identifier: String,
  /// Mentions if it defines a live workflow
  pub is_live: bool,
  /// The label of the workflow, used as displayed name
  pub label: String,
  /// Reference of this Workflow
  pub reference: Option<String>,
  /// Schema version of this Workflow
  pub schema_version: String,
  /// Status of this Workflow
  pub status: Option<Status>,
  /// Major version of this Workflow
  pub version_major: u32,
  /// Minor version of this Workflow
  pub version_minor: u32,
  /// Micro version of this Workflow
  pub version_micro: u32,
  /// Definition of available parameters to start the workflow
  #[serde(default, skip_serializing_if = "Vec::is_empty")]
  pub start_parameters: Vec<StartParameter>,
  /// List of steps
  #[serde(default)]
  pub steps: Vec<Step>,
  /// List of jobs
  #[serde(default)]
  pub jobs: Vec<Job>,
  /// List of tags to classify the workflow
  #[serde(default, skip_serializing_if = "Vec::is_empty")]
  pub tags: Vec<String>,
}

impl WorkflowInstance {
  pub fn schema_version(&self) -> SchemaVersion {
    match self.schema_version.as_str() {
      "1.8" => SchemaVersion::_1_8,
      "1.9" => SchemaVersion::_1_9,
      "1.10" => SchemaVersion::_1_10,
      "1.11" => SchemaVersion::_1_11,
      _ => unreachable!(),
    }
  }

  pub fn get_number_of_steps(&self) -> usize {
    self.steps.len()
  }

  pub fn get_passed_steps_count(&self) -> usize {
    let mut count = 0;
    for step in self.steps.clone() {
      if let Some(jobs_status) = step.jobs {
        if jobs_status.errors > 0
          || jobs_status.completed > 0
          || jobs_status.skipped > 0
          || jobs_status.processing > 0
        {
          count += 1
        }
      }
    }
    count
  }
}

#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct Status {
  pub id: u32,
  pub inserted_at: NaiveDateTime,
  pub state: String,
}

#[cfg(test)]
mod tests {
  use crate::WorkflowInstance;

  #[test]
  fn get_number_of_steps_tests() {
    let str_workflow = include_str!("../tests/resources/workflow_instances/sleeper.json");
    let workflow_sleeper: WorkflowInstance = serde_json::from_str(str_workflow).unwrap();
    assert_eq!(workflow_sleeper.get_number_of_steps(), 1);

    let str_workflow = include_str!("../tests/resources/workflow_instances/find_credits.json");
    let workflow_find_credits: WorkflowInstance = serde_json::from_str(str_workflow).unwrap();
    assert_eq!(workflow_find_credits.get_number_of_steps(), 11);
  }

  #[test]
  fn get_passed_steps_count_tests() {
    let str_workflow = include_str!("../tests/resources/workflow_instances/sleeper.json");
    let workflow_sleeper: WorkflowInstance = serde_json::from_str(str_workflow).unwrap();
    assert_eq!(workflow_sleeper.get_passed_steps_count(), 1);

    let str_workflow = include_str!("../tests/resources/workflow_instances/find_credits.json");
    let workflow_find_credits: WorkflowInstance = serde_json::from_str(str_workflow).unwrap();
    assert_eq!(workflow_find_credits.get_passed_steps_count(), 11);
  }
}