< 返回版块

owl-go 发表于 2021-11-08 10:26

Tags:rust redis

Cargo.toml

[package]
name = "redis_server"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
redis = { version = "0.17.0", features = [ "cluster","tokio-comp"] }
tokio = { version = "1", features = ["full"] }

redis_server.rs

use std::time::Duration;

use redis::{Commands, ConnectionLike, RedisResult};

pub struct RedisServer {
   cluster: Option<redis::cluster::ClusterConnection>,
   single: Option<redis::Connection>,
   cluster_mode: bool,
}

impl RedisServer {
   pub fn new(addr: String, auth: String, db: u8) -> Self {
       let addrs = parse_addr(addr, auth, db);
       let mut r = Self {
           cluster: None,
           single: None,
           cluster_mode: false,
      };
       if addrs.len() == 1 {
           let client = redis::Client::open(addrs[0].as_str()).unwrap();
           let conn = client.get_connection().unwrap();
           conn.set_read_timeout(Some(Duration::from_secs(3))).unwrap();
           conn.set_write_timeout(Some(Duration::from_secs(5)))
              .unwrap();
           r.single = Some(conn);
           r.cluster_mode = false;
      } else if addrs.len() > 1 {
           let clust_client = redis::cluster::ClusterClient::open(addrs).unwrap();
           let conn = clust_client.get_connection().unwrap();
           conn.set_read_timeout(Some(Duration::from_secs(3))).unwrap();
           conn.set_write_timeout(Some(Duration::from_secs(5)))
              .unwrap();

           conn.set_read_timeout(Some(Duration::from_secs(2))).unwrap();

           r.cluster = Some(conn);
           r.cluster_mode = true;
      }
       return r;
  }
}
impl RedisServer {
   pub fn keys(&mut self, key: String) -> RedisResult<Vec<String>> {
       // let keys = vec![];
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let keys: Vec<String> = conn.keys(key).unwrap();
               return Ok(keys);
          }
           Err(conn_err("no connection!"))
      } else {
           if let Some(conn) = &mut self.single {
               let keys: Vec<String> = conn.keys(key).unwrap();
               return Ok(keys);
          }
           Err(conn_err("no connection!"))
      }
  }
   pub fn exists(&mut self, key: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value: bool = conn.exists(key).unwrap();
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
       if let Some(conn) = &mut self.single {
           let value: bool = conn.exists(key).unwrap();
           return Ok(value);
      }
       Err(conn_err("no connection!"))
  }
   pub fn setnx(
      &mut self,
       key: String,
       value: String,
       seconds: usize,
  ) -> redis::RedisResult<bool> {
       let set_nx = |conn: &mut dyn ConnectionLike| -> RedisResult<bool> {
           let mut cmd = redis::cmd("set");
           match seconds {
               0 => {
                   let value: bool = cmd.arg(key).arg(value).query(conn)?;
                   return Ok(value);
              }
               _ => {
                   let value: bool = cmd
                      .arg(key)
                      .arg(value)
                      .arg("ex")
                      .arg(seconds)
                      .arg("nx")
                      .query(conn)?;
                   return Ok(value);
              }
          }
      };

       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               set_nx(conn)
          } else {
               Err(conn_err("no connection!"))
          }
      } else {
           if let Some(conn) = &mut self.single {
               set_nx(conn)
          } else {
               Err(conn_err("no connection!"))
          }
      }
  }
   pub fn set(&mut self, key: String, value: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value: bool = conn.set(key, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.set(key, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn get(&mut self, key: String) -> RedisResult<String> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.get(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.get(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn del(&mut self, key: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.del(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.del(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn expire(&mut self, key: String, seconds: usize) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.expire(key, seconds)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.expire(key, seconds)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn expire_at(&mut self, key: String, ts: usize) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.expire_at(key, ts)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.expire_at(key, ts)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn incr(&mut self, key: String) -> RedisResult<usize> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.incr(key, 1)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.incr(key, 1)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   //===============
   //hash
   pub fn hset(&mut self, key: String, field: String, value: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hset(key, field, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hset(key, field, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hget(&mut self, key: String, field: String) -> RedisResult<String> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hget(key, field)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hget(key, field)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hmset(&mut self, key: String, fields: &[(String, String)]) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hset_multiple(key, fields)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hset_multiple(key, fields)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hmget(&mut self, key: String, fields: Vec<String>) -> RedisResult<Vec<String>> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hget(key, fields)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hget(key, fields)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hincr_by(&mut self, key: String, field: String, delta: usize) -> RedisResult<usize> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hincr(key, field, delta)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hincr(key, field, delta)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hdel(&mut self, key: String, field: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hdel(key, field)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hdel(key, field)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hgetall(&mut self, key: String) -> RedisResult<Vec<(String, String)>> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hgetall(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hgetall(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hkeys(&mut self, key: String) -> RedisResult<Vec<String>> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hkeys(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hkeys(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn hexists(&mut self, key: String, field: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.hexists(key, field)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.hexists(key, field)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   //===============
   //list
   pub fn lpop(&mut self, key: String) -> RedisResult<String> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.lpop(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.lpop(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn rpush(&mut self, key: String, value: String) -> RedisResult<bool> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.rpush(key, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.rpush(key, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn llen(&mut self, key: String) -> RedisResult<usize> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.llen(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.llen(key)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn lrem(&mut self, key: String, count: isize, value: String) -> RedisResult<usize> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.lrem(key, count, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.lrem(key, count, value)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
   pub fn lrange(&mut self, key: String, start: isize, end: isize) -> RedisResult<Vec<String>> {
       if self.cluster_mode {
           if let Some(conn) = &mut self.cluster {
               let value = conn.lrange(key, start, end)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      } else {
           if let Some(conn) = &mut self.single {
               let value = conn.lrange(key, start, end)?;
               return Ok(value);
          }
           return Err(conn_err("no connection!"));
      }
  }
}

//redis://[<username>][:<password>@]<hostname>[:port][/<db>]

fn parse_addr(addr: String, auth: String, db: u8) -> Vec<String> {
   let mut vec = Vec::new();
   let addr = addr.split(",");
   for hostname in addr {
       let mut a = String::new();
       if hostname.starts_with("redis://") {
           a = hostname.to_owned();
      } else {
           a = format!("redis://:{}@{}/{}", auth, hostname, db);
      }
       vec.push(a);
  }
   vec
}

fn conn_err(desc: &'static str) -> redis::RedisError {
   redis::RedisError::from((redis::ErrorKind::ClientError, desc))
}

main.rs

#[allow(warnings, dead_code)]
use std::error::Error;

use redis_server;
fn main() -> Result<(), Box<dyn Error>> {
   // redis::test();
   // redis::init();
   // let value = redis::get(1);
   let addr = String::from("127.0.0.1:6379");
   let auth = String::from("");
   let db = 0;
   let mut client = redis_server::RedisServer::new(addr, auth, db);
   let key = String::from("test");
   let value = String::from("value1");
   let exist = match client.exists(key.to_owned()) {
       Ok(exist) => exist,
       Err(e) => {
           panic!("{}", e);
      }
  };
   let seconds = 200;
   let success = client.setnx(key, value, seconds).unwrap();
   println!("{}", success);

   let value = get(1);
   let user_key = String::from("user:1");
   let fields = vec![String::from("name"), String::from("age")];
   let user = client.hkeys(user_key).unwrap();
   println!("{:?}", user);
   let fields = [(String::from("name"), String::from("frank"))];
   let result = client.hmset(String::from("user:2"), &fields).unwrap();

   println!("{}", result);

Ext Link: https://mp.weixin.qq.com/s?__biz=MzIyMzMyMDA1Ng==&mid=2247483809&idx=1&sn=555a8235170d433c60c92b05ed128d3f&chksm=e8214336df56ca20f673049fc1a470c29760cd8282de3b488fabbc63c73589410a55e72d3814&token=380895688&lang=zh_CN#rd

评论区

写评论
作者 owl-go 2021-11-12 18:28

将redis库封装 根据设置的redis ip的个数自动选择是单点模式还是cluster模式 将常见的返回结果封装成对应的数据结果

--
👇
tokyohuang123: 谢谢分享 和原来的有啥区别

tokyohuang123 2021-11-10 10:17

谢谢分享 和原来的有啥区别

1 共 2 条评论, 1 页