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