diff --git a/ruma-common/CHANGELOG.md b/ruma-common/CHANGELOG.md index def250f5..fca94afe 100644 --- a/ruma-common/CHANGELOG.md +++ b/ruma-common/CHANGELOG.md @@ -3,6 +3,7 @@ Breaking changes: * Update set of conversion trait implementations for enums +* Replace `BTreeSet` by `IndexSet` in `push::Ruleset`. * … (there's a lot more, but this changelog was not kept up to date; PRs to improve it are welcome) diff --git a/ruma-common/Cargo.toml b/ruma-common/Cargo.toml index b87c7aa9..7d5c876f 100644 --- a/ruma-common/Cargo.toml +++ b/ruma-common/Cargo.toml @@ -17,6 +17,7 @@ ruma-identifiers = { version = "=0.18.0-alpha.1", path = "../ruma-identifiers" } ruma-serde = { version = "0.3.0", path = "../ruma-serde" } serde = { version = "1.0.118", features = ["derive"] } serde_json = { version = "1.0.60", features = ["raw_value"] } +indexmap = { version = "1.6.2", features = ["serde-1"] } [dev-dependencies] matches = "0.1.8" diff --git a/ruma-common/src/push.rs b/ruma-common/src/push.rs index 92200a7e..4b266b20 100644 --- a/ruma-common/src/push.rs +++ b/ruma-common/src/push.rs @@ -6,13 +6,13 @@ //! //! Push rules are grouped in `RuleSet`s, and are grouped in five kinds (for //! more details about the different kind of rules, see the `Ruleset` documentation, -//! or the specification). These five kinds are: +//! or the specification). These five kinds are, by order of priority: //! -//! - content rules //! - override rules -//! - underride rules +//! - content rules //! - room rules //! - sender rules +//! - underride rules //! //! Each of these kind of rule has a corresponding type that is //! just a wrapper around another type: @@ -34,8 +34,12 @@ //! There is also the `AnyPushRule` type that is the most generic form of push rule, with all //! the possible fields. -use std::collections::btree_set::{BTreeSet, IntoIter as BTreeSetIter}; +use std::hash::{Hash, Hasher}; +use indexmap::{ + set::{IndexSet, IntoIter as IndexSetIter}, + Equivalent, +}; use ruma_serde::StringEnum; use serde::{Deserialize, Serialize}; @@ -58,24 +62,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: BTreeSet, + pub content: IndexSet, /// 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_: BTreeSet, + pub override_: IndexSet, /// These rules change the behavior of all messages for a given room. - pub room: BTreeSet, + pub room: IndexSet, /// These rules configure notification behavior for messages from a specific Matrix user ID. - pub sender: BTreeSet, + pub sender: IndexSet, /// These rules are identical to override rules, but have a lower priority than `content`, /// `room` and `sender` rules. - pub underride: BTreeSet, + pub underride: IndexSet, } impl Ruleset { @@ -97,11 +101,11 @@ impl Ruleset { /// Iterator type for `Ruleset` #[derive(Debug)] pub struct RulesetIter { - content: BTreeSetIter, - override_: BTreeSetIter, - room: BTreeSetIter, - sender: BTreeSetIter, - underride: BTreeSetIter, + content: IndexSetIter, + override_: IndexSetIter, + room: IndexSetIter, + sender: IndexSetIter, + underride: IndexSetIter, } impl Iterator for RulesetIter { @@ -180,17 +184,11 @@ macro_rules! rulekind { } // The following trait are needed to be able to make - // a BTreeSet of the new type + // an IndexSet of the new type - impl Ord for $name { - fn cmp(&self, other: &Self) -> core::cmp::Ordering { - self.0.rule_id.cmp(&other.0.rule_id) - } - } - - impl PartialOrd for $name { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) + impl Hash for $name { + fn hash(&self, state: &mut H) { + self.0.rule_id.hash(state); } } @@ -201,6 +199,12 @@ macro_rules! rulekind { } impl Eq for $name {} + + impl Equivalent<$name> for str { + fn equivalent(&self, key: &$name) -> bool { + self == key.0.rule_id + } + } }; } diff --git a/ruma-common/src/push/predefined.rs b/ruma-common/src/push/predefined.rs index 9628642c..d72855a1 100644 --- a/ruma-common/src/push/predefined.rs +++ b/ruma-common/src/push/predefined.rs @@ -1,7 +1,7 @@ ///! Constructors for [predefined push rules]. ///! ///! [predefined push rules]: https://matrix.org/docs/spec/client_server/r0.6.1#predefined-rules -use maplit::btreeset; +use indexmap::indexset; use ruma_identifiers::UserId; use super::{ @@ -20,9 +20,9 @@ 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: btreeset![ContentPushRule::contains_user_name(user_id)], + content: indexset![ContentPushRule::contains_user_name(user_id)], #[cfg(feature = "unstable-pre-spec")] - override_: btreeset![ + override_: indexset![ OverridePushRule::master(), OverridePushRule::suppress_notices(), OverridePushRule::invite_for_me(user_id), @@ -33,7 +33,7 @@ impl Ruleset { OverridePushRule::reaction(), ], #[cfg(not(feature = "unstable-pre-spec"))] - override_: btreeset![ + override_: indexset![ OverridePushRule::master(), OverridePushRule::suppress_notices(), OverridePushRule::invite_for_me(user_id), @@ -42,7 +42,7 @@ impl Ruleset { OverridePushRule::tombstone(), OverridePushRule::roomnotif(), ], - underride: btreeset![ + underride: indexset![ UnderridePushRule::call(), UnderridePushRule::encrypted_room_one_to_one(), UnderridePushRule::room_one_to_one(),