pub struct Client<T: Connector = TcpConnector> { /* private fields */ }
Expand description
A Redis client.
A Client
can use various channels to connect to a Redis server.
By default it uses TCP, but UDS and custom streams are available.
Connection parameters used by a Client
can be configured using a Builder
.
A Client
manages a pool of connections to a Redis server.
Cloning a Client
will result in a copy that shares the pool with the original one.
You do not need to re-wrap it with Arc
or similar, since it already uses an Arc
internally.
Implementations
Constructs a client with default configurations.
If you need more tweaks use Client::builder()
instead.
Server hello response from the last connection created.
pub async fn raw_command<Req: Serialize, Resp: DeserializeOwned>(
&self,
request: Req
) -> Result<Resp, Error>
pub async fn raw_command<Req: Serialize, Resp: DeserializeOwned>(
&self,
request: Req
) -> Result<Resp, Error>
Sends any command and get a response.
Both command and response are serialized/deserialized using serde
.
See CommandSerializer
and Deserializer
for details.
Gets a connection from the pool, creating one if not available.
Normally, a dropped Connection
will be returned to the Client
’s pool.
Methods from Deref<Target = CommandHelper<ClientShared<T>>>
https://redis.io/commands/copy
source
and the destination
should be scalar types.
client.set(key1, "sheep").await?;
let res = client.copy(key1, key2, None, false).await?;
assert!(res);
let res: String = client.get(key2).await?;
assert_eq!("sheep", res);
keys
should be a sequence type.
client.set(key1, "Hello").await?;
client.set(key2, "World").await?;
let res = client.del([key1, key2]).await?;
assert_eq!(2, res);
https://redis.io/commands/exists
keys
should be a sequence type.
client.set(key1, "Hello").await?;
let res = client.exists(key1).await?;
assert_eq!(1, res);
let res = client.exists("nosuchkey").await?;
assert_eq!(0, res);
client.set(key2, "World").await?;
let res = client.exists([key1, key2, "nosuchkey"]).await?;
assert_eq!(2, res);
Same as .exists()
,
but takes single key and returns bool
.
key
should be a scalar type.
let res = client.exists_one(key).await?;
assert!(!res);
client.set(key, "Hello").await?;
let res = client.exists_one(key).await?;
assert!(res);
https://redis.io/commands/pexpire
Despite the name, this method uses PEXPIRE
, not EXPIRE
, for millisecond-level accuracy.
keys
should be a scalar type.
client.set(key, "Hello").await?;
let res = client.expire(key, Duration::from_secs(10)).await?;
assert!(res);
let res = client.ttl(key).await?;
assert!(helper::mostly_eq(res.unwrap(), Duration::from_secs(10)));
client.set(key, "Hello World").await?;
https://redis.io/commands/pexpireat
Despite the name, this method uses PEXPIREAT
, not EXPIREAT
, for millisecond-level accuracy.
keys
should be a scalar type.
client.set(key, "Hello").await?;
let res = client.exists_one(key).await?;
assert!(res);
let res = client.expireat(key, SystemTime::UNIX_EPOCH).await?;
assert!(res);
let res = client.exists_one(key).await?;
assert!(!res);
https://redis.io/commands/pttl
Despite the name, this method uses PTTL
, not TTL
, for millisecond-level accuracy.
keys
should be a scalar type.
client.set(key, "Hello").await?;
let res = client.expire(key, Duration::from_secs(10)).await?;
assert!(res);
let res = client.ttl(key).await?;
assert!(helper::mostly_eq(res.unwrap(), Duration::from_secs(10)));
https://redis.io/commands/scan
key
should be a scalar type.
client.set(key1, "value1").await?;
client.set(key2, "value2").await?;
client.set(key3, "value3").await?;
let mut cursor = 0;
let mut output = vec![];
loop {
let (next, res): (u64, Vec<String>) = client.scan(cursor, Some(pattern), None).await?;
output.extend(res);
cursor = next;
if next == 0 {
break;
}
}
output.sort();
assert_eq!(vec![key1.to_owned(), key2.into(), key3.into()], output);
https://redis.io/commands/hdel
key
should be a scalar type, and fields
should be a sequence type.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
field2: i32,
}
let res = client.hset(key, &Fields { field1: "foo".into(), field2: 42 }).await?;
assert_eq!(2, res);
let res = client.hdel(key, ("field1", "field2")).await?;
assert_eq!(2, res);
let res = client.hdel(key, "field1").await?;
assert_eq!(0, res);
https://redis.io/commands/hexists
key
and field
should be scalar types.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
}
let res = client.hset(key, &Fields { field1: "foo".into() }).await?;
assert_eq!(1, res);
let res = client.hexists(key, "field1").await?;
assert!(res);
let res = client.hexists(key, "field2").await?;
assert!(!res);
https://redis.io/commands/hget
key
and field
should be scalar types.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
}
let res = client.hset(key, &Fields { field1: "foo".into() }).await?;
assert_eq!(1, res);
let res: String = client.hget(key, "field1").await?;
assert_eq!("foo", res);
let res: Option<String> = client.hget(key, "field2").await?;
assert!(res.is_none());
https://redis.io/commands/hgetall
key
should be a scalar type.
#[derive(serde::Serialize, PartialEq)]
struct Fields {
field1: String,
field2: String,
}
let res = client.hset(key, &Fields { field1: "Hello".into(), field2: "World".into() }).await?;
assert_eq!(2, res);
let res: HashMap<String, String> = client.hgetall(key).await?;
assert_eq!(2, res.len());
assert_eq!("Hello", &res["field1"]);
assert_eq!("World", &res["field2"]);
https://redis.io/commands/hincrby
key
and field
should be scalar types.
#[derive(serde::Serialize)]
struct Fields {
field1: i32,
}
let res = client.hset(key, &Fields { field1: 5 }).await?;
assert_eq!(1, res);
let res = client.hincrby(key, "field1", 1).await?;
assert_eq!(6, res);
let res = client.hincrby(key, "field1", -1).await?;
assert_eq!(5, res);
let res = client.hincrby(key, "field1", -10).await?;
assert_eq!(-5, res);
https://redis.io/commands/hincrbyfloat
key
and field
should be scalar types.
#[derive(serde::Serialize)]
struct Fields {
field: f64,
}
let res = client.hset(key, &Fields { field: 10.50 }).await?;
assert_eq!(1, res);
let res = client.hincrbyfloat(key, "field", 0.1).await?;
assert_eq!(10.6, res);
let res = client.hincrbyfloat(key, "field", -5.0).await?;
assert_eq!(5.6, res);
let res = client.hset(key, &Fields { field: 5.0e3 }).await?;
assert_eq!(0, res);
let res = client.hincrbyfloat(key, "field", 2.0e2).await?;
assert_eq!(5200.0, res);
https://redis.io/commands/hkeys
key
should be a scalar type.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
field2: String,
}
let res = client.hset(key, &Fields { field1: "Hello".into(), field2: "World".into() }).await?;
assert_eq!(2, res);
let res: Vec<String> = client.hkeys(key).await?;
assert_eq!(&["field1".to_owned(), "field2".to_owned()][..], &res[..]);
https://redis.io/commands/hlen
key
should be a scalar type.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
field2: String,
}
let res = client.hset(key, &Fields { field1: "Hello".into(), field2: "World".into() }).await?;
assert_eq!(2, res);
let res = client.hlen(key).await?;
assert_eq!(2, res);
https://redis.io/commands/hmget
key
should be a scalar type and returned R
must be
a struct type with named fields, not enum or tuple struct.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
field2: String,
}
#[derive(serde::Deserialize, PartialEq, Debug)]
struct Query {
field1: String,
field2: String,
nofield: Option<i32>,
}
let res = client.hset(key, &Fields { field1: "Hello".into(), field2: "World".into() }).await?;
assert_eq!(2, res);
for _ in 0..10 {
let res: Query = client.hmget(key).await?;
assert_eq!(Query { field1: "Hello".into(), field2: "World".into(), nofield: None }, res);
}
pub async fn hrandfield<K, R>(&self, key: K) -> Result<R, Error> where
K: Serialize + Send,
R: DeserializeOwned,
pub async fn hrandfield<K, R>(&self, key: K) -> Result<R, Error> where
K: Serialize + Send,
R: DeserializeOwned,
https://redis.io/commands/hrandfield
HRANDFIELD
with just the key argument.
key
should be a scalar type.
#[derive(serde::Serialize)]
struct Fields {
head: String,
tails: String,
edge: String,
}
let res = client.hset(key, &Fields { head: "obverse".into(), tails: "reverse".into(), edge: "null".into() }).await?;
assert_eq!(3, res);
let res: String = client.hrandfield(key).await?;
assert!(["head".to_owned(), "tails".to_owned(), "edge".to_owned()].contains(&res), "res: {}", res);
pub async fn hrandfield_count<K, R>(
&self,
key: K,
count: isize
) -> Result<R, Error> where
K: Serialize + Send,
R: DeserializeOwned,
pub async fn hrandfield_count<K, R>(
&self,
key: K,
count: isize
) -> Result<R, Error> where
K: Serialize + Send,
R: DeserializeOwned,
https://redis.io/commands/hrandfield
HRANDFIELD
with count and optional WITHVALUES
specifier.
key
should be a scalar type.
#[derive(serde::Serialize)]
struct Fields {
head: String,
}
let res = client.hset(key, &Fields { head: "obverse".into() }).await?;
assert_eq!(1, res);
let res: Vec<String> = client.hrandfield_count(key, 3).await?;
assert_eq!(vec!["head".to_owned()], res);
let res: Vec<String> = client.hrandfield_count(key, -3).await?;
assert_eq!(vec!["head".to_owned(), "head".to_owned(), "head".to_owned()], res);
https://redis.io/commands/hscan
key
should be a scalar type.
#[derive(serde::Serialize)]
struct Fields {
name: String,
age: i32,
}
let res = client.hset(key, &Fields { name: "Jack".into(), age: 33 }).await?;
assert_eq!(2, res);
let (cursor, res): (u64, Vec<String>) = client.hscan(key, 0, None, None).await?;
assert_eq!(0, cursor);
assert_eq!(vec!["name".to_owned(), "Jack".to_owned(), "age".to_owned(), "33".to_owned()], res);
https://redis.io/commands/hset
key
should be a scalar type, and entries
should be a map-like type.
#[derive(serde::Serialize)]
struct Fields {
field1: String,
field2: i32,
}
let res = client.hset(key, &Fields { field1: "foo".into(), field2: 42 }).await?;
assert_eq!(2, res);
let res: String = client.hget(key, "field1").await?;
assert_eq!("foo", res);
https://redis.io/commands/hsetnx
key
, field
and value
should be scalar types.
#[derive(serde::Serialize)]
struct Fields {
field: f64,
}
let res = client.hsetnx(key, "field", "Hello").await?;
assert!(res);
let res = client.hsetnx(key, "field", "World").await?;
assert!(!res);
let res: String = client.hget(key, "field").await?;
assert_eq!("Hello", res);
https://redis.io/commands/hstrlen
key
and field
should be scalar types.
#[derive(serde::Serialize)]
struct Fields {
f1: String,
f2: usize,
f3: i32,
}
let res = client.hset(key, &Fields { f1: "HelloWorld".into(), f2: 99, f3: -256 }).await?;
assert_eq!(3, res);
let res = client.hstrlen(key, "f1").await?;
assert_eq!(10, res);
let res = client.hstrlen(key, "f2").await?;
assert_eq!(2, res);
let res = client.hstrlen(key, "f3").await?;
assert_eq!(4, res);
https://redis.io/commands/hvals
key
should be a scalar type.
#[derive(serde::Serialize, PartialEq)]
struct Fields {
field1: String,
field2: String,
}
let res = client.hset(key, &Fields { field1: "Hello".into(), field2: "World".into() }).await?;
assert_eq!(2, res);
let res: Vec<String> = client.hvals(key).await?;
assert_eq!(vec!["Hello".to_owned(), "World".to_owned()], res);
https://redis.io/commands/append
key
and value
should be scalar types.
let res = client.exists_one(key).await?;
assert!(!res);
let res = client.append(key, "Hello").await?;
assert_eq!(5, res);
let res = client.append(key, " World").await?;
assert_eq!(11, res);
let res: String = client.get(key).await?;
assert_eq!("Hello World", res);
https://redis.io/commands/decr
key
should be a scalar type.
client.set(key, "10").await?;
let res = client.decr(key).await?;
assert_eq!(9, res);
client.set(key, "234293482390480948029348230948").await?;
let res = client.decr(key).await;
assert!(res.is_err());
https://redis.io/commands/decrby
key
should be a scalar type.
client.set(key, "10").await?;
let res = client.decrby(key, 3).await?;
assert_eq!(7, res);
key
should be a scalar type.
let res: Option<i32> = client.get("nonexisting").await?;
assert!(res.is_none());
client.set(key, "Hello").await?;
let res: String = client.get(key).await?;
assert_eq!("Hello", res);
https://redis.io/commands/getrange
key
should be a scalar type.
client.set(key, "This is a string").await?;
let res: String = client.getrange(key, 0, 3).await?;
assert_eq!("This", res);
let res: String = client.getrange(key, -3, -1).await?;
assert_eq!("ing", res);
let res: String = client.getrange(key, 0, -1).await?;
assert_eq!("This is a string", res);
let res: String = client.getrange(key, 10, 100).await?;
assert_eq!("string", res);
https://redis.io/commands/incr
key
should be a scalar type.
client.set(key, "10").await?;
let res = client.incr(key).await?;
assert_eq!(11, res);
let res: i64 = client.get(key).await?;
assert_eq!(11, res);
https://redis.io/commands/incrby
key
should be a scalar type.
client.set(key, "10").await?;
let res = client.incrby(key, 5).await?;
assert_eq!(15, res);
https://redis.io/commands/incrbyfloat
key
should be a scalar type.
client.set(key, 10.50f64).await?;
let res = client.incrbyfloat(key, 0.1).await?;
assert_eq!(10.6, res);
let res = client.incrbyfloat(key, -5.0).await?;
assert_eq!(5.6, res);
client.set(key, "5.0e3").await?;
let res = client.incrbyfloat(key, 200.0).await?;
assert_eq!(5200.0, res);
https://redis.io/commands/mget
keys
should be a sequence type.
client.set(key1, "Hello").await?;
client.set(key2, "World").await?;
let res: Vec<Option<String>> = client.mget([key1, key2, "nonexisting"]).await?;
assert_eq!(vec![
Some("Hello".to_owned()),
Some("World".to_owned()),
None,
], res);
https://redis.io/commands/mset
entries
should be a map-like type.
let mut map = HashMap::new();
map.insert(key1, "Hello");
map.insert(key2, "World");
client.mset(&map).await?;
let res: String = client.get(key1).await?;
assert_eq!("Hello", res);
let res: String = client.get(key2).await?;
assert_eq!("World", res);
key
and value
should be scalar types.
client.set(key, "Hello").await?;
let res: String = client.get(key).await?;
assert_eq!("Hello", res);
https://redis.io/commands/setrange
key
and value
should be scalar types.
client.set(key1, "Hello World").await?;
let res = client.setrange(key1, 6, "Redis").await?;
assert_eq!(11, res);
let res: String = client.get(key1).await?;
assert_eq!("Hello Redis", res);
let res = client.setrange(key2, 6, "Redis").await?;
assert_eq!(11, res);
let res: String = client.get(key2).await?;
assert_eq!("\0\0\0\0\0\0Redis", res);
https://redis.io/commands/strlen
key
should be a scalar type.
client.set(key, "Hello world").await?;
let res = client.strlen(key).await?;
assert_eq!(11, res);
let res = client.strlen("nonexisting").await?;
assert_eq!(0, res);
pub async fn raw_command<Req, Resp>(&self, request: Req) -> Result<Resp, Error> where
Req: Serialize + Send,
Resp: DeserializeOwned,
pub async fn raw_command<Req, Resp>(&self, request: Req) -> Result<Resp, Error> where
Req: Serialize + Send,
Resp: DeserializeOwned,
Sends any command and get a response.
Both command and response are serialized/deserialized using serde
.
See CommandSerializer
and Deserializer
for details.
Trait Implementations
type Target = CommandHelper<ClientShared<T>>
type Target = CommandHelper<ClientShared<T>>
The resulting type after dereferencing.
Performs the conversion.
Performs the conversion.
fn raw_command<'a, Req, Resp>(
&'a self,
request: Req
) -> BoxFuture<'a, Result<Resp, Error>> where
Req: Serialize + Send + 'a,
Resp: DeserializeOwned + 'a,
fn raw_command<'a, Req, Resp>(
&'a self,
request: Req
) -> BoxFuture<'a, Result<Resp, Error>> where
Req: Serialize + Send + 'a,
Resp: DeserializeOwned + 'a,
Sends any command and get a response. Read more
Auto Trait Implementations
impl<T = TcpConnector> !RefUnwindSafe for Client<T>
impl<T = TcpConnector> !UnwindSafe for Client<T>
Blanket Implementations
Mutably borrows from an owned value. Read more