Skip to main content

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}