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