Skip to main content

fiberplane_models/
webhooks.rs

1use crate::timestamps::Timestamp;
2use base64uuid::Base64Uuid;
3#[cfg(feature = "fp-bindgen")]
4use fp_bindgen::prelude::Serializable;
5use serde::{Deserialize, Serialize};
6use strum_macros::{Display, EnumIter};
7use typed_builder::TypedBuilder;
8
9// this is not unused, it is used in the expansion of the `EnumIter` proc macro
10#[allow(unused_imports)]
11use strum::IntoEnumIterator;
12
13#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize, Display, EnumIter)]
14#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
15#[cfg_attr(
16    feature = "fp-bindgen",
17    derive(Serializable),
18    fp(rust_module = "fiberplane_models::webhooks")
19)]
20#[non_exhaustive]
21#[serde(rename_all = "snake_case")]
22pub enum WebhookCategory {
23    Ping,
24    FrontMatter,
25}
26
27impl From<&WebhookCategory> for i16 {
28    fn from(value: &WebhookCategory) -> Self {
29        match value {
30            WebhookCategory::Ping => 0,
31            WebhookCategory::FrontMatter => 1,
32        }
33    }
34}
35
36impl From<WebhookCategory> for i16 {
37    fn from(value: WebhookCategory) -> Self {
38        (&value).into()
39    }
40}
41
42// required to be a specialized `impl TryInto` (cannot use the free impl using `From`)
43// because only 0 and 1 are covered cases and std would have no idea how to handle that
44#[allow(clippy::from_over_into)]
45impl TryInto<WebhookCategory> for i16 {
46    type Error = InvalidWebhookCategoryError;
47
48    fn try_into(self) -> Result<WebhookCategory, Self::Error> {
49        match self {
50            0 => Ok(WebhookCategory::Ping),
51            1 => Ok(WebhookCategory::FrontMatter),
52            value => Err(InvalidWebhookCategoryError(value)),
53        }
54    }
55}
56
57#[derive(Debug, thiserror::Error, PartialEq, Eq)]
58#[cfg_attr(
59    feature = "fp-bindgen",
60    derive(Serializable),
61    fp(rust_module = "fiberplane_models::webhooks")
62)]
63#[error("unknown value {0}, expected 0 (ping) or 1 (front_matter)")]
64pub struct InvalidWebhookCategoryError(i16);
65
66#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
67#[cfg_attr(
68    feature = "fp-bindgen",
69    derive(Serializable),
70    fp(rust_module = "fiberplane_models::webhooks")
71)]
72#[non_exhaustive]
73#[serde(rename_all = "camelCase")]
74pub struct Webhook {
75    #[builder(setter(into))]
76    pub id: Base64Uuid,
77    #[builder(setter(into))]
78    pub workspace_id: Base64Uuid,
79
80    #[builder(setter(into))]
81    pub endpoint: String,
82    pub events: Vec<WebhookCategory>,
83    #[builder(default, setter(strip_option, into))]
84    #[serde(default, skip_serializing_if = "Option::is_none")]
85    pub shared_secret: Option<String>,
86    #[builder(default)]
87    pub enabled: bool,
88
89    /// Whether the last delivery was successful
90    #[builder(default)]
91    pub successful: bool,
92
93    #[builder(default, setter(strip_option, into))]
94    #[serde(default, skip_serializing_if = "Option::is_none")]
95    pub created_by: Option<Base64Uuid>,
96    #[builder(setter(into))]
97    pub created_at: Timestamp,
98    #[builder(setter(into))]
99    pub updated_at: Timestamp,
100}
101
102#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
103#[cfg_attr(
104    feature = "fp-bindgen",
105    derive(Serializable),
106    fp(rust_module = "fiberplane_models::webhooks")
107)]
108#[non_exhaustive]
109#[serde(rename_all = "camelCase")]
110pub struct NewWebhook {
111    #[builder(setter(into))]
112    pub endpoint: String,
113
114    pub events: Vec<WebhookCategory>,
115
116    #[builder(default)]
117    pub enabled: bool,
118}
119
120#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
121#[cfg_attr(
122    feature = "fp-bindgen",
123    derive(Serializable),
124    fp(rust_module = "fiberplane_models::webhooks")
125)]
126#[non_exhaustive]
127#[serde(rename_all = "camelCase")]
128pub struct UpdateWebhook {
129    #[builder(default, setter(strip_option, into))]
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub endpoint: Option<String>,
132
133    #[builder(default, setter(strip_option))]
134    #[serde(default, skip_serializing_if = "Option::is_none")]
135    pub events: Option<Vec<WebhookCategory>>,
136
137    #[builder(default)]
138    #[serde(default)]
139    pub regenerate_shared_secret: bool,
140
141    #[builder(default, setter(strip_option))]
142    #[serde(default, skip_serializing_if = "Option::is_none")]
143    pub enabled: Option<bool>,
144}
145
146#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
147#[cfg_attr(
148    feature = "fp-bindgen",
149    derive(Serializable),
150    fp(rust_module = "fiberplane_models::webhooks")
151)]
152#[non_exhaustive]
153#[serde(rename_all = "camelCase")]
154pub struct WebhookDelivery {
155    #[builder(setter(into))]
156    pub id: Base64Uuid,
157    #[builder(setter(into))]
158    pub webhook_id: Base64Uuid,
159    #[builder(setter(into))]
160    pub event: String,
161
162    #[builder(default, setter(strip_option))]
163    #[serde(default, skip_serializing_if = "Option::is_none")]
164    pub status_code: Option<i32>,
165    #[builder(default, setter(into, strip_option))]
166    #[serde(default, skip_serializing_if = "Option::is_none")]
167    pub status_text: Option<String>,
168
169    #[builder(default, setter(into))]
170    pub request_headers: String,
171    #[builder(default, setter(into))]
172    pub request_body: String,
173
174    #[builder(default, setter(into, strip_option))]
175    #[serde(default, skip_serializing_if = "Option::is_none")]
176    pub response_headers: Option<String>,
177    #[builder(default, setter(into, strip_option))]
178    #[serde(default, skip_serializing_if = "Option::is_none")]
179    pub response_body: Option<String>,
180
181    #[builder(setter(into))]
182    pub sent_request_at: Timestamp,
183    #[builder(default, setter(into, strip_option))]
184    #[serde(default, skip_serializing_if = "Option::is_none")]
185    pub received_response_at: Option<Timestamp>,
186}
187
188#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize, TypedBuilder)]
189#[cfg_attr(
190    feature = "fp-bindgen",
191    derive(Serializable),
192    fp(rust_module = "fiberplane_models::webhooks")
193)]
194#[non_exhaustive]
195#[serde(rename_all = "camelCase")]
196pub struct WebhookDeliverySummary {
197    #[builder(setter(into))]
198    pub id: Base64Uuid,
199
200    #[builder(setter(into))]
201    pub event: String,
202
203    pub successful: bool,
204
205    #[builder(setter(into))]
206    pub timestamp: Timestamp,
207}