Expand description
Defines types related to the RESP
protocol and their encoding/decoding
§Object Model
rustis provides an object model in the form of a generic data struct, comparable to the XML DOM,
and which matches perfectly the RESP protocol: the enum resp::Value
.
Each variant of this enum matches a RESP
type.
Because, navigating through a resp::Value
instance can be verbose and requires a lot of pattern matching,
rustis provides a resp::Value
to Rust type conversion with a serde
deserializer implementation of a resp::Value
reference.
This conversion is easily accessible through the associate function Value::into
.
§Command arguments
rustis provides an idiomatic way to pass arguments to commands.
Basically a Command
is a builder which accepts a command name and one ore more command arguments.
You will notice that each built-in command expects arguments through a set of traits defined in this module.
For each trait, you can add your own implementations for your custom types or request additional implementation for standard types.
§ToArgs
The trait ToArgs
allows to convert a complex type into one ore multiple argumentss.
Basically, the conversion function can add multiple arguments to an existing argument collection: the CommandArgs
struct.
Current implementation provides the following conversions:
i8
,u16
,i16
,u32
,i32
,u64
,i64
,usize
,isize
,f32
,f64
,bool
,String
,&String
,char
,&str
,BulkString
,Vec<u8>
,&[u8; N]
,[u8; N]
,&[u8]
Option<T>
whereT: SingleArg
(T, U)
(T, U, V)
Vec<T>
[T;N]
SmallVec<A>
BTreeSet<T>
HashSet<T, S>
BTreeMap<K, V>
HashMap<K, V, S>
CommandArgs
Nevertheless, ToArgs
is not expected directly in built-in commands arguments.
The following traits are used to constraints which implementations of ToArgs
are expected by a specific argument of a built-in command.
§SingleArg
Several Redis commands expect a Rust type that should be converted in a single command argument.
rustis uses the trait SingleArg
to implement this behavior.
Current implementation provides the following conversions:
i8
,u16
,i16
,u32
,i32
,u64
,i64
,usize
,isize
,f32
,f64
,bool
,String
,&String
,char
,&str
,BulkString
,Vec<u8>
,&[u8; N]
,[u8; N]
,&[u8]
Option<T>
whereT: SingleArg
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, StringCommands},
resp::{CommandArgs, ToArgs, SingleArg},
Result,
};
pub struct MyI32(i32);
impl ToArgs for MyI32 {
#[inline]
fn write_args(&self, args: &mut CommandArgs) {
args.arg(self.0);
}
}
impl SingleArg for MyI32 {}
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.set("key", 12).await?;
client.set("key", 12i64).await?;
client.set("key", 12.12).await?;
client.set("key", true).await?;
client.set("key", true).await?;
client.set("key", "value").await?;
client.set("key", "value".to_owned()).await?;
client.set("key", 'c').await?;
client.set("key", b"value").await?;
client.set("key", &b"value"[..]).await?;
client.set("key", b"value".to_vec()).await?;
client.set("key", MyI32(12)).await?;
Ok(())
}
§SingleArgCollection
Several Redis commands expect a collection with elements that will produced a single command argument each
rustis uses the trait SingleArgCollection
to implement this behavior.
Current implementation provides the following conversions:
T
(for the single item case)Vec<T>
[T;N]
SmallVec<A>
BTreeSet<T>
HashSet<T, S>
CommandArgs
where each of theses implementations must also implement ToArgs
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, ListCommands},
Result,
};
use smallvec::{SmallVec};
use std::collections::{HashSet, BTreeSet};
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.lpush("key", 12).await?;
client.lpush("key", [12, 13, 14]).await?;
client.lpush("key", vec![12, 13, 14]).await?;
client.lpush("key", SmallVec::from([12, 13, 14])).await?;
client.lpush("key", HashSet::from([12, 13, 14])).await?;
client.lpush("key", BTreeSet::from([12, 13, 14])).await?;
client.lpush("key", "value1").await?;
client.lpush("key", ["value1", "value2", "value13"]).await?;
client.lpush("key", vec!["value1", "value2", "value13"]).await?;
client.lpush("key", SmallVec::from(["value1", "value2", "value13"])).await?;
client.lpush("key", HashSet::from(["value1", "value2", "value13"])).await?;
client.lpush("key", BTreeSet::from(["value1", "value2", "value13"])).await?;
Ok(())
}
§MultipleArgsCollection
Several Redis commands expect a collection with elements that will produced multiple command arguments each
rustis uses the trait MultipleArgsCollection
to implement this behavior.
Current implementation provides the following conversions:
T
(for the single item case)Vec<T>
[T;N]
where each of theses implementations must also implement ToArgs
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, SortedSetCommands, ZAddOptions},
Result,
};
use std::collections::{HashSet, BTreeSet};
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.zadd("key", (1.0, "member1"), ZAddOptions::default()).await?;
client.zadd("key", [(1.0, "member1"), (2.0, "member2")], ZAddOptions::default()).await?;
client.zadd("key", vec![(1.0, "member1"), (2.0, "member2")], ZAddOptions::default()).await?;
Ok(())
}
§KeyValueArgsCollection
Several Redis commands expect one or multiple key/value pairs.
rustis uses the trait KeyValueArgsCollection
to implement this behavior.
Current implementation provides the following conversions:
(K, V)
(for the single item case)Vec<(K, V)>
[(K, V);N]
SmallVec<A>
whereA: Array<Item = (K, V)>
BTreeMap<K, V>
HashMap<K, V, S>
where each of theses implementations must also implement ToArgs
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, StringCommands},
Result,
};
use smallvec::{SmallVec};
use std::collections::{HashMap, BTreeMap};
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.mset(("key1", "value1")).await?;
client.mset([("key1", "value1"), ("key2", "value2")]).await?;
client.mset(vec![("key1", "value1"), ("key2", "value2")]).await?;
client.mset(SmallVec::from([("key1", "value1"), ("key2", "value2")])).await?;
client.mset(HashMap::from([("key1", "value1"), ("key2", "value2")])).await?;
client.mset(BTreeMap::from([("key1", "value1"), ("key2", "value2")])).await?;
client.mset(("key1", 12)).await?;
client.mset([("key1", 12), ("key2", 13)]).await?;
client.mset(vec![("key1", 12), ("key2", 13)]).await?;
client.mset(SmallVec::from([("key1", 12), ("key2", 13)])).await?;
client.mset(HashMap::from([("key1", 12), ("key2", 13)])).await?;
client.mset(BTreeMap::from([("key1", 12), ("key2", 13)])).await?;
Ok(())
}
§Command results
rustis provides an idiomatic way to convert command results into Rust types with the help of serde
You will notice that each built-in command returns a PreparedCommand<R>
struct where R
represents the Response
of the command.
The different command traits implementations (Client
, Pipeline
or Transaction
) add a constraint on the reponse R
:
it must implement serde Deserialize
trait.
Indeed, rustis provides a serde implementation of a RESP deserializer
.
Each custom struct or enum defined as a response of a built-command implements
serde Deserialize
trait,
in order to deserialize it automatically from a RESP Buffer.
Some more advanced traits allow to constraint more which Rust types are allowed for specific commands.
For each trait, you can add your own implementations for your custom types or request additional implementation for standard types.
§PrimitiveResponse
Several Redis commands return a simple primitive response.
rustis uses the trait PrimitiveResponse
to implement this behavior.
Current implementation provides the following deserializations from a RESP Buffer:
Value
- ()
u8
,i8
,u16
,i16
,u32
,i32
,u64
,i64
,usize
,isize
,f32
,f64
,bool
,String
,BulkString
,Option<T>
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, StringCommands},
resp::{PrimitiveResponse, deserialize_byte_buf},
Result,
};
use serde::Deserialize;
#[derive(Deserialize)]
pub struct MyI32(i32);
impl PrimitiveResponse for MyI32 {}
#[derive(Deserialize)]
pub struct Buffer(#[serde(deserialize_with = "deserialize_byte_buf")] pub Vec<u8>);
impl PrimitiveResponse for Buffer {}
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.set("key", 12).await?;
let _result: i32 = client.get("key").await?;
let _result: MyI32 = client.get("key").await?;
client.set("key", 12.12).await?;
let _result: f64 = client.get("key").await?;
client.set("key", true).await?;
let _result: bool = client.get("key").await?;
client.set("key", "value").await?;
let _result: String = client.get("key").await?;
let _result: Buffer = client.get("key").await?;
Ok(())
}
§CollectionResponse
Several Redis commands return a collection of items.
rustis uses the trait CollectionResponse
to implement this behavior.
Current implementation provides the following deserializations from a RESP Buffer:
Vec<T>
[T;N]
SmallVec<A>
BTreeSet<T>
HashSet<T, S>
where each of theses implementations must also implement Response
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, ListCommands},
Result,
};
use smallvec::{SmallVec};
use std::collections::{HashSet, BTreeSet};
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.lpush("key", [12, 13, 14]).await?;
let _values: Vec<Option<i32>> = client.rpop("key", 3).await?;
client.lpush("key", [12, 13, 14]).await?;
let _values: HashSet<Option<i32>> = client.rpop("key", 3).await?;
client.lpush("key", [12, 13, 14]).await?;
let _values: BTreeSet<Option<i32>> = client.rpop("key", 3).await?;
client.lpush("key", [12, 13, 14]).await?;
let _values: SmallVec<[Option<i32>;3]> = client.rpop("key", 3).await?;
Ok(())
}
§KeyValueCollectionResponse
Several Redis commands return a collection of key/value pairs
rustis uses the trait KeyValueCollectionResponse
to implement this behavior.
Current implementation provides the following deserializations from a RESP Buffer:
BTreeMap<K, V>
HashMap<K, V, S>
SmallVec<A>
whereA: Array<Item = (K, V)>
Vec<(K, V>)>
where each of theses implementations must also implement Response
§Example
use rustis::{
client::Client,
commands::{FlushingMode, ServerCommands, HashCommands},
Result,
};
use smallvec::{SmallVec};
use std::collections::{HashMap, BTreeMap};
#[cfg_attr(feature = "tokio-runtime", tokio::main)]
#[cfg_attr(feature = "async-std-runtime", async_std::main)]
async fn main() -> Result<()> {
// Connect the client to a Redis server from its IP and port
let client = Client::connect("127.0.0.1:6379").await?;
// Flush all existing data in Redis
client.flushdb(FlushingMode::Sync).await?;
client.hset("key", [("field1", 12), ("field2", 13)]).await?;
let _values: BTreeMap<String, i32> = client.hgetall("key").await?;
let _values: HashMap<String, i32> = client.hgetall("key").await?;
let _values: SmallVec<[(String, i32); 10]> = client.hgetall("key").await?;
let _values: Vec<(String, i32)> = client.hgetall("key").await?;
Ok(())
}
Structs§
- Bulk
String - Represents the Bulk String RESP type
- Command
- Generic command meant to be sent to the Redis Server
- Command
Args - Collection of arguments of
Command
. - Command
Args Into Iterator CommandArgs
into iterator- Command
Args Iterator CommandArgs
iterator- Json
- Wrapper type that deserializes a Redis bulk string as JSON into a Rust value.
- JsonRef
- Wrapper type that serializes a Rust value as JSON before sending it to Redis.
- KeyValue
Args Iterator - A wrapper type that adapts any clonable iterator of
(K, V)
pairs (where bothK
andV
implementSingleArg
) to theKeyValueArgsCollection
andToArgs
traits. - KeyValue
Args RefIterator - A wrapper type that adapts any clonable iterator of references to
(K, V)
pairs (where bothK
andV
implementSingleArg
) to theKeyValueArgsCollection
andToArgs
traits. - Resp
Array Chunks - An iterator over a RESP Array in byte slices
- RespBuf
- Represents a RESP Buffer incoming from the network
- Resp
Deserializer - Serde deserializer for
RESP3
- Resp
Serializer - Serde serializer for
RESP3
- Single
ArgIterator - A wrapper type that adapts any clonable iterator of
SingleArg
items to theSingleArgCollection
andToArgs
traits. - Single
ArgRef Iterator - A wrapper type that adapts any clonable iterator of references to
SingleArg
items to theSingleArgCollection
andToArgs
traits.
Enums§
- Value
- Generic Redis Object Model
Traits§
- Collection
Response - Marker for a collection response
- KeyValue
Args Collection - Marker for key/value collections of Args
- KeyValue
Collection Response - Marker for key/value collection response
- Multiple
Args Collection - Generic Marker for Collections of
ToArgs
- Primitive
Response - Marker for a primitive response
- Response
- Marker for a RESP Response
- Single
Arg - Generic Marker for single arguments (no collections nor tuples)
- Single
ArgCollection - Marker for collections of single items of
ToArgs
- ToArgs
- Types compatible with command args
Functions§
- cmd
- Shortcut function for creating a command.
- deserialize_
byte_ buf - Deserialize a byte buffer (Vec<u8>)
- deserialize_
bytes - Deserialize a byte slice (&[u8])
- deserialize_
vec_ of_ pairs - Deserialize a Vec of pairs from a sequence
- deserialize_
vec_ of_ triplets - Deserialize a Vec of triplets from a sequence
- key_
value_ args_ iter - Convenience function for constructing a
KeyValueArgsIterator
from any clonable iterator of(K, V)
pairs. - key_
value_ args_ ref_ iter - Convenience function for constructing a
KeyValueArgsRefIterator
from any clonable iterator of references to(K, V)
pairs. - serialize_
byte_ buf - Serialize a byte buffer (&[u8])
- single_
arg_ iter - Convenience function for constructing a
SingleArgIterator
from any clonable iterator ofSingleArg
items. - single_
arg_ ref_ iter - Convenience function for constructing a
SingleArgRefIterator
from any clonable iterator of references toSingleArg
items.