use thiserror::Error;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyConfigField {
EnvironmentPrefix,
Host,
Port,
Database,
KeyPrefix,
Username,
Password,
ConnectionTimeout,
ResponseTimeout,
RetryAttempts,
ConcurrencyLimit,
PipelineBufferSize,
TransportSecurity,
TlsCaCertificatePath,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyConfigErrorReason {
Empty,
TooLarge,
InvalidSyntax,
MustBePositive,
InvalidEncoding,
Incompatible,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeySetupErrorReason {
InvalidEndpoint,
TlsProviderUnavailable,
ConnectionUnavailable,
AuthenticationRejected,
TlsTrustUnavailable,
TlsTrustInvalid,
TlsTrustTooLarge,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyCommandErrorReason {
ConnectionUnavailable,
Timeout,
Rejected,
InvalidResponse,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyRetryHint {
DoNotRetry,
RetryIdempotentOperation,
RetryIdempotentOperationAfterBackoff,
}
impl ValkeyCommandErrorReason {
pub const fn retry_hint(self) -> ValkeyRetryHint {
match self {
Self::ConnectionUnavailable => ValkeyRetryHint::RetryIdempotentOperationAfterBackoff,
Self::Timeout => ValkeyRetryHint::RetryIdempotentOperation,
Self::Rejected | Self::InvalidResponse => ValkeyRetryHint::DoNotRetry,
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyDataKind {
Key,
Value,
TimeToLive,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyDataErrorReason {
Empty,
TooLarge,
OutOfRange,
}
#[derive(Debug, Error, Clone, Copy, PartialEq, Eq)]
pub enum ValkeyError {
#[error("valkey configuration is invalid")]
Config {
field: ValkeyConfigField,
reason: ValkeyConfigErrorReason,
},
#[error("valkey client setup failed")]
Setup {
reason: ValkeySetupErrorReason,
},
#[error("valkey command failed")]
Command {
reason: ValkeyCommandErrorReason,
},
#[error("valkey operation data is invalid")]
InvalidData {
kind: ValkeyDataKind,
reason: ValkeyDataErrorReason,
},
}
pub type ValkeyResult<T> = Result<T, ValkeyError>;
#[cfg(test)]
mod tests {
use super::{ValkeyCommandErrorReason, ValkeyRetryHint};
#[test]
fn retry_hints_never_claim_an_operation_is_safe_to_replay() {
assert_eq!(
ValkeyCommandErrorReason::ConnectionUnavailable.retry_hint(),
ValkeyRetryHint::RetryIdempotentOperationAfterBackoff
);
assert_eq!(
ValkeyCommandErrorReason::Timeout.retry_hint(),
ValkeyRetryHint::RetryIdempotentOperation
);
assert_eq!(
ValkeyCommandErrorReason::Rejected.retry_hint(),
ValkeyRetryHint::DoNotRetry
);
assert_eq!(
ValkeyCommandErrorReason::InvalidResponse.retry_hint(),
ValkeyRetryHint::DoNotRetry
);
}
}