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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
//! # Churust 🌀
//!
//! A Ktor-inspired, secure, easy-to-learn web framework for Rust
//! (**Churro + Rust**).
//!
//! Churust gives you Ktor's developer experience on a battle-tested async stack
//! (tokio + hyper + rustls): an application engine, a routing DSL, an
//! `install(plugin)` system, a phased interceptor pipeline, hybrid handlers
//! (call-style *and* typed extractors), typed app state, layered configuration,
//! and secure-by-default behavior (body limits, request timeouts, panic
//! isolation, opt-in TLS).
//!
//! This is the umbrella crate: depend on it and enable plugins via Cargo
//! features. Core types come from [`churust_core`] (re-exported here); the
//! `#[churust::main]` attribute comes from `churust-macros`.
//!
//! ## Quick start
//!
//! ```no_run
//! use churust::prelude::*;
//!
//! #[churust::main]
//! async fn main() -> std::io::Result<()> {
//! Churust::server()
//! .routing(|r| {
//! r.get("/", |_call: Call| async { "Hello from Churust 🌀" });
//! r.get("/users/{id}", |Path(id): Path<u64>| async move {
//! format!("user #{id}")
//! });
//! })
//! .start()
//! .await
//! }
//! ```
//!
//! ## Testing without a socket
//!
//! Any app can be driven in-process with [`TestClient`] — no port binding, so
//! tests are fast and deterministic:
//!
//! ```
//! use churust::prelude::*;
//! use churust::TestClient;
//!
//! # tokio::runtime::Runtime::new().unwrap().block_on(async {
//! let app = Churust::server()
//! .routing(|r| {
//! r.get("/ping", |_c: Call| async { "pong" });
//! })
//! .build();
//!
//! let res = TestClient::new(app).get("/ping").send().await;
//! assert_eq!(res.status(), StatusCode::OK);
//! assert_eq!(res.text(), "pong");
//! # });
//! ```
//!
//! ## Feature flags
//!
//! Plugins live behind Cargo features (all off by default):
//!
//! | Feature | Enables |
//! |-----------|------------------------------------------------------|
//! | `json` | `churust_json` — `Json<T>` + `ContentNegotiation` |
//! | `logging` | `churust_logging` — `CallLogging` |
//! | `cors` | `churust_cors` — `Cors` |
//! | `auth` | `churust_auth` — `Auth` + `Principal<P>` |
//! | `tls` | rustls TLS support in [`churust_core`] |
//! | `full` | all four plugins |
//!
//! ```toml
//! [dependencies]
//! churust = { version = "0.1", features = ["full"] }
//! tokio = { version = "1", features = ["full"] }
//! ```
//!
//! Bring the common items into scope with [`prelude`].
//!
//! ## The `#[churust::main]` attribute
//!
//! Builds a multi-threaded tokio runtime and blocks on the async body — the
//! Churust equivalent of `#[tokio::main]`:
//!
//! ```no_run
//! #[churust::main]
//! async fn main() -> std::io::Result<()> {
//! use churust::prelude::*;
//! let _app = Churust::server().build();
//! Ok(())
//! }
//! ```
pub use *;
/// The async entry-point attribute (see the crate-level docs). Wraps
/// `async fn main` in a tokio runtime.
pub use main;
/// WebSocket types (`WebSocket`, `WebSocketUpgrade`, `ws::Message`). Enabled by
/// the `ws` feature.
pub use ws;
/// Static file serving (`StaticFiles`). Enabled by the `fs` feature.
pub use fs;
/// Authentication plugin crate (`Auth`, `Principal<P>`). Enabled by the `auth`
/// feature.
pub use churust_auth as auth;
/// CORS plugin crate (`Cors`). Enabled by the `cors` feature.
pub use churust_cors as cors;
/// JSON plugin crate (`Json<T>`, `ContentNegotiation`). Enabled by the `json`
/// feature.
pub use churust_json as json;
/// Request-logging plugin crate (`CallLogging`). Enabled by the `logging`
/// feature.
pub use churust_logging as logging;
/// Common imports for everyday Churust apps.
///
/// Glob-import this (`use churust::prelude::*;`) to get the server builder,
/// the `Call` context, the response traits, the built-in extractors, the
/// `#[churust::main]` macro, and — when their Cargo features are enabled — the
/// plugin types (`Json`, `Cors`, `CallLogging`, `Auth`, `Principal`).