pub fn is_retryable_kind(kind: ferriskey::ErrorKind) -> bool {
use ferriskey::ErrorKind::*;
matches!(
kind,
IoError | FatalSendError | TryAgain | BusyLoadingError | ClusterDown
)
}
pub fn kind_to_stable_str(kind: ferriskey::ErrorKind) -> &'static str {
use ferriskey::ErrorKind::*;
match kind {
ResponseError => "response_error",
ParseError => "parse_error",
AuthenticationFailed => "authentication_failed",
PermissionDenied => "permission_denied",
TypeError => "type_error",
ExecAbortError => "exec_abort",
BusyLoadingError => "busy_loading",
NoScriptError => "no_script",
InvalidClientConfig => "invalid_client_config",
Moved => "moved",
Ask => "ask",
TryAgain => "try_again",
ClusterDown => "cluster_down",
CrossSlot => "cross_slot",
MasterDown => "master_down",
IoError => "io_error",
FatalSendError => "fatal_send",
FatalReceiveError => "fatal_receive",
ClientError => "client_error",
ExtensionError => "extension_error",
ReadOnly => "read_only",
MasterNameNotFoundBySentinel => "master_name_not_found_by_sentinel",
NoValidReplicasFoundBySentinel => "no_valid_replicas_found_by_sentinel",
_ => "unknown",
}
}
#[cfg(test)]
mod tests {
use super::*;
use ferriskey::ErrorKind;
#[test]
fn retryable_kinds_whitelist() {
assert!(is_retryable_kind(ErrorKind::IoError));
assert!(is_retryable_kind(ErrorKind::FatalSendError));
assert!(is_retryable_kind(ErrorKind::TryAgain));
assert!(is_retryable_kind(ErrorKind::BusyLoadingError));
assert!(is_retryable_kind(ErrorKind::ClusterDown));
}
#[test]
fn non_retryable_kinds() {
assert!(!is_retryable_kind(ErrorKind::FatalReceiveError));
assert!(!is_retryable_kind(ErrorKind::AuthenticationFailed));
assert!(!is_retryable_kind(ErrorKind::PermissionDenied));
assert!(!is_retryable_kind(ErrorKind::InvalidClientConfig));
assert!(!is_retryable_kind(ErrorKind::NoScriptError));
assert!(!is_retryable_kind(ErrorKind::Moved));
assert!(!is_retryable_kind(ErrorKind::Ask));
assert!(!is_retryable_kind(ErrorKind::ResponseError));
assert!(!is_retryable_kind(ErrorKind::ParseError));
assert!(!is_retryable_kind(ErrorKind::TypeError));
assert!(!is_retryable_kind(ErrorKind::ReadOnly));
}
#[test]
fn stable_str_for_common_kinds() {
assert_eq!(kind_to_stable_str(ErrorKind::IoError), "io_error");
assert_eq!(kind_to_stable_str(ErrorKind::FatalSendError), "fatal_send");
assert_eq!(kind_to_stable_str(ErrorKind::FatalReceiveError), "fatal_receive");
assert_eq!(kind_to_stable_str(ErrorKind::NoScriptError), "no_script");
assert_eq!(kind_to_stable_str(ErrorKind::AuthenticationFailed), "authentication_failed");
assert_eq!(kind_to_stable_str(ErrorKind::ClusterDown), "cluster_down");
assert_eq!(kind_to_stable_str(ErrorKind::Moved), "moved");
assert_eq!(kind_to_stable_str(ErrorKind::ReadOnly), "read_only");
}
#[test]
fn stable_str_is_snake_case_and_nonempty() {
use ferriskey::ErrorKind::*;
let all = [
ResponseError, ParseError, AuthenticationFailed, PermissionDenied,
TypeError, ExecAbortError, BusyLoadingError, NoScriptError,
InvalidClientConfig, Moved, Ask, TryAgain, ClusterDown, CrossSlot,
MasterDown, IoError, FatalSendError, FatalReceiveError, ClientError,
ExtensionError, ReadOnly,
];
for k in all {
let s = kind_to_stable_str(k);
assert!(!s.is_empty(), "empty stable str for {k:?}");
assert!(
s.chars().all(|c| c.is_ascii_lowercase() || c == '_'),
"non snake_case stable str '{s}' for {k:?}"
);
}
}
}