From 25d0b3ce59577f7d715419898edfb67ea59722f6 Mon Sep 17 00:00:00 2001 From: Jonas Platte Date: Mon, 9 Oct 2023 15:59:49 +0200 Subject: [PATCH] events: Move message relation types into separate module --- crates/ruma-events/src/room/message.rs | 146 +----------------- .../ruma-events/src/room/message/relation.rs | 145 +++++++++++++++++ 2 files changed, 149 insertions(+), 142 deletions(-) create mode 100644 crates/ruma-events/src/room/message/relation.rs diff --git a/crates/ruma-events/src/room/message.rs b/crates/ruma-events/src/room/message.rs index 7c3d87a4..aa539204 100644 --- a/crates/ruma-events/src/room/message.rs +++ b/crates/ruma-events/src/room/message.rs @@ -7,7 +7,7 @@ use std::borrow::Cow; use as_variant::as_variant; use ruma_common::{ serde::{JsonObject, Raw, StringEnum}, - EventId, OwnedEventId, OwnedUserId, RoomId, UserId, + OwnedEventId, OwnedUserId, RoomId, UserId, }; #[cfg(feature = "html")] use ruma_html::{sanitize_html, HtmlSanitizerMode, RemoveReplyFallback}; @@ -19,7 +19,7 @@ use self::reply::OriginalEventData; #[cfg(feature = "html")] use self::sanitize::remove_plain_reply_fallback; use crate::{ - relation::{CustomRelation, InReplyTo, RelationType, Replacement, Thread}, + relation::{InReplyTo, Replacement, Thread}, AnySyncTimelineEvent, Mentions, PrivOwnedStr, }; @@ -31,6 +31,7 @@ mod image; mod key_verification_request; mod location; mod notice; +mod relation; pub(crate) mod relation_serde; mod reply; pub mod sanitize; @@ -48,6 +49,7 @@ pub use self::{ key_verification_request::KeyVerificationRequestEventContent, location::{LocationInfo, LocationMessageEventContent}, notice::NoticeMessageEventContent, + relation::{Relation, RelationWithoutReplacement}, relation_serde::deserialize_relation, server_notice::{LimitType, ServerNoticeMessageEventContent, ServerNoticeType}, text::TextMessageEventContent, @@ -906,146 +908,6 @@ impl From for MessageType { } } -/// Message event relationship. -#[derive(Clone, Debug)] -#[allow(clippy::manual_non_exhaustive)] -#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -pub enum Relation { - /// An `m.in_reply_to` relation indicating that the event is a reply to another event. - Reply { - /// Information about another message being replied to. - in_reply_to: InReplyTo, - }, - - /// An event that replaces another event. - Replacement(Replacement), - - /// An event that belongs to a thread. - Thread(Thread), - - #[doc(hidden)] - _Custom(CustomRelation), -} - -impl Relation { - /// The type of this `Relation`. - /// - /// Returns an `Option` because the `Reply` relation does not have a`rel_type` field. - pub fn rel_type(&self) -> Option { - match self { - Relation::Reply { .. } => None, - Relation::Replacement(_) => Some(RelationType::Replacement), - Relation::Thread(_) => Some(RelationType::Thread), - Relation::_Custom(c) => Some(c.rel_type.as_str().into()), - } - } - - /// The ID of the event this relates to. - /// - /// This is the `event_id` field at the root of an `m.relates_to` object, except in the case of - /// a reply relation where it's the `event_id` field in the `m.in_reply_to` object. - pub fn event_id(&self) -> &EventId { - match self { - Relation::Reply { in_reply_to } => &in_reply_to.event_id, - Relation::Replacement(r) => &r.event_id, - Relation::Thread(t) => &t.event_id, - Relation::_Custom(c) => &c.event_id, - } - } - - /// The associated data. - /// - /// The returned JSON object won't contain the `rel_type` field, use - /// [`.rel_type()`][Self::rel_type] to access it. It also won't contain data - /// outside of `m.relates_to` (e.g. `m.new_content` for `m.replace` relations). - /// - /// Prefer to use the public variants of `Relation` where possible; this method is meant to - /// be used for custom relations only. - pub fn data(&self) -> Cow<'_, JsonObject> - where - C: Clone, - { - if let Relation::_Custom(c) = self { - Cow::Borrowed(&c.data) - } else { - Cow::Owned(self.serialize_data()) - } - } -} - -/// Message event relationship, except a replacement. -#[derive(Clone, Debug)] -#[allow(clippy::manual_non_exhaustive)] -#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -pub enum RelationWithoutReplacement { - /// An `m.in_reply_to` relation indicating that the event is a reply to another event. - Reply { - /// Information about another message being replied to. - in_reply_to: InReplyTo, - }, - - /// An event that belongs to a thread. - Thread(Thread), - - #[doc(hidden)] - _Custom(CustomRelation), -} - -impl RelationWithoutReplacement { - /// The type of this `Relation`. - /// - /// Returns an `Option` because the `Reply` relation does not have a`rel_type` field. - pub fn rel_type(&self) -> Option { - match self { - Self::Reply { .. } => None, - Self::Thread(_) => Some(RelationType::Thread), - Self::_Custom(c) => Some(c.rel_type.as_str().into()), - } - } - - /// The ID of the event this relates to. - /// - /// This is the `event_id` field at the root of an `m.relates_to` object, except in the case of - /// a reply relation where it's the `event_id` field in the `m.in_reply_to` object. - pub fn event_id(&self) -> &EventId { - match self { - Self::Reply { in_reply_to } => &in_reply_to.event_id, - Self::Thread(t) => &t.event_id, - Self::_Custom(c) => &c.event_id, - } - } - - /// The associated data. - /// - /// The returned JSON object won't contain the `rel_type` field, use - /// [`.rel_type()`][Self::rel_type] to access it. - /// - /// Prefer to use the public variants of `Relation` where possible; this method is meant to - /// be used for custom relations only. - pub fn data(&self) -> Cow<'_, JsonObject> { - if let Self::_Custom(c) = self { - Cow::Borrowed(&c.data) - } else { - Cow::Owned(self.serialize_data()) - } - } -} - -impl TryFrom> for RelationWithoutReplacement { - type Error = Replacement; - - fn try_from(value: Relation) -> Result { - let rel = match value { - Relation::Reply { in_reply_to } => Self::Reply { in_reply_to }, - Relation::Replacement(r) => return Err(r), - Relation::Thread(t) => Self::Thread(t), - Relation::_Custom(c) => Self::_Custom(c), - }; - - Ok(rel) - } -} - /// Metadata about an event to be replaced. /// /// To be used with [`RoomMessageEventContent::make_replacement`]. diff --git a/crates/ruma-events/src/room/message/relation.rs b/crates/ruma-events/src/room/message/relation.rs new file mode 100644 index 00000000..6f089866 --- /dev/null +++ b/crates/ruma-events/src/room/message/relation.rs @@ -0,0 +1,145 @@ +use std::borrow::Cow; + +use ruma_common::{serde::JsonObject, EventId}; + +use crate::relation::{CustomRelation, InReplyTo, RelationType, Replacement, Thread}; + +/// Message event relationship. +#[derive(Clone, Debug)] +#[allow(clippy::manual_non_exhaustive)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +pub enum Relation { + /// An `m.in_reply_to` relation indicating that the event is a reply to another event. + Reply { + /// Information about another message being replied to. + in_reply_to: InReplyTo, + }, + + /// An event that replaces another event. + Replacement(Replacement), + + /// An event that belongs to a thread. + Thread(Thread), + + #[doc(hidden)] + _Custom(CustomRelation), +} + +impl Relation { + /// The type of this `Relation`. + /// + /// Returns an `Option` because the `Reply` relation does not have a`rel_type` field. + pub fn rel_type(&self) -> Option { + match self { + Relation::Reply { .. } => None, + Relation::Replacement(_) => Some(RelationType::Replacement), + Relation::Thread(_) => Some(RelationType::Thread), + Relation::_Custom(c) => Some(c.rel_type.as_str().into()), + } + } + + /// The ID of the event this relates to. + /// + /// This is the `event_id` field at the root of an `m.relates_to` object, except in the case of + /// a reply relation where it's the `event_id` field in the `m.in_reply_to` object. + pub fn event_id(&self) -> &EventId { + match self { + Relation::Reply { in_reply_to } => &in_reply_to.event_id, + Relation::Replacement(r) => &r.event_id, + Relation::Thread(t) => &t.event_id, + Relation::_Custom(c) => &c.event_id, + } + } + + /// The associated data. + /// + /// The returned JSON object won't contain the `rel_type` field, use + /// [`.rel_type()`][Self::rel_type] to access it. It also won't contain data + /// outside of `m.relates_to` (e.g. `m.new_content` for `m.replace` relations). + /// + /// Prefer to use the public variants of `Relation` where possible; this method is meant to + /// be used for custom relations only. + pub fn data(&self) -> Cow<'_, JsonObject> + where + C: Clone, + { + if let Relation::_Custom(c) = self { + Cow::Borrowed(&c.data) + } else { + Cow::Owned(self.serialize_data()) + } + } +} + +/// Message event relationship, except a replacement. +#[derive(Clone, Debug)] +#[allow(clippy::manual_non_exhaustive)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +pub enum RelationWithoutReplacement { + /// An `m.in_reply_to` relation indicating that the event is a reply to another event. + Reply { + /// Information about another message being replied to. + in_reply_to: InReplyTo, + }, + + /// An event that belongs to a thread. + Thread(Thread), + + #[doc(hidden)] + _Custom(CustomRelation), +} + +impl RelationWithoutReplacement { + /// The type of this `Relation`. + /// + /// Returns an `Option` because the `Reply` relation does not have a`rel_type` field. + pub fn rel_type(&self) -> Option { + match self { + Self::Reply { .. } => None, + Self::Thread(_) => Some(RelationType::Thread), + Self::_Custom(c) => Some(c.rel_type.as_str().into()), + } + } + + /// The ID of the event this relates to. + /// + /// This is the `event_id` field at the root of an `m.relates_to` object, except in the case of + /// a reply relation where it's the `event_id` field in the `m.in_reply_to` object. + pub fn event_id(&self) -> &EventId { + match self { + Self::Reply { in_reply_to } => &in_reply_to.event_id, + Self::Thread(t) => &t.event_id, + Self::_Custom(c) => &c.event_id, + } + } + + /// The associated data. + /// + /// The returned JSON object won't contain the `rel_type` field, use + /// [`.rel_type()`][Self::rel_type] to access it. + /// + /// Prefer to use the public variants of `Relation` where possible; this method is meant to + /// be used for custom relations only. + pub fn data(&self) -> Cow<'_, JsonObject> { + if let Self::_Custom(c) = self { + Cow::Borrowed(&c.data) + } else { + Cow::Owned(self.serialize_data()) + } + } +} + +impl TryFrom> for RelationWithoutReplacement { + type Error = Replacement; + + fn try_from(value: Relation) -> Result { + let rel = match value { + Relation::Reply { in_reply_to } => Self::Reply { in_reply_to }, + Relation::Replacement(r) => return Err(r), + Relation::Thread(t) => Self::Thread(t), + Relation::_Custom(c) => Self::_Custom(c), + }; + + Ok(rel) + } +}