kutil_cli/run/
exit.rs

1use std::{error, fmt};
2
3//
4// Exit
5//
6
7/// Information on how to exit a program.
8#[derive(Clone, Debug)]
9pub struct Exit {
10    /// Exit code.
11    pub code: u8,
12
13    /// Optional goodbye message.
14    pub message: Option<String>,
15}
16
17impl Exit {
18    /// Constructor.
19    pub fn new(code: u8, message: Option<&str>) -> Self {
20        let message = message.map(|message| message.into());
21        Self { code, message }
22    }
23
24    /// Constructor.
25    pub fn new_from<ToStringT>(code: u8, to_string: ToStringT) -> Self
26    where
27        ToStringT: ToString,
28    {
29        Self { code, message: Some(to_string.to_string()) }
30    }
31
32    /// Successful exit (code 0) without a message.
33    pub fn success() -> Self {
34        0.into()
35    }
36}
37
38impl error::Error for Exit {}
39
40impl fmt::Display for Exit {
41    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
42        match &self.message {
43            Some(message) => write!(formatter, "{}: {}", self.code, message),
44            None => fmt::Display::fmt(&self.code, formatter),
45        }
46    }
47}
48
49// Conversions
50
51impl From<u8> for Exit {
52    fn from(value: u8) -> Self {
53        Self::new(value, None)
54    }
55}
56
57impl From<&str> for Exit {
58    fn from(message: &str) -> Self {
59        Self::new(1, Some(message))
60    }
61}
62
63//
64// HasExit
65//
66
67/// For types that can optionally have an [Exit].
68pub trait HasExit: fmt::Display {
69    /// Return the [Exit] if it exists.
70    fn get_exit(&self) -> Option<&Exit>;
71}