use std::io;
use std::net::ToSocketAddrs;
use cogo::net::TcpStream;
use crate::bytes::{ByteString};
use crate::client::Client;
use crate::cmd;
use crate::simple::SimpleClient;
use super::errors::ConnectError;
pub struct RedisConnector<A> {
address: A,
passwords: Vec<ByteString>,
}
impl<A> RedisConnector<A>
where
A: ToSocketAddrs + Clone,
{
pub fn new(address: A) -> RedisConnector<A> {
RedisConnector {
address: address.clone(),
passwords: Vec::new(),
}
}
}
impl<A> RedisConnector<A>
where
A: ToSocketAddrs + Clone,
{
pub fn password<U>(mut self, password: U) -> Self
where
U: AsRef<str>,
{
self.passwords.push(ByteString::from(password.as_ref().to_string()));
self
}
pub fn connector(self) -> RedisConnector<A> {
RedisConnector {
address: self.address,
passwords: self.passwords,
}
}
}
impl<A> RedisConnector<A>
where
A: ToSocketAddrs + Clone,
{
fn _connect(&mut self) -> Result<SimpleClient, ConnectError> {
let passwords = self.passwords.clone();
let conn = TcpStream::connect(self.address.clone())?;
if passwords.is_empty() {
Ok(SimpleClient::new(conn))
} else {
let client = SimpleClient::new(conn);
for password in passwords {
if client.exec(cmd::Auth(password))? {
return Ok(client);
}
}
Err(ConnectError::Unauthorized)
}
}
pub fn connect(&mut self) -> Result<Client, ConnectError> {
Ok(Client::new(self._connect()?))
}
pub fn connect_simple(&mut self) -> Result<SimpleClient, ConnectError> {
Ok(self._connect()?)
}
}