echo_library/types/workflow.rs
1use super::*;
2
3#[derive(Debug, PartialEq, Eq, ProvidesStaticType, Allocative, Clone, Deserialize, Serialize)]
4pub struct Workflow {
5 pub name: String,
6 pub version: String,
7 pub tasks: HashMap<String, Task>,
8}
9
10impl Workflow {
11 /// Finds the list of dependencies that the given task depends on.
12 ///
13 /// # Arguments
14 ///
15 /// * `task_name` - A string slice that holds the name of the task
16 /// * `workflow_index` - A integer that holds the index of the workflow where the given
17 /// task is stored
18 ///
19 /// # Returns
20 ///
21 /// * `Option<Vec<String>>` - An option containing a vector of dependencies if the task is
22 /// found, or None if the task have no dependency
23 ///
24 pub fn get_dependencies(&self, task_name: &str) -> Option<Vec<String>> {
25 let mut dependencies = Vec::<String>::new();
26
27 for task in self.tasks.get(task_name).unwrap().depend_on.iter() {
28 dependencies.push(task.task_name.clone());
29 }
30
31 Some(dependencies)
32 }
33
34 /// Performs depth-first search (DFS) in the workflow subgraph.
35 /// This method is invoked within the get_flow method to perform `Topological-Sorting`
36 /// # Arguments
37 ///
38 /// * `task_name` - A string slice that holds the name of the task where the DFS should start
39 /// * `visited` - A mutable reference to a HashMap that holds the list of task (node) names
40 /// and a boolean indicating whether it has been traversed
41 /// * `flow` - A mutable reference to a vector of strings that stores the flow of the DFS
42 /// traversal
43 /// * `workflow_index` - An integer that holds the index of the workflow where the given
44 /// task is located
45 ///
46 fn dfs(&self, task_name: &str, visited: &mut HashMap<String, bool>, flow: &mut Vec<String>) {
47 visited.insert(task_name.to_string(), true);
48
49 for depend_task in self.get_dependencies(task_name).unwrap().iter() {
50 if !visited[depend_task] {
51 self.dfs(depend_task, visited, flow);
52 }
53 }
54
55 flow.push(task_name.to_string());
56 }
57
58 /// Performs topological sort in the workflow graph.
59 /// This method is invoked by the parse_module.
60 ///
61 /// # Arguments
62 ///
63 /// * `workflow_index` - An integer that holds the index of the workflow for which
64 /// topological sort is to be performed
65 ///
66 /// # Returns
67 ///
68 /// * `Vec<String>` - A vector containing the list of task names in the order of the
69 /// topological sort
70 ///
71 pub fn get_flow(&self) -> Vec<String> {
72 let mut visited = HashMap::<String, bool>::new();
73 let mut flow = Vec::<String>::new();
74
75 for task in self.tasks.iter() {
76 visited.insert(task.0.to_string(), false);
77 }
78
79 for task in self.tasks.iter() {
80 if !visited[task.0] {
81 self.dfs(task.0, &mut visited, &mut flow)
82 }
83 }
84
85 flow
86 }
87}