1use std::num::TryFromIntError;
2
3use thiserror::Error;
4
5#[derive(Debug, Error)]
7pub enum ReconstructionCacheError {
8 #[error("reconstruction cache redis url must not be empty")]
10 EmptyRedisUrl,
11 #[error("redis TLS client certificate and key must be configured together")]
13 IncompleteRedisTlsClientIdentity,
14 #[error("reconstruction cache redis operation failed")]
16 Redis(#[from] redis::RedisError),
17 #[error("reconstruction cache numeric conversion exceeded supported bounds")]
19 NumericConversion(#[from] TryFromIntError),
20 #[error("reconstruction cache adapter operation failed")]
22 Operation,
23}
24
25#[cfg(test)]
26mod tests {
27 use std::error::Error as StdError;
28 use std::mem::discriminant;
29
30 use super::*;
31
32 #[allow(clippy::unwrap_used, clippy::shadow_unrelated)]
33 #[test]
34 fn error_source_returns_inner_error() {
35 assert!(ReconstructionCacheError::EmptyRedisUrl.source().is_none());
37
38 assert!(ReconstructionCacheError::Operation.source().is_none());
40 assert!(
41 ReconstructionCacheError::IncompleteRedisTlsClientIdentity
42 .source()
43 .is_none()
44 );
45
46 let redis_err = redis::RedisError::from((redis::ErrorKind::Io, "inner source"));
48 let err = ReconstructionCacheError::Redis(redis_err);
49 let source = err.source();
50 assert!(source.is_some());
51 assert!(
52 source
53 .unwrap()
54 .downcast_ref::<redis::RedisError>()
55 .is_some()
56 );
57
58 let int_err = i64::try_from(u64::MAX).unwrap_err();
60 let err = ReconstructionCacheError::NumericConversion(int_err);
61 let source = err.source();
62 assert!(source.is_some());
63 assert!(source.unwrap().downcast_ref::<TryFromIntError>().is_some());
64 }
65
66 #[test]
67 fn display_empty_redis_url() {
68 let err = ReconstructionCacheError::EmptyRedisUrl;
69 assert_eq!(
70 err.to_string(),
71 "reconstruction cache redis url must not be empty"
72 );
73 }
74
75 #[test]
76 fn display_operation() {
77 let err = ReconstructionCacheError::Operation;
78 assert_eq!(
79 err.to_string(),
80 "reconstruction cache adapter operation failed"
81 );
82 }
83
84 #[test]
85 fn display_incomplete_redis_tls_client_identity() {
86 let err = ReconstructionCacheError::IncompleteRedisTlsClientIdentity;
87 assert_eq!(
88 err.to_string(),
89 "redis TLS client certificate and key must be configured together"
90 );
91 }
92
93 #[test]
94 fn display_redis() {
95 let redis_err = redis::RedisError::from((redis::ErrorKind::Io, "test error"));
96 let err = ReconstructionCacheError::Redis(redis_err);
97 assert_eq!(
98 err.to_string(),
99 "reconstruction cache redis operation failed"
100 );
101 }
102
103 #[allow(clippy::unwrap_used)]
104 #[test]
105 fn display_numeric_conversion() {
106 let int_err = i64::try_from(u64::MAX).unwrap_err();
107 let err = ReconstructionCacheError::NumericConversion(int_err);
108 assert_eq!(
109 err.to_string(),
110 "reconstruction cache numeric conversion exceeded supported bounds"
111 );
112 }
113
114 #[test]
115 fn from_redis_error() {
116 let redis_err = redis::RedisError::from((redis::ErrorKind::Io, "test error"));
117 let err: ReconstructionCacheError = redis_err.into();
118 assert!(matches!(err, ReconstructionCacheError::Redis(_)));
119 }
120
121 #[allow(clippy::unwrap_used)]
122 #[test]
123 fn from_try_from_int_error() {
124 let int_err = i64::try_from(u64::MAX).unwrap_err();
125 let err: ReconstructionCacheError = int_err.into();
126 assert!(matches!(
127 err,
128 ReconstructionCacheError::NumericConversion(_)
129 ));
130 }
131
132 #[test]
133 fn debug_output_non_empty() {
134 let err = ReconstructionCacheError::EmptyRedisUrl;
135 let debug = format!("{err:?}");
136 assert!(!debug.is_empty());
137 }
138
139 #[test]
140 fn discriminant_matches_same_variant() {
141 let a = ReconstructionCacheError::EmptyRedisUrl;
142 let b = ReconstructionCacheError::EmptyRedisUrl;
143 assert_eq!(discriminant(&a), discriminant(&b));
144 }
145
146 #[test]
147 fn discriminant_differs_between_variants() {
148 let a = ReconstructionCacheError::EmptyRedisUrl;
149 let b = ReconstructionCacheError::Operation;
150 assert_ne!(discriminant(&a), discriminant(&b));
151 }
152}