use jmap_types::{Id, PatchObject, UTCDate, impl_string_enum};
use serde::{Deserialize, Serialize};
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct Person {
pub name: String,
pub email: Option<String>,
pub principal_id: Option<Id>,
pub calendar_address: Option<String>,
#[serde(flatten, default, skip_serializing_if = "serde_json::Map::is_empty")]
pub extra: serde_json::Map<String, serde_json::Value>,
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum NotificationType {
Created,
Updated,
Destroyed,
Other(String),
}
impl_string_enum!(NotificationType, "a JMAP CalendarEventNotification type string",
"created" => Created,
"updated" => Updated,
"destroyed" => Destroyed,
);
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CalendarEventNotification {
pub id: Id,
pub created: UTCDate,
pub changed_by: Person,
#[serde(skip_serializing_if = "Option::is_none")]
pub comment: Option<String>,
#[serde(rename = "type")]
pub notification_type: NotificationType,
pub calendar_event_id: Id,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_draft: Option<bool>,
pub event: serde_json::Value,
#[serde(skip_serializing_if = "Option::is_none")]
pub event_patch: Option<PatchObject>,
#[serde(flatten, default, skip_serializing_if = "serde_json::Map::is_empty")]
pub extra: serde_json::Map<String, serde_json::Value>,
}
fn calendar_alert_at_type_default() -> String {
"CalendarAlert".to_owned()
}
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CalendarAlert {
#[serde(rename = "@type", default = "calendar_alert_at_type_default")]
pub at_type: String,
pub account_id: Id,
pub calendar_event_id: Id,
pub uid: String,
pub recurrence_id: Option<String>,
pub alert_id: String,
#[serde(flatten, default, skip_serializing_if = "serde_json::Map::is_empty")]
pub extra: serde_json::Map<String, serde_json::Value>,
}
#[non_exhaustive]
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct NotificationFilterCondition {
#[serde(skip_serializing_if = "Option::is_none")]
pub after: Option<UTCDate>,
#[serde(skip_serializing_if = "Option::is_none")]
pub before: Option<UTCDate>,
#[serde(rename = "type", skip_serializing_if = "Option::is_none")]
pub notification_type: Option<NotificationType>,
#[serde(skip_serializing_if = "Option::is_none")]
pub calendar_event_ids: Option<Vec<Id>>,
}
pub type NotificationFilter = jmap_types::Filter<NotificationFilterCondition>;
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum CalendarEventNotificationComparatorProperty {
Created,
Other(String),
}
impl_string_enum!(CalendarEventNotificationComparatorProperty,
"a CalendarEventNotification sort property string",
"created" => Created,
);
#[non_exhaustive]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct CalendarEventNotificationComparator {
pub property: CalendarEventNotificationComparatorProperty,
#[serde(default = "bool_true", skip_serializing_if = "is_true")]
pub is_ascending: bool,
#[serde(skip_serializing_if = "Option::is_none")]
pub collation: Option<String>,
}
impl CalendarEventNotificationComparator {
pub fn new(property: CalendarEventNotificationComparatorProperty) -> Self {
Self {
property,
is_ascending: true,
collation: None,
}
}
}
fn bool_true() -> bool {
true
}
fn is_true(b: &bool) -> bool {
*b
}
#[cfg(test)]
mod comparator_tests {
use super::*;
#[test]
fn created_comparator_decodes_from_spec_name() {
let c: CalendarEventNotificationComparator =
serde_json::from_str(r#"{"property":"created"}"#).expect("must parse");
assert_eq!(
c.property,
CalendarEventNotificationComparatorProperty::Created
);
assert!(c.is_ascending);
assert_eq!(c.collation, None);
}
#[test]
fn unknown_property_round_trips() {
let json = serde_json::json!({"property":"calendarEventId","isAscending":false});
let c: CalendarEventNotificationComparator =
serde_json::from_value(json.clone()).expect("must parse");
assert_eq!(
c.property,
CalendarEventNotificationComparatorProperty::Other("calendarEventId".to_owned())
);
assert_eq!(serde_json::to_value(&c).unwrap(), json);
}
}