#[mechanism]Expand description
Concise route declaration for toolkit-zero socket-server routes.
Replaces an async fn item with a server.mechanism(…) statement at the
point of declaration. The function body is transplanted verbatim into the
.onconnect(…) closure; all variables from the enclosing scope are
accessible via move capture.
§Syntax
#[mechanism(server, METHOD, "/path")]
#[mechanism(server, METHOD, "/path", json)]
#[mechanism(server, METHOD, "/path", query)]
#[mechanism(server, METHOD, "/path", encrypted(key_expr))]
#[mechanism(server, METHOD, "/path", encrypted_query(key_expr))]
#[mechanism(server, METHOD, "/path", state(state_expr))]
#[mechanism(server, METHOD, "/path", state(state_expr), json)]
#[mechanism(server, METHOD, "/path", state(state_expr), query)]
#[mechanism(server, METHOD, "/path", state(state_expr), encrypted(key_expr))]
#[mechanism(server, METHOD, "/path", state(state_expr), encrypted_query(key_expr))]The first three arguments (server, METHOD, "/path") are positional.
json, query, state(…), encrypted(…), and encrypted_query(…) may
appear in any order after the path.
§Parameters
| Argument | Meaning |
|---|---|
server | Identifier of the Server variable in the enclosing scope |
METHOD | HTTP method: GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS |
"/path" | Route path string literal |
json | JSON-deserialised body; fn has one param (body: T) |
query | URL query params; fn has one param (params: T) |
encrypted(key) | VEIL-encrypted body; fn has one param (body: T) |
encrypted_query(key) | VEIL-encrypted query; fn has one param (params: T) |
state(expr) | State injection; fn first param is (state: S) |
When state is combined with a body mode the function receives two
parameters: the state clone first, the body or query second.
§Function signature
The decorated function:
- May be
asyncor non-async — it is always wrapped inasync move { … }. - May carry a return type annotation or none — it is ignored; Rust infers
the return type from the
reply!macro inside the body. - Must have exactly the number of parameters described in the table above.
§Example
ⓘ
use toolkit_zero::socket::server::{Server, mechanism, reply, Status, SerializationKey};
use serde::{Deserialize, Serialize};
use std::sync::{Arc, Mutex};
#[derive(Deserialize, Serialize, Clone)] struct Item { id: u32, name: String }
#[derive(Deserialize)] struct NewItem { name: String }
#[derive(Deserialize)] struct Filter { page: u32 }
#[tokio::main]
async fn main() {
let mut server = Server::default();
let db: Arc<Mutex<Vec<Item>>> = Arc::new(Mutex::new(vec![]));
// Plain GET — no body, no state
#[mechanism(server, GET, "/health")]
async fn health() { reply!() }
// POST — JSON body
#[mechanism(server, POST, "/items", json)]
async fn create_item(body: NewItem) {
reply!(json => Item { id: 1, name: body.name }, status => Status::Created)
}
// GET — query params
#[mechanism(server, GET, "/items", query)]
async fn list_items(filter: Filter) {
let _ = filter.page;
reply!()
}
// GET — state + query
#[mechanism(server, GET, "/items/all", state(db.clone()), query)]
async fn list_all(db: Arc<Mutex<Vec<Item>>>, filter: Filter) {
let items = db.lock().unwrap().clone();
reply!(json => items)
}
// POST — state + JSON body
#[mechanism(server, POST, "/items/add", state(db.clone()), json)]
async fn add_item(db: Arc<Mutex<Vec<Item>>>, body: NewItem) {
let id = db.lock().unwrap().len() as u32 + 1;
let item = Item { id, name: body.name };
db.lock().unwrap().push(item.clone());
reply!(json => item, status => Status::Created)
}
// POST — VEIL-encrypted body
#[mechanism(server, POST, "/secure", encrypted(SerializationKey::Default))]
async fn secure_post(body: NewItem) {
reply!(json => Item { id: 99, name: body.name })
}
server.serve(([127, 0, 0, 1], 8080)).await;
}