Rename CustomOrRawEvent -> CustomEvent and use raw json when failed

When deserialization fails we fallback to providing the user with a
serde_json::RawValue, basically the json string. Ruma should handle all
events that conform to a matrix event shape correctly by either
converting them to their type or returning a custom event.
master
Devin Ragotzy 2020-08-04 15:08:13 -04:00
parent c10120602a
commit cb8d5ce8fb
7 changed files with 31 additions and 21 deletions

View File

@ -32,7 +32,7 @@ impl WasmBot {
console::log_1(&format!("Received message event {:?}", &msg_body).into()); console::log_1(&format!("Received message event {:?}", &msg_body).into());
if msg_body.starts_with("!party") { if msg_body.starts_with("!party") {
let content = MessageEventContent::Text(TextMessageEventContent::new_plain( let content = MessageEventContent::Text(TextMessageEventContent::plain(
"🎉🎊🥳 let's PARTY with wasm!! 🥳🎊🎉".to_string(), "🎉🎊🥳 let's PARTY with wasm!! 🥳🎊🎉".to_string(),
)); ));

View File

@ -39,7 +39,7 @@
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
pub use matrix_sdk_base::JsonStore; pub use matrix_sdk_base::JsonStore;
pub use matrix_sdk_base::{ pub use matrix_sdk_base::{
CustomOrRawEvent, Error as BaseError, EventEmitter, Room, RoomState, Session, StateStore, CustomEvent, Error as BaseError, EventEmitter, Room, RoomState, Session, StateStore,
SyncRoom, SyncRoom,
}; };
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]

View File

@ -59,7 +59,7 @@ use crate::JsonStore;
use crate::{ use crate::{
error::Result, error::Result,
event_emitter::CustomOrRawEvent, event_emitter::CustomEvent,
events::presence::PresenceEvent, events::presence::PresenceEvent,
models::Room, models::Room,
session::Session, session::Session,
@ -1482,7 +1482,7 @@ impl BaseClient {
} }
AnySyncStateEvent::Custom(e) => { AnySyncStateEvent::Custom(e) => {
event_emitter event_emitter
.on_unrecognized_event(room, &CustomOrRawEvent::State(e)) .on_custom_event(room, &CustomEvent::State(e))
.await .await
} }
_ => {} _ => {}
@ -1497,7 +1497,7 @@ impl BaseClient {
} }
AnySyncMessageEvent::Custom(e) => { AnySyncMessageEvent::Custom(e) => {
event_emitter event_emitter
.on_unrecognized_event(room, &CustomOrRawEvent::Message(e)) .on_custom_event(room, &CustomEvent::Message(e))
.await .await
} }
_ => {} _ => {}
@ -1572,7 +1572,7 @@ impl BaseClient {
} }
AnySyncStateEvent::Custom(custom) => { AnySyncStateEvent::Custom(custom) => {
event_emitter event_emitter
.on_unrecognized_event(room, &CustomOrRawEvent::State(custom)) .on_custom_event(room, &CustomEvent::State(custom))
.await .await
} }
_ => {} _ => {}
@ -1821,8 +1821,7 @@ impl BaseClient {
} }
}; };
if let Some(ee) = &self.event_emitter.read().await.as_ref() { if let Some(ee) = &self.event_emitter.read().await.as_ref() {
ee.on_unrecognized_event(room, &CustomOrRawEvent::RawJson(event.json())) ee.on_unrecognized_event(room, event.json()).await;
.await;
} }
} }
@ -2210,9 +2209,9 @@ mod test {
struct EE(Arc<AtomicBool>); struct EE(Arc<AtomicBool>);
#[async_trait] #[async_trait]
impl EventEmitter for EE { impl EventEmitter for EE {
async fn on_unrecognized_event(&self, room: SyncRoom, event: &CustomOrRawEvent<'_>) { async fn on_custom_event(&self, room: SyncRoom, event: &CustomEvent<'_>) {
if let SyncRoom::Joined(_) = room { if let SyncRoom::Joined(_) = room {
if let CustomOrRawEvent::Message(event) = event { if let CustomEvent::Message(event) = event {
if event.content.event_type() == "m.room.not_real" { if event.content.event_type() == "m.room.not_real" {
self.0.swap(true, Ordering::SeqCst); self.0.swap(true, Ordering::SeqCst);
} }
@ -2311,9 +2310,9 @@ mod test {
struct EE(Arc<AtomicBool>); struct EE(Arc<AtomicBool>);
#[async_trait] #[async_trait]
impl EventEmitter for EE { impl EventEmitter for EE {
async fn on_unrecognized_event(&self, room: SyncRoom, event: &CustomOrRawEvent<'_>) { async fn on_custom_event(&self, room: SyncRoom, event: &CustomEvent<'_>) {
if let SyncRoom::Joined(_) = room { if let SyncRoom::Joined(_) = room {
if let CustomOrRawEvent::Message(custom) = event { if let CustomEvent::Message(custom) = event {
if custom.content.event_type == "m.reaction" if custom.content.event_type == "m.reaction"
&& custom.content.json.get("m.relates_to").is_some() && custom.content.json.get("m.relates_to").is_some()
{ {

View File

@ -49,9 +49,7 @@ pub type SyncRoom = RoomState<Arc<RwLock<Room>>>;
/// This represents the various "unrecognized" events. /// This represents the various "unrecognized" events.
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum CustomOrRawEvent<'c> { pub enum CustomEvent<'c> {
/// When an event can not be deserialized by ruma.
RawJson(&'c RawJsonValue),
/// A custom basic event. /// A custom basic event.
Basic(&'c BasicEvent<CustomEventContent>), Basic(&'c BasicEvent<CustomEventContent>),
/// A custom basic event. /// A custom basic event.
@ -264,7 +262,14 @@ pub trait EventEmitter: Send + Sync {
/// because the event was unknown to ruma. /// because the event was unknown to ruma.
/// ///
/// The only guarantee this method can give about the event is that it is valid JSON. /// The only guarantee this method can give about the event is that it is valid JSON.
async fn on_unrecognized_event(&self, _: SyncRoom, _: &CustomOrRawEvent<'_>) {} async fn on_unrecognized_event(&self, _: SyncRoom, _: &RawJsonValue) {}
/// Fires when `Client` receives a `Event::Custom` event or if deserialization fails
/// because the event was unknown to ruma.
///
/// The only guarantee this method can give about the event is that it is in the
/// shape of a valid matrix event.
async fn on_custom_event(&self, _: SyncRoom, _: &CustomEvent<'_>) {}
} }
#[cfg(test)] #[cfg(test)]
@ -468,9 +473,12 @@ mod test {
async fn on_presence_event(&self, _: SyncRoom, _: &PresenceEvent) { async fn on_presence_event(&self, _: SyncRoom, _: &PresenceEvent) {
self.0.lock().await.push("presence event".to_string()) self.0.lock().await.push("presence event".to_string())
} }
async fn on_unrecognized_event(&self, _: SyncRoom, _: &CustomOrRawEvent<'_>) { async fn on_unrecognized_event(&self, _: SyncRoom, _: &RawJsonValue) {
self.0.lock().await.push("unrecognized event".to_string()) self.0.lock().await.push("unrecognized event".to_string())
} }
async fn on_custom_event(&self, _: SyncRoom, _: &CustomEvent<'_>) {
self.0.lock().await.push("custom event".to_string())
}
} }
use crate::{identifiers::UserId, BaseClient, Session}; use crate::{identifiers::UserId, BaseClient, Session};
@ -584,10 +592,12 @@ mod test {
v.as_slice(), v.as_slice(),
[ [
"message", "message",
"unrecognized event", "message", // this is a message edit event
"redaction", "redaction",
"unrecognized event", "unrecognized event",
// "unrecognized event", this is actually a redacted "m.room.messages" event // "unrecognized event", this is actually a redacted "m.room.messages" event
// the ephemeral room events are looped over after the room events
"receipt event", "receipt event",
"typing event" "typing event"
], ],

View File

@ -49,7 +49,7 @@ mod session;
mod state; mod state;
pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType}; pub use client::{BaseClient, BaseClientConfig, RoomState, RoomStateType};
pub use event_emitter::{CustomOrRawEvent, EventEmitter, SyncRoom}; pub use event_emitter::{CustomEvent, EventEmitter, SyncRoom};
pub use models::Room; pub use models::Room;
pub use state::{AllRooms, ClientState}; pub use state::{AllRooms, ClientState};

View File

@ -1129,6 +1129,7 @@ mod test {
assert!(room.deref().power_levels.is_some()) assert!(room.deref().power_levels.is_some())
} }
#[cfg(feature = "messages")]
#[test] #[test]
fn message_edit_deser() { fn message_edit_deser() {
let json = matrix_sdk_test::test_json::MESSAGE_EDIT.deref(); let json = matrix_sdk_test::test_json::MESSAGE_EDIT.deref();

View File

@ -614,12 +614,12 @@ lazy_static! {
"msgtype": "m.text" "msgtype": "m.text"
}, },
"m.relates_to": { "m.relates_to": {
"event_id": "some event id", "event_id": "$someeventid:localhost",
"rel_type": "m.replace" "rel_type": "m.replace"
}, },
"msgtype": "m.text" "msgtype": "m.text"
}, },
"event_id": "edit event id", "event_id": "$editevid:localhost",
"origin_server_ts": 159026265, "origin_server_ts": 159026265,
"sender": "@alice:matrix.org", "sender": "@alice:matrix.org",
"type": "m.room.message", "type": "m.room.message",