rustis 0.25.0

Redis async driver for Rust
Documentation
[package]
name = "rustis"
version = "0.25.0"
keywords = ["redis", "database", "async", "cluster", "sentinel"]
categories = ["database", "asynchronous"]
description = "Redis async driver for Rust"
homepage = "https://github.com/dahomey-technologies/rustis"
repository = "https://github.com/dahomey-technologies/rustis"
documentation = "https://docs.rs/rustis"
readme = "README.md"
license = "MIT"
edition = "2024"
# Held here by let chains, used in 63 places. Edition 2024 alone would allow
# 1.85. Verified by the `msrv` CI job, which is what keeps this number true.
rust-version = "1.88"

# The library has no `#[bench]` functions: every benchmark is a criterion target
# with `harness = false`. Left at the default, `cargo bench` builds the lib test
# target under `[profile.bench]` — fat LTO, one codegen unit, the whole
# `cfg(test)` tree — for three minutes, to report `0 measured`.
[lib]
bench = false

[features]
default = ["tokio-runtime", "server-tests"]
tokio-runtime = ["tokio/macros", "tokio/net", "tokio/rt", "tokio/io-util"]
tokio-rustls = ["dep:tokio-rustls", "dep:webpki-roots", "rustls"]
tokio-native-tls = ["dep:tokio-native-tls", "native-tls"]
pool = ["dep:bb8"]
native-tls = ["dep:native-tls"]
rustls = ["dep:rustls"]
json = ["dep:serde_json"]
client-cache = ["dep:moka", "dep:dashmap"]
# Gates the half of the test suite that needs a live Redis. On by default, so
# the full suite is what `cargo test` runs; turning it off leaves the tests that
# need neither a server nor a network, which then all pass. It carries no
# dependency and gates nothing outside `cfg(test)`, so a dependent never builds
# anything different because of it.
server-tests = []
# Marker features, carrying no dependency of their own: they gate the
# `bench`-only module in the library and the `required-features` of the benchmark
# and web-example targets, whose crates are plain dev dependencies.
# `bench` exposes `resp::bench_support` to the benchmark crates. Not part of the
# public API; no stability guarantee, which is why it is absent from the docs.rs
# feature list below.
bench = []
# Exposes internal RESP parsing/deserialization entry points to the `cargo-fuzz`
# targets in `fuzz/`. Not part of the public API; no stability guarantee.
fuzzing = []
web-examples = []

[dependencies]
futures-util = { version = "0.3", features = ["sink"] }
futures-channel = { version = "0.3", features = ["sink"] }
bytes = { version = "1.12", features = ["serde"] }
tokio = { version = "1.53", features = ["time", "io-util", "sync"] }
tokio-util = { version = "0.7", features = ["codec"] }
atoi = "3.1"
itoa = "1.0"
fast-float2 = "0.2"
dtoa = "1.0"
smallvec = { version = "1.15", features = ["union", "serde"] }
# Lock-free MPMC queue backing the pub/sub channel. Its producer can pop the
# head, which is what lets a full channel drop its oldest message without the
# network task ever waiting on the subscriber.
crossbeam-queue = "0.3"
bb8 = { version = "0.9", optional = true }
url = "2.5"
tokio-rustls = { version = "0.26", optional = true }
webpki-roots = { version = "1.0", optional = true }
native-tls = { version = "0.2", optional = true }
rustls = { version = "0.23", optional = true }
tokio-native-tls = { version = "0.3", optional = true }
# The `log` feature makes every event also emit a `log` record, so a downstream
# crate wired to `env_logger` and friends keeps receiving output unchanged and
# only sees a difference if it installs a `tracing` subscriber.
tracing = { version = "0.1", features = ["log"] }
crc16 = "0.4"
rand = "0.10"
# Safe pin projection for the hand-written command future: the crate is
# `forbid(unsafe_code)` and the timeout it holds is `!Unpin`.
pin-project-lite = "0.2"
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0", optional = true }
socket2 = "0.6"
memchr = "2.7"
moka = { version = "0.12", features = ["future"], optional = true }
dashmap = { version = "6.2", optional = true }
thiserror = "2.0"

