1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
use crate::cli::Command;
use crate::cmd;
use crate::rules;
use crate::stdout;
use crate::watcher;
use crate::watches::Watches;

pub const DEFAULT_FILENAME: &str = ".watch.yaml";

/// # `WatchCommand`
///
/// Starts watcher to listen the change events configured
/// in watch.yaml
///
pub struct WatchCommand {
    watches: Watches,
    verbose: bool,
}

impl WatchCommand {
    pub fn new(watches: Watches, verbose: bool) -> Self {
        stdout::verbose(&format!("watches {:?}", watches), verbose);

        WatchCommand { watches, verbose }
    }
}

impl Command for WatchCommand {
    fn execute(&self) -> Result<(), String> {
        stdout::verbose("Verbose mode enabled.", self.verbose);

        if let Some(rules) = self.watches.run_on_init() {
            stdout::info("Running on init commands.");

            let results = rules::commands(rules)
                .iter()
                .map(cmd::execute)
                .collect::<Vec<Result<(), String>>>();

            stdout::present_results(results);
        }

        watcher::events(
            |file_changed| {
                if let Some(rules) = self.watches.watch(file_changed) {
                    if let Err(err) = cmd::execute(&"clear".to_owned()) {
                        stdout::error(&format!("failed to clear screen: {:?}", err));
                    }

                    stdout::verbose(
                        &format!("Triggered by change in: {}", file_changed),
                        self.verbose,
                    );

                    stdout::verbose(&format!("Rules: {:?}", rules), self.verbose);

                    let results = rules::template(rules::commands(rules), file_changed)
                        .iter()
                        .map(cmd::execute)
                        .collect::<Vec<Result<(), String>>>();
                    stdout::present_results(results);
                }
            },
            self.verbose,
        );
        Ok(())
    }
}