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}