rustapi_rs/lib.rs
1//! # RustAPI
2//!
3//! A FastAPI-like web framework for Rust.
4//!
5//! RustAPI combines Rust's performance and safety with FastAPI's "just write business logic"
6//! approach. It provides automatic OpenAPI documentation, declarative validation, and
7//! a developer-friendly experience.
8//!
9//! ## Quick Start
10//!
11//! ```rust,ignore
12//! use rustapi_rs::prelude::*;
13//!
14//! #[derive(Serialize, Schema)]
15//! struct Hello {
16//! message: String,
17//! }
18//!
19//! async fn hello() -> Json<Hello> {
20//! Json(Hello {
21//! message: "Hello, World!".to_string(),
22//! })
23//! }
24//!
25//! #[tokio::main]
26//! async fn main() -> std::result::Result<(), Box<dyn std::error::Error + Send + Sync>> {
27//! RustApi::new()
28//! .route("/", get(hello))
29//! .run("127.0.0.1:8080")
30//! .await
31//! }
32//! ```
33//!
34//! ## Features
35//!
36//! - **DX-First**: Minimal boilerplate, intuitive API
37//! - **Type-Safe**: Compile-time route and schema validation
38//! - **Auto Documentation**: OpenAPI + Swagger UI out of the box
39//! - **Declarative Validation**: Pydantic-style validation on structs
40//! - **Batteries Included**: JWT, CORS, rate limiting (optional features)
41//!
42//! ## Optional Features
43//!
44//! Enable these features in your `Cargo.toml`:
45//!
46//! - `jwt` - JWT authentication middleware and `AuthUser<T>` extractor
47//! - `cors` - CORS middleware with builder pattern configuration
48//! - `rate-limit` - IP-based rate limiting middleware
49//! - `config` - Configuration management with `.env` file support
50//! - `cookies` - Cookie parsing extractor
51//! - `sqlx` - SQLx database error conversion to ApiError
52//! - `extras` - Meta feature enabling jwt, cors, and rate-limit
53//! - `full` - All optional features enabled
54//!
55//! ```toml
56//! [dependencies]
57//! rustapi-rs = { version = "0.1", features = ["jwt", "cors"] }
58//! ```
59
60// Re-export core functionality
61pub use rustapi_core::*;
62
63// Re-export macros
64pub use rustapi_macros::*;
65
66// Re-export extras (feature-gated)
67#[cfg(feature = "jwt")]
68pub use rustapi_extras::jwt;
69#[cfg(feature = "jwt")]
70pub use rustapi_extras::{
71 create_token, AuthUser, JwtError, JwtLayer, JwtValidation, ValidatedClaims,
72};
73
74#[cfg(feature = "cors")]
75pub use rustapi_extras::cors;
76#[cfg(feature = "cors")]
77pub use rustapi_extras::{AllowedOrigins, CorsLayer};
78
79#[cfg(feature = "rate-limit")]
80pub use rustapi_extras::rate_limit;
81#[cfg(feature = "rate-limit")]
82pub use rustapi_extras::RateLimitLayer;
83
84#[cfg(feature = "config")]
85pub use rustapi_extras::config;
86#[cfg(feature = "config")]
87pub use rustapi_extras::{
88 env_or, env_parse, load_dotenv, load_dotenv_from, require_env, Config, ConfigError, Environment,
89};
90
91#[cfg(feature = "sqlx")]
92pub use rustapi_extras::sqlx;
93#[cfg(feature = "sqlx")]
94pub use rustapi_extras::{convert_sqlx_error, SqlxErrorExt};
95
96// Re-export TOON (feature-gated)
97#[cfg(feature = "toon")]
98pub mod toon {
99 //! TOON (Token-Oriented Object Notation) support
100 //!
101 //! TOON is a compact format for LLM communication that reduces token usage by 20-40%.
102 //!
103 //! # Example
104 //!
105 //! ```rust,ignore
106 //! use rustapi_rs::toon::{Toon, Negotiate, AcceptHeader};
107 //!
108 //! // As extractor
109 //! async fn handler(Toon(data): Toon<MyType>) -> impl IntoResponse { ... }
110 //!
111 //! // As response
112 //! async fn handler() -> Toon<MyType> { Toon(my_data) }
113 //!
114 //! // Content negotiation (returns JSON or TOON based on Accept header)
115 //! async fn handler(accept: AcceptHeader) -> Negotiate<MyType> {
116 //! Negotiate::new(my_data, accept.preferred)
117 //! }
118 //! ```
119 pub use rustapi_toon::*;
120}
121
122// Re-export WebSocket support (feature-gated)
123#[cfg(feature = "ws")]
124pub mod ws {
125 //! WebSocket support for real-time bidirectional communication
126 //!
127 //! This module provides WebSocket functionality through the `WebSocket` extractor,
128 //! enabling real-time communication patterns like chat, live updates, and streaming.
129 //!
130 //! # Example
131 //!
132 //! ```rust,ignore
133 //! use rustapi_rs::ws::{WebSocket, Message};
134 //!
135 //! async fn websocket_handler(ws: WebSocket) -> impl IntoResponse {
136 //! ws.on_upgrade(|mut socket| async move {
137 //! while let Some(Ok(msg)) = socket.recv().await {
138 //! if let Message::Text(text) = msg {
139 //! socket.send(Message::Text(format!("Echo: {}", text))).await.ok();
140 //! }
141 //! }
142 //! })
143 //! }
144 //! ```
145 pub use rustapi_ws::*;
146}
147
148// Re-export View/Template support (feature-gated)
149#[cfg(feature = "view")]
150pub mod view {
151 //! Template engine support for server-side rendering
152 //!
153 //! This module provides Tera-based templating with the `View<T>` response type,
154 //! enabling server-side HTML rendering with template inheritance and context.
155 //!
156 //! # Example
157 //!
158 //! ```rust,ignore
159 //! use rustapi_rs::view::{Templates, View, ContextBuilder};
160 //!
161 //! #[derive(Clone)]
162 //! struct AppState {
163 //! templates: Templates,
164 //! }
165 //!
166 //! async fn index(State(state): State<AppState>) -> View<()> {
167 //! View::new(&state.templates, "index.html")
168 //! .with("title", "Home")
169 //! .with("message", "Welcome!")
170 //! }
171 //! ```
172 pub use rustapi_view::*;
173}
174
175/// Prelude module - import everything you need with `use rustapi_rs::prelude::*`
176pub mod prelude {
177 // Core types
178 pub use rustapi_core::{
179 delete,
180 delete_route,
181 get,
182 get_route,
183 patch,
184 patch_route,
185 post,
186 post_route,
187 put,
188 put_route,
189 serve_dir,
190 sse_response,
191 // Error handling
192 ApiError,
193 Body,
194 ClientIp,
195 Created,
196 Extension,
197 HeaderValue,
198 Headers,
199 Html,
200 // Response types
201 IntoResponse,
202 // Extractors
203 Json,
204 KeepAlive,
205 // Multipart
206 Multipart,
207 MultipartConfig,
208 MultipartField,
209 NoContent,
210 Path,
211 Query,
212 Redirect,
213 // Request context
214 Request,
215 // Middleware
216 RequestId,
217 RequestIdLayer,
218 Response,
219 Result,
220 // Route type for macro-based routing
221 Route,
222 // Router
223 Router,
224 // App builder
225 RustApi,
226 RustApiConfig,
227 // Streaming responses
228 Sse,
229 SseEvent,
230 State,
231 // Static files
232 StaticFile,
233 StaticFileConfig,
234 StreamBody,
235 TracingLayer,
236 UploadedFile,
237 ValidatedJson,
238 WithStatus,
239 };
240
241 // Compression middleware (feature-gated in core)
242 #[cfg(feature = "compression")]
243 pub use rustapi_core::middleware::{CompressionAlgorithm, CompressionConfig};
244 #[cfg(feature = "compression")]
245 pub use rustapi_core::CompressionLayer;
246
247 // Cookies extractor (feature-gated in core)
248 #[cfg(feature = "cookies")]
249 pub use rustapi_core::Cookies;
250
251 // Re-export the route! macro
252 pub use rustapi_core::route;
253
254 // Re-export validation - use validator derive macro directly
255 pub use validator::Validate;
256
257 // Re-export OpenAPI schema derive
258 pub use rustapi_openapi::{IntoParams, Schema};
259
260 // Re-export commonly used external types
261 pub use serde::{Deserialize, Serialize};
262 pub use tracing::{debug, error, info, trace, warn};
263
264 // JWT types (feature-gated)
265 #[cfg(feature = "jwt")]
266 pub use rustapi_extras::{
267 create_token, AuthUser, JwtError, JwtLayer, JwtValidation, ValidatedClaims,
268 };
269
270 // CORS types (feature-gated)
271 #[cfg(feature = "cors")]
272 pub use rustapi_extras::{AllowedOrigins, CorsLayer};
273
274 // Rate limiting types (feature-gated)
275 #[cfg(feature = "rate-limit")]
276 pub use rustapi_extras::RateLimitLayer;
277
278 // Configuration types (feature-gated)
279 #[cfg(feature = "config")]
280 pub use rustapi_extras::{
281 env_or, env_parse, load_dotenv, load_dotenv_from, require_env, Config, ConfigError,
282 Environment,
283 };
284
285 // SQLx types (feature-gated)
286 #[cfg(feature = "sqlx")]
287 pub use rustapi_extras::{convert_sqlx_error, SqlxErrorExt};
288
289 // TOON types (feature-gated)
290 #[cfg(feature = "toon")]
291 pub use rustapi_toon::{AcceptHeader, LlmResponse, Negotiate, OutputFormat, Toon};
292
293 // WebSocket types (feature-gated)
294 #[cfg(feature = "ws")]
295 pub use rustapi_ws::{Broadcast, Message, WebSocket, WebSocketStream};
296
297 // View/Template types (feature-gated)
298 #[cfg(feature = "view")]
299 pub use rustapi_view::{ContextBuilder, Templates, TemplatesConfig, View};
300}
301
302#[cfg(test)]
303mod tests {
304 use super::prelude::*;
305
306 #[test]
307 fn prelude_imports_work() {
308 // This test ensures prelude exports compile correctly
309 let _: fn() -> Result<()> = || Ok(());
310 }
311}