wsforge_core/
lib.rs

1//! # WsForge Core - High-Performance WebSocket Framework
2//!
3//! `wsforge-core` is the foundational library for the WsForge WebSocket framework.
4//! It provides type-safe, ergonomic abstractions for building real-time WebSocket applications
5//! with exceptional performance and developer experience.
6//!
7//! ## Overview
8//!
9//! WsForge Core combines the power of `tokio-tungstenite` with a flexible, type-safe API inspired
10//! by modern web frameworks like Axum. It's designed for building production-ready WebSocket
11//! servers that are both fast and maintainable.
12//!
13//! ## Key Features
14//!
15//! - 🚀 **High Performance**: Built on tokio-tungstenite with zero-copy optimizations
16//! - 🔧 **Type-Safe Extractors**: Automatic extraction of JSON, State, Connection info
17//! - 🎯 **Flexible Handlers**: Return various types - String, Message, Result, JsonResponse
18//! - 📡 **Broadcasting**: Built-in broadcast, broadcast_except, and targeted messaging
19//! - ⚡ **Concurrent**: Lock-free connection management with DashMap
20//! - 🔄 **Lifecycle Hooks**: on_connect and on_disconnect callbacks
21//! - 🌐 **Hybrid Server**: Serve static files and WebSocket on same port
22//! - 🛡️ **Type Safety**: Compile-time guarantees for correctness
23//!
24//! ## Architecture
25//!
26//! ```
27//! ┌──────────────────────────────────────────────────────────────┐
28//! │                        Application                            │
29//! │  ┌────────────┐  ┌──────────┐  ┌───────────────────────┐   │
30//! │  │  Handlers  │  │  Router  │  │  State & Extractors   │   │
31//! │  └────────────┘  └──────────┘  └───────────────────────┘   │
32//! └──────────────────────────────────────────────────────────────┘
33//!                              │
34//! ┌──────────────────────────────────────────────────────────────┐
35//! │                      WsForge Core                             │
36//! │  ┌──────────────┐  ┌────────────────┐  ┌─────────────────┐ │
37//! │  │  Connection  │  │     Message     │  │   Static Files  │ │
38//! │  │   Manager    │  │     Router      │  │     Handler     │ │
39//! │  └──────────────┘  └────────────────┘  └─────────────────┘ │
40//! └──────────────────────────────────────────────────────────────┘
41//!                              │
42//! ┌──────────────────────────────────────────────────────────────┐
43//! │                    tokio-tungstenite                          │
44//! │                  (WebSocket Protocol)                         │
45//! └──────────────────────────────────────────────────────────────┘
46//! ```
47//!
48//! ## Module Structure
49//!
50//! - [`connection`]: WebSocket connection management and lifecycle
51//! - [`message`]: Message types and parsing utilities
52//! - [`handler`]: Handler trait and response types
53//! - [`extractor`]: Type-safe data extraction from messages
54//! - [`router`]: Routing and server management
55//! - [`state`]: Shared application state container
56//! - [`error`]: Error types and result handling
57//! - [`static_files`]: Static file serving for hybrid servers
58//!
59//! ## Quick Start Examples
60//!
61//! ### Echo Server
62//!
63//! The simplest possible WebSocket server:
64//!
65//! ```
66//! use wsforge_core::prelude::*;
67//!
68//! async fn echo(msg: Message) -> Result<Message> {
69//!     Ok(msg)
70//! }
71//!
72//! #[tokio::main]
73//! async fn main() -> Result<()> {
74//!     let router = Router::new()
75//!         .default_handler(handler(echo));
76//!
77//!     router.listen("127.0.0.1:8080").await?;
78//!     Ok(())
79//! }
80//! ```
81//!
82//! ### Chat Server with Broadcasting
83//!
84//! A real-time chat application:
85//!
86//! ```
87//! use wsforge_core::prelude::*;
88//! use std::sync::Arc;
89//! use serde::{Deserialize, Serialize};
90//!
91//! #[derive(Deserialize, Serialize)]
92//! struct ChatMessage {
93//!     username: String,
94//!     text: String,
95//! }
96//!
97//! async fn chat_handler(
98//!     Json(msg): Json<ChatMessage>,
99//!     conn: Connection,
100//!     State(manager): State<Arc<ConnectionManager>>,
101//! ) -> Result<()> {
102//!     println!("{}: {}", msg.username, msg.text);
103//!
104//!     // Broadcast to everyone except sender
105//!     let response = serde_json::to_string(&msg)?;
106//!     manager.broadcast_except(conn.id(), Message::text(response));
107//!
108//!     Ok(())
109//! }
110//!
111//! #[tokio::main]
112//! async fn main() -> Result<()> {
113//!     let router = Router::new()
114//!         .default_handler(handler(chat_handler))
115//!         .on_connect(|manager, conn_id| {
116//!             println!("✅ {} connected (Total: {})", conn_id, manager.count());
117//!         })
118//!         .on_disconnect(|manager, conn_id| {
119//!             println!("❌ {} disconnected", conn_id);
120//!         });
121//!
122//!     router.listen("127.0.0.1:8080").await?;
123//!     Ok(())
124//! }
125//! ```
126//!
127//! ### Web Application with Static Files
128//!
129//! Hybrid HTTP/WebSocket server:
130//!
131//! ```
132//! use wsforge_core::prelude::*;
133//! use std::sync::Arc;
134//!
135//! async fn ws_handler(
136//!     msg: Message,
137//!     State(manager): State<Arc<ConnectionManager>>,
138//! ) -> Result<()> {
139//!     manager.broadcast(msg);
140//!     Ok(())
141//! }
142//!
143//! #[tokio::main]
144//! async fn main() -> Result<()> {
145//!     let router = Router::new()
146//!         .serve_static("public")  // Serve HTML/CSS/JS
147//!         .default_handler(handler(ws_handler));
148//!
149//!     // Handles both:
150//!     // http://localhost:8080/        -> public/index.html
151//!     // ws://localhost:8080           -> WebSocket handler
152//!
153//!     router.listen("0.0.0.0:8080").await?;
154//!     Ok(())
155//! }
156//! ```
157//!
158//! ## Handler Patterns
159//!
160//! ### Simple Handler
161//!
162//! ```
163//! use wsforge_core::prelude::*;
164//!
165//! async fn simple_handler() -> Result<String> {
166//!     Ok("Hello, WebSocket!".to_string())
167//! }
168//! ```
169//!
170//! ### With JSON Extraction
171//!
172//! ```
173//! use wsforge_core::prelude::*;
174//! use serde::Deserialize;
175//!
176//! #[derive(Deserialize)]
177//! struct Request {
178//!     action: String,
179//!     data: String,
180//! }
181//!
182//! async fn json_handler(Json(req): Json<Request>) -> Result<String> {
183//!     Ok(format!("Action: {}, Data: {}", req.action, req.data))
184//! }
185//! ```
186//!
187//! ### With State and Connection
188//!
189//! ```
190//! use wsforge_core::prelude::*;
191//! use std::sync::Arc;
192//!
193//! async fn stateful_handler(
194//!     msg: Message,
195//!     conn: Connection,
196//!     State(manager): State<Arc<ConnectionManager>>,
197//! ) -> Result<String> {
198//!     Ok(format!(
199//!         "Connection {} | {} total connections",
200//!         conn.id(),
201//!         manager.count()
202//!     ))
203//! }
204//! ```
205//!
206//! ## Extractors
207//!
208//! WsForge provides powerful type-safe extractors:
209//!
210//! | Extractor | Description | Example |
211//! |-----------|-------------|---------|
212//! | `Message` | Raw message | `msg: Message` |
213//! | `Json<T>` | JSON deserialization | `Json(data): Json<MyStruct>` |
214//! | `Connection` | Active connection | `conn: Connection` |
215//! | `State<T>` | Shared state | `State(db): State<Arc<Database>>` |
216//! | `ConnectInfo` | Connection metadata | `ConnectInfo(info)` |
217//! | `Data` | Raw bytes | `Data(bytes): Data` |
218//!
219//! ## Response Types
220//!
221//! Handlers can return various types:
222//!
223//! ```
224//! use wsforge_core::prelude::*;
225//!
226//! // No response
227//! async fn handler1() -> Result<()> {
228//!     Ok(())
229//! }
230//!
231//! // Text response
232//! async fn handler2() -> Result<String> {
233//!     Ok("response".to_string())
234//! }
235//!
236//! // Raw message
237//! async fn handler3() -> Result<Message> {
238//!     Ok(Message::text("response"))
239//! }
240//!
241//! // Binary response
242//! async fn handler4() -> Result<Vec<u8>> {
243//!     Ok(vec!)[1][2][3][4]
244//! }
245//!
246//! // JSON response
247//! async fn handler5() -> Result<JsonResponse<serde_json::Value>> {
248//!     Ok(JsonResponse(serde_json::json!({"status": "ok"})))
249//! }
250//! ```
251//!
252//! ## Broadcasting Patterns
253//!
254//! ### Broadcast to All
255//!
256//! ```
257//! use wsforge_core::prelude::*;
258//! use std::sync::Arc;
259//!
260//! async fn broadcast_all(
261//!     msg: Message,
262//!     State(manager): State<Arc<ConnectionManager>>,
263//! ) -> Result<()> {
264//!     manager.broadcast(msg);
265//!     Ok(())
266//! }
267//! ```
268//!
269//! ### Broadcast Except Sender
270//!
271//! ```
272//! use wsforge_core::prelude::*;
273//! use std::sync::Arc;
274//!
275//! async fn broadcast_others(
276//!     msg: Message,
277//!     conn: Connection,
278//!     State(manager): State<Arc<ConnectionManager>>,
279//! ) -> Result<()> {
280//!     manager.broadcast_except(conn.id(), msg);
281//!     Ok(())
282//! }
283//! ```
284//!
285//! ### Targeted Broadcasting
286//!
287//! ```
288//! use wsforge_core::prelude::*;
289//! use std::sync::Arc;
290//!
291//! async fn broadcast_to_room(
292//!     msg: Message,
293//!     State(manager): State<Arc<ConnectionManager>>,
294//! ) -> Result<()> {
295//!     let room_members = vec!["conn_1".to_string(), "conn_2".to_string()];
296//!     manager.broadcast_to(&room_members, msg);
297//!     Ok(())
298//! }
299//! ```
300//!
301//! ## Error Handling
302//!
303//! WsForge provides comprehensive error handling:
304//!
305//! ```
306//! use wsforge_core::prelude::*;
307//!
308//! async fn safe_handler(msg: Message) -> Result<String> {
309//!     // Parse JSON
310//!     let data: serde_json::Value = msg.json()?;
311//!
312//!     // Validate
313//!     if data.is_null() {
314//!         return Err(Error::custom("Data cannot be null"));
315//!     }
316//!
317//!     // Process and return
318//!     Ok("processed".to_string())
319//! }
320//! ```
321//!
322//! ## Performance Characteristics
323//!
324//! - **Connection Management**: O(1) lock-free operations via DashMap
325//! - **Message Routing**: O(1) handler lookup
326//! - **Broadcasting**: O(n) where n is the number of connections
327//! - **Memory**: Zero-copy message handling where possible
328//! - **Concurrency**: Full async/await with tokio
329//!
330//! ## Testing
331//!
332//! WsForge handlers are easy to test:
333//!
334//! ```
335//! use wsforge_core::prelude::*;
336//!
337//! async fn my_handler(msg: Message) -> Result<String> {
338//!     Ok(format!("Echo: {}", msg.as_text().unwrap_or("")))
339//! }
340//!
341//! #[tokio::test]
342//! async fn test_handler() {
343//!     let msg = Message::text("hello");
344//!     let result = my_handler(msg).await.unwrap();
345//!     assert_eq!(result, "Echo: hello");
346//! }
347//! ```
348//!
349//! ## Production Considerations
350//!
351//! ### Rate Limiting
352//!
353//! ```
354//! use wsforge_core::prelude::*;
355//! use std::sync::Arc;
356//! use tokio::sync::RwLock;
357//! use std::collections::HashMap;
358//!
359//! struct RateLimiter {
360//!     limits: RwLock<HashMap<String, u32>>,
361//! }
362//!
363//! async fn rate_limited_handler(
364//!     msg: Message,
365//!     conn: Connection,
366//!     State(limiter): State<Arc<RateLimiter>>,
367//! ) -> Result<String> {
368//!     // Check rate limit
369//!     // Process if allowed
370//!     Ok("processed".to_string())
371//! }
372//! ```
373//!
374//! ### Graceful Shutdown
375//!
376//! ```
377//! use wsforge_core::prelude::*;
378//! use tokio::signal;
379//!
380//! #[tokio::main]
381//! async fn main() -> Result<()> {
382//!     let router = Router::new();
383//!
384//!     tokio::select! {
385//!         _ = router.listen("127.0.0.1:8080") => {},
386//!         _ = signal::ctrl_c() => {
387//!             println!("Shutting down gracefully...");
388//!         }
389//!     }
390//!
391//!     Ok(())
392//! }
393//! ```
394//!
395//! ## Further Reading
396//!
397//! - [Connection Management](connection/index.html)
398//! - [Message Handling](message/index.html)
399//! - [Handler Guide](handler/index.html)
400//! - [Extractor Reference](extractor/index.html)
401//! - [Router Configuration](router/index.html)
402//! - [State Management](state/index.html)
403
404// Enable documentation features for docs.rs
405#![cfg_attr(docsrs, feature(doc_cfg))]
406// Deny missing docs to ensure comprehensive documentation
407#![warn(missing_docs)]
408// Enable additional documentation lint rules
409#![warn(rustdoc::missing_crate_level_docs)]
410
411pub mod connection;
412pub mod error;
413pub mod extractor;
414pub mod handler;
415pub mod message;
416pub mod middleware;
417pub mod router;
418pub mod state;
419pub mod static_files;
420
421pub use connection::{Connection, ConnectionId};
422pub use error::{Error, Result};
423pub use extractor::{ConnectInfo, Data, Extension, Extensions, Json, Path, Query, State};
424pub use handler::{Handler, HandlerService, IntoResponse, JsonResponse, handler};
425pub use message::{Message, MessageType};
426pub use middleware::{LoggerMiddleware, Middleware, MiddlewareChain, Next};
427pub use router::{Route, Router};
428pub use state::AppState;
429pub use static_files::StaticFileHandler;
430
431/// Commonly used types and traits for WsForge applications.
432///
433/// This prelude module re-exports the most frequently used types, making it easier
434/// to get started with WsForge. Import this module to bring all essential types
435/// into scope with a single use statement.
436///
437/// # Examples
438///
439/// ```
440/// use wsforge_core::prelude::*;
441///
442/// // Now you have access to:
443/// // - Router, Message, Connection, ConnectionManager
444/// // - handler(), Error, Result
445/// // - Json, State, ConnectInfo
446/// // - And more!
447///
448/// async fn my_handler(msg: Message) -> Result<String> {
449///     Ok("Hello!".to_string())
450/// }
451///
452/// # fn example() {
453/// let router = Router::new()
454///     .default_handler(handler(my_handler));
455/// # }
456/// ```
457///
458/// # Included Types
459///
460/// ## Core Types
461/// - [`Router`]: Server router and configuration
462/// - [`Message`]: WebSocket message type
463/// - [`Connection`]: Active connection handle
464/// - [`ConnectionManager`]: Manages all connections
465/// - [`Error`], [`Result`]: Error handling
466///
467/// ## Extractors
468/// - [`Json<T>`]: JSON deserialization
469/// - [`State<T>`]: Shared state extraction
470/// - [`ConnectInfo`]: Connection metadata
471/// - [`Data`]: Raw byte extraction
472/// - [`Extension<T>`]: Custom extensions
473///
474/// ## Handlers
475/// - [`handler()`]: Convert functions to handlers
476/// - [`JsonResponse<T>`]: JSON response type
477/// - [`IntoResponse`]: Response conversion trait
478///
479/// ## State
480/// - [`AppState`]: Application state container
481/// - [`Extensions`]: Request-scoped data
482///
483/// ## Utilities
484/// - [`MessageType`]: Message type enum
485/// - [`StaticFileHandler`]: Static file serving
486pub mod prelude {
487    pub use crate::connection::{Connection, ConnectionId, ConnectionManager};
488    pub use crate::error::{Error, Result};
489    pub use crate::extractor::{
490        ConnectInfo, Data, Extension, Extensions, Json, Path, Query, State,
491    };
492    pub use crate::handler::{Handler, HandlerService, IntoResponse, JsonResponse, handler};
493    pub use crate::message::{Message, MessageType};
494    pub use crate::middleware::{LoggerMiddleware, Middleware, MiddlewareChain, Next};
495    pub use crate::router::{Route, Router};
496    pub use crate::state::AppState;
497    pub use crate::static_files::StaticFileHandler;
498}