acts_next/model/
workflow.rs

1use crate::{scheduler::NodeTree, Act, ActError, ModelBase, Result, Step, Vars};
2use serde::{Deserialize, Serialize};
3use serde_json::Value as JsonValue;
4
5#[derive(Debug, Clone, Default, Serialize, Deserialize)]
6pub struct Workflow {
7    #[serde(default)]
8    pub id: String,
9
10    #[serde(default)]
11    pub name: String,
12
13    #[serde(default)]
14    pub tag: String,
15
16    #[serde(default)]
17    pub steps: Vec<Step>,
18
19    #[serde(default)]
20    pub env: Vars,
21
22    #[serde(default)]
23    pub inputs: Vars,
24
25    #[serde(default)]
26    pub outputs: Vars,
27
28    #[serde(default)]
29    pub setup: Vec<Act>,
30
31    #[serde(default)]
32    ver: u32,
33}
34
35impl Workflow {
36    pub fn from_yml(s: &str) -> Result<Self> {
37        let workflow = serde_yaml::from_str::<Workflow>(s);
38        match workflow {
39            Ok(v) => Ok(v),
40            Err(e) => Err(ActError::Model(format!("{}", e))),
41        }
42    }
43
44    pub fn from_json(s: &str) -> Result<Self> {
45        let workflow = serde_json::from_str::<Workflow>(s);
46        match workflow {
47            Ok(v) => Ok(v),
48            Err(e) => Err(ActError::Model(format!("{}", e))),
49        }
50    }
51
52    pub fn set_env(&mut self, vars: &Vars) {
53        for (name, value) in vars {
54            self.env
55                .entry(name.clone())
56                .and_modify(|v| *v = value.clone())
57                .or_insert(value.clone());
58        }
59    }
60
61    pub fn set_inputs(&mut self, vars: &Vars) {
62        for (name, value) in vars {
63            self.inputs
64                .entry(name.clone())
65                .and_modify(|v| *v = value.clone())
66                .or_insert(value.clone());
67        }
68    }
69
70    pub fn print(&self) {
71        let mut root = NodeTree::new();
72        root.load(self).unwrap();
73        root.print();
74    }
75
76    pub fn tree_output(&self) -> String {
77        let mut root = NodeTree::new();
78        root.load(self).unwrap();
79        root.tree_output()
80    }
81
82    pub fn step(&self, id: &str) -> Option<&Step> {
83        match self.steps.iter().find(|s| s.id == id) {
84            Some(s) => Some(s),
85            None => None,
86        }
87    }
88    pub fn set_id(&mut self, id: &str) {
89        self.id = id.to_string();
90    }
91
92    pub fn set_ver(&mut self, ver: u32) {
93        self.ver = ver;
94    }
95
96    pub fn to_yml(&self) -> Result<String> {
97        match serde_yaml::to_string(self) {
98            Ok(s) => Ok(s),
99            Err(e) => Err(ActError::Model(e.to_string())),
100        }
101    }
102
103    pub fn to_json(&self) -> Result<String> {
104        match serde_json::to_string(self) {
105            Ok(s) => Ok(s),
106            Err(e) => Err(ActError::Model(e.to_string())),
107        }
108    }
109
110    pub fn valid(&self) -> Result<()> {
111        let mut root = NodeTree::new();
112        root.load(self)?;
113        Ok(())
114    }
115}
116
117impl ModelBase for Workflow {
118    fn id(&self) -> &str {
119        &self.id
120    }
121}
122
123/// for builder
124impl Workflow {
125    pub fn new() -> Self {
126        Default::default()
127    }
128
129    pub fn with_id(mut self, id: &str) -> Self {
130        self.id = id.to_string();
131        self
132    }
133
134    pub fn with_name(mut self, name: &str) -> Self {
135        self.name = name.to_string();
136        self
137    }
138
139    pub fn with_tag(mut self, tag: &str) -> Self {
140        self.tag = tag.to_string();
141        self
142    }
143
144    pub fn with_input(mut self, name: &str, value: JsonValue) -> Self {
145        self.inputs.insert(name.to_string(), value);
146        self
147    }
148
149    pub fn with_env(mut self, name: &str, value: JsonValue) -> Self {
150        self.env.insert(name.to_string(), value);
151        self
152    }
153
154    pub fn with_output(mut self, name: &str, value: JsonValue) -> Self {
155        self.outputs.insert(name.to_string(), value);
156        self
157    }
158
159    pub fn with_step(mut self, build: fn(Step) -> Step) -> Self {
160        let step = Step::default();
161        self.steps.push(build(step));
162        self
163    }
164
165    pub fn with_setup(mut self, build: fn(Vec<Act>) -> Vec<Act>) -> Self {
166        let stmts = Vec::new();
167        self.setup = build(stmts);
168        self
169    }
170}