From 11d50205657e70b4457ee314ef812fb06261986d Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Wed, 18 Jan 2023 09:38:37 +0100 Subject: [PATCH] events: Don't require threads to contain m.in_reply_to --- crates/ruma-common/src/events/relation.rs | 10 +++++-- .../events/room/encrypted/relation_serde.rs | 7 ++--- crates/ruma-common/src/events/room/message.rs | 2 +- .../src/events/room/message/relation_serde.rs | 7 ++--- crates/ruma-common/tests/events/encrypted.rs | 2 +- crates/ruma-common/tests/events/relations.rs | 28 +++++++++++++++++-- 6 files changed, 39 insertions(+), 17 deletions(-) diff --git a/crates/ruma-common/src/events/relation.rs b/crates/ruma-common/src/events/relation.rs index 0dc00977..78ef6e01 100644 --- a/crates/ruma-common/src/events/relation.rs +++ b/crates/ruma-common/src/events/relation.rs @@ -188,7 +188,7 @@ pub struct Thread { /// If this event is not a reply, this is used as a fallback mechanism for clients that do not /// support threads. This should point to the latest message-like event in the thread and /// `is_falling_back` must be set to `true`. - pub in_reply_to: InReplyTo, + pub in_reply_to: Option, /// Whether the `m.in_reply_to` field is a fallback for older clients or a genuine reply in a /// thread. @@ -199,13 +199,17 @@ impl Thread { /// Convenience method to create a regular `Thread` with the given event ID and latest /// message-like event ID. pub fn plain(event_id: OwnedEventId, latest_event_id: OwnedEventId) -> Self { - Self { event_id, in_reply_to: InReplyTo::new(latest_event_id), is_falling_back: true } + Self { event_id, in_reply_to: Some(InReplyTo::new(latest_event_id)), is_falling_back: true } } /// Convenience method to create a reply `Thread` with the given event ID and replied-to event /// ID. pub fn reply(event_id: OwnedEventId, reply_to_event_id: OwnedEventId) -> Self { - Self { event_id, in_reply_to: InReplyTo::new(reply_to_event_id), is_falling_back: false } + Self { + event_id, + in_reply_to: Some(InReplyTo::new(reply_to_event_id)), + is_falling_back: false, + } } } diff --git a/crates/ruma-common/src/events/room/encrypted/relation_serde.rs b/crates/ruma-common/src/events/room/encrypted/relation_serde.rs index 7cdd63d7..cc6b0075 100644 --- a/crates/ruma-common/src/events/room/encrypted/relation_serde.rs +++ b/crates/ruma-common/src/events/room/encrypted/relation_serde.rs @@ -16,10 +16,7 @@ where | RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { event_id, is_falling_back }), ) = ev.relates_to.relation { - let in_reply_to = ev - .relates_to - .in_reply_to - .ok_or_else(|| serde::de::Error::missing_field("m.in_reply_to"))?; + let in_reply_to = ev.relates_to.in_reply_to; return Ok(Some(Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }))); } let rel = if let Some(in_reply_to) = ev.relates_to.in_reply_to { @@ -69,7 +66,7 @@ impl Serialize for Relation { } Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }) => { RelatesToJsonRepr { - in_reply_to: Some(in_reply_to.clone()), + in_reply_to: in_reply_to.clone(), relation: Some(RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id: event_id.clone(), is_falling_back: *is_falling_back, diff --git a/crates/ruma-common/src/events/room/message.rs b/crates/ruma-common/src/events/room/message.rs index 2bec5b2b..64d09994 100644 --- a/crates/ruma-common/src/events/room/message.rs +++ b/crates/ruma-common/src/events/room/message.rs @@ -213,7 +213,7 @@ impl RoomMessageEventContent { self.relates_to = Some(Relation::Thread(Thread { event_id: thread_root, - in_reply_to: InReplyTo { event_id: previous_message.event_id.clone() }, + in_reply_to: Some(InReplyTo { event_id: previous_message.event_id.clone() }), is_falling_back: is_reply == ReplyWithinThread::No, })); diff --git a/crates/ruma-common/src/events/room/message/relation_serde.rs b/crates/ruma-common/src/events/room/message/relation_serde.rs index 5652e51c..60dda2c1 100644 --- a/crates/ruma-common/src/events/room/message/relation_serde.rs +++ b/crates/ruma-common/src/events/room/message/relation_serde.rs @@ -32,10 +32,7 @@ where | RelationJsonRepr::ThreadUnstable(ThreadUnstableJsonRepr { event_id, is_falling_back }), ) = ev.relates_to.relation { - let in_reply_to = ev - .relates_to - .in_reply_to - .ok_or_else(|| serde::de::Error::missing_field("m.in_reply_to"))?; + let in_reply_to = ev.relates_to.in_reply_to; return Ok(Some(Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }))); } @@ -92,7 +89,7 @@ where } Relation::Thread(Thread { event_id, in_reply_to, is_falling_back }) => { EventWithRelatesToJsonRepr::new(RelatesToJsonRepr { - in_reply_to: Some(in_reply_to.clone()), + in_reply_to: in_reply_to.clone(), relation: Some(RelationJsonRepr::ThreadStable(ThreadStableJsonRepr { event_id: event_id.clone(), is_falling_back: *is_falling_back, diff --git a/crates/ruma-common/tests/events/encrypted.rs b/crates/ruma-common/tests/events/encrypted.rs index 578e7a3a..fe49c022 100644 --- a/crates/ruma-common/tests/events/encrypted.rs +++ b/crates/ruma-common/tests/events/encrypted.rs @@ -381,7 +381,7 @@ fn content_thread_deserialization() { Some(Relation::Thread(thread)) => thread ); assert_eq!(thread.event_id, "$thread_root"); - assert_eq!(thread.in_reply_to.event_id, "$prev_event"); + assert_eq!(thread.in_reply_to.unwrap().event_id, "$prev_event"); assert!(!thread.is_falling_back); } diff --git a/crates/ruma-common/tests/events/relations.rs b/crates/ruma-common/tests/events/relations.rs index 8f1c1eab..258fd532 100644 --- a/crates/ruma-common/tests/events/relations.rs +++ b/crates/ruma-common/tests/events/relations.rs @@ -174,6 +174,30 @@ fn thread_reply_serialize() { #[test] fn thread_stable_deserialize() { + let json = json!({ + "msgtype": "m.text", + "body": "", + "m.relates_to": { + "rel_type": "m.thread", + "event_id": "$1598361704261elfgc", + }, + }); + + let thread = assert_matches!( + from_json_value::(json), + Ok(RoomMessageEventContent { + msgtype: MessageType::Text(_), + relates_to: Some(Relation::Thread(thread)), + .. + }) => thread + ); + assert_eq!(thread.event_id, "$1598361704261elfgc"); + assert_matches!(thread.in_reply_to, None); + assert!(!thread.is_falling_back); +} + +#[test] +fn thread_stable_reply_deserialize() { let json = json!({ "msgtype": "m.text", "body": "", @@ -195,7 +219,7 @@ fn thread_stable_deserialize() { }) => thread ); assert_eq!(thread.event_id, "$1598361704261elfgc"); - assert_eq!(thread.in_reply_to.event_id, "$latesteventid"); + assert_eq!(thread.in_reply_to.unwrap().event_id, "$latesteventid"); assert!(!thread.is_falling_back); } @@ -222,6 +246,6 @@ fn thread_unstable_deserialize() { }) => thread ); assert_eq!(thread.event_id, "$1598361704261elfgc"); - assert_eq!(thread.in_reply_to.event_id, "$latesteventid"); + assert_eq!(thread.in_reply_to.unwrap().event_id, "$latesteventid"); assert!(!thread.is_falling_back); }