1pub(crate) mod trait_impl;
2use crate::{Play, Playbook};
3use std::fmt;
4
5#[derive(Debug, Clone)]
53pub enum ExePlay {
54 Sequential(Vec<ExePlay>),
56 Parallel(Vec<ExePlay>),
58 Single(Box<Play>),
60}
61
62pub use ExePlay::Parallel as ExeParallel;
63pub use ExePlay::Sequential as ExeSequential;
64pub use ExePlay::Single as ExeSingle;
65
66#[derive(Debug, Clone, PartialEq, Eq, Hash)]
67pub struct StackName(String);
68
69impl From<&str> for StackName {
70 fn from(s: &str) -> Self {
71 StackName(s.to_string())
72 }
73}
74
75impl fmt::Display for StackName {
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 write!(f, "{}", self.0)
78 }
79}
80
81#[cfg(test)]
82mod test_exe_play_struct {
83 use super::*;
84 use crate::utils::test::*;
85
86 #[test]
87 fn test_sequential_play_exec() {
88 let _play_exec = ExeSequential(vec![
89 ExeSingle(Box::new(create_play_helper("sample1"))),
90 ExeSingle(Box::new(create_play_helper("sample2"))),
91 ExeParallel(vec![
92 ExeSingle(Box::new(create_play_helper("sample3"))),
93 ExeSingle(Box::new(create_play_helper("sample4"))),
94 ]),
95 ]);
96 }
97}
98
99impl ExePlay {
100 pub fn push(&mut self, p: ExePlay) {
110 match self {
111 ExePlay::Sequential(plays) => plays.push(p),
112 ExePlay::Parallel(plays) => plays.push(p),
113 ExePlay::Single(_) => {
114 let p1 = self.clone();
115 *self = ExeSequential(vec![p1, p]);
116 }
117 }
118 }
119 pub fn push_play(&mut self, p: Play) {
120 match self {
121 ExePlay::Sequential(plays) => plays.push(p.into()),
122 ExePlay::Parallel(plays) => plays.push(p.into()),
123 ExePlay::Single(_) => {
124 let p1 = self.clone();
125 *self = ExeSequential(vec![p1, p.into()]);
126 }
127 }
128 }
129}
130
131#[cfg(test)]
132mod test_exe_play {
133 use super::*;
134 use crate::utils::test::*;
135
136 #[test]
137 fn test_exe_play_single_push() {
138 let mut exe_play = ExeSingle(create_play_helper("sample1").into());
139 exe_play.push(create_play_helper("sample2").into());
140 match exe_play {
141 ExePlay::Sequential(plays) => {
142 assert_eq!(plays.len(), 2);
143 }
145 _ => unreachable!("exe_play should be ExeSequential"),
146 }
147 }
148 #[test]
149 fn test_exe_play_sequential_push() {
150 let mut exe_play = ExeSequential(vec![create_play_helper("sample1").into()]);
151 exe_play.push(create_play_helper("sample2").into());
152 match exe_play {
153 ExePlay::Sequential(plays) => {
154 assert_eq!(plays.len(), 2);
155 }
157 _ => unreachable!("exe_play should be ExeSequential"),
158 }
159 }
160 #[test]
161 fn test_exe_play_parallel_push() {
162 let mut exe_play = ExeParallel(vec![create_play_helper("sample1").into()]);
163 exe_play.push(create_play_helper("sample2").into());
164 match exe_play {
165 ExePlay::Parallel(plays) => {
166 assert_eq!(plays.len(), 2);
167 }
169 _ => unreachable!("exe_play should be ExeParallel"),
170 }
171 }
172}
173
174impl From<Play> for ExePlay {
175 fn from(play: Play) -> Self {
176 ExePlay::Single(Box::new(play))
177 }
178}
179
180impl From<Box<Play>> for ExePlay {
181 fn from(play: Box<Play>) -> Self {
182 ExePlay::Single(play)
183 }
184}
185
186impl From<Vec<ExePlay>> for ExePlay {
187 fn from(plays: Vec<ExePlay>) -> Self {
188 ExePlay::Sequential(plays)
189 }
190}
191
192#[cfg(test)]
193mod test_exe_play_from_impl {
194 use super::*;
195 use crate::utils::test::*;
196
197 #[test]
198 fn test_exe_play_from_play() {
199 let play = create_play_helper("sample");
200 let exe_play: ExePlay = play.into();
201 match exe_play {
202 ExePlay::Single(_) => {
203 }
205 _ => unreachable!("exe_play should be ExeSingle"),
206 }
207 }
208 #[test]
209 fn test_exe_play_from_play_vec() {
210 let plays = vec![
211 create_play_helper("sample1").into(),
212 create_play_helper("sample2").into(),
213 create_play_helper("sample3").into(),
214 ];
215 let exe_play: ExePlay = plays.into();
216 match exe_play {
217 ExePlay::Sequential(_) => {
218 }
220 _ => unreachable!("exe_play should be ExeSequential"),
221 }
222 }
223}
224
225#[derive(Debug, Clone)]
227pub enum ExePlaybook {
228 Sequential(Vec<ExePlaybook>),
229 Parallel(Vec<ExePlaybook>),
230 Single(Box<Playbook>),
231}
232
233impl ExePlaybook {
234 pub fn from_exe_play(name: &str, exe_play: ExePlay) -> Self {
235 match exe_play {
236 ExePlay::Sequential(plays) => Self::Sequential(
237 plays
238 .into_iter()
239 .enumerate()
240 .map(|(i, exe_play)| Self::from_exe_play(&format!("{name}_seq{i}"), exe_play))
241 .collect(),
242 ),
243 ExePlay::Parallel(plays) => Self::Parallel(
244 plays
245 .into_iter()
246 .enumerate()
247 .map(|(i, exe_play)| Self::from_exe_play(&format!("{name}_par{i}"), exe_play))
248 .collect(),
249 ),
250 ExePlay::Single(play) => Self::Single(Box::new(Playbook {
251 name: format!(
252 "{name}_{}",
253 play.name.as_str().to_lowercase().replace(' ', "_")
254 ),
255 plays: vec![*play],
256 })),
257 }
258 }
259}