1use serde::{Deserialize, Serialize};
2use std::collections::BTreeMap;
3
4use crate::error::{FlowError, Result};
5
6use super::JsonValue;
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
10#[non_exhaustive]
11pub struct HookCallbackRoute {
12 pub method: String,
14 pub path: String,
16}
17
18impl HookCallbackRoute {
19 pub fn new(method: impl Into<String>, path: impl Into<String>) -> Self {
21 Self {
22 method: method.into().to_ascii_uppercase(),
23 path: path.into(),
24 }
25 }
26
27 pub fn post(path: impl Into<String>) -> Self {
29 Self::new("POST", path)
30 }
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
39#[non_exhaustive]
40pub struct HookMetadata {
41 pub kind: String,
43 #[serde(skip_serializing_if = "Option::is_none")]
45 pub subject: Option<String>,
46 #[serde(skip_serializing_if = "Option::is_none")]
48 pub callback: Option<HookCallbackRoute>,
49 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
51 pub labels: BTreeMap<String, String>,
52 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
54 pub data: BTreeMap<String, JsonValue>,
55}
56
57impl HookMetadata {
58 pub fn new(kind: impl Into<String>) -> Self {
60 Self {
61 kind: kind.into(),
62 subject: None,
63 callback: None,
64 labels: BTreeMap::new(),
65 data: BTreeMap::new(),
66 }
67 }
68
69 pub fn human_approval(subject: impl Into<String>) -> Self {
71 Self::new("human_approval").with_subject(subject)
72 }
73
74 pub fn with_subject(mut self, subject: impl Into<String>) -> Self {
76 self.subject = Some(subject.into());
77 self
78 }
79
80 pub fn with_callback_route(mut self, callback: HookCallbackRoute) -> Self {
82 self.callback = Some(callback);
83 self
84 }
85
86 pub fn with_label(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
88 self.labels.insert(key.into(), value.into());
89 self
90 }
91
92 pub fn with_data(mut self, key: impl Into<String>, value: impl Into<JsonValue>) -> Self {
94 self.data.insert(key.into(), value.into());
95 self
96 }
97
98 pub fn into_json(self) -> Result<JsonValue> {
100 serde_json::to_value(self).map_err(FlowError::from)
101 }
102}