kuma_client/models/
notification.rs

1//! Models related to Uptime Kuma notification services
2
3use crate::deserialize::{
4    DeserializeBoolLenient, DeserializeNumberLenient, DeserializeValueLenient,
5};
6use derivative::Derivative;
7use serde::{Deserialize, Serialize};
8use serde_with::{serde_as, skip_serializing_none};
9
10const IGNORE_ATTRIBUTES: [&str; 6] = ["isDefault", "id", "active", "user_id", "config", "name"];
11
12/// Represents a notification service in Uptime Kuma.
13#[skip_serializing_none]
14#[serde_as]
15#[derive(Clone, Default, Debug, Serialize, Derivative, Deserialize, Eq)]
16#[derivative(PartialEq)]
17pub struct Notification {
18    /// The unique identifier for the notification service.
19    #[serde(rename = "id")]
20    #[serde_as(as = "Option<DeserializeNumberLenient>")]
21    pub id: Option<i32>,
22
23    /// The name of the notification.
24    #[serde(rename = "name")]
25    pub name: Option<String>,
26
27    /// Indicates whether the notification service is active or not.
28    #[serde(rename = "active")]
29    #[serde_as(as = "Option<DeserializeBoolLenient>")]
30    pub active: Option<bool>,
31
32    /// The user identifier associated with the notification service.
33    #[serde(rename = "user_id")]
34    #[serde(alias = "user_id")]
35    pub user_id: Option<i32>,
36
37    /// Indicates whether the notification service is enabled by default.
38    #[serde(rename = "isDefault")]
39    #[serde(alias = "is_default")]
40    #[serde_as(as = "Option<DeserializeBoolLenient>")]
41    pub is_default: Option<bool>,
42
43    /// Additional service specific configuration in JSON format.
44    #[serde(rename = "config")]
45    #[serde_as(as = "Option<DeserializeValueLenient>")]
46    #[derivative(PartialEq(compare_with = "config_eq"))]
47    pub config: Option<serde_json::Value>,
48}
49
50fn config_eq(a: &Option<serde_json::Value>, b: &Option<serde_json::Value>) -> bool {
51    match (a, b) {
52        (None, None) => true,
53        (Some(serde_json::Value::Object(map_a)), Some(serde_json::Value::Object(map_b))) => {
54            let count_a = map_a
55                .iter()
56                .filter(|(k, _)| !IGNORE_ATTRIBUTES.contains(&k.as_str()))
57                .count();
58
59            let count_b = map_b
60                .iter()
61                .filter(|(k, _)| !IGNORE_ATTRIBUTES.contains(&k.as_str()))
62                .count();
63
64            if count_a != count_b {
65                return false;
66            }
67
68            map_a
69                .iter()
70                .filter(|(k, _)| !IGNORE_ATTRIBUTES.contains(&k.as_str()))
71                .all(|(k, v)| map_b.get(k).map_or(false, |v_b| v == v_b))
72        }
73        _ => a == b,
74    }
75}
76
77/// A list of notification services.
78pub type NotificationList = Vec<Notification>;