Skip to main content

thunder/client/
mod.rs

1//! Thunder RPC client — multiplexed, config-driven (SPEC-003, `CLT-xxx`).
2//!
3//! One [`Client`] owns one TCP connection and multiplexes concurrent
4//! calls over it via a background reader task (CLT-001/010). Behavior is
5//! driven entirely by a [`Config`] (SPEC-002): handshake style, push
6//! policy, frame cap, in-flight bound, and error-string convention.
7//!
8//! The application supplies that config — Thunder has no product registry
9//! to look one up in. Start from [`Config::standard`] and set your
10//! identity; override a dimension only where you actually diverge.
11//!
12//! ```no_run
13//! use thunder::{Client, ClientConfig, Config, Value};
14//!
15//! # async fn demo() -> Result<(), thunder::ClientError> {
16//! let app = Config::standard().scheme("myapp").port(9000);
17//! let config = ClientConfig::new().api_key("secret").client_name("demo");
18//! let client = Client::connect_with("myapp://localhost", app, config).await?;
19//! let pong = client.call("PING", vec![]).await?;
20//! assert_eq!(pong.as_str(), Some("PONG"));
21//! client.close().await;
22//! # Ok(())
23//! # }
24//! ```
25//!
26//! The semantics here are the family's "uniform floor" (PRD NFR-07): the
27//! same contract ships in TypeScript, Python, and C#. Error classes on
28//! [`ClientError`] are stable public API (CLT-052) — branch on the class
29//! and `code`, never on message text.
30
31mod conn;
32mod endpoint;
33mod error;
34mod pool;
35
36pub use conn::{Client, ClientConfig, Credentials, HandshakeInfo};
37pub use endpoint::{parse_endpoint, Endpoint};
38pub use error::ClientError;
39pub use pool::{Pool, PooledConn};
40
41// The wire layer lives at `thunder::wire`; re-export the two types that
42// surface in this module's public API for ergonomics.
43pub use crate::wire::{Config, Value};