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.

Constructs a Builder to construct a Client with custom parameters.

Server hello response from the last connection created.

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);

https://redis.io/commands/del

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);
}

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);

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);

https://redis.io/commands/get

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);

https://redis.io/commands/set

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);

Sends any command and get a response.

Both command and response are serialized/deserialized using serde. See CommandSerializer and Deserializer for details.

Trait Implementations

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

The resulting type after dereferencing.

Dereferences the value.

Performs the conversion.

Performs the conversion.

Performs the conversion.

Sends any command and get a response. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Performs the conversion.

Performs the conversion.

The resulting type after obtaining ownership.

Creates owned data from borrowed data, usually by cloning. Read more

🔬 This is a nightly-only experimental API. (toowned_clone_into)

Uses borrowed data to replace owned data, usually by cloning. Read more

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.