wsforge-core 0.1.1

Core library for WsForge WebSocket framework
Documentation
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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
//! # WsForge Core - High-Performance WebSocket Framework
//!
//! `wsforge-core` is the foundational library for the WsForge WebSocket framework.
//! It provides type-safe, ergonomic abstractions for building real-time WebSocket applications
//! with exceptional performance and developer experience.
//!
//! ## Overview
//!
//! WsForge Core combines the power of `tokio-tungstenite` with a flexible, type-safe API inspired
//! by modern web frameworks like Axum. It's designed for building production-ready WebSocket
//! servers that are both fast and maintainable.
//!
//! ## Key Features
//!
//! - 🚀 **High Performance**: Built on tokio-tungstenite with zero-copy optimizations
//! - 🔧 **Type-Safe Extractors**: Automatic extraction of JSON, State, Connection info
//! - 🎯 **Flexible Handlers**: Return various types - String, Message, Result, JsonResponse
//! - 📡 **Broadcasting**: Built-in broadcast, broadcast_except, and targeted messaging
//! - ⚡ **Concurrent**: Lock-free connection management with DashMap
//! - 🔄 **Lifecycle Hooks**: on_connect and on_disconnect callbacks
//! - 🌐 **Hybrid Server**: Serve static files and WebSocket on same port
//! - 🛡️ **Type Safety**: Compile-time guarantees for correctness
//!
//! ## Architecture
//!
//! ```
//! ┌──────────────────────────────────────────────────────────────┐
//! │                        Application                            │
//! │  ┌────────────┐  ┌──────────┐  ┌───────────────────────┐   │
//! │  │  Handlers  │  │  Router  │  │  State & Extractors   │   │
//! │  └────────────┘  └──────────┘  └───────────────────────┘   │
//! └──────────────────────────────────────────────────────────────┘
//!//! ┌──────────────────────────────────────────────────────────────┐
//! │                      WsForge Core                             │
//! │  ┌──────────────┐  ┌────────────────┐  ┌─────────────────┐ │
//! │  │  Connection  │  │     Message     │  │   Static Files  │ │
//! │  │   Manager    │  │     Router      │  │     Handler     │ │
//! │  └──────────────┘  └────────────────┘  └─────────────────┘ │
//! └──────────────────────────────────────────────────────────────┘
//!//! ┌──────────────────────────────────────────────────────────────┐
//! │                    tokio-tungstenite                          │
//! │                  (WebSocket Protocol)                         │
//! └──────────────────────────────────────────────────────────────┘
//! ```
//!
//! ## Module Structure
//!
//! - [`connection`]: WebSocket connection management and lifecycle
//! - [`message`]: Message types and parsing utilities
//! - [`handler`]: Handler trait and response types
//! - [`extractor`]: Type-safe data extraction from messages
//! - [`router`]: Routing and server management
//! - [`state`]: Shared application state container
//! - [`error`]: Error types and result handling
//! - [`static_files`]: Static file serving for hybrid servers
//!
//! ## Quick Start Examples
//!
//! ### Echo Server
//!
//! The simplest possible WebSocket server:
//!
//! ```
//! use wsforge_core::prelude::*;
//!
//! async fn echo(msg: Message) -> Result<Message> {
//!     Ok(msg)
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//!     let router = Router::new()
//!         .default_handler(handler(echo));
//!
//!     router.listen("127.0.0.1:8080").await?;
//!     Ok(())
//! }
//! ```
//!
//! ### Chat Server with Broadcasting
//!
//! A real-time chat application:
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//! use serde::{Deserialize, Serialize};
//!
//! #[derive(Deserialize, Serialize)]
//! struct ChatMessage {
//!     username: String,
//!     text: String,
//! }
//!
//! async fn chat_handler(
//!     Json(msg): Json<ChatMessage>,
//!     conn: Connection,
//!     State(manager): State<Arc<ConnectionManager>>,
//! ) -> Result<()> {
//!     println!("{}: {}", msg.username, msg.text);
//!
//!     // Broadcast to everyone except sender
//!     let response = serde_json::to_string(&msg)?;
//!     manager.broadcast_except(conn.id(), Message::text(response));
//!
//!     Ok(())
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//!     let router = Router::new()
//!         .default_handler(handler(chat_handler))
//!         .on_connect(|manager, conn_id| {
//!             println!("✅ {} connected (Total: {})", conn_id, manager.count());
//!         })
//!         .on_disconnect(|manager, conn_id| {
//!             println!("❌ {} disconnected", conn_id);
//!         });
//!
//!     router.listen("127.0.0.1:8080").await?;
//!     Ok(())
//! }
//! ```
//!
//! ### Web Application with Static Files
//!
//! Hybrid HTTP/WebSocket server:
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//!
//! async fn ws_handler(
//!     msg: Message,
//!     State(manager): State<Arc<ConnectionManager>>,
//! ) -> Result<()> {
//!     manager.broadcast(msg);
//!     Ok(())
//! }
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//!     let router = Router::new()
//!         .serve_static("public")  // Serve HTML/CSS/JS
//!         .default_handler(handler(ws_handler));
//!
//!     // Handles both:
//!     // http://localhost:8080/        -> public/index.html
//!     // ws://localhost:8080           -> WebSocket handler
//!
//!     router.listen("0.0.0.0:8080").await?;
//!     Ok(())
//! }
//! ```
//!
//! ## Handler Patterns
//!
//! ### Simple Handler
//!
//! ```
//! use wsforge_core::prelude::*;
//!
//! async fn simple_handler() -> Result<String> {
//!     Ok("Hello, WebSocket!".to_string())
//! }
//! ```
//!
//! ### With JSON Extraction
//!
//! ```
//! use wsforge_core::prelude::*;
//! use serde::Deserialize;
//!
//! #[derive(Deserialize)]
//! struct Request {
//!     action: String,
//!     data: String,
//! }
//!
//! async fn json_handler(Json(req): Json<Request>) -> Result<String> {
//!     Ok(format!("Action: {}, Data: {}", req.action, req.data))
//! }
//! ```
//!
//! ### With State and Connection
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//!
//! async fn stateful_handler(
//!     msg: Message,
//!     conn: Connection,
//!     State(manager): State<Arc<ConnectionManager>>,
//! ) -> Result<String> {
//!     Ok(format!(
//!         "Connection {} | {} total connections",
//!         conn.id(),
//!         manager.count()
//!     ))
//! }
//! ```
//!
//! ## Extractors
//!
//! WsForge provides powerful type-safe extractors:
//!
//! | Extractor | Description | Example |
//! |-----------|-------------|---------|
//! | `Message` | Raw message | `msg: Message` |
//! | `Json<T>` | JSON deserialization | `Json(data): Json<MyStruct>` |
//! | `Connection` | Active connection | `conn: Connection` |
//! | `State<T>` | Shared state | `State(db): State<Arc<Database>>` |
//! | `ConnectInfo` | Connection metadata | `ConnectInfo(info)` |
//! | `Data` | Raw bytes | `Data(bytes): Data` |
//!
//! ## Response Types
//!
//! Handlers can return various types:
//!
//! ```
//! use wsforge_core::prelude::*;
//!
//! // No response
//! async fn handler1() -> Result<()> {
//!     Ok(())
//! }
//!
//! // Text response
//! async fn handler2() -> Result<String> {
//!     Ok("response".to_string())
//! }
//!
//! // Raw message
//! async fn handler3() -> Result<Message> {
//!     Ok(Message::text("response"))
//! }
//!
//! // Binary response
//! async fn handler4() -> Result<Vec<u8>> {
//!     Ok(vec!)[1][2][3][4]
//! }
//!
//! // JSON response
//! async fn handler5() -> Result<JsonResponse<serde_json::Value>> {
//!     Ok(JsonResponse(serde_json::json!({"status": "ok"})))
//! }
//! ```
//!
//! ## Broadcasting Patterns
//!
//! ### Broadcast to All
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//!
//! async fn broadcast_all(
//!     msg: Message,
//!     State(manager): State<Arc<ConnectionManager>>,
//! ) -> Result<()> {
//!     manager.broadcast(msg);
//!     Ok(())
//! }
//! ```
//!
//! ### Broadcast Except Sender
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//!
//! async fn broadcast_others(
//!     msg: Message,
//!     conn: Connection,
//!     State(manager): State<Arc<ConnectionManager>>,
//! ) -> Result<()> {
//!     manager.broadcast_except(conn.id(), msg);
//!     Ok(())
//! }
//! ```
//!
//! ### Targeted Broadcasting
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//!
//! async fn broadcast_to_room(
//!     msg: Message,
//!     State(manager): State<Arc<ConnectionManager>>,
//! ) -> Result<()> {
//!     let room_members = vec!["conn_1".to_string(), "conn_2".to_string()];
//!     manager.broadcast_to(&room_members, msg);
//!     Ok(())
//! }
//! ```
//!
//! ## Error Handling
//!
//! WsForge provides comprehensive error handling:
//!
//! ```
//! use wsforge_core::prelude::*;
//!
//! async fn safe_handler(msg: Message) -> Result<String> {
//!     // Parse JSON
//!     let data: serde_json::Value = msg.json()?;
//!
//!     // Validate
//!     if data.is_null() {
//!         return Err(Error::custom("Data cannot be null"));
//!     }
//!
//!     // Process and return
//!     Ok("processed".to_string())
//! }
//! ```
//!
//! ## Performance Characteristics
//!
//! - **Connection Management**: O(1) lock-free operations via DashMap
//! - **Message Routing**: O(1) handler lookup
//! - **Broadcasting**: O(n) where n is the number of connections
//! - **Memory**: Zero-copy message handling where possible
//! - **Concurrency**: Full async/await with tokio
//!
//! ## Testing
//!
//! WsForge handlers are easy to test:
//!
//! ```
//! use wsforge_core::prelude::*;
//!
//! async fn my_handler(msg: Message) -> Result<String> {
//!     Ok(format!("Echo: {}", msg.as_text().unwrap_or("")))
//! }
//!
//! #[tokio::test]
//! async fn test_handler() {
//!     let msg = Message::text("hello");
//!     let result = my_handler(msg).await.unwrap();
//!     assert_eq!(result, "Echo: hello");
//! }
//! ```
//!
//! ## Production Considerations
//!
//! ### Rate Limiting
//!
//! ```
//! use wsforge_core::prelude::*;
//! use std::sync::Arc;
//! use tokio::sync::RwLock;
//! use std::collections::HashMap;
//!
//! struct RateLimiter {
//!     limits: RwLock<HashMap<String, u32>>,
//! }
//!
//! async fn rate_limited_handler(
//!     msg: Message,
//!     conn: Connection,
//!     State(limiter): State<Arc<RateLimiter>>,
//! ) -> Result<String> {
//!     // Check rate limit
//!     // Process if allowed
//!     Ok("processed".to_string())
//! }
//! ```
//!
//! ### Graceful Shutdown
//!
//! ```
//! use wsforge_core::prelude::*;
//! use tokio::signal;
//!
//! #[tokio::main]
//! async fn main() -> Result<()> {
//!     let router = Router::new();
//!
//!     tokio::select! {
//!         _ = router.listen("127.0.0.1:8080") => {},
//!         _ = signal::ctrl_c() => {
//!             println!("Shutting down gracefully...");
//!         }
//!     }
//!
//!     Ok(())
//! }
//! ```
//!
//! ## Further Reading
//!
//! - [Connection Management](connection/index.html)
//! - [Message Handling](message/index.html)
//! - [Handler Guide](handler/index.html)
//! - [Extractor Reference](extractor/index.html)
//! - [Router Configuration](router/index.html)
//! - [State Management](state/index.html)

