crazy_train/step.rs
1//! This module defines the `StepTrait` trait, which outlines the necessary methods that
2//! any step in the execution process must implement. It also defines the `Plan` struct,
3//! which encapsulates a command to be executed as part of a step.
4//!
5
6use std::collections::HashMap;
7
8use crate::{
9 errors,
10 executer::{self, Output},
11 randomizer::Randomizer,
12};
13
14/// Enum representing the different types of steps that can be executed.
15#[derive(Debug)]
16pub enum Kind {
17 Setup,
18 Plan,
19 Check,
20 Test,
21}
22
23/// A trait that defines the behavior required for steps in the execution process.
24#[allow(clippy::module_name_repetitions)]
25pub trait StepTrait {
26 /// Prepares the setup by creating necessary directories and performing initialization steps.
27 ///
28 /// # Errors
29 ///
30 /// Returns an error if the setup fails, such as when it is unable to create the required directory.
31 fn setup(&self) -> errors::Result<()> {
32 Ok(())
33 }
34 /// Generates a plan for execution.
35 ///
36 /// # Errors
37 ///
38 /// when could not prepare the plan
39 fn plan(&self, randomizer: &Randomizer) -> errors::Result<Plan>;
40
41 /// Determines if the execution result indicates success for this step.
42 ///
43 /// the bool result point if the runner should continue to the next steps or not.
44 ///
45 /// # Errors
46 /// When plan result parsing is not the expected behavior.
47 fn is_success(
48 &self,
49 execution_result: &Output,
50 plan_ctx: &PlanCtx,
51 ) -> Result<bool, &'static str>;
52
53 /// Optionally returns a command to run as a check after the execution of the plan.
54 fn run_check(&self) -> Option<String> {
55 None
56 }
57
58 /// Optionally returns a command to run as a test after the execution of the plan.
59 fn run_test(&self) -> Option<String> {
60 None
61 }
62
63 /// Serializes the step to a YAML representation.
64 fn to_yaml(&self) -> serde_yaml::Value;
65}
66
67/// A struct that represents a plan for executing a command as part of a step.
68#[derive(Debug, Clone)]
69pub struct Plan {
70 pub id: String,
71 pub command: String,
72 pub ctx: PlanCtx,
73}
74
75#[derive(Default, Debug, Clone)]
76pub struct PlanCtx {
77 pub vars: HashMap<String, String>,
78}
79
80impl Plan {
81 /// Executes the command defined in the plan.
82 ///
83 /// # Errors
84 ///
85 /// on shell command failure.
86 pub fn execute(&self) -> errors::Result<executer::Output> {
87 executer::run_sh(&self.command)
88 }
89
90 #[must_use]
91 pub fn new<T>(command: impl Into<String>) -> Self {
92 Self {
93 id: std::any::type_name::<T>().to_string(),
94 command: command.into(),
95 ctx: PlanCtx::default(),
96 }
97 }
98
99 #[must_use]
100 pub fn with_vars<T>(command: impl Into<String>, vars: HashMap<String, String>) -> Self {
101 Self {
102 id: std::any::type_name::<T>().to_string(),
103 command: command.into(),
104 ctx: PlanCtx { vars },
105 }
106 }
107}