diff --git a/src/core/matrix/pdu/v2.rs b/src/core/matrix/pdu/v2.rs index bc790e721..5af84db59 100644 --- a/src/core/matrix/pdu/v2.rs +++ b/src/core/matrix/pdu/v2.rs @@ -1,6 +1,6 @@ use ruma::{ - EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, - ServerSignatures, UInt, UserId, events::TimelineEventType, + CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, + OwnedUserId, RoomId, ServerSignatures, UInt, UserId, events::TimelineEventType, }; use serde::{Deserialize, Serialize}; use serde_json::value::RawValue as RawJsonValue; @@ -33,6 +33,7 @@ pub struct PDU { /// For redaction events, the ID of the event being redacted. /// /// Not used in v11. + #[serde(skip_serializing_if = "Option::is_none")] pub redacts: Option, /// The room in which this event resides. pub room_id: OwnedRoomId, @@ -41,6 +42,7 @@ pub struct PDU { /// The signatures on this event. pub signatures: ServerSignatures, /// The state key for this PDU, if any. + #[serde(skip_serializing_if = "Option::is_none")] pub state_key: Option, /// The type of this PDU. #[serde(rename = "type")] @@ -50,8 +52,13 @@ pub struct PDU { /// /// This should be `None` when receiving from and transmitting over /// federation. + #[serde(skip_serializing_if = "Option::is_none")] pub unsigned: Option>, + /// Internal metadata that is important to the PDU but should not be + /// serialized into the final event. + /// + /// This field MUST NOT be sent to clients or federation. pub internal_metadata: PduMetadata, } @@ -90,7 +97,7 @@ impl ruma::state_res::Event for PDU { fn rejected(&self) -> bool { self.internal_metadata().rejected } } -impl super::Event for PDU { +impl crate::Event for PDU { fn as_pdu(&self) -> &Pdu { todo!() } fn into_pdu(self) -> Pdu { todo!() } @@ -125,3 +132,35 @@ impl super::Event for PDU { fn event_type(&self) -> &TimelineEventType { &self.event_type } } + +impl TryFrom<&RawJsonValue> for PDU { + type Error = crate::Error; + + fn try_from(value: &RawJsonValue) -> Result { + serde_json::from_str(value.get()).map_err(Into::into) + } +} + +impl TryFrom> for PDU { + type Error = crate::Error; + + fn try_from(value: Box) -> Result { + Self::try_from(value.as_ref()) + } +} + +impl TryFrom for PDU { + type Error = crate::Error; + + fn try_from(value: serde_json::Value) -> Result { + serde_json::from_value(value).map_err(Into::into) + } +} + +impl TryFrom for PDU { + type Error = crate::Error; + + fn try_from(value: CanonicalJsonObject) -> Result { + serde_json::from_value(serde_json::to_value(value)?).map_err(Into::into) + } +} diff --git a/src/core/matrix/pdu/v3.rs b/src/core/matrix/pdu/v3.rs index 48a594342..667866298 100644 --- a/src/core/matrix/pdu/v3.rs +++ b/src/core/matrix/pdu/v3.rs @@ -1,6 +1,6 @@ use ruma::{ - EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, - ServerSignatures, UInt, UserId, + CanonicalJsonObject, EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedRoomId, + OwnedUserId, RoomId, ServerSignatures, UInt, UserId, events::{StateEventType, TimelineEventType}, }; use serde::{Deserialize, Serialize}; @@ -33,12 +33,14 @@ pub struct PDU { pub prev_events: Vec, /// The room in which this event resides. /// May be None if the event is a create event. + #[serde(skip_serializing_if = "Option::is_none")] pub room_id: Option, /// The user who sent this event. pub sender: OwnedUserId, /// The signatures on this event. pub signatures: ServerSignatures, /// The state key for this PDU, if any. + #[serde(skip_serializing_if = "Option::is_none")] pub state_key: Option, /// The type of this PDU. #[serde(rename = "type")] @@ -48,8 +50,13 @@ pub struct PDU { /// /// This should be `None` when receiving from and transmitting over /// federation. + #[serde(skip_serializing_if = "Option::is_none")] pub unsigned: Option>, + /// Internal metadata that is important to the PDU but should not be + /// serialized into the final event. + /// + /// This field MUST NOT be sent to clients or federation. pub internal_metadata: PduMetadata, } @@ -88,7 +95,7 @@ impl ruma::state_res::Event for PDU { fn rejected(&self) -> bool { self.internal_metadata().rejected } } -impl super::Event for PDU { +impl crate::Event for PDU { fn as_pdu(&self) -> &Pdu { todo!() } fn into_pdu(self) -> Pdu { todo!() } @@ -140,3 +147,35 @@ impl super::Event for PDU { fn event_type(&self) -> &TimelineEventType { &self.event_type } } + +impl TryFrom<&RawJsonValue> for PDU { + type Error = crate::Error; + + fn try_from(value: &RawJsonValue) -> Result { + serde_json::from_str(value.get()).map_err(Into::into) + } +} + +impl TryFrom> for PDU { + type Error = crate::Error; + + fn try_from(value: Box) -> Result { + Self::try_from(value.as_ref()) + } +} + +impl TryFrom for PDU { + type Error = crate::Error; + + fn try_from(value: serde_json::Value) -> Result { + serde_json::from_value(value).map_err(Into::into) + } +} + +impl TryFrom for PDU { + type Error = crate::Error; + + fn try_from(value: CanonicalJsonObject) -> Result { + serde_json::from_value(serde_json::to_value(value)?).map_err(Into::into) + } +}