Skip to main content

odx_core/
exit.rs

1/// Process outcome of an odx command, mapped to a stable exit code.
2///
3/// | Variant | Code | Meaning |
4/// | --- | --- | --- |
5/// | [`Exit::Success`] | `0` | the command did what was asked |
6/// | [`Exit::Failure`] | `1` | operational failure: conflict, network, policy |
7/// | [`Exit::Usage`] | `2` | usage or configuration error |
8///
9/// ```
10/// use odx_core::Exit;
11///
12/// assert_eq!(Exit::Success.code(), 0);
13/// assert_eq!(Exit::Failure.code(), 1);
14/// assert_eq!(Exit::Usage.code(), 2);
15/// ```
16#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)]
17pub enum Exit {
18    /// The command succeeded.
19    #[default]
20    Success,
21    /// An operational failure, such as a merge conflict or a network error.
22    Failure,
23    /// A usage or configuration error.
24    Usage,
25}
26
27impl Exit {
28    /// The numeric process exit code.
29    pub const fn code(self) -> u8 {
30        match self {
31            Self::Success => 0,
32            Self::Failure => 1,
33            Self::Usage => 2,
34        }
35    }
36}
37
38#[cfg(test)]
39mod tests {
40    use super::Exit;
41
42    #[test]
43    fn codes_are_stable() {
44        let codes: Vec<u8> = [Exit::Success, Exit::Failure, Exit::Usage]
45            .into_iter()
46            .map(Exit::code)
47            .collect();
48        assert_eq!(codes, [0, 1, 2]);
49        assert_eq!(Exit::default(), Exit::Success);
50    }
51}