eggress_pproxy_compat/
exit_codes.rs1pub const EXIT_SUCCESS: i32 = 0;
6pub const EXIT_RUNTIME_FAILURE: i32 = 1;
7pub const EXIT_CLI_PARSE_ERROR: i32 = 2;
8pub const EXIT_CONFIG_VALIDATION: i32 = 3;
9pub const EXIT_BIND_FAILURE: i32 = 4;
10pub const EXIT_UNSUPPORTED_FEATURE: i32 = 5;
11pub const EXIT_PLATFORM_MISSING: i32 = 6;
12pub const EXIT_EXTERNAL_DEPENDENCY: i32 = 7;
13pub const EXIT_SIGINT: i32 = 130;
14pub const EXIT_SIGTERM: i32 = 143;
15
16#[derive(Debug, Clone, Copy, PartialEq, Eq)]
20pub enum ProcessExit {
21 Success,
23 RuntimeFailure,
25 CliParseError,
28 ConfigValidation,
30 BindFailure,
32 UnsupportedFeature,
34 PlatformMissing,
37 ExternalDependency,
40 Sigint,
42 Sigterm,
44}
45
46impl ProcessExit {
47 pub const fn code(self) -> i32 {
49 match self {
50 ProcessExit::Success => EXIT_SUCCESS,
51 ProcessExit::RuntimeFailure => EXIT_RUNTIME_FAILURE,
52 ProcessExit::CliParseError => EXIT_CLI_PARSE_ERROR,
53 ProcessExit::ConfigValidation => EXIT_CONFIG_VALIDATION,
54 ProcessExit::BindFailure => EXIT_BIND_FAILURE,
55 ProcessExit::UnsupportedFeature => EXIT_UNSUPPORTED_FEATURE,
56 ProcessExit::PlatformMissing => EXIT_PLATFORM_MISSING,
57 ProcessExit::ExternalDependency => EXIT_EXTERNAL_DEPENDENCY,
58 ProcessExit::Sigint => EXIT_SIGINT,
59 ProcessExit::Sigterm => EXIT_SIGTERM,
60 }
61 }
62
63 pub const fn name(self) -> &'static str {
65 match self {
66 ProcessExit::Success => "success",
67 ProcessExit::RuntimeFailure => "runtime_failure",
68 ProcessExit::CliParseError => "cli_parse_error",
69 ProcessExit::ConfigValidation => "config_validation",
70 ProcessExit::BindFailure => "bind_failure",
71 ProcessExit::UnsupportedFeature => "unsupported_feature",
72 ProcessExit::PlatformMissing => "platform_missing",
73 ProcessExit::ExternalDependency => "external_dependency",
74 ProcessExit::Sigint => "interrupted_by_sigint",
75 ProcessExit::Sigterm => "terminated_by_sigterm",
76 }
77 }
78}
79
80impl From<ProcessExit> for i32 {
81 fn from(exit: ProcessExit) -> Self {
82 exit.code()
83 }
84}
85
86pub fn exit_code_name(code: i32) -> &'static str {
87 match code {
88 EXIT_SUCCESS => "success",
89 EXIT_RUNTIME_FAILURE => "runtime_failure",
90 EXIT_CLI_PARSE_ERROR => "cli_parse_error",
91 EXIT_CONFIG_VALIDATION => "config_validation",
92 EXIT_BIND_FAILURE => "bind_failure",
93 EXIT_UNSUPPORTED_FEATURE => "unsupported_feature",
94 EXIT_PLATFORM_MISSING => "platform_missing",
95 EXIT_EXTERNAL_DEPENDENCY => "external_dependency",
96 EXIT_SIGINT => "interrupted_by_sigint",
97 EXIT_SIGTERM => "terminated_by_sigterm",
98 _ => "unknown",
99 }
100}
101
102#[cfg(test)]
103mod tests {
104 use super::*;
105
106 #[test]
107 fn typed_outcomes_match_numeric_contract() {
108 let cases = [
109 (ProcessExit::Success, EXIT_SUCCESS),
110 (ProcessExit::RuntimeFailure, EXIT_RUNTIME_FAILURE),
111 (ProcessExit::CliParseError, EXIT_CLI_PARSE_ERROR),
112 (ProcessExit::ConfigValidation, EXIT_CONFIG_VALIDATION),
113 (ProcessExit::BindFailure, EXIT_BIND_FAILURE),
114 (ProcessExit::UnsupportedFeature, EXIT_UNSUPPORTED_FEATURE),
115 (ProcessExit::PlatformMissing, EXIT_PLATFORM_MISSING),
116 (ProcessExit::ExternalDependency, EXIT_EXTERNAL_DEPENDENCY),
117 (ProcessExit::Sigint, EXIT_SIGINT),
118 (ProcessExit::Sigterm, EXIT_SIGTERM),
119 ];
120 for (outcome, code) in cases {
121 assert_eq!(outcome.code(), code);
122 assert_eq!(i32::from(outcome), code);
123 assert_eq!(outcome.name(), exit_code_name(code));
124 }
125 }
126
127 #[test]
128 fn signal_exits_remain_stable() {
129 assert_eq!(ProcessExit::Sigint.code(), 130);
130 assert_eq!(ProcessExit::Sigterm.code(), 143);
131 }
132}