use xy_protocol::RestartPolicy; #[derive(Debug, PartialEq, Eq)] pub enum RestartDecision { Restart, StayStopped, MarkFailed, } pub fn decide( policy: RestartPolicy, exit_code: Option, retry_cap_reached: bool, ) -> RestartDecision { let clean = matches!(exit_code, Some(0)); let want = match policy { RestartPolicy::Never => false, RestartPolicy::OnFailure => !clean, RestartPolicy::Always => true, }; if !want { return RestartDecision::StayStopped; } if retry_cap_reached { RestartDecision::MarkFailed } else { RestartDecision::Restart } } #[cfg(test)] mod tests { use super::*; #[test] fn never_never_restarts() { assert_eq!( decide(RestartPolicy::Never, Some(0), false), RestartDecision::StayStopped ); assert_eq!( decide(RestartPolicy::Never, Some(1), false), RestartDecision::StayStopped ); assert_eq!( decide(RestartPolicy::Never, None, false), RestartDecision::StayStopped ); } #[test] fn on_failure_skips_clean() { assert_eq!( decide(RestartPolicy::OnFailure, Some(0), false), RestartDecision::StayStopped ); } #[test] fn on_failure_restarts_nonzero() { assert_eq!( decide(RestartPolicy::OnFailure, Some(1), false), RestartDecision::Restart ); } #[test] fn on_failure_restarts_signal() { assert_eq!( decide(RestartPolicy::OnFailure, None, false), RestartDecision::Restart ); } #[test] fn always_restarts_on_clean() { assert_eq!( decide(RestartPolicy::Always, Some(0), false), RestartDecision::Restart ); } #[test] fn cap_reached_marks_failed() { assert_eq!( decide(RestartPolicy::Always, Some(0), true), RestartDecision::MarkFailed ); assert_eq!( decide(RestartPolicy::OnFailure, Some(1), true), RestartDecision::MarkFailed ); } #[test] fn cap_reached_never_still_stopped() { assert_eq!( decide(RestartPolicy::Never, Some(1), true), RestartDecision::StayStopped ); } }