// Enable documentation features for docs.rs
#![cfg_attr(docsrs, feature(doc_cfg))]
// Deny missing docs to ensure comprehensive documentation
#![warn(missing_docs)]
// Enable additional documentation lint rules
#![warn(rustdoc::missing_crate_level_docs)]

pub mod connection;
pub mod error;
pub mod extractor;
pub mod handler;
pub mod message;
pub mod middleware;
pub mod router;
pub mod state;
pub mod static_files;

pub use connection::{Connection, ConnectionId};
pub use error::{Error, Result};
pub use extractor::{ConnectInfo, Data, Extension, Extensions, Json, Path, Query, State};
pub use handler::{Handler, HandlerService, IntoResponse, JsonResponse, handler};
pub use message::{Message, MessageType};
pub use middleware::{LoggerMiddleware, Middleware, MiddlewareChain, Next};
pub use router::{Route, Router};
pub use state::AppState;
pub use static_files::StaticFileHandler;

/// Commonly used types and traits for WsForge applications.
///
/// This prelude module re-exports the most frequently used types, making it easier
/// to get started with WsForge. Import this module to bring all essential types
/// into scope with a single use statement.
///
/// # Examples
///
/// ```
/// use wsforge_core::prelude::*;
///
/// // Now you have access to:
/// // - Router, Message, Connection, ConnectionManager
/// // - handler(), Error, Result
/// // - Json, State, ConnectInfo
/// // - And more!
///
/// async fn my_handler(msg: Message) -> Result<String> {
///     Ok("Hello!".to_string())
/// }
///
/// # fn example() {
/// let router = Router::new()
///     .default_handler(handler(my_handler));
/// # }
/// ```
///
/// # Included Types
///
/// ## Core Types
/// - [`Router`]: Server router and configuration
/// - [`Message`]: WebSocket message type
/// - [`Connection`]: Active connection handle
/// - [`ConnectionManager`]: Manages all connections
/// - [`Error`], [`Result`]: Error handling
///
/// ## Extractors
/// - [`Json<T>`]: JSON deserialization
/// - [`State<T>`]: Shared state extraction
/// - [`ConnectInfo`]: Connection metadata
/// - [`Data`]: Raw byte extraction
/// - [`Extension<T>`]: Custom extensions
///
/// ## Handlers
/// - [`handler()`]: Convert functions to handlers
/// - [`JsonResponse<T>`]: JSON response type
/// - [`IntoResponse`]: Response conversion trait
///
/// ## State
/// - [`AppState`]: Application state container
/// - [`Extensions`]: Request-scoped data
///
/// ## Utilities
/// - [`MessageType`]: Message type enum
/// - [`StaticFileHandler`]: Static file serving
pub mod prelude {
    pub use crate::connection::{Connection, ConnectionId, ConnectionManager};
    pub use crate::error::{Error, Result};
    pub use crate::extractor::{
        ConnectInfo, Data, Extension, Extensions, Json, Path, Query, State,
    };
    pub use crate::handler::{Handler, HandlerService, IntoResponse, JsonResponse, handler};
    pub use crate::message::{Message, MessageType};
    pub use crate::middleware::{LoggerMiddleware, Middleware, MiddlewareChain, Next};
    pub use crate::router::{Route, Router};
    pub use crate::state::AppState;
    pub use crate::static_files::StaticFileHandler;
}