diff --git a/ruma-common/src/push.rs b/ruma-common/src/push.rs index 6db0232a..f67d2f99 100644 --- a/ruma-common/src/push.rs +++ b/ruma-common/src/push.rs @@ -2,6 +2,8 @@ //! //! [push]: https://matrix.org/docs/spec/client_server/r0.6.1#id89 +use std::collections::BTreeSet; + use ruma_common::StringEnum; use serde::{Deserialize, Serialize}; @@ -16,6 +18,34 @@ pub use self::{ condition::{ComparisonOperator, PushCondition, RoomMemberCountIs}, }; +macro_rules! ord_by_rule_id { + ($t:ty) => { + impl Ord for $t { + fn cmp(&self, other: &Self) -> core::cmp::Ordering { + self.rule_id.cmp(&other.rule_id) + } + } + + impl PartialOrd for $t { + fn partial_cmp(&self, other: &Self) -> Option { + Some(self.cmp(other)) + } + } + + impl PartialEq for $t { + fn eq(&self, other: &Self) -> bool { + self.rule_id == other.rule_id + } + } + + impl Eq for $t {} + }; +} + +ord_by_rule_id!(PushRule); +ord_by_rule_id!(ConditionalPushRule); +ord_by_rule_id!(PatternedPushRule); + /// A push ruleset scopes a set of rules according to some criteria. /// /// For example, some rules may only be applied for messages from a particular sender, a particular @@ -24,24 +54,24 @@ pub use self::{ #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] pub struct Ruleset { /// These rules configure behavior for (unencrypted) messages that match certain patterns. - pub content: Vec, + pub content: BTreeSet, /// These user-configured rules are given the highest priority. /// /// This field is named `override_` instead of `override` because the latter is a reserved /// keyword in Rust. #[serde(rename = "override")] - pub override_: Vec, + pub override_: BTreeSet, /// These rules change the behavior of all messages for a given room. - pub room: Vec, + pub room: BTreeSet, /// These rules configure notification behavior for messages from a specific Matrix user ID. - pub sender: Vec, + pub sender: BTreeSet, /// These rules are identical to override rules, but have a lower priority than `content`, /// `room` and `sender` rules. - pub underride: Vec, + pub underride: BTreeSet, } impl Ruleset { diff --git a/ruma-common/src/push/predefined.rs b/ruma-common/src/push/predefined.rs index 4092cca3..09cc177f 100644 --- a/ruma-common/src/push/predefined.rs +++ b/ruma-common/src/push/predefined.rs @@ -8,6 +8,21 @@ use super::{ use ruma_identifiers::UserId; +macro_rules! set { + ($( $elt:expr ),*) => { + { + use std::collections::BTreeSet; + + let mut s = BTreeSet::new(); + $( s.insert( $elt ); )* + s + } + }; + ($( $elt:expr ),* ,) => { + set![ $( $elt ),* ] + }; +} + impl Ruleset { /// The list of all [predefined push rules]. /// @@ -19,8 +34,8 @@ impl Ruleset { /// user's ID (for instance those to send notifications when they are mentioned). pub fn server_default(user_id: &UserId) -> Self { Self { - content: vec![PatternedPushRule::contains_user_name(user_id)], - override_: vec![ + content: set![PatternedPushRule::contains_user_name(user_id)], + override_: set![ ConditionalPushRule::master(), ConditionalPushRule::suppress_notices(), ConditionalPushRule::invite_for_me(user_id), @@ -29,7 +44,7 @@ impl Ruleset { ConditionalPushRule::tombstone(), ConditionalPushRule::roomnotif(), ], - underride: vec![ + underride: set![ ConditionalPushRule::call(), ConditionalPushRule::encrypted_room_one_to_one(), ConditionalPushRule::room_one_to_one(),