diff --git a/crates/ruma-common/CHANGELOG.md b/crates/ruma-common/CHANGELOG.md index 6fded09b..32c17c45 100644 --- a/crates/ruma-common/CHANGELOG.md +++ b/crates/ruma-common/CHANGELOG.md @@ -7,7 +7,9 @@ Breaking changes: Improvements: -- Add method to update the server-default push rules in a `Ruleset` +- Add convenience methods for `push::Ruleset`: + - To update the server-default push rules + - To remove a user-defined push rule # 0.11.3 diff --git a/crates/ruma-common/src/push.rs b/crates/ruma-common/src/push.rs index bcf93b74..7cc8bf63 100644 --- a/crates/ruma-common/src/push.rs +++ b/crates/ruma-common/src/push.rs @@ -311,6 +311,47 @@ impl Ruleset { pub fn get_actions(&self, event: &Raw, context: &PushConditionRoomCtx) -> &[Action] { self.get_match(event, context).map(|rule| rule.actions()).unwrap_or(&[]) } + + /// Removes a user-defined rule in the rule set. + /// + /// Returns an error if the parameters are invalid. + pub fn remove( + &mut self, + kind: RuleKind, + rule_id: impl AsRef, + ) -> Result<(), RemovePushRuleError> { + let rule_id = rule_id.as_ref(); + + if let Some(rule) = self.get(kind.clone(), rule_id) { + if rule.is_server_default() { + return Err(RemovePushRuleError::ServerDefault); + } + } else { + return Err(RemovePushRuleError::NotFound); + } + + match kind { + RuleKind::Override => { + self.override_.shift_remove(rule_id); + } + RuleKind::Underride => { + self.underride.shift_remove(rule_id); + } + RuleKind::Sender => { + self.sender.shift_remove(rule_id); + } + RuleKind::Room => { + self.room.shift_remove(rule_id); + } + RuleKind::Content => { + self.content.shift_remove(rule_id); + } + // This has been handled in the `self.get` call earlier. + RuleKind::_Custom(_) => unreachable!(), + } + + Ok(()) + } } /// A push rule is a single rule that states under what conditions an event should be passed onto a @@ -901,6 +942,19 @@ where Ok(()) } +/// The error type returned when trying to remove a user-defined push rule from a `Ruleset`. +#[derive(Debug, Error)] +#[non_exhaustive] +pub enum RemovePushRuleError { + /// The rule is a server-default rules and they can't be removed. + #[error("server-default rules cannot be removed")] + ServerDefault, + + /// The rule was not found. + #[error("rule not found")] + NotFound, +} + #[cfg(test)] mod tests { use std::collections::BTreeMap; diff --git a/crates/ruma-common/src/push/iter.rs b/crates/ruma-common/src/push/iter.rs index 62ad7e1a..b978a938 100644 --- a/crates/ruma-common/src/push/iter.rs +++ b/crates/ruma-common/src/push/iter.rs @@ -53,6 +53,11 @@ impl AnyPushRule { self.as_ref().rule_id() } + /// Whether the push rule is a server-default rule. + pub fn is_server_default(&self) -> bool { + self.as_ref().is_server_default() + } + /// Check if the push rule applies to the event. /// /// # Arguments @@ -168,6 +173,17 @@ impl<'a> AnyPushRuleRef<'a> { } } + /// Whether the push rule is a server-default rule. + pub fn is_server_default(self) -> bool { + match self { + Self::Override(rule) => rule.default, + Self::Underride(rule) => rule.default, + Self::Content(rule) => rule.default, + Self::Room(rule) => rule.default, + Self::Sender(rule) => rule.default, + } + } + /// Check if the push rule applies to the event. /// /// # Arguments