Move some types from ruma_events::push_rules to ruma_common::push
This commit is contained in:
parent
3ec0936a28
commit
83d8f8c43e
@ -2,6 +2,7 @@
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use ruma_common::push::{Action, PushCondition};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::{Display, EnumString};
|
||||
|
||||
@ -18,9 +19,6 @@ pub mod set_pushrule;
|
||||
pub mod set_pushrule_actions;
|
||||
pub mod set_pushrule_enabled;
|
||||
|
||||
pub use ruma_common::push::Action;
|
||||
pub use ruma_events::push_rules::PushCondition;
|
||||
|
||||
/// The kinds of push rules that are available
|
||||
#[derive(
|
||||
Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, Display, EnumString,
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! [GET /_matrix/client/r0/pushrules/](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules)
|
||||
//! [GET /_matrix/client/r0/pushrules/](https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-pushrules)
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_events::push_rules::Ruleset;
|
||||
use ruma_common::push::Ruleset;
|
||||
|
||||
ruma_api! {
|
||||
metadata {
|
||||
|
@ -1,7 +1,7 @@
|
||||
//! [GET /_matrix/client/r0/pushrules/global/](https://matrix.org/docs/spec/client_server/r0.6.0#get-matrix-client-r0-pushrules)
|
||||
//! [GET /_matrix/client/r0/pushrules/global/](https://matrix.org/docs/spec/client_server/r0.6.1#get-matrix-client-r0-pushrules)
|
||||
|
||||
use ruma_api::ruma_api;
|
||||
use ruma_events::push_rules::Ruleset;
|
||||
use ruma_common::push::Ruleset;
|
||||
|
||||
ruma_api! {
|
||||
metadata {
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Common types for the [push notifications module][push]
|
||||
//!
|
||||
//! [push]: https://matrix.org/docs/spec/client_server/r0.6.0#id89
|
||||
//! [push]: https://matrix.org/docs/spec/client_server/r0.6.1#id89
|
||||
|
||||
use std::fmt::{self, Formatter};
|
||||
|
||||
@ -9,6 +9,97 @@ use serde_json::value::RawValue as RawJsonValue;
|
||||
|
||||
mod tweak_serde;
|
||||
|
||||
/// 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
|
||||
/// room, or by default. The push ruleset contains the entire set of scopes and rules.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Ruleset {
|
||||
/// These rules configure behavior for (unencrypted) messages that match certain patterns.
|
||||
pub content: Vec<PatternedPushRule>,
|
||||
|
||||
/// 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<ConditionalPushRule>,
|
||||
|
||||
/// These rules change the behavior of all messages for a given room.
|
||||
pub room: Vec<PushRule>,
|
||||
|
||||
/// These rules configure notification behavior for messages from a specific Matrix user ID.
|
||||
pub sender: Vec<PushRule>,
|
||||
|
||||
/// These rules are identical to override rules, but have a lower priority than `content`,
|
||||
/// `room` and `sender` rules.
|
||||
pub underride: Vec<ConditionalPushRule>,
|
||||
}
|
||||
|
||||
/// A push rule is a single rule that states under what conditions an event should be passed onto a
|
||||
/// push gateway and how the notification should be presented.
|
||||
///
|
||||
/// These rules are stored on the user's homeserver. They are manually configured by the user, who
|
||||
/// can create and view them via the Client/Server API.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PushRule {
|
||||
/// Actions to determine if and how a notification is delivered for events matching this rule.
|
||||
pub actions: Vec<Action>,
|
||||
|
||||
/// Whether this is a default rule, or has been set explicitly.
|
||||
pub default: bool,
|
||||
|
||||
/// Whether the push rule is enabled or not.
|
||||
pub enabled: bool,
|
||||
|
||||
/// The ID of this rule.
|
||||
pub rule_id: String,
|
||||
}
|
||||
|
||||
/// Like `PushRule`, but with an additional `conditions` field.
|
||||
///
|
||||
/// Only applicable to underride and override rules.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct ConditionalPushRule {
|
||||
/// Actions to determine if and how a notification is delivered for events matching this rule.
|
||||
pub actions: Vec<Action>,
|
||||
|
||||
/// Whether this is a default rule, or has been set explicitly.
|
||||
pub default: bool,
|
||||
|
||||
/// Whether the push rule is enabled or not.
|
||||
pub enabled: bool,
|
||||
|
||||
/// The ID of this rule.
|
||||
pub rule_id: String,
|
||||
|
||||
/// The conditions that must hold true for an event in order for a rule to be applied to an event.
|
||||
///
|
||||
/// A rule with no conditions always matches.
|
||||
pub conditions: Vec<PushCondition>,
|
||||
}
|
||||
|
||||
/// Like `PushRule`, but with an additional `pattern` field.
|
||||
///
|
||||
/// Only applicable to content rules.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PatternedPushRule {
|
||||
/// Actions to determine if and how a notification is delivered for events matching this rule.
|
||||
pub actions: Vec<Action>,
|
||||
|
||||
/// Whether this is a default rule, or has been set explicitly.
|
||||
pub default: bool,
|
||||
|
||||
/// Whether the push rule is enabled or not.
|
||||
pub enabled: bool,
|
||||
|
||||
/// The ID of this rule.
|
||||
pub rule_id: String,
|
||||
|
||||
/// The glob-style pattern to match against.
|
||||
pub pattern: String,
|
||||
}
|
||||
|
||||
/// This represents the different actions that should be taken when a rule is matched, and
|
||||
/// controls how notifications are delivered to the client.
|
||||
///
|
||||
@ -115,12 +206,53 @@ impl Serialize for Action {
|
||||
}
|
||||
}
|
||||
|
||||
/// A condition that must apply for an associated push rule's action to be taken.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[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 {
|
||||
/// A decimal integer optionally prefixed by one of `==`, `<`, `>`, `>=` or `<=`.
|
||||
///
|
||||
/// A prefix of `<` matches rooms where the member count is strictly less than the given
|
||||
/// number and so forth. If no prefix is present, this parameter defaults to `==`.
|
||||
is: String,
|
||||
},
|
||||
|
||||
/// 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 matches::assert_matches;
|
||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||
|
||||
use super::{Action, Tweak};
|
||||
use super::{Action, PushCondition, Tweak};
|
||||
|
||||
#[test]
|
||||
fn serialize_string_action() {
|
||||
@ -184,4 +316,103 @@ mod tests {
|
||||
Action::SetTweak(Tweak::Highlight(true))
|
||||
);
|
||||
}
|
||||
|
||||
#[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".to_string(),
|
||||
pattern: "m.notice".to_string(),
|
||||
})
|
||||
.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: "2".to_string() }).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".to_string() })
|
||||
.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::<PushCondition>(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::<PushCondition>(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::<PushCondition>(json_data).unwrap(),
|
||||
PushCondition::RoomMemberCount { is }
|
||||
if is == "2"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_sender_notification_permission_condition() {
|
||||
let json_data = json!({
|
||||
"key": "room",
|
||||
"kind": "sender_notification_permission"
|
||||
});
|
||||
assert_matches!(
|
||||
from_json_value::<PushCondition>(json_data).unwrap(),
|
||||
PushCondition::SenderNotificationPermission {
|
||||
key
|
||||
} if key == "room"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
//! Types for the the *m.push_rules* event.
|
||||
|
||||
use ruma_common::push::Ruleset;
|
||||
use ruma_events_macros::BasicEventContent;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
@ -16,246 +17,11 @@ pub struct PushRulesEventContent {
|
||||
pub global: Ruleset,
|
||||
}
|
||||
|
||||
pub use ruma_common::push::Action;
|
||||
|
||||
/// 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
|
||||
/// room, or by default. The push ruleset contains the entire set of scopes and rules.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct Ruleset {
|
||||
/// These rules configure behavior for (unencrypted) messages that match certain patterns.
|
||||
pub content: Vec<PatternedPushRule>,
|
||||
|
||||
/// 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<ConditionalPushRule>,
|
||||
|
||||
/// These rules change the behavior of all messages for a given room.
|
||||
pub room: Vec<PushRule>,
|
||||
|
||||
/// These rules configure notification behavior for messages from a specific Matrix user ID.
|
||||
pub sender: Vec<PushRule>,
|
||||
|
||||
/// These rules are identical to override rules, but have a lower priority than `content`,
|
||||
/// `room` and `sender` rules.
|
||||
pub underride: Vec<ConditionalPushRule>,
|
||||
}
|
||||
|
||||
/// A push rule is a single rule that states under what conditions an event should be passed onto a
|
||||
/// push gateway and how the notification should be presented.
|
||||
///
|
||||
/// These rules are stored on the user's homeserver. They are manually configured by the user, who
|
||||
/// can create and view them via the Client/Server API.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PushRule {
|
||||
/// Actions to determine if and how a notification is delivered for events matching this rule.
|
||||
pub actions: Vec<Action>,
|
||||
|
||||
/// Whether this is a default rule, or has been set explicitly.
|
||||
pub default: bool,
|
||||
|
||||
/// Whether the push rule is enabled or not.
|
||||
pub enabled: bool,
|
||||
|
||||
/// The ID of this rule.
|
||||
pub rule_id: String,
|
||||
}
|
||||
|
||||
/// Like `PushRule`, but with an additional `conditions` field.
|
||||
///
|
||||
/// Only applicable to underride and override rules.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct ConditionalPushRule {
|
||||
/// Actions to determine if and how a notification is delivered for events matching this rule.
|
||||
pub actions: Vec<Action>,
|
||||
|
||||
/// Whether this is a default rule, or has been set explicitly.
|
||||
pub default: bool,
|
||||
|
||||
/// Whether the push rule is enabled or not.
|
||||
pub enabled: bool,
|
||||
|
||||
/// The ID of this rule.
|
||||
pub rule_id: String,
|
||||
|
||||
/// The conditions that must hold true for an event in order for a rule to be applied to an event.
|
||||
///
|
||||
/// A rule with no conditions always matches.
|
||||
pub conditions: Vec<PushCondition>,
|
||||
}
|
||||
|
||||
/// Like `PushRule`, but with an additional `pattern` field.
|
||||
///
|
||||
/// Only applicable to content rules.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
pub struct PatternedPushRule {
|
||||
/// Actions to determine if and how a notification is delivered for events matching this rule.
|
||||
pub actions: Vec<Action>,
|
||||
|
||||
/// Whether this is a default rule, or has been set explicitly.
|
||||
pub default: bool,
|
||||
|
||||
/// Whether the push rule is enabled or not.
|
||||
pub enabled: bool,
|
||||
|
||||
/// The ID of this rule.
|
||||
pub rule_id: String,
|
||||
|
||||
/// The glob-style pattern to match against.
|
||||
pub pattern: String,
|
||||
}
|
||||
|
||||
/// A condition that must apply for an associated push rule's action to be taken.
|
||||
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||
#[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 {
|
||||
/// A decimal integer optionally prefixed by one of `==`, `<`, `>`, `>=` or `<=`.
|
||||
///
|
||||
/// A prefix of `<` matches rooms where the member count is strictly less than the given
|
||||
/// number and so forth. If no prefix is present, this parameter defaults to `==`.
|
||||
is: String,
|
||||
},
|
||||
|
||||
/// 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 matches::assert_matches;
|
||||
use serde_json::{from_value as from_json_value, json, to_value as to_json_value};
|
||||
use serde_json::{from_value as from_json_value, json};
|
||||
|
||||
use super::{PushCondition, PushRulesEvent};
|
||||
use crate::EventJson;
|
||||
|
||||
#[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".to_string(),
|
||||
pattern: "m.notice".to_string(),
|
||||
})
|
||||
.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: "2".to_string() }).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".to_string() })
|
||||
.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::<PushCondition>(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::<PushCondition>(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::<PushCondition>(json_data).unwrap(),
|
||||
PushCondition::RoomMemberCount { is }
|
||||
if is == "2"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn deserialize_sender_notification_permission_condition() {
|
||||
let json_data = json!({
|
||||
"key": "room",
|
||||
"kind": "sender_notification_permission"
|
||||
});
|
||||
assert_matches!(
|
||||
from_json_value::<PushCondition>(json_data).unwrap(),
|
||||
PushCondition::SenderNotificationPermission {
|
||||
key
|
||||
} if key == "room"
|
||||
);
|
||||
}
|
||||
use super::PushRulesEvent;
|
||||
|
||||
#[test]
|
||||
fn sanity_check() {
|
||||
@ -452,7 +218,6 @@ mod tests {
|
||||
"type": "m.push_rules"
|
||||
});
|
||||
|
||||
let _ =
|
||||
from_json_value::<EventJson<PushRulesEvent>>(json_data).unwrap().deserialize().unwrap();
|
||||
assert!(from_json_value::<PushRulesEvent>(json_data).is_ok());
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user