ocy_core/
cleaner.rs

1use crate::{
2    command::CommandExecutor,
3    filesystem::FileSystemClean,
4    models::{RemovalAction, RemovalCandidate},
5};
6use eyre::Report;
7use eyre::Result;
8
9pub struct Cleaner<CS, CE, FS, N>
10where
11    CS: IntoIterator<Item = RemovalCandidate>,
12    FS: FileSystemClean,
13    CE: CommandExecutor,
14    N: CleanerNotifier,
15{
16    candidates: CS,
17    fs: FS,
18    command_executor: CE,
19    notifier: N,
20}
21
22pub trait CleanerNotifier {
23    fn notify_removal_started(&self, candidate: &RemovalCandidate);
24    fn notify_removal_success(&self, candidate: RemovalCandidate);
25    fn notify_removal_failed(&self, candidate: RemovalCandidate, report: Report);
26    fn notify_removal_finish(&self);
27}
28
29impl<CS, CE, FS, N> Cleaner<CS, CE, FS, N>
30where
31    CS: IntoIterator<Item = RemovalCandidate>,
32    FS: FileSystemClean,
33    CE: CommandExecutor,
34    N: CleanerNotifier,
35{
36    pub fn new(candidates: CS, fs: FS, command_executor: CE, notifier: N) -> Self {
37        Self {
38            candidates,
39            fs,
40            command_executor,
41            notifier,
42        }
43    }
44
45    pub fn clean(self) {
46        for candidate in self.candidates {
47            self.notifier.notify_removal_started(&candidate);
48            match clean_candidate(&self.fs, &self.command_executor, &candidate) {
49                Ok(_) => {
50                    self.notifier.notify_removal_success(candidate);
51                }
52                Err(report) => {
53                    self.notifier.notify_removal_failed(candidate, report);
54                }
55            }
56        }
57        self.notifier.notify_removal_finish();
58    }
59}
60
61fn clean_candidate(
62    fs: &impl FileSystemClean,
63    command_executor: &impl CommandExecutor,
64    candidate: &RemovalCandidate,
65) -> Result<()> {
66    match &candidate.action {
67        RemovalAction::Delete { file_info, .. } => fs.remove_file(file_info),
68        RemovalAction::RunCommand { work_dir, command } => {
69            command_executor.execute_command(work_dir, command)
70        }
71    }
72}