use serde::{de, Deserialize, Serialize, Serializer};
use serde_json::value::RawValue as RawJsonValue;
#[cfg(feature = "unstable-msc3931")]
use super::RoomVersionFeature;
use super::{PushCondition, RoomMemberCountIs, ScalarJsonValue};
use crate::serde::from_raw_json_value;
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"
| "event_property_is"
| "event_property_contains" => {
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 {
EventMatch {
key: String,
pattern: String,
},
ContainsDisplayName,
RoomMemberCount {
is: RoomMemberCountIs,
},
SenderNotificationPermission {
key: String,
},
#[cfg(feature = "unstable-msc3931")]
#[serde(rename = "org.matrix.msc3931.room_version_supports")]
RoomVersionSupports {
feature: RoomVersionFeature,
},
EventPropertyIs {
key: String,
value: ScalarJsonValue,
},
EventPropertyContains {
key: String,
value: ScalarJsonValue,
},
}
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 }
}
PushConditionSerDeHelper::EventPropertyIs { key, value } => {
Self::EventPropertyIs { key, value }
}
PushConditionSerDeHelper::EventPropertyContains { key, value } => {
Self::EventPropertyContains { key, value }
}
}
}
}
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::EventPropertyIs { key, value } => Self::EventPropertyIs { key, value },
PushCondition::EventPropertyContains { key, value } => {
Self::EventPropertyContains { key, value }
}
PushCondition::_Custom(_) => unimplemented!(),
}
}
}