common: Add borrowing iteration of push rulesets

This commit is contained in:
Jonas Platte 2021-04-17 16:57:47 +02:00
parent 8171e34eac
commit ab42d379b8
No known key found for this signature in database
GPG Key ID: 7D261D771D915378
2 changed files with 80 additions and 2 deletions

View File

@ -30,7 +30,7 @@ pub use self::{
condition::{
ComparisonOperator, FlattenedJson, PushCondition, PushConditionRoomCtx, RoomMemberCountIs,
},
iter::{AnyPushRule, RulesetIntoIter},
iter::{AnyPushRule, RulesetIntoIter, RulesetIter},
};
/// A push ruleset scopes a set of rules according to some criteria.
@ -67,6 +67,13 @@ impl Ruleset {
Default::default()
}
/// Creates a borrowing iterator over all push rules in this `Ruleset`.
///
/// For an owning iterator, use `.into_iter()`.
pub fn iter(&self) -> RulesetIter {
self.into_iter()
}
/// Adds a rule to the rule set.
///
/// Returns `true` if the new rule was correctly added, and `false`

View File

@ -1,4 +1,4 @@
use indexmap::set::IntoIter as IndexSetIntoIter;
use indexmap::set::{IntoIter as IndexSetIntoIter, Iter as IndexSetIter};
use super::{ConditionalPushRule, PatternedPushRule, Ruleset, SimplePushRule};
@ -83,3 +83,74 @@ impl IntoIterator for Ruleset {
}
}
}
/// Reference to any kind of push rule.
#[derive(Clone, Copy, Debug)]
pub enum AnyPushRuleRef<'a> {
/// Rules that override all other kinds.
Override(&'a ConditionalPushRule),
/// Content-specific rules.
Content(&'a PatternedPushRule),
/// Room-specific rules.
Room(&'a SimplePushRule),
/// Sender-specific rules.
Sender(&'a SimplePushRule),
/// Lowest priority rules.
Underride(&'a ConditionalPushRule),
}
impl<'a> AnyPushRuleRef<'a> {
/// Get the `rule_id` of the push rule.
pub fn rule_id(self) -> &'a str {
match self {
Self::Override(rule) => &rule.rule_id,
Self::Underride(rule) => &rule.rule_id,
Self::Content(rule) => &rule.rule_id,
Self::Room(rule) => &rule.rule_id,
Self::Sender(rule) => &rule.rule_id,
}
}
}
/// Iterator type for `Ruleset`
#[derive(Debug)]
pub struct RulesetIter<'a> {
content: IndexSetIter<'a, PatternedPushRule>,
override_: IndexSetIter<'a, ConditionalPushRule>,
room: IndexSetIter<'a, SimplePushRule>,
sender: IndexSetIter<'a, SimplePushRule>,
underride: IndexSetIter<'a, ConditionalPushRule>,
}
impl<'a> Iterator for RulesetIter<'a> {
type Item = AnyPushRuleRef<'a>;
fn next(&mut self) -> Option<Self::Item> {
self.override_
.next()
.map(AnyPushRuleRef::Override)
.or_else(|| self.content.next().map(AnyPushRuleRef::Content))
.or_else(|| self.room.next().map(AnyPushRuleRef::Room))
.or_else(|| self.sender.next().map(AnyPushRuleRef::Sender))
.or_else(|| self.underride.next().map(AnyPushRuleRef::Underride))
}
}
impl<'a> IntoIterator for &'a Ruleset {
type Item = AnyPushRuleRef<'a>;
type IntoIter = RulesetIter<'a>;
fn into_iter(self) -> Self::IntoIter {
RulesetIter {
content: self.content.iter(),
override_: self.override_.iter(),
room: self.room.iter(),
sender: self.sender.iter(),
underride: self.underride.iter(),
}
}
}