push: Allow to deserialize PushCondition with unknown kind
This commit is contained in:
		
							parent
							
								
									9460702b00
								
							
						
					
					
						commit
						97fd0c3419
					
				| @ -9,6 +9,7 @@ Bug fixes: | |||||||
| * Fix deserialization of `RoomMessageEventContent` and `RoomEncryptedEventContent` when there | * Fix deserialization of `RoomMessageEventContent` and `RoomEncryptedEventContent` when there | ||||||
|   is no relation |   is no relation | ||||||
| * Fix deserialization of `StateUnsigned` when the `prev_content` is redacted | * Fix deserialization of `StateUnsigned` when the `prev_content` is redacted | ||||||
|  | * Allow to deserialize `PushCondition` with unknown kind | ||||||
| 
 | 
 | ||||||
| Breaking changes: | Breaking changes: | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -39,6 +39,7 @@ pub use self::{ | |||||||
|     action::{Action, Tweak}, |     action::{Action, Tweak}, | ||||||
|     condition::{ |     condition::{ | ||||||
|         ComparisonOperator, FlattenedJson, PushCondition, PushConditionRoomCtx, RoomMemberCountIs, |         ComparisonOperator, FlattenedJson, PushCondition, PushConditionRoomCtx, RoomMemberCountIs, | ||||||
|  |         _CustomPushCondition, | ||||||
|     }, |     }, | ||||||
|     iter::{AnyPushRule, AnyPushRuleRef, RulesetIntoIter, RulesetIter}, |     iter::{AnyPushRule, AnyPushRuleRef, RulesetIntoIter, RulesetIter}, | ||||||
|     predefined::{ |     predefined::{ | ||||||
|  | |||||||
| @ -13,6 +13,7 @@ use crate::{power_levels::NotificationPowerLevels, serde::Raw, OwnedRoomId, Owne | |||||||
| #[cfg(feature = "unstable-msc3931")] | #[cfg(feature = "unstable-msc3931")] | ||||||
| use crate::{PrivOwnedStr, RoomVersionId}; | use crate::{PrivOwnedStr, RoomVersionId}; | ||||||
| 
 | 
 | ||||||
|  | mod push_condition_serde; | ||||||
| mod room_member_count_is; | mod room_member_count_is; | ||||||
| 
 | 
 | ||||||
| pub use room_member_count_is::{ComparisonOperator, RoomMemberCountIs}; | pub use room_member_count_is::{ComparisonOperator, RoomMemberCountIs}; | ||||||
| @ -57,9 +58,8 @@ impl RoomVersionFeature { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /// A condition that must apply for an associated push rule's action to be taken.
 | /// A condition that must apply for an associated push rule's action to be taken.
 | ||||||
| #[derive(Clone, Debug, Deserialize, Serialize)] | #[derive(Clone, Debug)] | ||||||
| #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||||
| #[serde(tag = "kind", rename_all = "snake_case")] |  | ||||||
| pub enum PushCondition { | pub enum PushCondition { | ||||||
|     /// A glob pattern match on a field of the event.
 |     /// A glob pattern match on a field of the event.
 | ||||||
|     EventMatch { |     EventMatch { | ||||||
| @ -95,11 +95,13 @@ pub enum PushCondition { | |||||||
| 
 | 
 | ||||||
|     /// Apply the rule only to rooms that support a given feature.
 |     /// Apply the rule only to rooms that support a given feature.
 | ||||||
|     #[cfg(feature = "unstable-msc3931")] |     #[cfg(feature = "unstable-msc3931")] | ||||||
|     #[serde(rename = "org.matrix.msc3931.room_version_supports")] |  | ||||||
|     RoomVersionSupports { |     RoomVersionSupports { | ||||||
|         /// The feature the room must support for the push rule to apply.
 |         /// The feature the room must support for the push rule to apply.
 | ||||||
|         feature: RoomVersionFeature, |         feature: RoomVersionFeature, | ||||||
|     }, |     }, | ||||||
|  | 
 | ||||||
|  |     #[doc(hidden)] | ||||||
|  |     _Custom(_CustomPushCondition), | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| pub(super) fn check_event_match( | pub(super) fn check_event_match( | ||||||
| @ -168,10 +170,24 @@ impl PushCondition { | |||||||
|                 } |                 } | ||||||
|                 RoomVersionFeature::_Custom(_) => false, |                 RoomVersionFeature::_Custom(_) => false, | ||||||
|             }, |             }, | ||||||
|  |             Self::_Custom(_) => false, | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | /// An unknown push condition.
 | ||||||
|  | #[doc(hidden)] | ||||||
|  | #[derive(Clone, Debug, Deserialize, Serialize)] | ||||||
|  | #[allow(clippy::exhaustive_structs)] | ||||||
|  | pub struct _CustomPushCondition { | ||||||
|  |     /// The kind of the condition.
 | ||||||
|  |     kind: String, | ||||||
|  | 
 | ||||||
|  |     /// The additional fields that the condition contains.
 | ||||||
|  |     #[serde(flatten)] | ||||||
|  |     data: BTreeMap<String, JsonValue>, | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /// The context of the room associated to an event to be able to test all push conditions.
 | /// The context of the room associated to an event to be able to test all push conditions.
 | ||||||
| #[derive(Clone, Debug)] | #[derive(Clone, Debug)] | ||||||
| #[allow(clippy::exhaustive_structs)] | #[allow(clippy::exhaustive_structs)] | ||||||
|  | |||||||
							
								
								
									
										131
									
								
								crates/ruma-common/src/push/condition/push_condition_serde.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										131
									
								
								crates/ruma-common/src/push/condition/push_condition_serde.rs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,131 @@ | |||||||
|  | use serde::{de, Deserialize, Serialize, Serializer}; | ||||||
|  | use serde_json::value::RawValue as RawJsonValue; | ||||||
|  | 
 | ||||||
|  | use crate::serde::from_raw_json_value; | ||||||
|  | 
 | ||||||
|  | #[cfg(feature = "unstable-msc3931")] | ||||||
|  | use super::RoomVersionFeature; | ||||||
|  | use super::{PushCondition, RoomMemberCountIs}; | ||||||
|  | 
 | ||||||
|  | impl Serialize for PushCondition { | ||||||
|  |     fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> | ||||||
|  |     where | ||||||
|  |         S: Serializer, | ||||||
|  |     { | ||||||
|  |         match self { | ||||||
|  |             PushCondition::_Custom(custom) => custom.serialize(serializer), | ||||||
|  |             _ => PushConditionSerDeHelper::from(self.clone()).serialize(serializer), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<'de> Deserialize<'de> for PushCondition { | ||||||
|  |     fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> | ||||||
|  |     where | ||||||
|  |         D: de::Deserializer<'de>, | ||||||
|  |     { | ||||||
|  |         let json = Box::<RawJsonValue>::deserialize(deserializer)?; | ||||||
|  |         let ExtractKind { kind } = from_raw_json_value(&json)?; | ||||||
|  | 
 | ||||||
|  |         match kind.as_ref() { | ||||||
|  |             "event_match" | ||||||
|  |             | "contains_display_name" | ||||||
|  |             | "room_member_count" | ||||||
|  |             | "sender_notification_permission" => { | ||||||
|  |                 let helper: PushConditionSerDeHelper = from_raw_json_value(&json)?; | ||||||
|  |                 Ok(helper.into()) | ||||||
|  |             } | ||||||
|  |             #[cfg(feature = "unstable-msc3931")] | ||||||
|  |             "org.matrix.msc3931.room_version_supports" => { | ||||||
|  |                 let helper: PushConditionSerDeHelper = from_raw_json_value(&json)?; | ||||||
|  |                 Ok(helper.into()) | ||||||
|  |             } | ||||||
|  |             _ => from_raw_json_value(&json).map(Self::_Custom), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Deserialize)] | ||||||
|  | struct ExtractKind { | ||||||
|  |     kind: String, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | #[derive(Serialize, Deserialize)] | ||||||
|  | #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] | ||||||
|  | #[serde(tag = "kind", rename_all = "snake_case")] | ||||||
|  | enum PushConditionSerDeHelper { | ||||||
|  |     /// 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, | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /// Matches unencrypted messages where `content.body` contains the owner's display name in that
 | ||||||
|  |     /// room.
 | ||||||
|  |     ContainsDisplayName, | ||||||
|  | 
 | ||||||
|  |     /// Matches the current number of members in the room.
 | ||||||
|  |     RoomMemberCount { | ||||||
|  |         /// The condition on the current number of members in the room.
 | ||||||
|  |         is: RoomMemberCountIs, | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /// 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, | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     /// Apply the rule only to rooms that support a given feature.
 | ||||||
|  |     #[cfg(feature = "unstable-msc3931")] | ||||||
|  |     #[serde(rename = "org.matrix.msc3931.room_version_supports")] | ||||||
|  |     RoomVersionSupports { | ||||||
|  |         /// The feature the room must support for the push rule to apply.
 | ||||||
|  |         feature: RoomVersionFeature, | ||||||
|  |     }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<PushConditionSerDeHelper> for PushCondition { | ||||||
|  |     fn from(value: PushConditionSerDeHelper) -> Self { | ||||||
|  |         match value { | ||||||
|  |             PushConditionSerDeHelper::EventMatch { key, pattern } => { | ||||||
|  |                 Self::EventMatch { key, pattern } | ||||||
|  |             } | ||||||
|  |             PushConditionSerDeHelper::ContainsDisplayName => Self::ContainsDisplayName, | ||||||
|  |             PushConditionSerDeHelper::RoomMemberCount { is } => Self::RoomMemberCount { is }, | ||||||
|  |             PushConditionSerDeHelper::SenderNotificationPermission { key } => { | ||||||
|  |                 Self::SenderNotificationPermission { key } | ||||||
|  |             } | ||||||
|  |             #[cfg(feature = "unstable-msc3931")] | ||||||
|  |             PushConditionSerDeHelper::RoomVersionSupports { feature } => { | ||||||
|  |                 Self::RoomVersionSupports { feature } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl From<PushCondition> for PushConditionSerDeHelper { | ||||||
|  |     fn from(value: PushCondition) -> Self { | ||||||
|  |         match value { | ||||||
|  |             PushCondition::EventMatch { key, pattern } => Self::EventMatch { key, pattern }, | ||||||
|  |             PushCondition::ContainsDisplayName => Self::ContainsDisplayName, | ||||||
|  |             PushCondition::RoomMemberCount { is } => Self::RoomMemberCount { is }, | ||||||
|  |             PushCondition::SenderNotificationPermission { key } => { | ||||||
|  |                 Self::SenderNotificationPermission { key } | ||||||
|  |             } | ||||||
|  |             #[cfg(feature = "unstable-msc3931")] | ||||||
|  |             PushCondition::RoomVersionSupports { feature } => Self::RoomVersionSupports { feature }, | ||||||
|  |             PushCondition::_Custom(_) => unimplemented!(), | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user