events: Remove custom module
… and shuffle things around so there's still a content type that can be used for _Custom event enum variants.
This commit is contained in:
parent
fe337f8d5b
commit
b08e8cff9d
@ -89,7 +89,7 @@ fn expand_event_enum(
|
|||||||
)*
|
)*
|
||||||
/// An event not defined by the Matrix specification
|
/// An event not defined by the Matrix specification
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
_Custom(#ruma_events::#event_struct<#ruma_events::custom::_CustomEventContent>),
|
_Custom(#ruma_events::#event_struct<#ruma_events::_custom::CustomEventContent>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#deserialize_impl
|
#deserialize_impl
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
Breaking changes:
|
Breaking changes:
|
||||||
|
|
||||||
* Remove `RedactedStrippedStateEvent`
|
* Remove `RedactedStrippedStateEvent`
|
||||||
* It was not used anywhere since stripped state events are never actually redacted.
|
* It was not used anywhere since stripped state events are never actually redacted
|
||||||
* Use `Box<RawJsonValue>` instead of `JsonValue` for PDU `content` field
|
* Use `Box<RawJsonValue>` instead of `JsonValue` for PDU `content` field
|
||||||
* Require `room::message::MessageType` to always contain a body
|
* Require `room::message::MessageType` to always contain a body
|
||||||
* The `new` constructor now also has a body parameter
|
* The `new` constructor now also has a body parameter
|
||||||
@ -11,6 +11,8 @@ Breaking changes:
|
|||||||
* Remove unneeded redacted event content enums
|
* Remove unneeded redacted event content enums
|
||||||
* Update `reply` and `html_reply` types to `impl Display` on `RoomMessageEventContent`'s reply
|
* Update `reply` and `html_reply` types to `impl Display` on `RoomMessageEventContent`'s reply
|
||||||
constructors
|
constructors
|
||||||
|
* Remove the `custom` module, which has been redundant for a while
|
||||||
|
* If you are still using it and are unclear on the upgrade path, please get in touch
|
||||||
|
|
||||||
Improvements:
|
Improvements:
|
||||||
|
|
||||||
|
60
crates/ruma-events/src/_custom.rs
Normal file
60
crates/ruma-events/src/_custom.rs
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
use ruma_identifiers::RoomVersionId;
|
||||||
|
use serde::Serialize;
|
||||||
|
use serde_json::value::RawValue as RawJsonValue;
|
||||||
|
|
||||||
|
use crate::{
|
||||||
|
EphemeralRoomEventContent, EventContent, GlobalAccountDataEventContent, HasDeserializeFields,
|
||||||
|
MessageEventContent, RedactContent, RedactedEventContent, RedactedMessageEventContent,
|
||||||
|
RedactedStateEventContent, RoomAccountDataEventContent, StateEventContent,
|
||||||
|
ToDeviceEventContent,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// A custom event's type. Used for event enum `_Custom` variants.
|
||||||
|
// FIXME: Serialize shouldn't be required here, but it's currently a supertrait of EventContent
|
||||||
|
#[derive(Clone, Debug, Serialize)]
|
||||||
|
#[allow(clippy::exhaustive_structs)]
|
||||||
|
pub struct CustomEventContent {
|
||||||
|
#[serde(skip)]
|
||||||
|
event_type: Box<str>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RedactContent for CustomEventContent {
|
||||||
|
type Redacted = Self;
|
||||||
|
|
||||||
|
fn redact(self, _: &RoomVersionId) -> Self {
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventContent for CustomEventContent {
|
||||||
|
fn event_type(&self) -> &str {
|
||||||
|
&self.event_type
|
||||||
|
}
|
||||||
|
|
||||||
|
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
|
||||||
|
Ok(Self { event_type: event_type.into() })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RedactedEventContent for CustomEventContent {
|
||||||
|
fn empty(event_type: &str) -> serde_json::Result<Self> {
|
||||||
|
Ok(Self { event_type: event_type.into() })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_serialize_fields(&self) -> bool {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn has_deserialize_fields() -> HasDeserializeFields {
|
||||||
|
HasDeserializeFields::False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GlobalAccountDataEventContent for CustomEventContent {}
|
||||||
|
impl RoomAccountDataEventContent for CustomEventContent {}
|
||||||
|
impl ToDeviceEventContent for CustomEventContent {}
|
||||||
|
impl EphemeralRoomEventContent for CustomEventContent {}
|
||||||
|
impl MessageEventContent for CustomEventContent {}
|
||||||
|
impl StateEventContent for CustomEventContent {}
|
||||||
|
impl RedactedMessageEventContent for CustomEventContent {}
|
||||||
|
impl RedactedStateEventContent for CustomEventContent {}
|
@ -1,150 +0,0 @@
|
|||||||
//! Types for custom events outside of the Matrix specification.
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use ruma_identifiers::RoomVersionId;
|
|
||||||
use serde::Serialize;
|
|
||||||
use serde_json::{value::RawValue as RawJsonValue, Value as JsonValue};
|
|
||||||
|
|
||||||
use crate::{
|
|
||||||
EphemeralRoomEventContent, EventContent, GlobalAccountDataEventContent, HasDeserializeFields,
|
|
||||||
MessageEventContent, RedactContent, RedactedEventContent, RedactedMessageEventContent,
|
|
||||||
RedactedStateEventContent, RoomAccountDataEventContent, StateEventContent,
|
|
||||||
ToDeviceEventContent,
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A custom event's type and `content` JSON object.
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
|
||||||
#[allow(clippy::exhaustive_structs)]
|
|
||||||
pub struct CustomEventContent {
|
|
||||||
/// The event type string.
|
|
||||||
#[serde(skip)]
|
|
||||||
pub event_type: String,
|
|
||||||
|
|
||||||
/// The actual `content` JSON object.
|
|
||||||
#[serde(flatten)]
|
|
||||||
pub data: BTreeMap<String, JsonValue>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RedactContent for CustomEventContent {
|
|
||||||
type Redacted = RedactedCustomEventContent;
|
|
||||||
|
|
||||||
fn redact(self, _: &RoomVersionId) -> RedactedCustomEventContent {
|
|
||||||
RedactedCustomEventContent { event_type: self.event_type }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventContent for CustomEventContent {
|
|
||||||
fn event_type(&self) -> &str {
|
|
||||||
&self.event_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_parts(event_type: &str, content: &RawJsonValue) -> serde_json::Result<Self> {
|
|
||||||
let data = serde_json::from_str(content.get())?;
|
|
||||||
Ok(Self { event_type: event_type.to_owned(), data })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// A custom event must satisfy all of the event content marker traits since
|
|
||||||
// they can be used for any event kind.
|
|
||||||
impl GlobalAccountDataEventContent for CustomEventContent {}
|
|
||||||
|
|
||||||
impl RoomAccountDataEventContent for CustomEventContent {}
|
|
||||||
|
|
||||||
impl ToDeviceEventContent for CustomEventContent {}
|
|
||||||
|
|
||||||
impl EphemeralRoomEventContent for CustomEventContent {}
|
|
||||||
|
|
||||||
impl MessageEventContent for CustomEventContent {}
|
|
||||||
|
|
||||||
impl StateEventContent for CustomEventContent {}
|
|
||||||
|
|
||||||
/// A custom event that has been redacted.
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
|
||||||
#[allow(clippy::exhaustive_structs)]
|
|
||||||
pub struct RedactedCustomEventContent {
|
|
||||||
// This field is marked skipped but will be present because deserialization
|
|
||||||
// passes the `type` field of the JSON event to the events `EventContent::from_parts` method.
|
|
||||||
/// The event type string for this custom event "m.whatever".
|
|
||||||
#[serde(skip)]
|
|
||||||
pub event_type: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventContent for RedactedCustomEventContent {
|
|
||||||
fn event_type(&self) -> &str {
|
|
||||||
&self.event_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
|
|
||||||
Ok(Self { event_type: event_type.to_owned() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RedactedEventContent for RedactedCustomEventContent {
|
|
||||||
fn empty(event_type: &str) -> serde_json::Result<Self> {
|
|
||||||
Ok(Self { event_type: event_type.to_owned() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_serialize_fields(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_deserialize_fields() -> HasDeserializeFields {
|
|
||||||
HasDeserializeFields::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RedactedMessageEventContent for RedactedCustomEventContent {}
|
|
||||||
|
|
||||||
impl RedactedStateEventContent for RedactedCustomEventContent {}
|
|
||||||
|
|
||||||
/// A custom event's type. Used for event enum `_Custom` variants.
|
|
||||||
#[doc(hidden)]
|
|
||||||
// FIXME: Serialize shouldn't be required here, but it's currently a supertrait of EventContent
|
|
||||||
#[derive(Clone, Debug, Serialize)]
|
|
||||||
#[allow(clippy::exhaustive_structs)]
|
|
||||||
pub struct _CustomEventContent {
|
|
||||||
#[serde(skip)]
|
|
||||||
event_type: Box<str>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RedactContent for _CustomEventContent {
|
|
||||||
type Redacted = Self;
|
|
||||||
|
|
||||||
fn redact(self, _: &RoomVersionId) -> Self {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl EventContent for _CustomEventContent {
|
|
||||||
fn event_type(&self) -> &str {
|
|
||||||
&self.event_type
|
|
||||||
}
|
|
||||||
|
|
||||||
fn from_parts(event_type: &str, _content: &RawJsonValue) -> serde_json::Result<Self> {
|
|
||||||
Ok(Self { event_type: event_type.into() })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl RedactedEventContent for _CustomEventContent {
|
|
||||||
fn empty(event_type: &str) -> serde_json::Result<Self> {
|
|
||||||
Ok(Self { event_type: event_type.into() })
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_serialize_fields(&self) -> bool {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
|
|
||||||
fn has_deserialize_fields() -> HasDeserializeFields {
|
|
||||||
HasDeserializeFields::False
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl GlobalAccountDataEventContent for _CustomEventContent {}
|
|
||||||
impl RoomAccountDataEventContent for _CustomEventContent {}
|
|
||||||
impl ToDeviceEventContent for _CustomEventContent {}
|
|
||||||
impl EphemeralRoomEventContent for _CustomEventContent {}
|
|
||||||
impl MessageEventContent for _CustomEventContent {}
|
|
||||||
impl StateEventContent for _CustomEventContent {}
|
|
||||||
impl RedactedMessageEventContent for _CustomEventContent {}
|
|
||||||
impl RedactedStateEventContent for _CustomEventContent {}
|
|
@ -124,6 +124,9 @@ use serde_json::value::RawValue as RawJsonValue;
|
|||||||
|
|
||||||
use self::room::redaction::SyncRoomRedactionEvent;
|
use self::room::redaction::SyncRoomRedactionEvent;
|
||||||
|
|
||||||
|
// Needs to be public for trybuild tests
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub mod _custom;
|
||||||
mod enums;
|
mod enums;
|
||||||
mod event_kinds;
|
mod event_kinds;
|
||||||
mod unsigned;
|
mod unsigned;
|
||||||
@ -151,7 +154,6 @@ pub mod macros {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub mod call;
|
pub mod call;
|
||||||
pub mod custom;
|
|
||||||
pub mod direct;
|
pub mod direct;
|
||||||
pub mod dummy;
|
pub mod dummy;
|
||||||
pub mod forwarded_room_key;
|
pub mod forwarded_room_key;
|
||||||
|
@ -1,150 +0,0 @@
|
|||||||
use js_int::uint;
|
|
||||||
use maplit::btreemap;
|
|
||||||
use matches::assert_matches;
|
|
||||||
use ruma_common::MilliSecondsSinceUnixEpoch;
|
|
||||||
use ruma_events::{
|
|
||||||
custom::CustomEventContent, AnyStateEvent, AnySyncRoomEvent, AnySyncStateEvent, MessageEvent,
|
|
||||||
StateEvent, Unsigned,
|
|
||||||
};
|
|
||||||
use ruma_identifiers::{event_id, room_id, user_id};
|
|
||||||
use serde_json::{
|
|
||||||
from_value as from_json_value, json, to_value as to_json_value, Value as JsonValue,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn custom_state_event() -> JsonValue {
|
|
||||||
json!({
|
|
||||||
"content": {
|
|
||||||
"m.relates_to": {
|
|
||||||
"event_id": "$MDitXXXXXX",
|
|
||||||
"key": "👍",
|
|
||||||
"rel_type": "m.annotation"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"event_id": "$h29iv0s8:example.com",
|
|
||||||
"origin_server_ts": 10,
|
|
||||||
"room_id": "!room:room.com",
|
|
||||||
"sender": "@carl:example.com",
|
|
||||||
"state_key": "",
|
|
||||||
"type": "m.reaction",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 85
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn serialize_custom_message_event() {
|
|
||||||
let aliases_event = MessageEvent {
|
|
||||||
content: CustomEventContent {
|
|
||||||
data: btreemap! {
|
|
||||||
"body".into() => " * edited message".into(),
|
|
||||||
"m.new_content".into() => json!({
|
|
||||||
"body": "edited message",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
}),
|
|
||||||
"m.relates_to".into() => json!({
|
|
||||||
"event_id": "some event id",
|
|
||||||
"rel_type": "m.replace"
|
|
||||||
}),
|
|
||||||
"msgtype".into() => "m.text".into()
|
|
||||||
},
|
|
||||||
event_type: "m.room.message".into(),
|
|
||||||
},
|
|
||||||
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
|
|
||||||
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10)),
|
|
||||||
room_id: room_id!("!room:room.com").to_owned(),
|
|
||||||
sender: user_id!("@carl:example.com").to_owned(),
|
|
||||||
unsigned: Unsigned::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let actual = to_json_value(&aliases_event).unwrap();
|
|
||||||
let expected = json!({
|
|
||||||
"content": {
|
|
||||||
"body": " * edited message",
|
|
||||||
"m.new_content": {
|
|
||||||
"body": "edited message",
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"m.relates_to": {
|
|
||||||
"event_id": "some event id",
|
|
||||||
"rel_type": "m.replace"
|
|
||||||
},
|
|
||||||
"msgtype": "m.text"
|
|
||||||
},
|
|
||||||
"event_id": "$h29iv0s8:example.com",
|
|
||||||
"origin_server_ts": 10,
|
|
||||||
"sender": "@carl:example.com",
|
|
||||||
"room_id": "!room:room.com",
|
|
||||||
"type": "m.room.message",
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn serialize_custom_state_event() {
|
|
||||||
let aliases_event = StateEvent {
|
|
||||||
content: CustomEventContent {
|
|
||||||
data: btreemap! {
|
|
||||||
"custom".into() => 10.into()
|
|
||||||
},
|
|
||||||
event_type: "m.made.up".into(),
|
|
||||||
},
|
|
||||||
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
|
|
||||||
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(10)),
|
|
||||||
prev_content: None,
|
|
||||||
room_id: room_id!("!roomid:room.com").to_owned(),
|
|
||||||
sender: user_id!("@carl:example.com").to_owned(),
|
|
||||||
state_key: "".into(),
|
|
||||||
unsigned: Unsigned::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let actual = to_json_value(&aliases_event).unwrap();
|
|
||||||
let expected = json!({
|
|
||||||
"content": {
|
|
||||||
"custom": 10
|
|
||||||
},
|
|
||||||
"event_id": "$h29iv0s8:example.com",
|
|
||||||
"origin_server_ts": 10,
|
|
||||||
"room_id": "!roomid:room.com",
|
|
||||||
"sender": "@carl:example.com",
|
|
||||||
"state_key": "",
|
|
||||||
"type": "m.made.up",
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn deserialize_custom_state_event() {
|
|
||||||
let json_data = custom_state_event();
|
|
||||||
assert_matches!(from_json_value::<AnyStateEvent>(json_data), Ok(_));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn deserialize_custom_state_sync_event() {
|
|
||||||
let json_data = custom_state_event();
|
|
||||||
assert_matches!(from_json_value::<AnySyncStateEvent>(json_data), Ok(_));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn deserialize_custom_message_sync_event() {
|
|
||||||
let json_data = json!({
|
|
||||||
"content": {
|
|
||||||
"body": "👍"
|
|
||||||
},
|
|
||||||
"event_id": "$h29iv0s8:example.com",
|
|
||||||
"origin_server_ts": 10,
|
|
||||||
"room_id": "!room:room.com",
|
|
||||||
"sender": "@carl:example.com",
|
|
||||||
"type": "m.ruma_custom",
|
|
||||||
"unsigned": {
|
|
||||||
"age": 85
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
assert_matches!(
|
|
||||||
from_json_value::<AnySyncRoomEvent>(json_data),
|
|
||||||
Ok(AnySyncRoomEvent::Message(_))
|
|
||||||
);
|
|
||||||
}
|
|
@ -2,7 +2,6 @@ use js_int::uint;
|
|||||||
use matches::assert_matches;
|
use matches::assert_matches;
|
||||||
use ruma_common::MilliSecondsSinceUnixEpoch;
|
use ruma_common::MilliSecondsSinceUnixEpoch;
|
||||||
use ruma_events::{
|
use ruma_events::{
|
||||||
custom::RedactedCustomEventContent,
|
|
||||||
room::{
|
room::{
|
||||||
aliases::RedactedRoomAliasesEventContent,
|
aliases::RedactedRoomAliasesEventContent,
|
||||||
create::{RedactedRoomCreateEventContent, RoomCreateEventContent},
|
create::{RedactedRoomCreateEventContent, RoomCreateEventContent},
|
||||||
@ -244,32 +243,6 @@ fn redacted_custom_event_serialize() {
|
|||||||
assert_eq!(x.event_id(), event_id!("$h29iv0s8:example.com"))
|
assert_eq!(x.event_id(), event_id!("$h29iv0s8:example.com"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn redacted_custom_event_deserialize() {
|
|
||||||
let unsigned = unsigned();
|
|
||||||
|
|
||||||
let redacted = RedactedSyncStateEvent {
|
|
||||||
content: RedactedCustomEventContent { event_type: "m.made.up".into() },
|
|
||||||
event_id: event_id!("$h29iv0s8:example.com").to_owned(),
|
|
||||||
sender: user_id!("@carl:example.com").to_owned(),
|
|
||||||
state_key: "hello there".into(),
|
|
||||||
origin_server_ts: MilliSecondsSinceUnixEpoch(uint!(1)),
|
|
||||||
unsigned: unsigned.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
let expected = json!({
|
|
||||||
"event_id": "$h29iv0s8:example.com",
|
|
||||||
"origin_server_ts": 1,
|
|
||||||
"sender": "@carl:example.com",
|
|
||||||
"state_key": "hello there",
|
|
||||||
"unsigned": unsigned,
|
|
||||||
"type": "m.made.up",
|
|
||||||
});
|
|
||||||
|
|
||||||
let actual = to_json_value(&redacted).unwrap();
|
|
||||||
assert_eq!(actual, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn redact_method_properly_redacts() {
|
fn redact_method_properly_redacts() {
|
||||||
let ev = json!({
|
let ev = json!({
|
||||||
|
Loading…
x
Reference in New Issue
Block a user