[dev-dependencies]
# The benchmark and web-example crates belong here, not in `[dependencies]`.
# They were optional dependencies so that a Cargo feature could gate them, which
# made competing drivers — `fred`, `redis` — read as dependencies of this crate
# on crates.io. Benches and examples are dev targets, so a dev dependency is
# enough: `required-features` still keeps their targets out of an ordinary build,
# and nothing here reaches a downstream consumer.
criterion = { version = "0.8", features = ["async_tokio"] }
fred = "10.1"
redis = { version = "1.5", features = ["aio", "tokio-comp"] }
axum = "0.8"
actix-web = "4.14"
pprof = { version = "0.15", features = ["flamegraph"] }
# Held at 3.x: serial_test 4.x requires Rust 1.93, above the crate's MSRV.
serial_test = "3.3"
tokio = { version = "1.53", features = ["rt-multi-thread"] }
rand = "0.10"
# The suite reads the crate's output through `env_logger`, which is the point:
# it exercises the `tracing/log` bridge that downstream `log` users rely on.
env_logger = "0.11"
log = "0.4"
tracing-subscriber = "0.3"
smallvec = { version = "1.15", features = ["serde"] }
rustls-pemfile = "2.2"
# Real third-party types for `tests/arg_arity.rs`, which proves that a foreign
# type is a valid command argument with no impl from this crate — the claim a
# marker trait could not have made. `serde_json` is also an optional runtime
# dependency of the `json` feature; declared here too so the test compiles
# whatever features the suite runs with.
uuid = { version = "1", features = ["serde", "v4"] }
serde_json = "1.0"

# Every test here connects to a Redis, so the target itself is gated: the
# hermetic run must not even build it.
[[test]]
name = "arg_arity"
required-features = ["server-tests"]

[package.metadata.docs.rs]
features = ["tokio-runtime", "tokio-rustls", "pool", "json", "client-cache"]
rustdoc-args = ["--cfg", "docsrs"]

[[bench]]
name = "generic_api"
harness = false
required-features = ["bench"]

[[bench]]
name = "multiplexer"
harness = false
required-features = ["bench"]

[[bench]]
name = "throughput"
harness = false
required-features = ["bench"]

[[bench]]
name = "into_future"
harness = false
required-features = ["bench"]

[[bench]]
name = "native_api"
harness = false
required-features = ["bench"]

[[bench]]
name = "pipeline"
harness = false
required-features = ["bench"]

[[bench]]
name = "fast_path"
harness = false
required-features = ["bench"]

[[bench]]
name = "parse_integer"
harness = false
required-features = ["bench"]

[[bench]]
name = "large_array_parsing"
harness = false
required-features = ["bench"]

[[bench]]
name = "resp_parsing"
harness = false
required-features = ["bench"]

[[bench]]
name = "tape_memory"
harness = false
required-features = ["bench"]

[[bench]]
name = "command_encode"
harness = false
required-features = ["bench"]

[[bench]]
name = "large_reply_reserve"
harness = false
required-features = ["bench"]

# The only bench that needs a TLS stack, so it names one: `bench` alone would
# leave the target unbuildable.
[[bench]]
name = "tls_round_trip"
harness = false
required-features = ["bench", "tokio-rustls"]

[[bench]]
name = "cluster_routing"
harness = false
required-features = ["bench"]

[[bench]]
name = "cluster_read_alloc"
harness = false
required-features = ["bench"]

[[bench]]
name = "struct_decode"
harness = false
required-features = ["bench"]

[[bench]]
name = "pub_sub_decode"
harness = false
required-features = ["bench"]

[[example]]
name = "actix_crud"
required-features = ["tokio-runtime", "web-examples"]

[[example]]
name = "actix_long_polling_pubsub"
required-features = ["tokio-runtime", "web-examples"]

[[example]]
name = "axum_crud"
required-features = ["tokio-runtime", "web-examples"]

[[example]]
name = "axum_long_polling_pubsub"
required-features = ["tokio-runtime", "web-examples"]

[[example]]
name = "cbor"
required-features = ["tokio-runtime"]

[[example]]
name = "pprof_pipeline"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "resp_profiling"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "command_construction_profiling"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "pprof_multiplexer_get"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "pprof_send_vs_receive"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "conn_scaling_probe"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "head_to_head"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "wakeup_cost_probe"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "strace_workload"
required-features = ["tokio-runtime", "bench"]

[[example]]
name = "cache_stampede_probe"
required-features = ["tokio-runtime", "client-cache", "bench"]

[[example]]
name = "simple"
required-features = ["tokio-runtime"]

[[example]]
name = "pipelining"
required-features = ["tokio-runtime"]

[[example]]
name = "transaction"
required-features = ["tokio-runtime"]

[[example]]
name = "scripting"
required-features = ["tokio-runtime"]

[[example]]
name = "cluster"
required-features = ["tokio-runtime"]

[[example]]
name = "sentinel"
required-features = ["tokio-runtime"]

[[example]]
name = "tls"
required-features = ["tokio-runtime", "tokio-rustls"]

[[example]]
name = "client_side_caching"
required-features = ["tokio-runtime", "client-cache"]

[profile.dev]
opt-level = 0
debug = true
debug-assertions = true
overflow-checks = true

[profile.bench]
opt-level = 3
lto = "fat"
codegen-units = 1