rustis/
lib.rs

1#![cfg_attr(docsrs, feature(doc_cfg))]
2/*!
3rustis is a Redis client for Rust.
4# Philosophy
5* Low allocations
6* Full async library
7* Lock free implementation
8* Rust idiomatic API
9
10# Features
11* Support all [Redis Commands](https://redis.io/commands/) until Redis 7.0
12* Async support ([tokio](https://tokio.rs/) or [async-std](https://async.rs/))
13* Different client types:
14  * Single client
15  * [Multiplexed](https://redis.com/blog/multiplexing-explained/) client
16  * Pooled client manager (based on [bb8](https://docs.rs/bb8/latest/bb8/))
17* Automatic command batching
18* Advanced reconnection & retry strategy
19* [Pipelining](https://redis.io/docs/manual/pipelining/) support
20* Configuration with Redis URL or dedicated builder
21* [TLS](https://redis.io/docs/manual/security/encryption/) support
22* [Transaction](https://redis.io/docs/manual/transactions/) support
23* [Pub/sub](https://redis.io/docs/manual/pubsub/) support
24* [Sentinel](https://redis.io/docs/manual/sentinel/) support
25* [LUA Scripts/Functions](https://redis.io/docs/manual/programmability/) support
26* [Cluster](https://redis.io/docs/manual/scaling/) support
27* [Redis Stack](https://redis.io/docs/stack/) support:
28  * [RedisJSON v2.4](https://redis.io/docs/stack/json/) support
29  * [RedisSearch v2.6](https://redis.io/docs/stack/search/) support
30  * [RedisGraph v2.10](https://redis.io/docs/stack/graph/) support
31  * [RedisBloom v2.4](https://redis.io/docs/stack/bloom/) support
32  * [RedisTimeSeries v1.8](https://redis.io/docs/stack/timeseries/) support
33
34# Optional Features
35| Feature | Description |
36| ------- | ----------- |
37| `tokio-runtime` | [Tokio](https://tokio.rs/) runime (default) |
38| `async-std-runtime` | [async-std](https://async.rs/) runtime (optional) |
39| `tokio-tls` | Tokio TLS support (optional) |
40| `async-std-tls` | async-std TLS support (optional) |
41| `pool` | Pooled client manager (optional) |
42| `redis-json` | [RedisJSON v2.4](https://redis.io/docs/stack/json/) support (optional) |
43| `redis-search` | [RedisSearch v2.6](https://redis.io/docs/stack/search/) support (optional) |
44| `redis-graph` | [RedisGraph v2.10](https://redis.io/docs/stack/graph/) support (optional) |
45| `redis-bloom` | [RedisBloom v2.4](https://redis.io/docs/stack/bloom/) support (optional) |
46| `redis-time-series` | [RedisTimeSeries v1.8](https://redis.io/docs/stack/timeseries/) support (optional) |
47| `redis-stack` | activate `redis-json`, `redis-search`, `redis-graph`, `redis-bloom` & `redis-time-series` at the same time (optional) |
48
49# Basic Usage
50
51```
52use rustis::{
53    client::Client, 
54    commands::{FlushingMode, ServerCommands, StringCommands},
55    Result,
56};
57
58#[cfg_attr(feature = "tokio-runtime", tokio::main)]
59#[cfg_attr(feature = "async-std-runtime", async_std::main)]
60async fn main() -> Result<()> {
61    // Connect the client to a Redis server from its IP and port
62    let client = Client::connect("127.0.0.1:6379").await?;
63
64    // Flush all existing data in Redis
65    client.flushdb(FlushingMode::Sync).await?;
66
67    // sends the command SET to Redis. This command is defined in the StringCommands trait
68    client.set("key", "value").await?;
69
70    // sends the command GET to Redis. This command is defined in the StringCommands trait
71    let value: String = client.get("key").await?;
72    println!("value: {value:?}");
73
74    Ok(())
75}
76```
77
78# Client
79See the module [`client`] to discover which are the 3 
80usages of the [`Client`](client::Client) struct and how to configure it.
81
82You will also learn how to use pipeline, pub/sub and transactions.
83
84# RESP
85RESP is the [Redis Serialization Protocol](https://redis.io/docs/reference/protocol-spec/).
86
87See the module [`resp`] to discover how **rustis** 
88allows programmers to communicate with Redis in a Rust idiomatic way.
89
90You will learn how to:
91* Manipulate the **rustis** object model, the enum [`Value`](resp::Value), which is a generic Rust data structure over RESP.
92* Convert Rust type into Rust Commands with the [`Command`](resp::Command) struct and the [`ToArgs`](resp::ToArgs) trait.
93* Convert Rust command responses into Rust type with serde and helpful marker traits.
94
95# Commands
96In order to send [Commands](https://redis.io/commands/) to the Redis server,
97**rustis** offers two API levels:
98* High-level Built-in commands that implement all [Redis 7.0](https://redis.com/blog/redis-7-generally-available/) commands +
99  [Redis Stack](https://redis.io/docs/stack/) commands.
100* Low-level Generic command API to express any request that may not exist in **rustis**:
101  * new official commands not yet implemented by **rustis**.
102  * commands exposed by additional [Redis modules](https://redis.io/resources/modules/)
103    not included in [Redis Stack](https://redis.io/docs/stack/).
104
105## Built-in commands
106See the module [`commands`] to discover how Redis built-in commands are organized in different traits.
107
108## Generic command API
109To use the generic command API, you can use the [`cmd`](crate::resp::cmd) function to specify the name of the command,
110followed by one or multiple calls to the [`Commmand::arg`](crate::resp::Command::arg) associated function to add arguments to the command.
111
112This command can then be passed as a parameter to one of the following associated functions,
113depending on the client, transaction or pipeline struct used:
114* [`send`](crate::client::Client::send)
115* [`send_and_forget`](crate::client::Client::send_and_forget)
116* [`send_batch`](crate::client::Client::send_batch)
117
118```
119use rustis::{client::Client, resp::cmd, Result};
120
121#[cfg_attr(feature = "tokio-runtime", tokio::main)]
122#[cfg_attr(feature = "async-std-runtime", async_std::main)]
123async fn main() -> Result<()> {
124    let client = Client::connect("127.0.0.1:6379").await?;
125
126    client
127        .send(
128            cmd("MSET")
129                .arg("key1")
130                .arg("value1")
131                .arg("key2")
132                .arg("value2")
133                .arg("key3")
134                .arg("value3")
135                .arg("key4")
136                .arg("value4"),
137            None,
138        )
139        .await?
140        .to::<()>()?;
141
142    let values: Vec<String> = client
143        .send(
144            cmd("MGET").arg("key1").arg("key2").arg("key3").arg("key4"),
145            None,
146        )
147        .await?
148        .to()?;
149
150    assert_eq!(vec!["value1".to_owned(), "value2".to_owned(), "value3".to_owned(), "value4".to_owned()], values);
151
152    Ok(())
153}
154```
155*/
156
157pub mod client;
158pub mod commands;
159mod error;
160mod network;
161pub mod resp;
162
163#[cfg(feature = "pool")]
164pub use bb8;
165pub use error::*;
166use network::*;
167
168/// Library general result type.
169pub type Result<T> = std::result::Result<T, Error>;
170/// Library general future type.
171pub type Future<'a, T> = futures_util::future::BoxFuture<'a, Result<T>>;
172
173#[cfg(all(feature = "tokio-runtime", feature = "async-std-runtime"))]
174compile_error!("feature \"tokio-runtime\" and feature \"async-std-runtime\" cannot be enabled at the same time");
175
176#[cfg(all(feature = "pool", feature = "async-std-runtime"))]
177compile_error!("feature \"pool\" is only compatible with \"tokio-runtime\" (bb8 constraint)");
178
179#[cfg(test)]
180mod tests;