salvo_craft/lib.rs
1//! Modular handler crafting for Salvo web framework.
2//!
3//! This crate provides the `#[craft]` attribute macro that enables a more
4//! ergonomic way to define handlers as methods on structs, allowing for
5//! better code organization and state sharing.
6//!
7//! # Overview
8//!
9//! Instead of writing standalone handler functions, you can organize related
10//! handlers as methods on a struct, with shared state accessible via `self`:
11//!
12//! ```ignore
13//! use salvo::prelude::*;
14//! use salvo_craft::craft;
15//!
16//! #[derive(Clone)]
17//! pub struct UserService {
18//! db: DatabasePool,
19//! }
20//!
21//! #[craft]
22//! impl UserService {
23//! fn new(db: DatabasePool) -> Self {
24//! Self { db }
25//! }
26//!
27//! #[craft(handler)]
28//! async fn get_user(&self, id: PathParam<i64>) -> Result<Json<User>, StatusError> {
29//! let user = self.db.get_user(*id).await?;
30//! Ok(Json(user))
31//! }
32//!
33//! #[craft(handler)]
34//! async fn list_users(&self) -> Json<Vec<User>> {
35//! Json(self.db.list_users().await)
36//! }
37//! }
38//! ```
39//!
40//! # Usage
41//!
42//! ## Basic Handler
43//!
44//! Use `#[craft(handler)]` to mark a method as a handler:
45//!
46//! ```ignore
47//! #[craft]
48//! impl MyService {
49//! #[craft(handler)]
50//! fn hello(&self) -> &'static str {
51//! "Hello, World!"
52//! }
53//! }
54//! ```
55//!
56//! ## With OpenAPI Support
57//!
58//! Use `#[craft(endpoint(...))]` for handlers that should be included in
59//! OpenAPI documentation:
60//!
61//! ```ignore
62//! #[craft]
63//! impl MyService {
64//! #[craft(endpoint(tags("users"), status_codes(200, 404)))]
65//! async fn get_user(&self, id: PathParam<i64>) -> Result<Json<User>, StatusError> {
66//! // ...
67//! }
68//! }
69//! ```
70//!
71//! # Method Receivers
72//!
73//! The `#[craft]` macro supports different method receivers:
74//!
75//! | Receiver | Requirement | Use Case |
76//! |----------|-------------|----------|
77//! | `&self` | Type must implement `Clone` | Most common, shared state |
78//! | `Arc<Self>` | None | Explicit reference counting |
79//! | None (static) | None | Stateless handlers |
80//!
81//! ## Examples
82//!
83//! ```ignore
84//! #[derive(Clone)]
85//! pub struct Service { /* ... */ }
86//!
87//! #[craft]
88//! impl Service {
89//! // Uses &self - Service must be Clone
90//! #[craft(handler)]
91//! fn with_ref(&self) -> String { /* ... */ }
92//!
93//! // Uses Arc<Self> - explicit shared ownership
94//! #[craft(handler)]
95//! fn with_arc(self: Arc<Self>) -> String { /* ... */ }
96//!
97//! // Static method - no self
98//! #[craft(handler)]
99//! fn static_handler() -> String { /* ... */ }
100//! }
101//! ```
102//!
103//! # Router Integration
104//!
105//! Craft handlers are used with routers just like regular handlers:
106//!
107//! ```ignore
108//! let service = UserService::new(db_pool);
109//!
110//! let router = Router::new()
111//! .push(Router::with_path("users/<id>").get(service.get_user()))
112//! .push(Router::with_path("users").get(service.list_users()));
113//! ```
114
115pub use salvo_craft_macros::*;