redis_asio/lib.rs
1//! redis-asio is a Redis client library written in pure Rust based on
2//! asynchronous `tokio` library.
3//!
4//! The library provides a `base` module for low-level request sending and
5//! response handling, and a `stream` module that contains specific interfaces
6//! for work with Redis-Stream "https://redis.io/topics/streams-intro".
7//!
8//! The library works with binary-safe strings that allows users to serialize
9//! their message structures and send via
10//! RESP protocol "https://redis.io/topics/protocol".
11//!
12//! # Use in project
13//!
14//! Depend on the redis-asio in project via Cargo:
15//!
16//! ```toml
17//! [dependencies]
18//! redis-async = "0.1"
19//! ```
20//!
21//! Resolve the crate interfaces:
22//!
23//! ```rust
24//! extern crate redis_asio;
25//! ```
26//!
27//! # Motivating examples
28//!
29//! ## SET, GET value from cache
30//! ```rust,no_run
31//! use std::net::SocketAddr;
32//! use futures::Future;
33//! use redis_asio::{RedisCoreConnection, RedisValue, command, from_redis_value};
34//!
35//! let address = &"127.0.0.1:6379".parse::<SocketAddr>().unwrap();
36//!
37//! let set_req = command("SET").arg("foo").arg(123);
38//! let get_req = command("GET").arg("foo");
39//!
40//! let future = RedisCoreConnection::connect(address)
41//! .and_then(move |con| {
42//! // send "SET foo 123" request
43//! con.send(set_req)
44//! })
45//! .and_then(|(con, response)| {
46//! // check if the value has been set
47//! assert_eq!(RedisValue::Ok, response);
48//! // send "GET foo" request
49//! con.send(get_req)
50//! })
51//! .map(move |(_, response)|
52//! // check if the received value is the same
53//! assert_eq!(123, from_redis_value(&response).unwrap()))
54//! .map_err(|_| unreachable!());
55//! // start the Tokio runtime using the `future`
56//! tokio::run(future);
57//! ```
58//!
59//! ## Subscribe to a Redis Stream
60//!
61//! Subscribe to a Redis stream and process all incoming entries.
62//! Redis Streams requires to send XREAD/XREADGROUP requests every time
63//! the client receives a response on the previous,
64//! in other words Redis Streams does not provide an interface to subscribe
65//! to a Redis stream.
66//!
67//! In the Crate the subscription is possible by hidden requests sending
68//! within the Crate engine.
69//!
70//! Request that will be sent to get new entries in the following example:
71//! "XREADGROUP GROUP mygroup Bob BLOCK 0 STREAMS mystream <"
72//!
73//! ```rust,no_run
74//! use std::net::SocketAddr;
75//! use futures::{Future, Stream};
76//! use redis_asio::stream::{RedisStream, SubscribeOptions, StreamEntry,
77//! RedisGroup};
78//!
79//! let address = &"127.0.0.1:6379".parse::<SocketAddr>().unwrap();
80//! // create options to pass it into RedisStream::subscribe()
81//! let group_info = RedisGroup::new("mygroup".to_string(), "Bob".to_string());
82//! let subscribe_options =
83//! SubscribeOptions::with_group(vec!["mystream".to_string()], group_info);
84//!
85//! let future = RedisStream::connect(address)
86//! .and_then(move |stream: RedisStream| {
87//! stream.subscribe(subscribe_options)
88//! })
89//! .and_then(|subscribe| /*:Subscribe*/ {
90//! // pass the closure that will be called on each incoming entries
91//! subscribe.for_each(|entries: Vec<StreamEntry>| {
92//! for entry in entries.into_iter() {
93//! println!("Received: {:?}", entry);
94//! }
95//! Ok(())
96//! })
97//! })
98//! .map_err(|err| eprintln!("something went wrong: {}", err));
99//! // start the Tokio runtime using the `future`
100//! tokio::run(future);
101//! ```
102//!
103//! ## Send an entry into a Redis Stream
104//!
105//! Send an entry into a Redis stream.
106//! Request that will be sent to push a specified entry in the following example:
107//! "XADD mystream * type 3 data \"Hello, world\""
108//!
109//! ```rust,no_run
110//! use std::net::SocketAddr;
111//! use std::collections::HashMap;
112//! use futures::Future;
113//! use redis_asio::{RedisArgument, IntoRedisArgument};
114//! use redis_asio::stream::{RedisStream, SendEntryOptions, EntryId};
115//!
116//! let address = &"127.0.0.1:6379".parse::<SocketAddr>().unwrap();
117//! // create options to pass it into RedisStream::send_entry()
118//! let send_options = SendEntryOptions::new("mystream".to_string());
119//!
120//! // create key-value pairs
121//! let mut request: HashMap<String, RedisArgument> = HashMap::new();
122//! request.insert("type".to_string(), 3i32.into_redis_argument());
123//! request.insert("data".to_string(), "Hello, world!".into_redis_argument());
124//!
125//! let future = RedisStream::connect(address)
126//! .and_then(move |stream: RedisStream| {
127//! // HashMap<String, RedisArgument> satisfies the
128//! // HashMap<String, ToRedisArgument>
129//! stream.send_entry(send_options, request)
130//! })
131//! .map(|(_, inserted_entry_id): (RedisStream, EntryId)| {
132//! println!("{:?} has sent", inserted_entry_id.to_string());
133//! })
134//! .map_err(|err| eprintln!("something went wrong: {}", err));
135//! tokio::run(future);
136//! ```
137
138mod base;
139pub mod stream;
140
141pub use base::{RedisCoreConnection, RedisResult, RedisValue, RedisCommand, RedisError,
142 RedisErrorKind, RedisArgument, FromRedisValue, IntoRedisArgument, command,
143 from_redis_value};
144
145use base::{RespInternalValue, RedisCodec};