medic_lib/step_result/
mod.rs1use std::io::{self, Write};
2use std::ops::{ControlFlow, FromResidual, Try};
3
4pub enum StepResult {
5 StepOk,
6 StepError(String, Option<String>, Option<String>),
7}
8
9impl std::process::Termination for StepResult {
10 fn report(self) -> std::process::ExitCode {
11 match self {
12 StepResult::StepOk => std::process::ExitCode::from(0),
13 StepResult::StepError(msg, stdout, stderr) => {
14 eprintln!("\x1b[31;1mError:\x1b[0m {msg}\r\n");
15 if let Some(stdout) = stdout {
16 if !stdout.is_empty() {
17 eprintln!("\x1b[31;1mstdout:\x1b[0m\r\n{stdout}");
18 }
19 }
20 if let Some(stderr) = stderr {
21 if !stderr.is_empty() {
22 eprintln!("\x1b[31;1mstderr:\x1b[0m\r\n{stderr}");
23 }
24 }
25 io::stderr().flush().unwrap();
26
27 std::process::ExitCode::from(1)
28 }
29 }
30 }
31}
32
33pub struct ResultCodeResidual(String, Option<String>, Option<String>);
34
35impl Try for StepResult {
36 type Output = ();
37 type Residual = ResultCodeResidual;
38
39 fn branch(self) -> ControlFlow<Self::Residual> {
40 match self {
41 StepResult::StepError(msg, stdout, stderr) => {
42 ControlFlow::Break(ResultCodeResidual(msg, stdout, stderr))
43 }
44 StepResult::StepOk => ControlFlow::Continue(()),
45 }
46 }
47 fn from_output((): ()) -> Self {
48 StepResult::StepOk
49 }
50}
51
52impl FromResidual for StepResult {
53 fn from_residual(r: ResultCodeResidual) -> Self {
54 Self::StepError(r.0, r.1, r.2)
55 }
56}