diff --git a/ruma-common/src/presence.rs b/ruma-common/src/presence.rs index 52c33556..f5b7d855 100644 --- a/ruma-common/src/presence.rs +++ b/ruma-common/src/presence.rs @@ -7,6 +7,7 @@ use strum::{Display, EnumString}; /// A description of a user's connectivity and availability for chat. #[derive(Clone, Copy, Debug, PartialEq, Display, EnumString, Deserialize, Serialize)] +#[non_exhaustive] #[serde(rename_all = "snake_case")] #[strum(serialize_all = "snake_case")] pub enum PresenceState { diff --git a/ruma-common/src/push.rs b/ruma-common/src/push.rs index 2ceb04f6..ac2ea650 100644 --- a/ruma-common/src/push.rs +++ b/ruma-common/src/push.rs @@ -18,7 +18,11 @@ pub use self::{ /// /// 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)] +/// +/// To create an instance of this type, use its `Default` implementation and set the fields you +/// need. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[non_exhaustive] pub struct Ruleset { /// These rules configure behavior for (unencrypted) messages that match certain patterns. pub content: Vec, @@ -46,7 +50,11 @@ pub struct Ruleset { /// /// 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. +/// +/// To create an instance of this type, first create a `PushRuleInit` and convert it via +/// `PushRule::from` / `.into()`. #[derive(Clone, Debug, Deserialize, Serialize)] +#[non_exhaustive] pub struct PushRule { /// Actions to determine if and how a notification is delivered for events matching this rule. pub actions: Vec, @@ -61,10 +69,40 @@ pub struct PushRule { pub rule_id: String, } +/// Initial set of fields of `PushRule`. +/// +/// This struct will not be updated even if additional fields are added to `PushRule` in a new +/// (non-breaking) release of the Matrix specification. +#[derive(Debug)] +pub struct PushRuleInit { + /// Actions to determine if and how a notification is delivered for events matching this rule. + pub actions: Vec, + + /// 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, +} + +impl From for PushRule { + fn from(init: PushRuleInit) -> Self { + let PushRuleInit { actions, default, enabled, rule_id } = init; + Self { actions, default, enabled, rule_id } + } +} + /// Like `PushRule`, but with an additional `conditions` field. /// /// Only applicable to underride and override rules. +/// +/// To create an instance of this type, first create a `ConditionalPushRuleInit` and convert it via +/// `ConditionalPushRule::from` / `.into()`. #[derive(Clone, Debug, Deserialize, Serialize)] +#[non_exhaustive] pub struct ConditionalPushRule { /// Actions to determine if and how a notification is delivered for events matching this rule. pub actions: Vec, @@ -84,10 +122,45 @@ pub struct ConditionalPushRule { pub conditions: Vec, } +/// Initial set of fields of `ConditionalPushRule`. +/// +/// This struct will not be updated even if additional fields are added to `ConditionalPushRule` in +/// a new (non-breaking) release of the Matrix specification. +#[derive(Debug)] +pub struct ConditionalPushRuleInit { + /// Actions to determine if and how a notification is delivered for events matching this rule. + pub actions: Vec, + + /// 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, +} + +impl From for ConditionalPushRule { + fn from(init: ConditionalPushRuleInit) -> Self { + let ConditionalPushRuleInit { actions, default, enabled, rule_id, conditions } = init; + Self { actions, default, enabled, rule_id, conditions } + } +} + /// Like `PushRule`, but with an additional `pattern` field. /// /// Only applicable to content rules. +/// +/// To create an instance of this type, first create a `PatternedPushRuleInit` and convert it via +/// `PatternedPushRule::from` / `.into()`. #[derive(Clone, Debug, Deserialize, Serialize)] +#[non_exhaustive] pub struct PatternedPushRule { /// Actions to determine if and how a notification is delivered for events matching this rule. pub actions: Vec, @@ -104,3 +177,32 @@ pub struct PatternedPushRule { /// The glob-style pattern to match against. pub pattern: String, } + +/// Initial set of fields of `PatterenedPushRule`. +/// +/// This struct will not be updated even if additional fields are added to `PatterenedPushRule` in a new +/// (non-breaking) release of the Matrix specification. +#[derive(Debug)] +pub struct PatternedPushRuleInit { + /// Actions to determine if and how a notification is delivered for events matching this rule. + pub actions: Vec, + + /// 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, +} + +impl From for PatternedPushRule { + fn from(init: PatternedPushRuleInit) -> Self { + let PatternedPushRuleInit { actions, default, enabled, rule_id, pattern } = init; + Self { actions, default, enabled, rule_id, pattern } + } +} diff --git a/ruma-common/src/push/action.rs b/ruma-common/src/push/action.rs index 18d18450..39407a5f 100644 --- a/ruma-common/src/push/action.rs +++ b/ruma-common/src/push/action.rs @@ -26,6 +26,7 @@ pub enum Action { /// The `set_tweak` action. #[derive(Clone, Debug, Deserialize, Serialize)] +#[non_exhaustive] #[serde(from = "tweak_serde::Tweak", into = "tweak_serde::Tweak")] pub enum Tweak { /// A string representing the sound to be played when this notification arrives. diff --git a/ruma-common/src/push/any_push_rule.rs b/ruma-common/src/push/any_push_rule.rs index 68517d5b..6bc5b6de 100644 --- a/ruma-common/src/push/any_push_rule.rs +++ b/ruma-common/src/push/any_push_rule.rs @@ -6,11 +6,17 @@ use std::{ use serde::{Deserialize, Serialize}; -use super::{Action, ConditionalPushRule, PatternedPushRule, PushCondition, PushRule}; +use super::{ + Action, ConditionalPushRule, ConditionalPushRuleInit, PatternedPushRule, PatternedPushRuleInit, + PushCondition, PushRule, PushRuleInit, +}; /// Like `PushRule`, but may represent any kind of push rule /// thanks to `pattern` and `conditions` being optional. +/// +/// To create an instance of this type, use one of its `From` implementations. #[derive(Clone, Debug, Serialize, Deserialize)] +#[non_exhaustive] pub struct AnyPushRule { /// The actions to perform when this rule is matched. pub actions: Vec, @@ -55,6 +61,27 @@ impl From for AnyPushRule { } } +impl From for AnyPushRule { + fn from(init: PushRuleInit) -> Self { + let PushRuleInit { actions, default, enabled, rule_id } = init; + Self { actions, default, enabled, rule_id, pattern: None, conditions: None } + } +} + +impl From for AnyPushRule { + fn from(init: ConditionalPushRuleInit) -> Self { + let ConditionalPushRuleInit { actions, default, enabled, rule_id, conditions } = init; + Self { actions, default, enabled, rule_id, pattern: None, conditions: Some(conditions) } + } +} + +impl From for AnyPushRule { + fn from(init: PatternedPushRuleInit) -> Self { + let PatternedPushRuleInit { actions, default, enabled, rule_id, pattern } = init; + Self { actions, default, enabled, rule_id, pattern: Some(pattern), conditions: None } + } +} + impl From for PushRule { fn from(push_rule: AnyPushRule) -> Self { let AnyPushRule { actions, default, enabled, rule_id, .. } = push_rule; @@ -65,6 +92,7 @@ impl From for PushRule { /// An error that happens when `AnyPushRule` cannot /// be converted into `PatternedPushRule` #[derive(Debug)] +#[non_exhaustive] pub struct MissingPatternError; impl Display for MissingPatternError { @@ -92,6 +120,7 @@ impl TryFrom for PatternedPushRule { /// An error that happens when `AnyPushRule` cannot /// be converted into `ConditionalPushRule` #[derive(Debug)] +#[non_exhaustive] pub struct MissingConditionsError; impl Display for MissingConditionsError {