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}