1use std::error::Error;
2use std::fmt::{self, Display, Formatter};
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub enum InvalidPolicyKind {
6 ZeroInterval,
7 ZeroRatePerMinute,
8 IntervalOutOfRange,
9}
10
11#[derive(Debug)]
12pub struct InvalidPolicyError {
13 kind: InvalidPolicyKind,
14 message: &'static str,
15}
16
17impl InvalidPolicyError {
18 pub fn kind(&self) -> InvalidPolicyKind {
19 self.kind
20 }
21
22 pub fn message(&self) -> &'static str {
23 self.message
24 }
25
26 pub(crate) fn zero_interval() -> Self {
27 Self {
28 kind: InvalidPolicyKind::ZeroInterval,
29 message: "min interval must be greater than zero",
30 }
31 }
32
33 pub(crate) fn zero_rpm() -> Self {
34 Self {
35 kind: InvalidPolicyKind::ZeroRatePerMinute,
36 message: "per-minute rate must be greater than zero",
37 }
38 }
39
40 pub(crate) fn interval_out_of_range() -> Self {
41 Self {
42 kind: InvalidPolicyKind::IntervalOutOfRange,
43 message: "policy interval is too large to represent",
44 }
45 }
46}
47
48impl Display for InvalidPolicyError {
49 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
50 f.write_str(self.message)
51 }
52}
53
54impl Error for InvalidPolicyError {}
55
56#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum RateLimitErrorKind {
58 InvalidPolicy,
59 Connection,
60 Backend,
61 Time,
62 Unknown,
63}
64
65#[derive(Debug)]
66pub enum RateLimitError {
67 InvalidPolicy(InvalidPolicyError),
68 Backend {
69 kind: RateLimitErrorKind,
70 source: Box<dyn Error + Send + Sync>,
71 },
72}
73
74impl RateLimitError {
75 pub fn kind(&self) -> RateLimitErrorKind {
76 match self {
77 Self::InvalidPolicy(_) => RateLimitErrorKind::InvalidPolicy,
78 Self::Backend { kind, .. } => *kind,
79 }
80 }
81
82 #[cfg(feature = "valkey")]
83 pub(crate) fn backend<E>(kind: RateLimitErrorKind, source: E) -> Self
84 where
85 E: Error + Send + Sync + 'static,
86 {
87 Self::Backend {
88 kind,
89 source: Box::new(source),
90 }
91 }
92}
93
94impl Display for RateLimitError {
95 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
96 match self {
97 Self::InvalidPolicy(error) => write!(f, "invalid policy: {error}"),
98 Self::Backend { source, .. } => write!(f, "{source}"),
99 }
100 }
101}
102
103impl Error for RateLimitError {
104 fn source(&self) -> Option<&(dyn Error + 'static)> {
105 match self {
106 Self::InvalidPolicy(error) => Some(error),
107 Self::Backend { source, .. } => Some(source.as_ref()),
108 }
109 }
110}
111
112impl From<InvalidPolicyError> for RateLimitError {
113 fn from(value: InvalidPolicyError) -> Self {
114 Self::InvalidPolicy(value)
115 }
116}
117
118#[cfg(feature = "valkey")]
119#[derive(Debug)]
120pub enum ValkeyError {
121 Redis(redis::RedisError),
122 InvalidTime(std::time::SystemTimeError),
123 IntervalOutOfRange(std::num::TryFromIntError),
124}
125
126#[cfg(feature = "valkey")]
127impl Display for ValkeyError {
128 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
129 match self {
130 Self::Redis(error) => write!(f, "{error}"),
131 Self::InvalidTime(error) => write!(f, "{error}"),
132 Self::IntervalOutOfRange(error) => write!(f, "{error}"),
133 }
134 }
135}
136
137#[cfg(feature = "valkey")]
138impl Error for ValkeyError {
139 fn source(&self) -> Option<&(dyn Error + 'static)> {
140 match self {
141 Self::Redis(error) => Some(error),
142 Self::InvalidTime(error) => Some(error),
143 Self::IntervalOutOfRange(error) => Some(error),
144 }
145 }
146}