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
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
//! # Hyperlite
//!
//! Hyperlite is a lightweight HTTP framework built on top of `hyper`, `tokio`, and
//! `tower` for building fast, composable web services without sacrificing control.
//!
//! ## Philosophy
//! - Stay close to `hyper` primitives for maximum flexibility.
//! - Embrace Tower's `Service` trait for middleware-first composition.
//! - Provide type-safe request and response helpers without macros.
//! - Favor zero-cost abstractions over hidden magic.
//!
//! ## Key Features
//! - Fast path-based routing powered by [`matchit`](https://docs.rs/matchit).
//! - Tower middleware compatibility, including tracing, CORS, and authentication layers.
//! - Ergonomic response builders and JSON helpers.
//! - Built-in server runner with graceful shutdown handling.
//! - Focus on predictable upgrades by avoiding breaking framework changes.
//! - ✅ Type-safe request extraction helpers for bodies, queries, paths, and extensions.
//!
//! ## Quick Example
//! ```rust,no_run
//! use bytes::Bytes;
//! use hyper::{Method, Request, Response, StatusCode};
//! use hyperlite::{serve, success, BoxBody, Router};
//! use http_body_util::Full;
//! use serde::Serialize;
//! use std::net::SocketAddr;
//! use std::sync::Arc;
//!
//! #[derive(Clone)]
//! struct AppState;
//!
//! #[derive(Serialize)]
//! struct Greeting {
//! message: String,
//! }
//!
//! async fn hello_handler(
//! _req: Request<BoxBody>,
//! _state: Arc<AppState>,
//! ) -> Result<Response<Full<Bytes>>, hyperlite::BoxError> {
//! Ok(success(
//! StatusCode::OK,
//! Greeting {
//! message: "Hello, World!".to_string(),
//! },
//! ))
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<(), hyperlite::BoxError> {
//! let state = AppState;
//! let router = Router::new(state).route(
//! "/hello",
//! Method::GET,
//! Arc::new(|req, state| Box::pin(hello_handler(req, state))),
//! );
//!
//! let addr: SocketAddr = "127.0.0.1:3000".parse().unwrap();
//! serve(addr, router).await
//! }
//! ```
//!
//! For richer walkthroughs, inspect the `examples/` directory:
//! - `hello_world.rs` – Minimal single-route server.
//! - `with_state.rs` – Shared state with all extractors.
//! - `with_middleware.rs` – Complete Tower middleware stack.
//!
//! Run any example via `cargo run --example <name>`.
//!
//! ## Request Extraction
//! ```rust,no_run
//! use bytes::Bytes;
//! use hyper::{Method, Request, Response, StatusCode};
//! use hyperlite::{parse_json_body, path_param, query_params, BoxBody, BoxError, Router, success};
//! use http_body_util::Full;
//! use serde::{Deserialize, Serialize};
//! use std::sync::Arc;
//! use uuid::Uuid;
//!
//! #[derive(Clone)]
//! struct AppState;
//!
//! #[derive(Deserialize)]
//! struct CreatePost { title: String, body: String }
//!
//! #[derive(Deserialize)]
//! struct Pagination { page: u32, limit: u32 }
//!
//! #[derive(Serialize)]
//! struct Post { id: Uuid, title: String }
//!
//! async fn create_post(
//! req: Request<BoxBody>,
//! _state: Arc<AppState>,
//! ) -> Result<Response<Full<Bytes>>, BoxError> {
//! let payload = parse_json_body::<CreatePost>(req).await?;
//! Ok(success(StatusCode::CREATED, Post {
//! id: Uuid::new_v4(),
//! title: payload.title,
//! }))
//! }
//!
//! async fn list_posts(
//! req: Request<BoxBody>,
//! _state: Arc<AppState>,
//! ) -> Result<Response<Full<Bytes>>, BoxError> {
//! let params = query_params::<Pagination>(&req)?;
//! Ok(success(StatusCode::OK, format!("page={}", params.page)))
//! }
//!
//! async fn get_post(
//! req: Request<BoxBody>,
//! _state: Arc<AppState>,
//! ) -> Result<Response<Full<Bytes>>, BoxError> {
//! let post_id: Uuid = path_param(&req, "id")?;
//! Ok(success(StatusCode::OK, Post { id: post_id, title: "Example".into() }))
//! }
//!
//! #[tokio::main]
//! # async fn main() -> Result<(), BoxError> {
//! let state = AppState;
//! let router = Router::new(state)
//! .route("/posts", Method::POST, Arc::new(|req, state| Box::pin(create_post(req, state))))
//! .route("/posts", Method::GET, Arc::new(|req, state| Box::pin(list_posts(req, state))))
//! .route("/posts/{id}", Method::GET, Arc::new(|req, state| Box::pin(get_post(req, state))));
//!
//! let addr: std::net::SocketAddr = "127.0.0.1:3000".parse().unwrap();
//! hyperlite::serve(addr, router).await
//! }
//! ```
//!
//! See `examples/with_state.rs` for a full application using these helpers in
//! tandem with shared state and realistic routing patterns.
//!
//! ## Examples
//!
//! ```text
//! cargo run --example hello_world
//! cargo run --example with_state
//! RUST_LOG=info cargo run --example with_middleware
//! ```
//!
//! Each example demonstrates progressively more advanced patterns, from simple
//! routing to full middleware stacks with distributed tracing.
//!
//! ## When To Use
//! Choose Hyperlite when you want the ergonomics of a framework while keeping
//! full control over the underlying HTTP server and middleware stack.
//!
// Planned modules to be implemented in future phases.
pub use ;
pub use ;
pub use ;
pub use serve;
/// Boxed error type used across Hyperlite.
pub type BoxError = ;
/// Convenience result type used by Hyperlite components.
pub type Result<T> = Result;