1use qail_core::ast::Qail;
16
17use crate::error::{RedisError, RedisResult};
18use crate::transport::Transport;
19use crate::value::Value;
20
21pub struct RedisDriver {
23 transport: Transport,
24 resp3: bool,
25}
26
27impl RedisDriver {
28 pub async fn connect(host: &str, port: u16) -> RedisResult<Self> {
30 let mut transport = Transport::connect(host, port).await?;
31
32 let resp3 = transport.upgrade_to_resp3().await.unwrap_or(false);
34
35 Ok(Self { transport, resp3 })
36 }
37
38 pub async fn execute(&mut self, cmd: &Qail) -> RedisResult<Value> {
40 self.transport.execute(cmd).await
41 }
42
43 pub fn is_resp3(&self) -> bool {
45 self.resp3
46 }
47
48 pub async fn get(&mut self, key: &str) -> RedisResult<Option<Vec<u8>>> {
52 let cmd = Qail::redis_get(key);
53 match self.execute(&cmd).await? {
54 Value::Null => Ok(None),
55 Value::Bulk(data) => Ok(Some(data)),
56 Value::String(s) => Ok(Some(s.into_bytes())),
57 other => Err(RedisError::Protocol(format!(
58 "Unexpected GET response: {:?}",
59 other
60 ))),
61 }
62 }
63
64 pub async fn get_str(&mut self, key: &str) -> RedisResult<Option<String>> {
66 match self.get(key).await? {
67 Some(bytes) => Ok(Some(
68 String::from_utf8(bytes)
69 .map_err(|e| RedisError::Protocol(e.to_string()))?,
70 )),
71 None => Ok(None),
72 }
73 }
74
75 pub async fn set(&mut self, key: &str, value: &[u8]) -> RedisResult<()> {
77 let cmd = Qail::redis_set(key, value.to_vec());
78 self.execute(&cmd).await?;
79 Ok(())
80 }
81
82 pub async fn set_ex(&mut self, key: &str, value: &[u8], seconds: i64) -> RedisResult<()> {
84 use crate::cmd::RedisExt;
85 let cmd = Qail::redis_set(key, value.to_vec()).redis_ex(seconds);
86 self.execute(&cmd).await?;
87 Ok(())
88 }
89
90 pub async fn del(&mut self, key: &str) -> RedisResult<i64> {
92 let cmd = Qail::redis_del(key);
93 match self.execute(&cmd).await? {
94 Value::Integer(n) => Ok(n),
95 other => Err(RedisError::Protocol(format!(
96 "Unexpected DEL response: {:?}",
97 other
98 ))),
99 }
100 }
101
102 pub async fn incr(&mut self, key: &str) -> RedisResult<i64> {
104 let cmd = Qail::redis_incr(key);
105 match self.execute(&cmd).await? {
106 Value::Integer(n) => Ok(n),
107 other => Err(RedisError::Protocol(format!(
108 "Unexpected INCR response: {:?}",
109 other
110 ))),
111 }
112 }
113
114 pub async fn ttl(&mut self, key: &str) -> RedisResult<i64> {
116 let cmd = Qail::redis_ttl(key);
117 match self.execute(&cmd).await? {
118 Value::Integer(n) => Ok(n),
119 other => Err(RedisError::Protocol(format!(
120 "Unexpected TTL response: {:?}",
121 other
122 ))),
123 }
124 }
125
126 pub async fn expire(&mut self, key: &str, seconds: i64) -> RedisResult<bool> {
128 let cmd = Qail::redis_expire(key, seconds);
129 match self.execute(&cmd).await? {
130 Value::Integer(1) => Ok(true),
131 Value::Integer(0) => Ok(false),
132 other => Err(RedisError::Protocol(format!(
133 "Unexpected EXPIRE response: {:?}",
134 other
135 ))),
136 }
137 }
138
139 pub async fn exists(&mut self, key: &str) -> RedisResult<bool> {
141 let cmd = Qail::redis_exists(key);
142 match self.execute(&cmd).await? {
143 Value::Integer(n) => Ok(n > 0),
144 other => Err(RedisError::Protocol(format!(
145 "Unexpected EXISTS response: {:?}",
146 other
147 ))),
148 }
149 }
150
151 pub async fn ping(&mut self) -> RedisResult<bool> {
153 let cmd = Qail::redis_ping();
154 match self.execute(&cmd).await? {
155 Value::String(s) if s == "PONG" => Ok(true),
156 Value::Bulk(b) if b == b"PONG" => Ok(true),
157 _ => Ok(false),
158 }
159 }
160}