Skip to main content

broccoli_server_sdk/types/
http.rs

1use std::collections::HashMap;
2
3use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
6pub struct PluginHttpAuth {
7    pub user_id: i32,
8    pub username: String,
9    pub role: String,
10    #[serde(default)]
11    pub permissions: Vec<String>,
12}
13
14/// Data passed to the Wasm plugin when a route is triggered.
15#[derive(Debug, Clone, Serialize, Deserialize)]
16pub struct PluginHttpRequest {
17    pub method: String,
18    #[serde(default)]
19    pub path: String,
20    #[serde(default)]
21    pub params: HashMap<String, String>,
22    #[serde(default)]
23    pub query: HashMap<String, String>,
24    #[serde(default)]
25    pub headers: HashMap<String, String>,
26    #[serde(default)]
27    pub body: Option<serde_json::Value>,
28    #[serde(default)]
29    pub auth: Option<PluginHttpAuth>,
30}
31
32impl PluginHttpRequest {
33    pub fn user_id(&self) -> Option<i32> {
34        self.auth.as_ref().map(|auth| auth.user_id)
35    }
36
37    pub fn has_permission(&self, permission: &str) -> bool {
38        self.auth
39            .as_ref()
40            .is_some_and(|auth| auth.permissions.iter().any(|p| p == permission))
41    }
42}
43
44/// Response returned by the Wasm plugin after processing a route.
45#[derive(Debug, Clone, Serialize, Deserialize)]
46pub struct PluginHttpResponse {
47    pub status: u16,
48    #[serde(default, skip_serializing_if = "Option::is_none")]
49    pub headers: Option<HashMap<String, String>>,
50    #[serde(default, skip_serializing_if = "Option::is_none")]
51    pub body: Option<serde_json::Value>,
52}
53
54impl PluginHttpResponse {
55    /// Create an error response with a JSON `{ "error": "<message>" }` body.
56    pub fn error(status: u16, message: impl Into<String>) -> Self {
57        Self {
58            status,
59            headers: None,
60            body: Some(serde_json::json!({ "error": message.into() })),
61        }
62    }
63}