diff --git a/crates/ruma-client-api/CHANGELOG.md b/crates/ruma-client-api/CHANGELOG.md index 11513f08..e51c341d 100644 --- a/crates/ruma-client-api/CHANGELOG.md +++ b/crates/ruma-client-api/CHANGELOG.md @@ -10,6 +10,8 @@ Improvements: the `RUMA_UNSTABLE_EXHAUSTIVE_TYPES` environment variable. - Add `ErrorKind::ThreepidMediumNotSupported`, according to MSC4178. - Add `ErrorKind::UserSuspended`, according to MSC3823. +- `EmailPusherData` allows to set custom data for the pusher in the `data` field, due + to a clarification in the spec. # 0.19.0 diff --git a/crates/ruma-client-api/src/push.rs b/crates/ruma-client-api/src/push.rs index 32966a6c..6542cdc9 100644 --- a/crates/ruma-client-api/src/push.rs +++ b/crates/ruma-client-api/src/push.rs @@ -286,9 +286,13 @@ impl PusherIds { } /// Information for an email pusher. -#[derive(Clone, Debug, Default)] +#[derive(Clone, Debug, Default, Serialize, Deserialize)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -pub struct EmailPusherData; +#[serde(transparent, default)] +pub struct EmailPusherData { + /// Custom data for the pusher. + pub data: JsonObject, +} impl EmailPusherData { /// Creates a new empty `EmailPusherData`. diff --git a/crates/ruma-client-api/src/push/pusher_serde.rs b/crates/ruma-client-api/src/push/pusher_serde.rs index 7682f511..5b49d159 100644 --- a/crates/ruma-client-api/src/push/pusher_serde.rs +++ b/crates/ruma-client-api/src/push/pusher_serde.rs @@ -1,8 +1,8 @@ -use ruma_common::serde::{from_raw_json_value, JsonObject}; +use ruma_common::serde::from_raw_json_value; use serde::{de, ser::SerializeStruct, Deserialize, Serialize}; use serde_json::value::RawValue as RawJsonValue; -use super::{EmailPusherData, Pusher, PusherIds, PusherKind}; +use super::{Pusher, PusherIds, PusherKind}; #[derive(Debug, Deserialize)] struct PusherDeHelper { @@ -41,9 +41,9 @@ impl Serialize for PusherKind { st.serialize_field("kind", &"http")?; st.serialize_field("data", data)?; } - PusherKind::Email(_) => { + PusherKind::Email(data) => { st.serialize_field("kind", &"email")?; - st.serialize_field("data", &JsonObject::new())?; + st.serialize_field("data", data)?; } PusherKind::_Custom(custom) => { st.serialize_field("kind", &custom.kind)?; @@ -71,7 +71,7 @@ impl<'de> Deserialize<'de> for PusherKind { match kind.as_ref() { "http" => from_raw_json_value(&data).map(Self::Http), - "email" => Ok(Self::Email(EmailPusherData)), + "email" => from_raw_json_value(&data).map(Self::Email), _ => from_raw_json_value(&json).map(Self::_Custom), } } @@ -81,13 +81,17 @@ impl<'de> Deserialize<'de> for PusherKind { mod tests { use assert_matches2::assert_matches; use ruma_common::{push::HttpPusherData, serde::JsonObject}; - 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, to_value as to_json_value, Value as JsonValue, + }; use crate::push::{CustomPusherData, EmailPusherData, PusherKind}; #[test] fn serialize_email() { - let action = PusherKind::Email(EmailPusherData::new()); + // With default data fields. + let mut data = EmailPusherData::new(); + let action = PusherKind::Email(data.clone()); assert_eq!( to_json_value(action).unwrap(), @@ -96,11 +100,27 @@ mod tests { "data": {}, }) ); + + // With custom data fields. + data.data.insert("custom_key".to_owned(), "value".into()); + let action = PusherKind::Email(data); + + assert_eq!( + to_json_value(action).unwrap(), + json!({ + "kind": "email", + "data": { + "custom_key": "value", + }, + }) + ); } #[test] fn serialize_http() { - let action = PusherKind::Http(HttpPusherData::new("http://localhost".to_owned())); + // With default data fields. + let mut data = HttpPusherData::new("http://localhost".to_owned()); + let action = PusherKind::Http(data.clone()); assert_eq!( to_json_value(action).unwrap(), @@ -111,6 +131,21 @@ mod tests { }, }) ); + + // With custom data fields. + data.data.insert("custom_key".to_owned(), "value".into()); + let action = PusherKind::Http(data); + + assert_eq!( + to_json_value(action).unwrap(), + json!({ + "kind": "http", + "data": { + "url": "http://localhost", + "custom_key": "value", + }, + }) + ); } #[test] @@ -131,16 +166,32 @@ mod tests { #[test] fn deserialize_email() { + // With default data fields. let json = json!({ "kind": "email", "data": {}, }); - assert_matches!(from_json_value(json).unwrap(), PusherKind::Email(_)); + assert_matches!(from_json_value(json).unwrap(), PusherKind::Email(data)); + assert!(data.data.is_empty()); + + // With custom data fields. + let json = json!({ + "kind": "email", + "data": { + "custom_key": "value", + }, + }); + + assert_matches!(from_json_value(json).unwrap(), PusherKind::Email(data)); + assert_eq!(data.data.len(), 1); + assert_matches!(data.data.get("custom_key"), Some(JsonValue::String(custom_value))); + assert_eq!(custom_value, "value"); } #[test] fn deserialize_http() { + // With default data fields. let json = json!({ "kind": "http", "data": { @@ -151,6 +202,21 @@ mod tests { assert_matches!(from_json_value(json).unwrap(), PusherKind::Http(data)); assert_eq!(data.url, "http://localhost"); assert_eq!(data.format, None); + assert!(data.data.is_empty()); + + // With custom data fields. + let json = json!({ + "kind": "http", + "data": { + "url": "http://localhost", + "custom_key": "value", + }, + }); + + assert_matches!(from_json_value(json).unwrap(), PusherKind::Http(data)); + assert_eq!(data.data.len(), 1); + assert_matches!(data.data.get("custom_key"), Some(JsonValue::String(custom_value))); + assert_eq!(custom_value, "value"); } #[test] diff --git a/crates/ruma-common/CHANGELOG.md b/crates/ruma-common/CHANGELOG.md index 6ce6f663..23664d58 100644 --- a/crates/ruma-common/CHANGELOG.md +++ b/crates/ruma-common/CHANGELOG.md @@ -11,6 +11,15 @@ Improvements: configured by setting the `RUMA_IDENTIFIERS_STORAGE` environment variable at compile time. It has the benefit of not requiring to re-compile all the crates of the dependency chain when the value is changed. +- The `unstable-exhaustive-types` cargo feature was replaced by the + `ruma_unstable_exhaustive_types` compile-time `cfg` setting. Like all `cfg` + settings, it can be enabled at compile-time with the `RUSTFLAGS` environment + variable, or inside `.cargo/config.toml`. It can also be enabled by setting + the `RUMA_UNSTABLE_EXHAUSTIVE_TYPES` environment variable. +- `HttpPusherData` allows to set custom data for the pusher in the `data` field, + due to a clarification in the spec. + - The `default_payload` field that was behind the `unstable-unspecified` was + removed. It can be added manually to the custom data. # 0.14.1 diff --git a/crates/ruma-common/src/push.rs b/crates/ruma-common/src/push.rs index 47a778c5..6ded08f8 100644 --- a/crates/ruma-common/src/push.rs +++ b/crates/ruma-common/src/push.rs @@ -18,13 +18,11 @@ use std::hash::{Hash, Hasher}; use indexmap::{Equivalent, IndexSet}; use serde::{Deserialize, Serialize}; -#[cfg(feature = "unstable-unspecified")] -use serde_json::Value as JsonValue; use thiserror::Error; use tracing::instrument; use crate::{ - serde::{Raw, StringEnum}, + serde::{JsonObject, Raw, StringEnum}, OwnedRoomId, OwnedUserId, PrivOwnedStr, }; @@ -702,27 +700,15 @@ pub struct HttpPusherData { #[serde(skip_serializing_if = "Option::is_none")] pub format: Option, - /// iOS (+ macOS?) specific default payload that will be sent to apple push notification - /// service. - /// - /// For more information, see [Sygnal docs][sygnal]. - /// - /// [sygnal]: https://github.com/matrix-org/sygnal/blob/main/docs/applications.md#ios-applications-beware - // Not specified, issue: https://github.com/matrix-org/matrix-spec/issues/921 - #[cfg(feature = "unstable-unspecified")] - #[serde(default, skip_serializing_if = "JsonValue::is_null")] - pub default_payload: JsonValue, + /// Custom data for the pusher. + #[serde(flatten, default, skip_serializing_if = "JsonObject::is_empty")] + pub data: JsonObject, } impl HttpPusherData { /// Creates a new `HttpPusherData` with the given URL. pub fn new(url: String) -> Self { - Self { - url, - format: None, - #[cfg(feature = "unstable-unspecified")] - default_payload: JsonValue::default(), - } + Self { url, format: None, data: JsonObject::default() } } } diff --git a/crates/ruma-push-gateway-api/CHANGELOG.md b/crates/ruma-push-gateway-api/CHANGELOG.md index c79cf64b..66fa6c36 100644 --- a/crates/ruma-push-gateway-api/CHANGELOG.md +++ b/crates/ruma-push-gateway-api/CHANGELOG.md @@ -1,5 +1,21 @@ # [unreleased] +Improvements: + +- The `unstable-exhaustive-types` cargo feature was replaced by the + `ruma_unstable_exhaustive_types` compile-time `cfg` setting. Like all `cfg` + settings, it can be enabled at compile-time with the `RUSTFLAGS` environment + variable, or inside `.cargo/config.toml`. It can also be enabled by setting + the `RUMA_UNSTABLE_EXHAUSTIVE_TYPES` environment variable. +- `PusherData` allows to set custom data for the pusher in the `data` field, due + to a clarification in the spec. + - The `default_payload` field that was behind the `unstable-unspecified` was + removed. It can be added manually to the custom data. + +# 0.10.0 + +Upgrade `ruma-events` to 0.29.0. + # 0.9.0 Breaking changes: diff --git a/crates/ruma-push-gateway-api/src/send_event_notification.rs b/crates/ruma-push-gateway-api/src/send_event_notification.rs index b349447b..b85a5f36 100644 --- a/crates/ruma-push-gateway-api/src/send_event_notification.rs +++ b/crates/ruma-push-gateway-api/src/send_event_notification.rs @@ -12,14 +12,12 @@ pub mod v1 { api::{request, response, Metadata}, metadata, push::{PushFormat, Tweak}, - serde::StringEnum, + serde::{JsonObject, StringEnum}, OwnedEventId, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, SecondsSinceUnixEpoch, }; use ruma_events::TimelineEventType; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue as RawJsonValue; - #[cfg(feature = "unstable-unspecified")] - use serde_json::value::Value as JsonValue; use crate::PrivOwnedStr; @@ -246,16 +244,9 @@ pub mod v1 { #[serde(skip_serializing_if = "Option::is_none")] pub format: Option, - /// iOS (+ macOS?) specific default payload that will be sent to apple push notification - /// service. - /// - /// For more information, see [Sygnal docs][sygnal]. - /// - /// [sygnal]: https://github.com/matrix-org/sygnal/blob/main/docs/applications.md#ios-applications-beware - // Not specified, issue: https://github.com/matrix-org/matrix-spec/issues/921 - #[cfg(feature = "unstable-unspecified")] - #[serde(default, skip_serializing_if = "JsonValue::is_null")] - pub default_payload: JsonValue, + /// Custom data for the pusher. + #[serde(flatten, default, skip_serializing_if = "JsonObject::is_empty")] + pub data: JsonObject, } impl PusherData { @@ -264,34 +255,17 @@ pub mod v1 { Default::default() } - /// Returns `true` if all fields are `None`. + /// Returns `true` if all fields are `None` or empty. pub fn is_empty(&self) -> bool { - #[cfg(not(feature = "unstable-unspecified"))] - { - self.format.is_none() - } - - #[cfg(feature = "unstable-unspecified")] - { - self.format.is_none() && self.default_payload.is_null() - } + self.format.is_none() && self.data.is_empty() } } impl From for PusherData { fn from(data: ruma_common::push::HttpPusherData) -> Self { - let ruma_common::push::HttpPusherData { - format, - #[cfg(feature = "unstable-unspecified")] - default_payload, - .. - } = data; + let ruma_common::push::HttpPusherData { format, data, .. } = data; - Self { - format, - #[cfg(feature = "unstable-unspecified")] - default_payload, - } + Self { format, data } } } diff --git a/crates/ruma/Cargo.toml b/crates/ruma/Cargo.toml index d3e03694..79302707 100644 --- a/crates/ruma/Cargo.toml +++ b/crates/ruma/Cargo.toml @@ -277,7 +277,6 @@ unstable-pdu = ["ruma-events?/unstable-pdu"] unstable-unspecified = [ "ruma-common/unstable-unspecified", "ruma-federation-api?/unstable-unspecified", - "ruma-push-gateway-api?/unstable-unspecified", ] # Private features, only used in test / benchmarking code