events: Move message relation types into separate module
This commit is contained in:
		
							parent
							
								
									cf59d6ecb1
								
							
						
					
					
						commit
						25d0b3ce59
					
				| @ -7,7 +7,7 @@ use std::borrow::Cow; | |||||||
| use as_variant::as_variant; | use as_variant::as_variant; | ||||||
| use ruma_common::{ | use ruma_common::{ | ||||||
|     serde::{JsonObject, Raw, StringEnum}, |     serde::{JsonObject, Raw, StringEnum}, | ||||||
|     EventId, OwnedEventId, OwnedUserId, RoomId, UserId, |     OwnedEventId, OwnedUserId, RoomId, UserId, | ||||||
| }; | }; | ||||||
| #[cfg(feature = "html")] | #[cfg(feature = "html")] | ||||||
| use ruma_html::{sanitize_html, HtmlSanitizerMode, RemoveReplyFallback}; | use ruma_html::{sanitize_html, HtmlSanitizerMode, RemoveReplyFallback}; | ||||||
| @ -19,7 +19,7 @@ use self::reply::OriginalEventData; | |||||||
| #[cfg(feature = "html")] | #[cfg(feature = "html")] | ||||||
| use self::sanitize::remove_plain_reply_fallback; | use self::sanitize::remove_plain_reply_fallback; | ||||||
| use crate::{ | use crate::{ | ||||||
|     relation::{CustomRelation, InReplyTo, RelationType, Replacement, Thread}, |     relation::{InReplyTo, Replacement, Thread}, | ||||||
|     AnySyncTimelineEvent, Mentions, PrivOwnedStr, |     AnySyncTimelineEvent, Mentions, PrivOwnedStr, | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| @ -31,6 +31,7 @@ mod image; | |||||||
| mod key_verification_request; | mod key_verification_request; | ||||||
| mod location; | mod location; | ||||||
| mod notice; | mod notice; | ||||||
|  | mod relation; | ||||||
| pub(crate) mod relation_serde; | pub(crate) mod relation_serde; | ||||||
| mod reply; | mod reply; | ||||||
| pub mod sanitize; | pub mod sanitize; | ||||||
| @ -48,6 +49,7 @@ pub use self::{ | |||||||
|     key_verification_request::KeyVerificationRequestEventContent, |     key_verification_request::KeyVerificationRequestEventContent, | ||||||
|     location::{LocationInfo, LocationMessageEventContent}, |     location::{LocationInfo, LocationMessageEventContent}, | ||||||
|     notice::NoticeMessageEventContent, |     notice::NoticeMessageEventContent, | ||||||
|  |     relation::{Relation, RelationWithoutReplacement}, | ||||||
|     relation_serde::deserialize_relation, |     relation_serde::deserialize_relation, | ||||||
|     server_notice::{LimitType, ServerNoticeMessageEventContent, ServerNoticeType}, |     server_notice::{LimitType, ServerNoticeMessageEventContent, ServerNoticeType}, | ||||||
|     text::TextMessageEventContent, |     text::TextMessageEventContent, | ||||||
| @ -906,146 +908,6 @@ impl From<RoomMessageEventContent> 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<C> { |  | ||||||
|     /// 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<C>), |  | ||||||
| 
 |  | ||||||
|     /// An event that belongs to a thread.
 |  | ||||||
|     Thread(Thread), |  | ||||||
| 
 |  | ||||||
|     #[doc(hidden)] |  | ||||||
|     _Custom(CustomRelation), |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| impl<C> Relation<C> { |  | ||||||
|     /// 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<RelationType> { |  | ||||||
|         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<RelationType> { |  | ||||||
|         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<C> TryFrom<Relation<C>> for RelationWithoutReplacement { |  | ||||||
|     type Error = Replacement<C>; |  | ||||||
| 
 |  | ||||||
|     fn try_from(value: Relation<C>) -> Result<Self, Self::Error> { |  | ||||||
|         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.
 | /// Metadata about an event to be replaced.
 | ||||||
| ///
 | ///
 | ||||||
| /// To be used with [`RoomMessageEventContent::make_replacement`].
 | /// To be used with [`RoomMessageEventContent::make_replacement`].
 | ||||||
|  | |||||||
							
								
								
									
										145
									
								
								crates/ruma-events/src/room/message/relation.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										145
									
								
								crates/ruma-events/src/room/message/relation.rs
									
									
									
									
									
										Normal file
									
								
							| @ -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<C> { | ||||||
|  |     /// 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<C>), | ||||||
|  | 
 | ||||||
|  |     /// An event that belongs to a thread.
 | ||||||
|  |     Thread(Thread), | ||||||
|  | 
 | ||||||
|  |     #[doc(hidden)] | ||||||
|  |     _Custom(CustomRelation), | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | impl<C> Relation<C> { | ||||||
|  |     /// 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<RelationType> { | ||||||
|  |         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<RelationType> { | ||||||
|  |         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<C> TryFrom<Relation<C>> for RelationWithoutReplacement { | ||||||
|  |     type Error = Replacement<C>; | ||||||
|  | 
 | ||||||
|  |     fn try_from(value: Relation<C>) -> Result<Self, Self::Error> { | ||||||
|  |         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) | ||||||
|  |     } | ||||||
|  | } | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user