Skip to content

Commit b4cccdf

Browse files
authored
Cut further done on dependencies (make script optional) (redis-rs#271)
1 parent 4b494e4 commit b4cccdf

File tree

9 files changed

+123
-69
lines changed

9 files changed

+123
-69
lines changed

Cargo.toml

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,28 +15,51 @@ edition = "2018"
1515
all-features = true
1616

1717
[dependencies]
18+
# These two are generally really common simple dependencies so it does not seem
19+
# much of a point to optimize these, but these could in theory be removed for
20+
# an indirection through std::Formatter.
1821
dtoa = "0.4"
1922
itoa = "0.4.3"
23+
24+
# This is a dependency that already exists in url
2025
percent-encoding = "2.1"
21-
sha1 = ">= 0.2, < 0.7"
26+
27+
# We need this for redis url parsing
2228
url = "2.1"
23-
combine = "3.8.1"
29+
30+
# We need this for script support
31+
sha1 = { version = ">= 0.2, < 0.7", optional = true }
32+
33+
# Dependency that is shared with tokio. If we manage to make tokio optional we
34+
# could also remove this.
2435
bytes = "0.5"
36+
37+
# These are needed for parsing at the moment
38+
combine = "3.8.1"
2539
futures-util = { version = "0.3.0", features = ["sink"], default-features = false }
2640
futures-executor = "0.3.0"
41+
42+
# Only needed for AIO
2743
pin-project-lite = { version = "0.1", optional = true }
28-
tokio-util = { version = "0.2", features = ["codec"] }
29-
tokio = "0.2"
44+
tokio-util = { version = "0.2", features = ["codec"], optional = true }
45+
46+
# Only needed for the r2d2 feature
47+
r2d2 = { version = "0.8.8", optional = true }
48+
49+
# Only needed for cluster
3050
crc16 = { version = "0.4.0", optional = true }
3151
rand = { version = "0.7.0", optional = true }
32-
r2d2 = { version = "0.8.8", optional = true }
52+
53+
# Unfortunately currently a necessary dependency
54+
tokio = "0.2"
3355

3456
[features]
35-
default = ["geospatial", "aio"]
36-
aio = ["pin-project-lite", "tokio/sync", "tokio/stream", "tokio/tcp", "tokio/uds", "tokio/io-util"]
57+
default = ["geospatial", "aio", "script"]
58+
aio = ["pin-project-lite", "tokio/sync", "tokio/stream", "tokio/tcp", "tokio/uds", "tokio/io-util", "tokio-util"]
3759
tokio-rt-core = ["aio", "tokio/rt-core"]
3860
geospatial = []
3961
cluster = ["crc16", "rand"]
62+
script = ["sha1"]
4063

4164
[dev-dependencies]
4265
rand = "0.7"

src/aio.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@ use tokio::{
1616
};
1717
use tokio_util::codec::Decoder;
1818

19+
#[cfg(unix)]
20+
use futures_util::future::Either;
1921
use futures_util::{
20-
future::{Either, Future, FutureExt, TryFutureExt},
22+
future::{Future, FutureExt, TryFutureExt},
2123
ready,
2224
sink::Sink,
2325
stream::{Stream, StreamExt},

src/connection.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ impl ActualConnection {
270270
open: true,
271271
}),
272272
#[cfg(not(unix))]
273-
ConnectionAddr::Unix(ref path) => {
273+
ConnectionAddr::Unix(ref _path) => {
274274
fail!((
275275
ErrorKind::InvalidClientConfig,
276276
"Cannot connect to unix sockets \

src/lib.rs

Lines changed: 35 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,15 @@
4949
//!
5050
//! ## Optional Features
5151
//!
52-
//! There are currently two features defined that can enable additional
53-
//! functionality if so desired.
52+
//! There are a few features defined that can enable additional functionality
53+
//! if so desired. Some of them are turned on by default.
54+
//!
55+
//! * `aio`: enables async IO support (enabled by default)
56+
//! * `geospatial`: enables geospatial support (enabled by default)
57+
//! * `script`: enables script support (enabled by default)
58+
//! * `r2d2`: enables r2d2 connection pool support (optional)
59+
//! * `cluster`: enables redis cluster support (optional)
60+
//! * `tokio-rt-core`: enables support for tokio-rt (optional)
5461
//!
5562
//! ## Connection Parameters
5663
//!
@@ -267,25 +274,30 @@
267274
//! # }
268275
//! ```
269276
//!
270-
//! # Scripts
271-
//!
272-
//! Lua scripts are supported through the `Script` type in a convenient
273-
//! way (it does not support pipelining currently). It will automatically
274-
//! load the script if it does not exist and invoke it.
275-
//!
276-
//! Example:
277-
//!
278-
//! ```rust,no_run
279-
//! # fn do_something() -> redis::RedisResult<()> {
280-
//! # let client = redis::Client::open("redis://127.0.0.1/").unwrap();
281-
//! # let mut con = client.get_connection().unwrap();
282-
//! let script = redis::Script::new(r"
283-
//! return tonumber(ARGV[1]) + tonumber(ARGV[2]);
284-
//! ");
285-
//! let result : isize = script.arg(1).arg(2).invoke(&mut con)?;
286-
//! assert_eq!(result, 3);
287-
//! # Ok(()) }
288-
//! ```
277+
#![cfg_attr(
278+
feature = "script",
279+
doc = r##"
280+
# Scripts
281+
282+
Lua scripts are supported through the `Script` type in a convenient
283+
way (it does not support pipelining currently). It will automatically
284+
load the script if it does not exist and invoke it.
285+
286+
Example:
287+
288+
```rust,no_run
289+
# fn do_something() -> redis::RedisResult<()> {
290+
# let client = redis::Client::open("redis://127.0.0.1/").unwrap();
291+
# let mut con = client.get_connection().unwrap();
292+
let script = redis::Script::new(r"
293+
return tonumber(ARGV[1]) + tonumber(ARGV[2]);
294+
");
295+
let result : isize = script.arg(1).arg(2).invoke(&mut con)?;
296+
assert_eq!(result, 3);
297+
# Ok(()) }
298+
```
299+
"##
300+
)]
289301
//!
290302
//! # Async
291303
//!
@@ -339,6 +351,8 @@ pub use crate::connection::{
339351
IntoConnectionInfo, Msg, PubSub,
340352
};
341353
pub use crate::parser::{parse_redis_value, parse_redis_value_async, Parser};
354+
355+
#[cfg(feature = "script")]
342356
pub use crate::script::{Script, ScriptInvocation};
343357

344358
pub use crate::types::{

src/parser.rs

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ use std::str;
55

66
use crate::types::{make_extension_error, ErrorKind, RedisError, RedisResult, Value};
77

8-
use bytes::{Buf, BytesMut};
98
use combine::{combine_parse_partial, combine_parser_impl, parse_mode, parser};
109
use futures_util::{
1110
future,
1211
task::{self, Poll},
1312
};
1413
use tokio::io::{AsyncBufRead, AsyncRead};
15-
use tokio_util::codec::{Decoder, Encoder};
1614

1715
use combine;
1816
use combine::byte::{byte, crlf, take_until_bytes};
@@ -147,51 +145,61 @@ parser! {
147145
}
148146
}
149147

150-
#[derive(Default)]
151-
pub struct ValueCodec {
152-
state: AnySendPartialState,
153-
}
148+
#[cfg(feature = "aio")]
149+
mod aio_support {
150+
use super::*;
151+
use bytes::{Buf, BytesMut};
152+
use tokio_util::codec::{Decoder, Encoder};
154153

155-
impl Encoder for ValueCodec {
156-
type Item = Vec<u8>;
157-
type Error = RedisError;
158-
fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
159-
dst.extend_from_slice(item.as_ref());
160-
Ok(())
154+
#[derive(Default)]
155+
pub struct ValueCodec {
156+
state: AnySendPartialState,
161157
}
162-
}
163158

164-
impl Decoder for ValueCodec {
165-
type Item = Value;
166-
type Error = RedisError;
167-
fn decode(&mut self, bytes: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
168-
let (opt, removed_len) = {
169-
let buffer = &bytes[..];
170-
let stream = combine::easy::Stream(combine::stream::PartialStream(buffer));
171-
match combine::stream::decode(value(), stream, &mut self.state) {
172-
Ok(x) => x,
173-
Err(err) => {
174-
let err = err
175-
.map_position(|pos| pos.translate_position(buffer))
176-
.map_range(|range| format!("{:?}", range))
177-
.to_string();
178-
return Err(RedisError::from((
179-
ErrorKind::ResponseError,
180-
"parse error",
181-
err,
182-
)));
159+
impl Encoder for ValueCodec {
160+
type Item = Vec<u8>;
161+
type Error = RedisError;
162+
fn encode(&mut self, item: Self::Item, dst: &mut BytesMut) -> Result<(), Self::Error> {
163+
dst.extend_from_slice(item.as_ref());
164+
Ok(())
165+
}
166+
}
167+
168+
impl Decoder for ValueCodec {
169+
type Item = Value;
170+
type Error = RedisError;
171+
fn decode(&mut self, bytes: &mut BytesMut) -> Result<Option<Self::Item>, Self::Error> {
172+
let (opt, removed_len) = {
173+
let buffer = &bytes[..];
174+
let stream = combine::easy::Stream(combine::stream::PartialStream(buffer));
175+
match combine::stream::decode(value(), stream, &mut self.state) {
176+
Ok(x) => x,
177+
Err(err) => {
178+
let err = err
179+
.map_position(|pos| pos.translate_position(buffer))
180+
.map_range(|range| format!("{:?}", range))
181+
.to_string();
182+
return Err(RedisError::from((
183+
ErrorKind::ResponseError,
184+
"parse error",
185+
err,
186+
)));
187+
}
183188
}
184-
}
185-
};
189+
};
186190

187-
bytes.advance(removed_len);
188-
match opt {
189-
Some(result) => Ok(Some(result?)),
190-
None => Ok(None),
191+
bytes.advance(removed_len);
192+
match opt {
193+
Some(result) => Ok(Some(result?)),
194+
None => Ok(None),
195+
}
191196
}
192197
}
193198
}
194199

200+
#[cfg(feature = "aio")]
201+
pub use self::aio_support::*;
202+
195203
// https://github.com/tokio-rs/tokio/pull/1687
196204
async fn fill_buf<R>(reader: &mut R) -> io::Result<&[u8]>
197205
where

src/script.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#![cfg(feature = "script")]
12
use sha1::Sha1;
23

34
use crate::cmd::cmd;

tests/test_async.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use futures::{future, prelude::*};
66

77
use crate::support::*;
88

9-
use redis::{aio::MultiplexedConnection, RedisError, RedisResult};
9+
use redis::{aio::MultiplexedConnection, RedisResult};
1010

1111
mod support;
1212

@@ -236,7 +236,10 @@ fn test_transaction_multiplexed_connection() {
236236
}
237237

238238
#[test]
239+
#[cfg(feature = "script")]
239240
fn test_script() {
241+
use redis::RedisError;
242+
240243
// Note this test runs both scripts twice to test when they have already been loaded
241244
// into Redis and when they need to be loaded in
242245
let script1 = redis::Script::new("return redis.call('SET', KEYS[1], ARGV[1])");
@@ -267,6 +270,7 @@ fn test_script() {
267270
}
268271

269272
#[test]
273+
#[cfg(feature = "script")]
270274
fn test_script_returning_complex_type() {
271275
let ctx = TestContext::new();
272276
block_on_all(async {

tests/test_basic.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -568,6 +568,7 @@ fn scoped_pubsub() {
568568
}
569569

570570
#[test]
571+
#[cfg(feature = "script")]
571572
fn test_script() {
572573
let ctx = TestContext::new();
573574
let mut con = ctx.connection();

tests/test_cluster.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ fn test_cluster_eval() {
4343
}
4444

4545
#[test]
46+
#[cfg(feature = "script")]
4647
fn test_cluster_script() {
4748
let cluster = TestClusterContext::new(3, 0);
4849
let mut con = cluster.connection();

0 commit comments

Comments
 (0)