1use std::fmt::Display;
2
3pub type CliResult<T> = Result<T, CliError>;
4
5#[derive(Debug, PartialEq)]
6pub struct CliError {
7 pub msg: String,
8 pub status: i32,
9}
10
11impl<D: Display> From<D> for CliError {
12 fn from(value: D) -> Self {
13 let msg = value.to_string();
14 Self { msg, status: 1 }
15 }
16}
17
18pub trait Exit {
19 type O;
20
21 fn exit(self);
22 fn exit_if_err(self) -> Self::O;
23 fn exit_silently(self);
24}
25
26impl<O> Exit for CliResult<O> {
27 type O = O;
28
29 fn exit(self) {
30 match self {
31 Ok(_) => std::process::exit(0),
32 Err(err) => {
33 eprintln!("{}", err.msg);
34 std::process::exit(err.status);
35 }
36 }
37 }
38
39 fn exit_if_err(self) -> Self::O {
40 match self {
41 Ok(o) => o,
42 Err(err) => {
43 eprintln!("{}", err.msg);
44 std::process::exit(err.status);
45 }
46 }
47 }
48
49 fn exit_silently(self) {
50 let status = match self {
51 Ok(_) => 0,
52 Err(e) => e.status,
53 };
54
55 std::process::exit(status);
56 }
57}