1pub use crate::config::ConfigError;
2use crate::{ConnectionAddr, ConnectionInfo, RedisConnectionInfo};
3
4use super::{CreatePoolError, Pool, PoolBuilder, PoolConfig, Runtime};
5
6#[derive(Clone, Debug)]
41#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
42pub struct Config {
43 pub urls: Option<Vec<String>>,
47 #[cfg_attr(feature = "serde", serde(default))]
51 pub server_type: SentinelServerType,
52 #[cfg_attr(feature = "serde", serde(default = "default_master_name"))]
54 pub master_name: String,
55 pub connections: Option<Vec<ConnectionInfo>>,
57 pub node_connection_info: Option<SentinelNodeConnectionInfo>,
59 pub pool: Option<PoolConfig>,
61}
62
63impl Config {
64 pub fn create_pool(&self, runtime: Option<Runtime>) -> Result<Pool, CreatePoolError> {
70 let mut builder = self.builder().map_err(CreatePoolError::Config)?;
71 if let Some(runtime) = runtime {
72 builder = builder.runtime(runtime);
73 }
74 builder.build().map_err(CreatePoolError::Build)
75 }
76
77 pub fn builder(&self) -> Result<PoolBuilder, ConfigError> {
83 let manager = match (&self.urls, &self.connections) {
84 (Some(urls), None) => super::Manager::new(
85 urls.iter().map(|url| url.as_str()).collect(),
86 self.master_name.clone(),
87 self.node_connection_info.clone(),
88 self.server_type,
89 )?,
90 (None, Some(connections)) => super::Manager::new(
91 connections.clone(),
92 self.master_name.clone(),
93 self.node_connection_info.clone(),
94 self.server_type,
95 )?,
96 (None, None) => super::Manager::new(
97 vec![ConnectionInfo::default()],
98 self.master_name.clone(),
99 self.node_connection_info.clone(),
100 self.server_type,
101 )?,
102 (Some(_), Some(_)) => return Err(ConfigError::UrlAndConnectionSpecified),
103 };
104 let pool_config = self.get_pool_config();
105 Ok(Pool::builder(manager).config(pool_config))
106 }
107
108 #[must_use]
111 pub fn get_pool_config(&self) -> PoolConfig {
112 self.pool.unwrap_or_default()
113 }
114
115 #[must_use]
118 pub fn from_urls<T: Into<Vec<String>>>(
119 urls: T,
120 master_name: String,
121 server_type: SentinelServerType,
122 ) -> Config {
123 Config {
124 urls: Some(urls.into()),
125 connections: None,
126 master_name,
127 server_type,
128 pool: None,
129 node_connection_info: None,
130 }
131 }
132
133 pub fn with_node_connection_info(
135 mut self,
136 node_connection_info: Option<SentinelNodeConnectionInfo>,
137 ) -> Self {
138 self.node_connection_info = node_connection_info;
139 self
140 }
141}
142
143impl Default for Config {
144 fn default() -> Self {
145 let default_connection_info = ConnectionInfo {
146 addr: ConnectionAddr::Tcp("127.0.0.1".to_string(), 26379),
147 ..ConnectionInfo::default()
148 };
149
150 Self {
151 urls: None,
152 connections: Some(vec![default_connection_info.clone()]),
153 server_type: SentinelServerType::Master,
154 master_name: default_master_name(),
155 pool: None,
156 node_connection_info: None,
157 }
158 }
159}
160
161fn default_master_name() -> String {
162 "mymaster".to_string()
163}
164
165#[derive(Debug, Clone, Copy, Default)]
167#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
168pub enum SentinelServerType {
169 #[default]
170 Master,
172 Replica,
174}
175
176impl From<redis::sentinel::SentinelServerType> for SentinelServerType {
177 fn from(value: redis::sentinel::SentinelServerType) -> Self {
178 match value {
179 redis::sentinel::SentinelServerType::Master => SentinelServerType::Master,
180 redis::sentinel::SentinelServerType::Replica => SentinelServerType::Replica,
181 }
182 }
183}
184
185impl From<SentinelServerType> for redis::sentinel::SentinelServerType {
186 fn from(value: SentinelServerType) -> Self {
187 match value {
188 SentinelServerType::Master => redis::sentinel::SentinelServerType::Master,
189 SentinelServerType::Replica => redis::sentinel::SentinelServerType::Replica,
190 }
191 }
192}
193
194#[derive(Debug, Clone, Copy, Default)]
196#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
197pub enum TlsMode {
198 #[default]
199 Secure,
201 Insecure,
203}
204
205impl From<redis::TlsMode> for TlsMode {
206 fn from(value: redis::TlsMode) -> Self {
207 match value {
208 redis::TlsMode::Insecure => TlsMode::Insecure,
209 redis::TlsMode::Secure => TlsMode::Secure,
210 }
211 }
212}
213
214impl From<TlsMode> for redis::TlsMode {
215 fn from(value: TlsMode) -> Self {
216 match value {
217 TlsMode::Insecure => redis::TlsMode::Insecure,
218 TlsMode::Secure => redis::TlsMode::Secure,
219 }
220 }
221}
222
223#[derive(Clone, Debug, Default)]
225#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
226#[cfg_attr(feature = "serde", serde(crate = "serde"))]
227pub struct SentinelNodeConnectionInfo {
228 pub tls_mode: Option<TlsMode>,
231
232 pub redis_connection_info: Option<RedisConnectionInfo>,
234}
235
236impl From<SentinelNodeConnectionInfo> for redis::sentinel::SentinelNodeConnectionInfo {
237 fn from(info: SentinelNodeConnectionInfo) -> Self {
238 Self {
239 tls_mode: info.tls_mode.map(|m| m.into()),
240 redis_connection_info: info.redis_connection_info.map(|i| i.into()),
241 }
242 }
243}
244
245impl From<redis::sentinel::SentinelNodeConnectionInfo> for SentinelNodeConnectionInfo {
246 fn from(info: redis::sentinel::SentinelNodeConnectionInfo) -> Self {
247 Self {
248 tls_mode: info.tls_mode.map(|m| m.into()),
249 redis_connection_info: info.redis_connection_info.map(|m| m.into()),
250 }
251 }
252}