From 39a4dc911f4145b500fb082fb7cbeb2285ea525f Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 20 Mar 2023 13:03:53 +0100 Subject: [PATCH] Remove event contents from (Sync)TimelineEvent Debug impls --- .../src/deserialized_responses.rs | 86 +++++++++++++++++-- 1 file changed, 77 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk-common/src/deserialized_responses.rs b/crates/matrix-sdk-common/src/deserialized_responses.rs index e7a91c864..4c86d993e 100644 --- a/crates/matrix-sdk-common/src/deserialized_responses.rs +++ b/crates/matrix-sdk-common/src/deserialized_responses.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeMap; +use std::{collections::BTreeMap, fmt}; use ruma::{ events::{AnySyncTimelineEvent, AnyTimelineEvent}, @@ -180,7 +180,7 @@ pub struct EncryptionInfo { /// A customized version of a room event coming from a sync that holds optional /// encryption info. -#[derive(Clone, Debug, Deserialize, Serialize)] +#[derive(Clone, Deserialize, Serialize)] pub struct SyncTimelineEvent { /// The actual event. pub event: Raw, @@ -193,6 +193,14 @@ pub struct SyncTimelineEvent { } impl SyncTimelineEvent { + /// Create a new `SyncTimelineEvent` from the given raw event. + /// + /// This is a convenience constructor for when you don't need to set + /// `encryption_info` or `push_action`, for example inside a test. + pub fn new(event: Raw) -> Self { + Self { event, encryption_info: None, push_actions: vec![] } + } + /// Get the event id of this `SyncTimelineEvent` if the event has any valid /// id. pub fn event_id(&self) -> Option { @@ -200,6 +208,18 @@ impl SyncTimelineEvent { } } +#[cfg(not(tarpaulin_include))] +impl fmt::Debug for SyncTimelineEvent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let SyncTimelineEvent { event, encryption_info, push_actions } = self; + f.debug_struct("SyncTimelineEvent") + .field("event", &DebugRawEvent(event)) + .field("encryption_info", encryption_info) + .field("push_actions", push_actions) + .finish() + } +} + impl From> for SyncTimelineEvent { fn from(inner: Raw) -> Self { Self { encryption_info: None, event: inner, push_actions: Vec::default() } @@ -220,7 +240,7 @@ impl From for SyncTimelineEvent { } } -#[derive(Clone, Debug)] +#[derive(Clone)] pub struct TimelineEvent { /// The actual event. pub event: Raw, @@ -241,6 +261,42 @@ impl TimelineEvent { } } +#[cfg(not(tarpaulin_include))] +impl fmt::Debug for TimelineEvent { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let TimelineEvent { event, encryption_info, push_actions } = self; + f.debug_struct("TimelineEvent") + .field("event", &DebugRawEvent(event)) + .field("encryption_info", encryption_info) + .field("push_actions", push_actions) + .finish() + } +} + +struct DebugRawEvent<'a, T>(&'a Raw); + +#[cfg(not(tarpaulin_include))] +impl fmt::Debug for DebugRawEvent<'_, T> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("RawEvent") + .field("event_id", &DebugEventId(self.0.get_field("event_id"))) + .finish_non_exhaustive() + } +} + +struct DebugEventId(serde_json::Result>); + +#[cfg(not(tarpaulin_include))] +impl fmt::Debug for DebugEventId { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match &self.0 { + Ok(Some(id)) => id.fmt(f), + Ok(None) => f.write_str("Missing"), + Err(e) => f.debug_tuple("Invalid").field(&e).finish(), + } + } +} + #[cfg(test)] mod tests { use ruma::{ @@ -251,18 +307,30 @@ mod tests { use super::{SyncTimelineEvent, TimelineEvent}; - #[test] - fn room_event_to_sync_room_event() { - let event = json!({ - "content": RoomMessageEventContent::text_plain("foobar"), + fn example_event() -> serde_json::Value { + json!({ + "content": RoomMessageEventContent::text_plain("secret"), "type": "m.room.message", "event_id": "$xxxxx:example.org", "room_id": "!someroom:example.com", "origin_server_ts": 2189, "sender": "@carl:example.com", - }); + }) + } - let room_event = TimelineEvent::new(Raw::new(&event).unwrap().cast()); + #[test] + fn sync_timeline_debug_content() { + let room_event = SyncTimelineEvent::new(Raw::new(&example_event()).unwrap().cast()); + let debug_s = format!("{room_event:?}"); + assert!( + !debug_s.contains("secret"), + "Debug representation contains event content!\n{debug_s}" + ); + } + + #[test] + fn room_event_to_sync_room_event() { + let room_event = TimelineEvent::new(Raw::new(&example_event()).unwrap().cast()); let converted_room_event: SyncTimelineEvent = room_event.into(); let converted_event: AnySyncTimelineEvent =