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)]
10pub struct HookCallbackRoute {
11 pub method: String,
12 pub path: String,
13}
14
15impl HookCallbackRoute {
16 pub fn new(method: impl Into<String>, path: impl Into<String>) -> Self {
17 Self {
18 method: method.into().to_ascii_uppercase(),
19 path: path.into(),
20 }
21 }
22
23 pub fn post(path: impl Into<String>) -> Self {
24 Self::new("POST", path)
25 }
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
34pub struct HookMetadata {
35 pub kind: String,
36 #[serde(skip_serializing_if = "Option::is_none")]
37 pub subject: Option<String>,
38 #[serde(skip_serializing_if = "Option::is_none")]
39 pub callback: Option<HookCallbackRoute>,
40 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
41 pub labels: BTreeMap<String, String>,
42 #[serde(default, skip_serializing_if = "BTreeMap::is_empty")]
43 pub data: BTreeMap<String, JsonValue>,
44}
45
46impl HookMetadata {
47 pub fn new(kind: impl Into<String>) -> Self {
48 Self {
49 kind: kind.into(),
50 subject: None,
51 callback: None,
52 labels: BTreeMap::new(),
53 data: BTreeMap::new(),
54 }
55 }
56
57 pub fn human_approval(subject: impl Into<String>) -> Self {
58 Self::new("human_approval").with_subject(subject)
59 }
60
61 pub fn with_subject(mut self, subject: impl Into<String>) -> Self {
62 self.subject = Some(subject.into());
63 self
64 }
65
66 pub fn with_callback_route(mut self, callback: HookCallbackRoute) -> Self {
67 self.callback = Some(callback);
68 self
69 }
70
71 pub fn with_label(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
72 self.labels.insert(key.into(), value.into());
73 self
74 }
75
76 pub fn with_data(mut self, key: impl Into<String>, value: impl Into<JsonValue>) -> Self {
77 self.data.insert(key.into(), value.into());
78 self
79 }
80
81 pub fn into_json(self) -> Result<JsonValue> {
82 serde_json::to_value(self).map_err(FlowError::from)
83 }
84}