use serde::{Deserialize, Serialize}; mod room_member_count_is; pub use room_member_count_is::{ComparisonOperator, RoomMemberCountIs}; /// A condition that must apply for an associated push rule's action to be taken. #[derive(Clone, Debug, Deserialize, Serialize)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] #[serde(tag = "kind", rename_all = "snake_case")] pub enum PushCondition { /// This is a glob pattern match on a field of the event. EventMatch { /// The dot-separated field of the event to match. key: String, /// The glob-style pattern to match against. /// /// Patterns with no special glob characters should be treated as having asterisks prepended /// and appended when testing the condition. pattern: String, }, /// This matches unencrypted messages where `content.body` contains the owner's display name in /// that room. ContainsDisplayName, /// This matches the current number of members in the room. RoomMemberCount { /// The condition on the current number of members in the room. is: RoomMemberCountIs, }, /// This takes into account the current power levels in the room, ensuring the sender of the /// event has high enough power to trigger the notification. SenderNotificationPermission { /// The field in the power level event the user needs a minimum power level for. /// /// Fields must be specified under the `notifications` property in the power level event's /// `content`. key: String, }, } #[cfg(test)] mod tests { use js_int::uint; use matches::assert_matches; use serde_json::{from_value as from_json_value, json, to_value as to_json_value}; use super::{PushCondition, RoomMemberCountIs}; #[test] fn serialize_event_match_condition() { let json_data = json!({ "key": "content.msgtype", "kind": "event_match", "pattern": "m.notice" }); assert_eq!( to_json_value(&PushCondition::EventMatch { key: "content.msgtype".into(), pattern: "m.notice".into(), }) .unwrap(), json_data ); } #[test] fn serialize_contains_display_name_condition() { assert_eq!( to_json_value(&PushCondition::ContainsDisplayName).unwrap(), json!({ "kind": "contains_display_name" }) ); } #[test] fn serialize_room_member_count_condition() { let json_data = json!({ "is": "2", "kind": "room_member_count" }); assert_eq!( to_json_value(&PushCondition::RoomMemberCount { is: RoomMemberCountIs::from(uint!(2)) }) .unwrap(), json_data ); } #[test] fn serialize_sender_notification_permission_condition() { let json_data = json!({ "key": "room", "kind": "sender_notification_permission" }); assert_eq!( json_data, to_json_value(&PushCondition::SenderNotificationPermission { key: "room".into() }) .unwrap() ); } #[test] fn deserialize_event_match_condition() { let json_data = json!({ "key": "content.msgtype", "kind": "event_match", "pattern": "m.notice" }); assert_matches!( from_json_value::(json_data).unwrap(), PushCondition::EventMatch { key, pattern } if key == "content.msgtype" && pattern == "m.notice" ); } #[test] fn deserialize_contains_display_name_condition() { assert_matches!( from_json_value::(json!({ "kind": "contains_display_name" })).unwrap(), PushCondition::ContainsDisplayName ); } #[test] fn deserialize_room_member_count_condition() { let json_data = json!({ "is": "2", "kind": "room_member_count" }); assert_matches!( from_json_value::(json_data).unwrap(), PushCondition::RoomMemberCount { is } if is == RoomMemberCountIs::from(uint!(2)) ); } #[test] fn deserialize_sender_notification_permission_condition() { let json_data = json!({ "key": "room", "kind": "sender_notification_permission" }); assert_matches!( from_json_value::(json_data).unwrap(), PushCondition::SenderNotificationPermission { key } if key == "room" ); } }