1#![allow(clippy::needless_doctest_main)]
36#![deny(missing_docs, missing_debug_implementations)]
37
38pub use bb8;
39pub use redis_cluster_async;
40
41use async_trait::async_trait;
42use redis_cluster_async::{
43 redis::{ErrorKind, IntoConnectionInfo, RedisError},
44 Client, Connection,
45};
46
47#[derive(Clone)]
49pub struct RedisConnectionManager {
50 client: Client,
51}
52
53impl std::fmt::Debug for RedisConnectionManager {
55 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
56 f.debug_struct("RedisConnectionManager")
57 .field("client", &format!("pointer({:p})", &self.client))
58 .finish()
59 }
60}
61
62impl RedisConnectionManager {
63 pub fn new<T: IntoConnectionInfo>(infos: Vec<T>) -> Result<RedisConnectionManager, RedisError> {
66 Ok(RedisConnectionManager {
67 client: Client::open(infos.into_iter().collect())?,
68 })
69 }
70}
71
72#[async_trait]
73impl bb8::ManageConnection for RedisConnectionManager {
74 type Connection = Connection;
75 type Error = RedisError;
76
77 async fn connect(&self) -> Result<Self::Connection, Self::Error> {
78 self.client.get_connection().await
79 }
80
81 async fn is_valid(&self, conn: &mut Self::Connection) -> Result<(), Self::Error> {
82 let pong: String = redis::cmd("PING").query_async(conn).await?;
83 match pong.as_str() {
84 "PONG" => Ok(()),
85 _ => Err((ErrorKind::ResponseError, "ping request").into()),
86 }
87 }
88
89 fn has_broken(&self, _: &mut Self::Connection) -> bool {
90 false
91 }
92}