sdoc/workflow/
mod.rs

1#[cfg(test)]
2mod test;
3
4use dto::Response;
5use util;
6
7#[derive( Debug, PartialEq)]
8pub struct Work {
9    instruction: Instruction,
10    error: Option<Instruction>
11}
12
13impl Work {
14    pub fn instruction(instruction: Instruction) -> Work {
15        Work { instruction, error: None }
16    }
17    pub fn response(response: Response) -> Work {
18        Work { instruction: Instruction::ExitCode(response), error: None }
19    }
20    pub fn on_error(self, instruction: Instruction) -> Work {
21        Work { error: Some(instruction), ..self }
22    }
23
24    fn run(self, runner: &InstructionRunner) -> Response {
25        match runner.run(&self.instruction) {
26            Response::Err(error) => {
27                self.error
28                    .map(|a| runner.run(&a))
29                    .unwrap_or(Response::Err(error))
30            },
31            r => r
32        }
33    }
34}
35
36#[derive( Debug, PartialEq, Clone)]
37pub enum Instruction {
38    Display(String, Response),
39    SystemCommand(String, bool),
40    ExitCode(Response)
41}
42
43pub trait InstructionRunner {
44    fn run(&self, instruction: &Instruction) -> Response;
45}
46
47pub struct SystemRunner;
48impl InstructionRunner for SystemRunner {
49    fn run(&self, instruction: &Instruction) -> Response {
50        match *instruction {
51            Instruction::Display(ref string, ref response) => {
52                println!("{}", string);
53                response.clone()
54            },
55            Instruction::SystemCommand(ref shell, output) => util::run_system_command(shell, output),
56            Instruction::ExitCode(ref response) => response.clone()
57        }
58    }
59}
60
61pub fn run_workflow(workflow: Vec<Work>, runner: &InstructionRunner) -> Response {
62    let mut response = Response::Ok;
63    'work: for work in workflow {
64        response = work.run(runner);
65        if let Response::Err(_) = response {
66            break 'work;
67        }
68    }
69    response
70}