treeboot_core/
executor.rs1use crate::commands::{CommandExecutionOptions, execute_commands};
2use crate::files::{FileApplyOptions, apply_file_operations};
3use crate::{ActionPlan, Reporter, Result};
4
5#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
7pub struct ExecuteOptions {
8 pub strict: bool,
10 pub force: bool,
12 pub dry_run: bool,
14 pub skip_commands: bool,
16}
17
18#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
20pub struct ExecutionReport {
21 pub file_action_count: usize,
23}
24
25#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
27pub struct Executor {
28 options: ExecuteOptions,
29}
30
31impl Executor {
32 #[must_use]
34 pub const fn new(options: ExecuteOptions) -> Self {
35 Self { options }
36 }
37
38 pub fn execute_files(
45 &self,
46 plan: &ActionPlan,
47 reporter: &mut dyn Reporter,
48 ) -> Result<ExecutionReport> {
49 let report = apply_file_operations(
50 plan,
51 FileApplyOptions {
52 strict: self.options.strict,
53 force: self.options.force,
54 dry_run: self.options.dry_run,
55 },
56 reporter,
57 )?;
58
59 Ok(ExecutionReport {
60 file_action_count: report.action_count,
61 })
62 }
63
64 pub fn execute_commands(&self, plan: &ActionPlan, reporter: &mut dyn Reporter) -> Result<()> {
70 execute_commands(
71 plan,
72 CommandExecutionOptions {
73 dry_run: self.options.dry_run,
74 },
75 reporter,
76 )
77 }
78
79 pub fn execute(
86 &self,
87 plan: &ActionPlan,
88 reporter: &mut dyn Reporter,
89 ) -> Result<ExecutionReport> {
90 let report = self.execute_files(plan, reporter)?;
91
92 if !self.options.skip_commands {
93 self.execute_commands(plan, reporter)?;
94 }
95
96 Ok(report)
97 }
98}