ready_set_sdk/
exit_code.rs1use crate::error::Error;
9
10#[derive(Debug, Clone, Copy, PartialEq, Eq)]
12#[non_exhaustive]
13pub enum ExitCode {
14 Ok,
16 UserError,
18 SystemError,
20 DependencyMissing,
22 NotCargoWorkspace,
24 ContractViolation,
26 UnknownSubcommand,
28 Signaled(u8),
33}
34
35impl ExitCode {
36 #[must_use]
41 pub const fn as_u8(self) -> u8 {
42 match self {
43 Self::Ok => 0,
44 Self::UserError => 1,
45 Self::SystemError => 2,
46 Self::DependencyMissing => 3,
47 Self::NotCargoWorkspace => 4,
48 Self::ContractViolation => 5,
49 Self::UnknownSubcommand => 127,
50 Self::Signaled(n) => 128_u8.saturating_add(n),
51 }
52 }
53}
54
55impl From<ExitCode> for std::process::ExitCode {
56 fn from(value: ExitCode) -> Self {
57 Self::from(value.as_u8())
58 }
59}
60
61impl From<&Error> for ExitCode {
62 fn from(value: &Error) -> Self {
63 match value {
64 Error::TomlParse(_) | Error::JsonParse(_) => Self::UserError,
65 Error::MissingDependency { .. } => Self::DependencyMissing,
66 Error::ContractViolation(_) => Self::ContractViolation,
67 _ => Self::SystemError,
71 }
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 #[test]
80 fn numeric_values_match_contract() {
81 assert_eq!(ExitCode::Ok.as_u8(), 0);
82 assert_eq!(ExitCode::UserError.as_u8(), 1);
83 assert_eq!(ExitCode::SystemError.as_u8(), 2);
84 assert_eq!(ExitCode::DependencyMissing.as_u8(), 3);
85 assert_eq!(ExitCode::NotCargoWorkspace.as_u8(), 4);
86 assert_eq!(ExitCode::ContractViolation.as_u8(), 5);
87 assert_eq!(ExitCode::UnknownSubcommand.as_u8(), 127);
88 assert_eq!(ExitCode::Signaled(0).as_u8(), 128);
89 assert_eq!(ExitCode::Signaled(2).as_u8(), 130); assert_eq!(ExitCode::Signaled(15).as_u8(), 143); assert_eq!(ExitCode::Signaled(255).as_u8(), 255); }
93
94 #[test]
95 fn maps_errors_to_codes() {
96 let io = Error::Io(std::io::Error::other("nope"));
97 assert_eq!(ExitCode::from(&io), ExitCode::SystemError);
98
99 let dep = Error::MissingDependency {
100 name: "git".into(),
101 hint: None,
102 };
103 assert_eq!(ExitCode::from(&dep), ExitCode::DependencyMissing);
104
105 let contract = Error::contract("bad");
106 assert_eq!(ExitCode::from(&contract), ExitCode::ContractViolation);
107
108 let toml = Error::TomlParse("oops".into());
109 assert_eq!(ExitCode::from(&toml), ExitCode::UserError);
110 }
111}