1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
//! kevy-client-async — async client for kevy, runtime-agnostic core
//! with feature-gated transports for `tokio`, `smol`, and `async-std`.
//!
//! # Status
//!
//! Phase-4 first cut (T4.x). Surface is intentionally a near-1:1 mirror
//! of the blocking [`kevy_client::Connection`], plus the pipeline-first
//! sugar locked by RFC 2026-06-18-v3-cluster Q4 part b. See
//! `docs/async.md` (added T4.26) for the full guide.
//!
//! # Runtime selection
//!
//! Exactly one of the following Cargo features must be enabled:
//!
//! | feature | transport |
//! |-------------|--------------------------------------|
//! | `tokio` | `tokio::net::TcpStream` (T4.5) |
//! | `smol` | `smol::net::TcpStream` (T4.6) |
//! | `async-std` | `async_std::net::TcpStream` (T4.7) |
//!
//! `default = ["tokio"]` is a dev convenience so `cargo test
//! --workspace` builds without flags; **lib consumers should set
//! `default-features = false`** and pick their runtime explicitly so
//! the wrong one is never silently inherited. Enabling zero or more
//! than one triggers a `compile_error!` from this crate (T4.8).
//!
//! # Dep-rule exemption
//!
//! This crate is the sole carved exemption from the project's
//! 0-crates.io-dep rule. Rationale: the Rust async ecosystem has no
//! std-only viable substrate. The exemption is per-crate and per-dep:
//! `kevy-client-async` may dep tokio / smol / async-std (and only those
//! three) with `default-features = false` + minimum-surface features
//! and an inline `# EXEMPTION` Cargo.toml comment. See RFC F5 and
//! memory `feedback-pure-rust-no-c-principle.md`.
//!
//! # Error compatibility
//!
//! Every async method returns `std::io::Result<T>` with the same
//! `ErrorKind` variants the blocking [`kevy_client`](https://docs.rs/kevy-client)
//! surface produces. This is contract, not coincidence — it lets
//! caller code carry over without changing match arms.
//!
//! | source | `ErrorKind` |
//! |---------------------------------------|--------------------|
//! | RESP `-ERR …` reply | `Other` |
//! | unexpected reply variant | `Other` |
//! | malformed RESP frame | `InvalidData` |
//! | server closed connection mid-read | `UnexpectedEof` |
//! | unknown URL scheme / bad port / etc. | `InvalidInput` |
//! | TLS / AUTH / embed URL scheme | `Unsupported` |
//! | underlying socket I/O | (native kind) |
//!
//! Wider error context (the RESP error string, the unexpected
//! variant name) is carried in the `io::Error`'s message — fetch with
//! `.to_string()` / `.into_inner()`.
pub use AsyncRespCodec;
pub use AsyncConnection;
pub use ;
// T4.8 — compile-time runtime selection gate. We enforce
// **exactly-one**: zero enabled = no IO substrate (silent shell);
// more than one enabled = ambiguous transport pick + bloats the build
// with unused runtimes. Either fails the build with a clear message.
compile_error!;
compile_error!;