redis_universal_client/
lib.rs1use redis::{cluster::ClusterClient, Client, ErrorKind, RedisError, RedisResult};
2
3#[derive(Clone)]
5pub enum UniversalClient {
6 Client(Client),
7 Cluster(ClusterClient),
8}
9
10impl UniversalClient {
11 pub fn get_connection(&self) -> redis::RedisResult<UniversalConnection> {
12 match self {
13 Self::Client(cli) => cli.get_connection().map(UniversalConnection::Client),
14 Self::Cluster(cli) => cli.get_connection().map(UniversalConnection::Cluster),
15 }
16 }
17
18 pub fn open<T: redis::IntoConnectionInfo + Clone>(
22 addrs: Vec<T>,
23 ) -> RedisResult<UniversalClient> {
24 let mut addrs = addrs;
25
26 if addrs.is_empty() {
27 return Err(RedisError::from((
28 ErrorKind::InvalidClientConfig,
29 "No address specified",
30 )));
31 }
32
33 if addrs.len() == 1 {
34 Client::open(addrs.remove(0)).map(Self::Client)
35 } else {
36 ClusterClient::open(addrs).map(Self::Cluster)
37 }
38 }
39}
40
41pub struct UniversalBuilder<T> {
42 addrs: Vec<T>,
43 cluster: bool,
44}
45
46impl<T> UniversalBuilder<T> {
47 pub fn new(addrs: Vec<T>) -> UniversalBuilder<T> {
48 UniversalBuilder {
49 addrs,
50 cluster: false,
51 }
52 }
53
54 pub fn cluster(mut self, flag: bool) -> UniversalBuilder<T> {
55 self.cluster = flag;
56 self
57 }
58
59 pub fn build(self) -> RedisResult<UniversalClient>
60 where
61 T: redis::IntoConnectionInfo + Clone,
62 {
63 let UniversalBuilder { mut addrs, cluster } = self;
64
65 if addrs.is_empty() {
66 return Err(RedisError::from((
67 ErrorKind::InvalidClientConfig,
68 "No address specified",
69 )));
70 }
71
72 if cluster {
73 ClusterClient::open(addrs).map(UniversalClient::Cluster)
74 } else {
75 Client::open(addrs.remove(0)).map(UniversalClient::Client)
76 }
77 }
78}
79
80pub enum UniversalConnection {
81 Client(redis::Connection),
82 Cluster(redis::cluster::ClusterConnection),
83}
84
85impl redis::ConnectionLike for UniversalConnection {
86 fn req_packed_command(&mut self, cmd: &[u8]) -> RedisResult<redis::Value> {
87 match self {
88 Self::Client(conn) => conn.req_packed_command(cmd),
89 Self::Cluster(conn) => conn.req_packed_command(cmd),
90 }
91 }
92
93 fn req_packed_commands(
94 &mut self,
95 cmd: &[u8],
96 offset: usize,
97 count: usize,
98 ) -> RedisResult<Vec<redis::Value>> {
99 match self {
100 Self::Client(conn) => conn.req_packed_commands(cmd, offset, count),
101 Self::Cluster(conn) => conn.req_packed_commands(cmd, offset, count),
102 }
103 }
104
105 fn get_db(&self) -> i64 {
106 match self {
107 Self::Client(conn) => conn.get_db(),
108 Self::Cluster(conn) => conn.get_db(),
109 }
110 }
111
112 fn is_open(&self) -> bool {
113 match self {
114 Self::Client(conn) => conn.is_open(),
115 Self::Cluster(conn) => conn.is_open(),
116 }
117 }
118
119 fn check_connection(&mut self) -> bool {
120 match self {
121 Self::Client(conn) => conn.check_connection(),
122 Self::Cluster(conn) => conn.check_connection(),
123 }
124 }
125}