diff --git a/ruma-events-macros/src/gen.rs b/ruma-events-macros/src/gen.rs index fe1b6ac9..9a5c587f 100644 --- a/ruma-events-macros/src/gen.rs +++ b/ruma-events-macros/src/gen.rs @@ -154,8 +154,8 @@ impl ToTokens for RumaEvent { } /// Additional key-value pairs not signed by the homeserver. - fn unsigned(&self) -> Option<&serde_json::Value> { - self.unsigned.as_ref() + fn unsigned(&self) -> &serde_json::Map { + &self.unsigned } } } @@ -296,8 +296,8 @@ fn populate_room_event_fields(content_name: Ident, fields: Vec) -> Vec, + #[serde(default, skip_serializing_if = "serde_json::Map::is_empty")] + pub unsigned: serde_json::Map, }; fields.extend(punctuated_fields.into_iter().map(|p| p.field)); diff --git a/src/lib.rs b/src/lib.rs index 9a4b6e5a..1219f392 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -126,7 +126,7 @@ use serde::{ ser::SerializeMap, Deserialize, Deserializer, Serialize, Serializer, }; -use serde_json::Value; +use serde_json::{Map, Value}; pub use self::{custom::CustomEvent, custom_room::CustomRoomEvent, custom_state::CustomStateEvent}; @@ -394,7 +394,7 @@ pub trait RoomEvent: Event { fn sender(&self) -> &UserId; /// Additional key-value pairs not signed by the homeserver. - fn unsigned(&self) -> Option<&Value>; + fn unsigned(&self) -> &Map; } /// An event that describes persistent state about a room. @@ -461,7 +461,7 @@ mod custom_room { use ruma_events_macros::FromRaw; use serde::{Deserialize, Serialize}; - use serde_json::Value; + use serde_json::{Map, Value}; /// A custom room event not covered by the Matrix specification. #[derive(Clone, Debug, FromRaw, PartialEq, Serialize)] @@ -481,7 +481,8 @@ mod custom_room { /// The unique identifier for the user who sent this event. pub sender: ruma_identifiers::UserId, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(skip_serializing_if = "serde_json::Map::is_empty")] + pub unsigned: Map, } /// The payload for `CustomRoomEvent`. @@ -522,8 +523,8 @@ mod custom_room { &self.sender } /// Additional key-value pairs not signed by the homeserver. - fn unsigned(&self) -> Option<&serde_json::Value> { - self.unsigned.as_ref() + fn unsigned(&self) -> &Map { + &self.unsigned } } @@ -548,7 +549,8 @@ mod custom_room { /// The unique identifier for the user who sent this event. pub sender: ruma_identifiers::UserId, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, } } } @@ -558,7 +560,7 @@ mod custom_state { use ruma_events_macros::FromRaw; use serde::{Deserialize, Serialize}; - use serde_json::Value; + use serde_json::{Map, Value}; /// A custom state event not covered by the Matrix specification. #[derive(Clone, Debug, FromRaw, PartialEq, Serialize)] @@ -582,7 +584,8 @@ mod custom_state { /// A key that determines which piece of room state the event represents. pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(skip_serializing_if = "serde_json::Map::is_empty")] + pub unsigned: Map, } /// The payload for `CustomStateEvent`. @@ -623,8 +626,8 @@ mod custom_state { &self.sender } /// Additional key-value pairs not signed by the homeserver. - fn unsigned(&self) -> Option<&serde_json::Value> { - self.unsigned.as_ref() + fn unsigned(&self) -> &Map { + &self.unsigned } } @@ -664,7 +667,8 @@ mod custom_state { /// A key that determines which piece of room state the event represents. pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, } } } diff --git a/src/macros.rs b/src/macros.rs index 91838a4a..b2bb7bbb 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -73,8 +73,8 @@ macro_rules! impl_room_event { } /// Additional key-value pairs not signed by the homeserver. - fn unsigned(&self) -> Option<&Value> { - self.unsigned.as_ref() + fn unsigned(&self) -> &serde_json::Map { + &self.unsigned } } }; diff --git a/src/room/canonical_alias.rs b/src/room/canonical_alias.rs index 42208cc1..66580066 100644 --- a/src/room/canonical_alias.rs +++ b/src/room/canonical_alias.rs @@ -3,7 +3,7 @@ use js_int::UInt; use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; -use serde_json::Value; +use serde_json::{Map, Value}; use crate::{util::empty_string_as_none, Event, EventType, FromRaw}; @@ -33,7 +33,7 @@ pub struct CanonicalAliasEvent { pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + pub unsigned: Map, } /// The payload for `CanonicalAliasEvent`. @@ -85,7 +85,7 @@ impl Serialize for CanonicalAliasEvent { len += 1; } - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { len += 1; } @@ -107,7 +107,7 @@ impl Serialize for CanonicalAliasEvent { state.serialize_field("state_key", &self.state_key)?; state.serialize_field("type", &self.event_type())?; - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { state.serialize_field("unsigned", &self.unsigned)?; } @@ -150,7 +150,8 @@ pub(crate) mod raw { pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, } /// The payload of a `CanonicalAliasEvent`. @@ -173,6 +174,7 @@ mod tests { use js_int::UInt; use ruma_identifiers::{EventId, RoomAliasId, UserId}; + use serde_json::Map; use super::{CanonicalAliasEvent, CanonicalAliasEventContent}; use crate::EventResult; @@ -189,7 +191,7 @@ mod tests { room_id: None, sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "".to_string(), - unsigned: None, + unsigned: Map::new(), }; let actual = serde_json::to_string(&canonical_alias_event).unwrap(); diff --git a/src/room/encrypted.rs b/src/room/encrypted.rs index e6eb7e9e..912e59a2 100644 --- a/src/room/encrypted.rs +++ b/src/room/encrypted.rs @@ -4,7 +4,7 @@ use std::collections::HashMap; use js_int::UInt; use ruma_identifiers::{DeviceId, EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; -use serde_json::{from_value, Value}; +use serde_json::{from_value, Map, Value}; use crate::{Algorithm, Event, EventType, FromRaw}; @@ -31,7 +31,7 @@ pub struct EncryptedEvent { pub sender: UserId, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + pub unsigned: Map, } /// The payload for `EncryptedEvent`. @@ -93,7 +93,7 @@ impl Serialize for EncryptedEvent { len += 1; } - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { len += 1; } @@ -110,7 +110,7 @@ impl Serialize for EncryptedEvent { state.serialize_field("sender", &self.sender)?; state.serialize_field("type", &self.event_type())?; - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { state.serialize_field("unsigned", &self.unsigned)?; } @@ -165,7 +165,8 @@ pub(crate) mod raw { pub sender: UserId, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, } /// The payload for `EncryptedEvent`. diff --git a/src/room/member.rs b/src/room/member.rs index 00bd5a21..e88f309e 100644 --- a/src/room/member.rs +++ b/src/room/member.rs @@ -225,7 +225,7 @@ mod tests { use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; - use serde_json::json; + use serde_json::{json, Map}; use super::*; use crate::util::serde_json_eq_try_from_raw; @@ -245,7 +245,7 @@ mod tests { room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "example.com".to_string(), - unsigned: None, + unsigned: Map::new(), prev_content: None, }; let json = json!({ @@ -277,7 +277,7 @@ mod tests { room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "example.com".to_string(), - unsigned: None, + unsigned: Map::new(), prev_content: Some(MemberEventContent { avatar_url: None, displayname: None, @@ -333,7 +333,7 @@ mod tests { room_id: Some(RoomId::try_from("!jEsUZKDJdhlrceRyVU:example.org").unwrap()), sender: UserId::try_from("@alice:example.org").unwrap(), state_key: "@alice:example.org".to_string(), - unsigned: None, + unsigned: Map::new(), prev_content: None, }; let json = json!({ @@ -388,7 +388,7 @@ mod tests { room_id: Some(RoomId::try_from("!jEsUZKDJdhlrceRyVU:example.org").unwrap()), sender: UserId::try_from("@alice:example.org").unwrap(), state_key: "@alice:example.org".to_string(), - unsigned: None, + unsigned: Map::new(), prev_content: Some(MemberEventContent { avatar_url: Some("mxc://example.org/SEsfnsuifSDFSSEF".to_owned()), displayname: Some("Alice Margatroid".to_owned()), diff --git a/src/room/message.rs b/src/room/message.rs index 57fe736c..da81de4c 100644 --- a/src/room/message.rs +++ b/src/room/message.rs @@ -3,7 +3,7 @@ use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Deserializer, Serialize, Serializer}; -use serde_json::{from_value, Value}; +use serde_json::{from_value, Map, Value}; use super::{EncryptedFile, ImageInfo, ThumbnailInfo}; use crate::{Event, EventType, FromRaw}; @@ -30,7 +30,7 @@ pub struct MessageEvent { pub sender: UserId, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + pub unsigned: Map, } /// The payload for `MessageEvent`. @@ -119,7 +119,7 @@ impl Serialize for MessageEvent { len += 1; } - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { len += 1; } @@ -136,7 +136,7 @@ impl Serialize for MessageEvent { state.serialize_field("sender", &self.sender)?; state.serialize_field("type", &self.event_type())?; - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { state.serialize_field("unsigned", &self.unsigned)?; } @@ -193,7 +193,8 @@ pub(crate) mod raw { pub sender: UserId, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, } /// The payload for `MessageEvent`. diff --git a/src/room/name.rs b/src/room/name.rs index ee652523..42480455 100644 --- a/src/room/name.rs +++ b/src/room/name.rs @@ -3,7 +3,7 @@ use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; -use serde_json::Value; +use serde_json::{Map, Value}; use crate::{util::empty_string_as_none, Event as _, EventType, InvalidInput, TryFromRaw}; @@ -33,7 +33,7 @@ pub struct NameEvent { pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + pub unsigned: Map, } /// The payload for `NameEvent`. @@ -92,7 +92,7 @@ impl Serialize for NameEvent { len += 1; } - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { len += 1; } @@ -114,7 +114,7 @@ impl Serialize for NameEvent { state.serialize_field("state_key", &self.state_key)?; state.serialize_field("type", &self.event_type())?; - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { state.serialize_field("unsigned", &self.unsigned)?; } @@ -175,7 +175,8 @@ pub(crate) mod raw { pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, } /// The payload of a `NameEvent`. @@ -196,7 +197,7 @@ mod tests { use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; - use serde_json::Value; + use serde_json::Map; use crate::EventResult; @@ -214,7 +215,7 @@ mod tests { room_id: None, sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "".to_string(), - unsigned: None, + unsigned: Map::new(), }; let actual = serde_json::to_string(&name_event).unwrap(); @@ -237,7 +238,7 @@ mod tests { room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "".to_string(), - unsigned: Some(serde_json::from_str::(r#"{"foo":"bar"}"#).unwrap()), + unsigned: serde_json::from_str(r#"{"foo":"bar"}"#).unwrap(), }; let actual = serde_json::to_string(&name_event).unwrap(); diff --git a/src/room/pinned_events.rs b/src/room/pinned_events.rs index 0812e133..8bb84d5e 100644 --- a/src/room/pinned_events.rs +++ b/src/room/pinned_events.rs @@ -21,7 +21,7 @@ mod tests { use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; - use serde_json::to_string; + use serde_json::{to_string, Map}; use crate::{ room::pinned_events::{PinnedEventsEvent, PinnedEventsEventContent}, @@ -43,7 +43,7 @@ mod tests { room_id: Some(RoomId::new("example.com").unwrap()), sender: UserId::new("example.com").unwrap(), state_key: "".to_string(), - unsigned: None, + unsigned: Map::new(), }; let serialized_event = to_string(&event).unwrap(); diff --git a/src/room/power_levels.rs b/src/room/power_levels.rs index 1497b386..aad4bd46 100644 --- a/src/room/power_levels.rs +++ b/src/room/power_levels.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; use js_int::{Int, UInt}; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; -use serde_json::Value; +use serde_json::{Map, Value}; use crate::{Event as _, EventType, FromRaw}; @@ -29,7 +29,7 @@ pub struct PowerLevelsEvent { pub room_id: Option, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + pub unsigned: Map, /// The unique identifier for the user who sent this event. pub sender: UserId, @@ -139,7 +139,7 @@ impl Serialize for PowerLevelsEvent { len += 1; } - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { len += 1; } @@ -161,7 +161,7 @@ impl Serialize for PowerLevelsEvent { state.serialize_field("state_key", &self.state_key)?; state.serialize_field("type", &self.event_type())?; - if self.unsigned.is_some() { + if !self.unsigned.is_empty() { state.serialize_field("unsigned", &self.unsigned)?; } @@ -198,7 +198,8 @@ pub(crate) mod raw { pub room_id: Option, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, /// The unique identifier for the user who sent this event. pub sender: UserId, @@ -307,7 +308,7 @@ mod tests { use js_int::{Int, UInt}; use maplit::hashmap; use ruma_identifiers::{EventId, RoomId, UserId}; - use serde_json::Value; + use serde_json::Map; use super::{ default_power_level, NotificationPowerLevels, PowerLevelsEvent, PowerLevelsEventContent, @@ -335,7 +336,7 @@ mod tests { origin_server_ts: UInt::from(1u32), prev_content: None, room_id: None, - unsigned: None, + unsigned: Map::new(), sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "".to_string(), }; @@ -390,7 +391,7 @@ mod tests { }, }), room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), - unsigned: Some(serde_json::from_str::(r#"{"foo":"bar"}"#).unwrap()), + unsigned: serde_json::from_str(r#"{"foo":"bar"}"#).unwrap(), sender: user, state_key: "".to_string(), }; diff --git a/src/room/server_acl.rs b/src/room/server_acl.rs index 5a1a054a..c0e63ed7 100644 --- a/src/room/server_acl.rs +++ b/src/room/server_acl.rs @@ -3,7 +3,7 @@ use js_int::UInt; use ruma_identifiers::{EventId, RoomId, UserId}; use serde::{ser::SerializeStruct, Deserialize, Serialize, Serializer}; -use serde_json::Value; +use serde_json::{Map, Value}; use crate::{util::default_true, Event as _, EventType, FromRaw}; @@ -33,7 +33,7 @@ pub struct ServerAclEvent { pub state_key: String, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + pub unsigned: Map, } /// The payload for `ServerAclEvent`. @@ -137,7 +137,8 @@ pub(crate) mod raw { pub room_id: Option, /// Additional key-value pairs not signed by the homeserver. - pub unsigned: Option, + #[serde(default)] + pub unsigned: Map, /// The unique identifier for the user who sent this event. pub sender: UserId, diff --git a/tests/ruma_events_macros.rs b/tests/ruma_events_macros.rs index 0cb96a9a..e1cf116c 100644 --- a/tests/ruma_events_macros.rs +++ b/tests/ruma_events_macros.rs @@ -4,7 +4,7 @@ use js_int::UInt; use ruma_events::util::serde_json_eq_try_from_raw; use ruma_events_macros::ruma_event; use ruma_identifiers::{EventId, RoomAliasId, RoomId, UserId}; -use serde_json::{json, Value}; +use serde_json::json; // See note about wrapping macro expansion in a module from `src/lib.rs` mod common_case { @@ -34,7 +34,7 @@ mod common_case { room_id: None, sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "example.com".to_string(), - unsigned: None, + unsigned: serde_json::Map::new(), }; let json = json!({ "content": { @@ -63,7 +63,7 @@ mod common_case { room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "example.com".to_string(), - unsigned: None, + unsigned: serde_json::Map::new(), }; let json = json!({ "content": { @@ -96,7 +96,7 @@ mod common_case { room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), sender: UserId::try_from("@carl:example.com").unwrap(), state_key: "example.com".to_string(), - unsigned: Some(serde_json::from_str::(r#"{"foo":"bar"}"#).unwrap()), + unsigned: serde_json::from_str(r#"{"foo":"bar"}"#).unwrap(), }; let json = json!({ "content": { @@ -147,7 +147,7 @@ mod extra_fields { origin_server_ts: UInt::try_from(1).unwrap(), room_id: Some(RoomId::try_from("!n8f893n9:example.com").unwrap()), sender: UserId::try_from("@carl:example.com").unwrap(), - unsigned: Some(serde_json::from_str::(r#"{"foo":"bar"}"#).unwrap()), + unsigned: serde_json::from_str(r#"{"foo":"bar"}"#).unwrap(), }; let json = json!({ "content": {