adminx_core/actions.rs
1// adminx-core/src/actions.rs
2//
3// Framework-neutral custom actions: extra id-scoped operations a resource
4// exposes beyond CRUD (e.g. "publish", "approve", "toggle-status"). The handler
5// is a plain fn pointer returning a neutral `ApiResponse`, so it works under any
6// web adapter. Wired by adapters at `POST /{base}/{id}/action/{name}`.
7
8use crate::request::ReqCtx;
9use crate::response::ApiResponse;
10use serde_json::Value;
11use std::future::Future;
12use std::pin::Pin;
13
14/// Boxed future returned by an action handler.
15pub type ActionFuture = Pin<Box<dyn Future<Output = ApiResponse> + Send>>;
16
17/// An action handler receives the (cloned) request context, the target record
18/// id, and the JSON request body (`{}` when none was sent).
19pub type ActionHandler = fn(ReqCtx, String, Value) -> ActionFuture;
20
21/// Describes a custom action exposed by a resource.
22pub struct CustomAction {
23 /// URL/segment name, e.g. `"publish"`.
24 pub name: &'static str,
25 /// Human label for the UI button (defaults to `name`).
26 pub label: Option<&'static str>,
27 /// Server-side handler.
28 pub handler: ActionHandler,
29}
30
31impl CustomAction {
32 pub fn new(name: &'static str, handler: ActionHandler) -> Self {
33 Self {
34 name,
35 label: None,
36 handler,
37 }
38 }
39
40 pub fn labeled(name: &'static str, label: &'static str, handler: ActionHandler) -> Self {
41 Self {
42 name,
43 label: Some(label),
44 handler,
45 }
46 }
47
48 pub fn display_label(&self) -> &'static str {
49 self.label.unwrap_or(self.name)
50 }
51}