1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
extern crate redis;
use std::error;
use std::fmt;
use std::fmt::Display;
#[derive(Debug)]
pub enum ErrorInfo {
RedisError(redis::RedisError),
Description(&'static str),
TimeoutError(&'static str)
}
#[derive(Debug)]
pub struct RedisError {
pub info: ErrorInfo
}
impl error::Error for RedisError {
fn description(&self) -> &str {
match self.info {
ErrorInfo::RedisError(ref cause) => cause.description(),
ErrorInfo::Description(description) => description,
ErrorInfo::TimeoutError(description) => description,
}
}
fn cause(&self) -> Option<&error::Error> {
match self.info {
ErrorInfo::RedisError(ref cause) => Some(cause as &error::Error),
_ => None,
}
}
}
impl Display for RedisError {
fn fmt(
&self,
format: &mut fmt::Formatter,
) -> Result<(), fmt::Error> {
match self.info {
ErrorInfo::RedisError(ref cause) => cause.fmt(format),
ErrorInfo::Description(description) => description.fmt(format),
ErrorInfo::TimeoutError(description) => description.fmt(format),
}
}
}
pub trait RedisArg: Sized + ToString {}
macro_rules! as_redis_arg {
($t:ty) => (
impl RedisArg for $t {}
)
}
impl<'a> RedisArg for &'a str {}
as_redis_arg!(i8);
as_redis_arg!(i16);
as_redis_arg!(u16);
as_redis_arg!(i32);
as_redis_arg!(u32);
as_redis_arg!(i64);
as_redis_arg!(u64);
as_redis_arg!(f32);
as_redis_arg!(f64);
as_redis_arg!(isize);
as_redis_arg!(usize);
as_redis_arg!(bool);
pub type Message = redis::Msg;
pub type RedisResult<T> = Result<T, RedisError>;
pub type RedisEmptyResult = RedisResult<()>;
pub type RedisMessageResult = RedisResult<Message>;
pub type RedisStringResult = RedisResult<String>;
pub type RedisBoolResult = RedisResult<bool>;
#[cfg(test)]
mod tests {
use super::*;
use std::error::Error;
use std::io::Write;
#[test]
fn redis_error_description() {
let redis_error = RedisError { info: ErrorInfo::Description("test") };
assert_eq!(redis_error.description(), "test");
assert!(redis_error.cause().is_none());
let mut writer = Vec::new();
write!(&mut writer, "formatted {}", redis_error).unwrap();
assert_eq!(writer, b"formatted test");
}
#[test]
fn redis_error_timeout_error() {
let redis_error = RedisError { info: ErrorInfo::TimeoutError("timeout") };
assert_eq!(redis_error.description(), "timeout");
assert!(redis_error.cause().is_none());
let mut writer = Vec::new();
write!(&mut writer, "formatted {}", redis_error).unwrap();
assert_eq!(writer, b"formatted timeout");
}
}