kutil_cli/
run.rs

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
use super::exit::*;

use {
    anstream::eprintln,
    owo_colors::OwoColorize,
    std::{fmt, process::*},
};

/// A replacement for `main`.
pub type Runner<E> = fn() -> Result<(), E>;

/// Runs a [Runner], handling a returned [Exit].
///
/// If the exit has a goodbye message, it will be printed to stderr. If
/// the exit code is an error (non-zero) it will be in red.
///
/// Non-exit errors will be displayed in red.
///
/// Designed to be the only content for your `main` function. The
/// good stuff should go into your [Runner].
pub fn run<E: HasExit + fmt::Display>(run: Runner<E>) -> ExitCode {
    match run() {
        Ok(_) => ExitCode::SUCCESS,

        Err(err) => match err.get_exit() {
            Some(exit) => {
                if let Some(message) = &exit.message {
                    if exit.code == 0 {
                        eprintln!("{}", message);
                    } else {
                        eprintln!("{}", message.red());
                    }
                }
                ExitCode::from(exit.code)
            }

            _ => {
                eprintln!("{}", err.red());
                ExitCode::FAILURE
            }
        },
    }
}