pub use crate::config::ConfigError;
use crate::{ConnectionAddr, ConnectionInfo, RedisConnectionInfo};
use serde::{Deserialize, Serialize};
use super::{CreatePoolError, Pool, PoolBuilder, PoolConfig, Runtime};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub struct Config {
pub urls: Option<Vec<String>>,
#[serde(default)]
pub server_type: SentinelServerType,
#[serde(default = "default_master_name")]
pub master_name: String,
pub connections: Option<Vec<ConnectionInfo>>,
pub node_connection_info: Option<SentinelNodeConnectionInfo>,
pub pool: Option<PoolConfig>,
}
impl Config {
pub fn create_pool(&self, runtime: Option<Runtime>) -> Result<Pool, CreatePoolError> {
let mut builder = self.builder().map_err(CreatePoolError::Config)?;
if let Some(runtime) = runtime {
builder = builder.runtime(runtime);
}
builder.build().map_err(CreatePoolError::Build)
}
pub fn builder(&self) -> Result<PoolBuilder, ConfigError> {
let manager = match (&self.urls, &self.connections) {
(Some(urls), None) => super::Manager::new(
urls.iter().map(|url| url.as_str()).collect(),
self.master_name.clone(),
self.node_connection_info.clone(),
self.server_type,
)?,
(None, Some(connections)) => super::Manager::new(
connections.clone(),
self.master_name.clone(),
self.node_connection_info.clone(),
self.server_type,
)?,
(None, None) => super::Manager::new(
vec![ConnectionInfo::default()],
self.master_name.clone(),
self.node_connection_info.clone(),
self.server_type,
)?,
(Some(_), Some(_)) => return Err(ConfigError::UrlAndConnectionSpecified),
};
let pool_config = self.get_pool_config();
Ok(Pool::builder(manager).config(pool_config))
}
#[must_use]
pub fn get_pool_config(&self) -> PoolConfig {
self.pool.unwrap_or_default()
}
#[must_use]
pub fn from_urls<T: Into<Vec<String>>>(
urls: T,
master_name: String,
server_type: SentinelServerType,
) -> Config {
Config {
urls: Some(urls.into()),
connections: None,
master_name,
server_type,
pool: None,
node_connection_info: None,
}
}
pub fn with_node_connection_info(
mut self,
node_connection_info: Option<SentinelNodeConnectionInfo>,
) -> Self {
self.node_connection_info = node_connection_info;
self
}
}
impl Default for Config {
fn default() -> Self {
let default_connection_info = ConnectionInfo {
addr: ConnectionAddr::Tcp("127.0.0.1".to_string(), 26379),
..ConnectionInfo::default()
};
Self {
urls: None,
connections: Some(vec![default_connection_info.clone()]),
server_type: SentinelServerType::Master,
master_name: default_master_name(),
pool: None,
node_connection_info: None,
}
}
}
fn default_master_name() -> String {
"mymaster".to_string()
}
#[derive(Debug, Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum SentinelServerType {
#[default]
Master,
Replica,
}
impl From<redis::sentinel::SentinelServerType> for SentinelServerType {
fn from(value: redis::sentinel::SentinelServerType) -> Self {
match value {
redis::sentinel::SentinelServerType::Master => SentinelServerType::Master,
redis::sentinel::SentinelServerType::Replica => SentinelServerType::Replica,
}
}
}
impl From<SentinelServerType> for redis::sentinel::SentinelServerType {
fn from(value: SentinelServerType) -> Self {
match value {
SentinelServerType::Master => redis::sentinel::SentinelServerType::Master,
SentinelServerType::Replica => redis::sentinel::SentinelServerType::Replica,
}
}
}
#[derive(Debug, Clone, Copy, Default)]
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
pub enum TlsMode {
#[default]
Secure,
Insecure,
}
impl From<redis::TlsMode> for TlsMode {
fn from(value: redis::TlsMode) -> Self {
match value {
redis::TlsMode::Insecure => TlsMode::Insecure,
redis::TlsMode::Secure => TlsMode::Secure,
}
}
}
impl From<TlsMode> for redis::TlsMode {
fn from(value: TlsMode) -> Self {
match value {
TlsMode::Insecure => redis::TlsMode::Insecure,
TlsMode::Secure => redis::TlsMode::Secure,
}
}
}
#[derive(Clone, Debug, Default)]
#[cfg_attr(feature = "serde", derive(Deserialize, Serialize))]
#[cfg_attr(feature = "serde", serde(crate = "serde"))]
pub struct SentinelNodeConnectionInfo {
pub tls_mode: Option<TlsMode>,
pub redis_connection_info: Option<RedisConnectionInfo>,
}
impl From<SentinelNodeConnectionInfo> for redis::sentinel::SentinelNodeConnectionInfo {
fn from(info: SentinelNodeConnectionInfo) -> Self {
Self {
tls_mode: info.tls_mode.map(|m| m.into()),
redis_connection_info: info.redis_connection_info.map(|i| i.into()),
}
}
}
impl From<redis::sentinel::SentinelNodeConnectionInfo> for SentinelNodeConnectionInfo {
fn from(info: redis::sentinel::SentinelNodeConnectionInfo) -> Self {
Self {
tls_mode: info.tls_mode.map(|m| m.into()),
redis_connection_info: info.redis_connection_info.map(|m| m.into()),
}
}
}