Move matrix-sdk to ruma monorepo

master
Devin R 2020-06-20 17:18:20 -04:00
parent a3441429da
commit eb5949dbc2
19 changed files with 715 additions and 615 deletions

View File

@ -2,7 +2,10 @@ use std::{env, process::exit};
use matrix_sdk::{ use matrix_sdk::{
self, self,
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent}, events::{
room::message::{MessageEventContent, TextMessageEventContent},
MessageEventStub,
},
Client, ClientConfig, EventEmitter, JsonStore, SyncRoom, SyncSettings, Client, ClientConfig, EventEmitter, JsonStore, SyncRoom, SyncSettings,
}; };
use matrix_sdk_common_macros::async_trait; use matrix_sdk_common_macros::async_trait;
@ -22,9 +25,9 @@ impl CommandBot {
#[async_trait] #[async_trait]
impl EventEmitter for CommandBot { impl EventEmitter for CommandBot {
async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) { async fn on_room_message(&self, room: SyncRoom, event: &MessageEventStub<MessageEventContent>) {
if let SyncRoom::Joined(room) = room { if let SyncRoom::Joined(room) = room {
let msg_body = if let MessageEvent { let msg_body = if let MessageEventStub {
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
.. ..
} = event } = event
@ -37,8 +40,7 @@ impl EventEmitter for CommandBot {
if msg_body.contains("!party") { if msg_body.contains("!party") {
let content = MessageEventContent::Text(TextMessageEventContent { let content = MessageEventContent::Text(TextMessageEventContent {
body: "🎉🎊🥳 let's PARTY!! 🥳🎊🎉".to_string(), body: "🎉🎊🥳 let's PARTY!! 🥳🎊🎉".to_string(),
format: None, formatted: None,
formatted_body: None,
relates_to: None, relates_to: None,
}); });
// we clone here to hold the lock for as little time as possible. // we clone here to hold the lock for as little time as possible.

View File

@ -3,7 +3,10 @@ use url::Url;
use matrix_sdk::{ use matrix_sdk::{
self, self,
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent}, events::{
room::message::{MessageEventContent, TextMessageEventContent},
MessageEventStub,
},
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings, Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings,
}; };
use matrix_sdk_common_macros::async_trait; use matrix_sdk_common_macros::async_trait;
@ -12,9 +15,9 @@ struct EventCallback;
#[async_trait] #[async_trait]
impl EventEmitter for EventCallback { impl EventEmitter for EventCallback {
async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) { async fn on_room_message(&self, room: SyncRoom, event: &MessageEventStub<MessageEventContent>) {
if let SyncRoom::Joined(room) = room { if let SyncRoom::Joined(room) = room {
if let MessageEvent { if let MessageEventStub {
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
sender, sender,
.. ..

View File

@ -1,7 +1,7 @@
use matrix_sdk::{ use matrix_sdk::{
api::r0::sync::sync_events::Response as SyncResponse, api::r0::sync::sync_events::Response as SyncResponse,
events::collections::all::RoomEvent, events::room::message::{MessageEventContent, TextMessageEventContent},
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent}, events::MessageEventStub,
identifiers::RoomId, identifiers::RoomId,
Client, ClientConfig, SyncSettings, Client, ClientConfig, SyncSettings,
}; };
@ -12,11 +12,15 @@ use web_sys::console;
struct WasmBot(Client); struct WasmBot(Client);
impl WasmBot { impl WasmBot {
async fn on_room_message(&self, room_id: &RoomId, event: RoomEvent) { async fn on_room_message(
let msg_body = if let RoomEvent::RoomMessage(MessageEvent { &self,
room_id: &RoomId,
event: MessageEventStub<MessageEventContent>,
) {
let msg_body = if let MessageEventStub {
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
.. ..
}) = event } = event
{ {
msg_body.clone() msg_body.clone()
} else { } else {

View File

@ -773,7 +773,7 @@ impl Client {
/// ///
/// # let homeserver = Url::parse("http://example.com").unwrap(); /// # let homeserver = Url::parse("http://example.com").unwrap();
/// let mut builder = RoomBuilder::default(); /// let mut builder = RoomBuilder::default();
/// builder.creation_content(false) /// builder.creation_content(false, None)
/// .initial_state(vec![]) /// .initial_state(vec![])
/// .visibility(Visibility::Public) /// .visibility(Visibility::Public)
/// .name("name") /// .name("name")
@ -939,9 +939,9 @@ impl Client {
/// # use matrix_sdk::{Client, SyncSettings}; /// # use matrix_sdk::{Client, SyncSettings};
/// # use url::Url; /// # use url::Url;
/// # use futures::executor::block_on; /// # use futures::executor::block_on;
/// # use ruma_identifiers::RoomId; /// # use matrix_sdk::identifiers::RoomId;
/// # use std::convert::TryFrom; /// # use std::convert::TryFrom;
/// use matrix_sdk::events::room::message::{MessageEventContent, TextMessageEventContent}; /// use matrix_sdk::events::room::message::{FormattedBody, MessageEventContent, TextMessageEventContent};
/// # block_on(async { /// # block_on(async {
/// # let homeserver = Url::parse("http://localhost:8080").unwrap(); /// # let homeserver = Url::parse("http://localhost:8080").unwrap();
/// # let mut client = Client::new(homeserver).unwrap(); /// # let mut client = Client::new(homeserver).unwrap();
@ -950,8 +950,7 @@ impl Client {
/// ///
/// let content = MessageEventContent::Text(TextMessageEventContent { /// let content = MessageEventContent::Text(TextMessageEventContent {
/// body: "Hello world".to_owned(), /// body: "Hello world".to_owned(),
/// format: None, /// formatted: None,
/// formatted_body: None,
/// relates_to: None, /// relates_to: None,
/// }); /// });
/// let txn_id = Uuid::new_v4(); /// let txn_id = Uuid::new_v4();
@ -1515,8 +1514,9 @@ mod test {
set_read_marker, Invite3pid, MessageEventContent, set_read_marker, Invite3pid, MessageEventContent,
}; };
use super::{Client, ClientConfig, Session, SyncSettings, Url}; use super::{Client, ClientConfig, Session, SyncSettings, Url};
use crate::events::collections::all::RoomEvent; use crate::events::room::member::MembershipState;
use crate::events::room::message::TextMessageEventContent; use crate::events::room::message::TextMessageEventContent;
use crate::identifiers::{EventId, RoomId, RoomIdOrAliasId, UserId}; use crate::identifiers::{EventId, RoomId, RoomIdOrAliasId, UserId};
use crate::{RegistrationBuilder, RoomListFilterBuilder}; use crate::{RegistrationBuilder, RoomListFilterBuilder};
@ -1639,8 +1639,8 @@ mod test {
client.restore_login(session).await.unwrap(); client.restore_login(session).await.unwrap();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_room_event(EventsJson::Member, RoomEvent::RoomMember) .add_state_event(EventsFile::Member)
.add_room_event(EventsJson::PowerLevels, RoomEvent::RoomPowerLevels) .add_state_event(EventsFile::PowerLevels)
.build_sync_response(); .build_sync_response();
client client
@ -2069,7 +2069,7 @@ mod test {
let homeserver = Url::from_str(&mockito::server_url()).unwrap(); let homeserver = Url::from_str(&mockito::server_url()).unwrap();
let user_id = UserId::try_from("@example:localhost").unwrap(); let user_id = UserId::try_from("@example:localhost").unwrap();
let room_id = RoomId::try_from("!testroom:example.org").unwrap(); let room_id = RoomId::try_from("!testroom:example.org").unwrap();
let event_id = EventId::new("example.org").unwrap(); let event_id = EventId::try_from("$xxxxxx:example.org").unwrap();
let session = Session { let session = Session {
access_token: "1234".to_owned(), access_token: "1234".to_owned(),
@ -2105,7 +2105,7 @@ mod test {
let homeserver = Url::from_str(&mockito::server_url()).unwrap(); let homeserver = Url::from_str(&mockito::server_url()).unwrap();
let user_id = UserId::try_from("@example:localhost").unwrap(); let user_id = UserId::try_from("@example:localhost").unwrap();
let room_id = RoomId::try_from("!testroom:example.org").unwrap(); let room_id = RoomId::try_from("!testroom:example.org").unwrap();
let event_id = EventId::new("example.org").unwrap(); let event_id = EventId::try_from("$xxxxxx:example.org").unwrap();
let session = Session { let session = Session {
access_token: "1234".to_owned(), access_token: "1234".to_owned(),
@ -2205,9 +2205,8 @@ mod test {
let content = MessageEventContent::Text(TextMessageEventContent { let content = MessageEventContent::Text(TextMessageEventContent {
body: "Hello world".to_owned(), body: "Hello world".to_owned(),
format: None,
formatted_body: None,
relates_to: None, relates_to: None,
formatted: None,
}); });
let txn_id = Uuid::new_v4(); let txn_id = Uuid::new_v4();
let response = client let response = client

View File

@ -29,7 +29,7 @@ use matrix_sdk_common::{
/// # let mut rt = tokio::runtime::Runtime::new().unwrap(); /// # let mut rt = tokio::runtime::Runtime::new().unwrap();
/// # rt.block_on(async { /// # rt.block_on(async {
/// let mut builder = RoomBuilder::default(); /// let mut builder = RoomBuilder::default();
/// builder.creation_content(false) /// builder.creation_content(false, None)
/// .initial_state(vec![]) /// .initial_state(vec![])
/// .visibility(Visibility::Public) /// .visibility(Visibility::Public)
/// .name("name") /// .name("name")
@ -63,9 +63,15 @@ impl RoomBuilder {
/// Set the `CreationContent`. /// Set the `CreationContent`.
/// ///
/// Weather users on other servers can join this room. /// Weather users on other servers can join this room.
pub fn creation_content(&mut self, federate: bool) -> &mut Self { pub fn creation_content(
let federate = Some(federate); &mut self,
self.creation_content = Some(CreationContent { federate }); federate: bool,
predecessor: Option<PreviousRoom>,
) -> &mut Self {
self.creation_content = Some(CreationContent {
federate,
predecessor,
});
self self
} }
@ -500,7 +506,7 @@ mod test {
let mut builder = RoomBuilder::new(); let mut builder = RoomBuilder::new();
builder builder
.creation_content(false) .creation_content(false, None)
.initial_state(vec![]) .initial_state(vec![])
.visibility(Visibility::Public) .visibility(Visibility::Public)
.name("room_name") .name("room_name")

View File

@ -25,21 +25,22 @@ use std::result::Result as StdResult;
use crate::api::r0 as api; use crate::api::r0 as api;
use crate::error::Result; use crate::error::Result;
use crate::events::collections::all::{RoomEvent, StateEvent};
use crate::events::presence::PresenceEvent; use crate::events::presence::PresenceEvent;
// `NonRoomEvent` is what it is aliased as // `NonRoomEvent` is what it is aliased as
use crate::event_emitter::CustomOrRawEvent; use crate::event_emitter::CustomOrRawEvent;
use crate::events::collections::only::Event as NonRoomEvent;
use crate::events::ignored_user_list::IgnoredUserListEvent; use crate::events::ignored_user_list::IgnoredUserListEvent;
use crate::events::push_rules::{PushRulesEvent, Ruleset}; use crate::events::push_rules::PushRulesEvent;
use crate::events::room::member::MemberEventContent; use crate::events::room::member::MemberEventContent;
use crate::events::stripped::AnyStrippedStateEvent;
use crate::events::EventJson;
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::models::Room; use crate::models::Room;
use crate::push::Ruleset;
use crate::session::Session; use crate::session::Session;
use crate::state::{AllRooms, ClientState, StateStore}; use crate::state::{AllRooms, ClientState, StateStore};
use crate::EventEmitter; use crate::EventEmitter;
use matrix_sdk_common::events::{
AnyBasicEvent, AnyEphemeralRoomEvent, AnyMessageEventStub, AnyRoomEventStub, AnyStateEventStub,
AnyStrippedStateEventStub, EventJson,
};
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
use matrix_sdk_common::locks::Mutex; use matrix_sdk_common::locks::Mutex;
@ -54,7 +55,9 @@ use crate::api::r0::keys::{
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
use crate::api::r0::to_device::send_event_to_device; use crate::api::r0::to_device::send_event_to_device;
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
use crate::events::room::{encrypted::EncryptedEventContent, message::MessageEventContent}; use crate::events::room::{
encrypted::EncryptedEventContent, message::MessageEventContent as MsgEventContent,
};
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
use crate::identifiers::DeviceId; use crate::identifiers::DeviceId;
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
@ -90,7 +93,9 @@ pub struct AdditionalUnsignedData {
/// ///
/// [synapse-bug]: <https://github.com/matrix-org/matrix-doc/issues/684#issuecomment-641182668> /// [synapse-bug]: <https://github.com/matrix-org/matrix-doc/issues/684#issuecomment-641182668>
/// [discussion]: <https://github.com/matrix-org/matrix-doc/issues/684#issuecomment-641182668> /// [discussion]: <https://github.com/matrix-org/matrix-doc/issues/684#issuecomment-641182668>
fn hoist_room_event_prev_content(event: &mut EventJson<RoomEvent>) -> Option<EventJson<RoomEvent>> { fn hoist_room_event_prev_content(
event: &EventJson<AnyRoomEventStub>,
) -> Option<EventJson<AnyRoomEventStub>> {
let prev_content = serde_json::from_str::<AdditionalEventData>(event.json().get()) let prev_content = serde_json::from_str::<AdditionalEventData>(event.json().get())
.map(|more_unsigned| more_unsigned.unsigned) .map(|more_unsigned| more_unsigned.unsigned)
.map(|additional| additional.prev_content) .map(|additional| additional.prev_content)
@ -98,6 +103,7 @@ fn hoist_room_event_prev_content(event: &mut EventJson<RoomEvent>) -> Option<Eve
.flatten()?; .flatten()?;
let mut ev = event.deserialize().ok()?; let mut ev = event.deserialize().ok()?;
match &mut ev { match &mut ev {
RoomEvent::RoomMember(ref mut member) if member.prev_content.is_none() => { RoomEvent::RoomMember(ref mut member) if member.prev_content.is_none() => {
if let Ok(prev) = prev_content.deserialize() { if let Ok(prev) = prev_content.deserialize() {
@ -113,7 +119,9 @@ fn hoist_room_event_prev_content(event: &mut EventJson<RoomEvent>) -> Option<Eve
/// Transform state event by hoisting `prev_content` field from `unsigned` to the top level. /// Transform state event by hoisting `prev_content` field from `unsigned` to the top level.
/// ///
/// See comment of `hoist_room_event_prev_content`. /// See comment of `hoist_room_event_prev_content`.
fn hoist_state_event_prev_content(event: &EventJson<StateEvent>) -> Option<EventJson<StateEvent>> { fn hoist_state_event_prev_content(
event: &EventJson<AnyStateEventStub>,
) -> Option<EventJson<AnyStateEventStub>> {
let prev_content = serde_json::from_str::<AdditionalEventData>(event.json().get()) let prev_content = serde_json::from_str::<AdditionalEventData>(event.json().get())
.map(|more_unsigned| more_unsigned.unsigned) .map(|more_unsigned| more_unsigned.unsigned)
.map(|additional| additional.prev_content) .map(|additional| additional.prev_content)
@ -122,11 +130,10 @@ fn hoist_state_event_prev_content(event: &EventJson<StateEvent>) -> Option<Event
let mut ev = event.deserialize().ok()?; let mut ev = event.deserialize().ok()?;
match &mut ev { match &mut ev {
StateEvent::RoomMember(ref mut member) if member.prev_content.is_none() => { AnyRoomEventStub::State(AnyStateEventStub::RoomMember(ref mut member))
if let Ok(prev) = prev_content.deserialize() { if member.prev_content.is_none() =>
member.prev_content = Some(prev) {
} member.prev_content = Some(prev_content.deserialize().ok()?);
Some(EventJson::from(ev)) Some(EventJson::from(ev))
} }
_ => None, _ => None,
@ -134,7 +141,7 @@ fn hoist_state_event_prev_content(event: &EventJson<StateEvent>) -> Option<Event
} }
fn stripped_deserialize_prev_content( fn stripped_deserialize_prev_content(
event: &EventJson<AnyStrippedStateEvent>, event: &EventJson<AnyStrippedStateEventStub>,
) -> Option<AdditionalUnsignedData> { ) -> Option<AdditionalUnsignedData> {
serde_json::from_str::<AdditionalEventData>(event.json().get()) serde_json::from_str::<AdditionalEventData>(event.json().get())
.map(|more_unsigned| more_unsigned.unsigned) .map(|more_unsigned| more_unsigned.unsigned)
@ -733,8 +740,8 @@ impl BaseClient {
let room_lock = self.get_or_create_joined_room(&room_id).await?; let room_lock = self.get_or_create_joined_room(&room_id).await?;
let mut room = room_lock.write().await; let mut room = room_lock.write().await;
if let RoomEvent::RoomMember(mem_event) = &mut e { if let AnyRoomEventStub::State(AnyStateEventStub::RoomMember(mem_event)) = &mut e {
let changed = room.handle_membership(mem_event); let changed = room.handle_membership(mem_event, room_id);
// The memberlist of the room changed, invalidate the group session // The memberlist of the room changed, invalidate the group session
// of the room. // of the room.
@ -765,13 +772,13 @@ impl BaseClient {
pub async fn receive_joined_state_event( pub async fn receive_joined_state_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &StateEvent, event: &AnyStateEventStub,
) -> Result<bool> { ) -> Result<bool> {
let room_lock = self.get_or_create_joined_room(room_id).await?; let room_lock = self.get_or_create_joined_room(room_id).await?;
let mut room = room_lock.write().await; let mut room = room_lock.write().await;
if let StateEvent::RoomMember(e) = event { if let AnyStateEventStub::RoomMember(e) = event {
let changed = room.handle_membership(e); let changed = room.handle_membership(e, room_id);
// The memberlist of the room changed, invalidate the group session // The memberlist of the room changed, invalidate the group session
// of the room. // of the room.
@ -782,7 +789,7 @@ impl BaseClient {
Ok(changed) Ok(changed)
} else { } else {
Ok(room.receive_state_event(event)) Ok(room.receive_state_event(event, room_id))
} }
} }
@ -799,7 +806,7 @@ impl BaseClient {
pub async fn receive_invite_state_event( pub async fn receive_invite_state_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &AnyStrippedStateEvent, event: &AnyStrippedStateEventStub,
) -> Result<bool> { ) -> Result<bool> {
let room_lock = self.get_or_create_invited_room(room_id).await?; let room_lock = self.get_or_create_invited_room(room_id).await?;
let mut room = room_lock.write().await; let mut room = room_lock.write().await;
@ -819,13 +826,13 @@ impl BaseClient {
pub async fn receive_left_timeline_event( pub async fn receive_left_timeline_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &EventJson<RoomEvent>, event: &EventJson<AnyRoomEventStub>,
) -> Result<bool> { ) -> Result<bool> {
match event.deserialize() { match event.deserialize() {
Ok(e) => { Ok(e) => {
let room_lock = self.get_or_create_left_room(room_id).await?; let room_lock = self.get_or_create_left_room(room_id).await?;
let mut room = room_lock.write().await; let mut room = room_lock.write().await;
Ok(room.receive_timeline_event(&e)) Ok(room.receive_timeline_event(&e, room_id))
} }
_ => Ok(false), _ => Ok(false),
} }
@ -844,11 +851,11 @@ impl BaseClient {
pub async fn receive_left_state_event( pub async fn receive_left_state_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &StateEvent, event: &AnyStateEventStub,
) -> Result<bool> { ) -> Result<bool> {
let room_lock = self.get_or_create_left_room(room_id).await?; let room_lock = self.get_or_create_left_room(room_id).await?;
let mut room = room_lock.write().await; let mut room = room_lock.write().await;
Ok(room.receive_state_event(event)) Ok(room.receive_state_event(event, room_id))
} }
/// Receive a presence event from a sync response and updates the client state. /// Receive a presence event from a sync response and updates the client state.
@ -880,11 +887,10 @@ impl BaseClient {
/// * `room_id` - The unique id of the room the event belongs to. /// * `room_id` - The unique id of the room the event belongs to.
/// ///
/// * `event` - The presence event for a specified room member. /// * `event` - The presence event for a specified room member.
pub async fn receive_account_data_event(&self, room_id: &RoomId, event: &NonRoomEvent) -> bool { pub async fn receive_account_data_event(&self, _: &RoomId, event: &AnyBasicEvent) -> bool {
match event { match &event {
NonRoomEvent::IgnoredUserList(iu) => self.handle_ignored_users(iu).await, AnyBasicEvent::IgnoredUserList(event) => self.handle_ignored_users(&event).await,
NonRoomEvent::Presence(p) => self.receive_presence_event(room_id, p).await, AnyBasicEvent::PushRules(event) => self.handle_push_rules(&event).await,
NonRoomEvent::PushRules(pr) => self.handle_push_rules(pr).await,
_ => false, _ => false,
} }
} }
@ -898,13 +904,18 @@ impl BaseClient {
/// * `room_id` - The unique id of the room the event belongs to. /// * `room_id` - The unique id of the room the event belongs to.
/// ///
/// * `event` - The presence event for a specified room member. /// * `event` - The presence event for a specified room member.
pub async fn receive_ephemeral_event(&self, room_id: &RoomId, event: &NonRoomEvent) -> bool { pub async fn receive_ephemeral_event(
match event { &self,
NonRoomEvent::IgnoredUserList(iu) => self.handle_ignored_users(iu).await, _room_id: &RoomId,
NonRoomEvent::Presence(p) => self.receive_presence_event(room_id, p).await, event: &AnyEphemeralRoomEvent,
NonRoomEvent::PushRules(pr) => self.handle_push_rules(pr).await, ) -> bool {
_ => false, match &event {
} AnyEphemeralRoomEvent::FullyRead(_) => {}
AnyEphemeralRoomEvent::Receipt(_) => {}
AnyEphemeralRoomEvent::Typing(_) => {}
_ => {}
};
false
} }
/// Get the current, if any, sync token of the client. /// Get the current, if any, sync token of the client.
@ -1055,6 +1066,8 @@ impl BaseClient {
self.emit_account_data_event(room_id, &e, RoomStateType::Joined) self.emit_account_data_event(room_id, &e, RoomStateType::Joined)
.await; .await;
} }
self.emit_account_data_event(room_id, &e, RoomStateType::Joined)
.await;
} }
} }
} }
@ -1190,7 +1203,7 @@ impl BaseClient {
if let Ok(mut e) = event.deserialize() { if let Ok(mut e) = event.deserialize() {
// if the event is a m.room.member event the server will sometimes // if the event is a m.room.member event the server will sometimes
// send the `prev_content` field as part of the unsigned field. // send the `prev_content` field as part of the unsigned field.
if let AnyStrippedStateEvent::RoomMember(_) = &mut e { if let AnyStrippedStateEventStub::RoomMember(_) = &mut e {
if let Some(raw_content) = stripped_deserialize_prev_content(event) { if let Some(raw_content) = stripped_deserialize_prev_content(event) {
let prev_content = match raw_content.prev_content { let prev_content = match raw_content.prev_content {
Some(json) => json.deserialize().ok(), Some(json) => json.deserialize().ok(),
@ -1313,7 +1326,7 @@ impl BaseClient {
pub async fn encrypt( pub async fn encrypt(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
content: MessageEventContent, content: MsgEventContent,
) -> Result<EncryptedEventContent> { ) -> Result<EncryptedEventContent> {
let mut olm = self.olm.lock().await; let mut olm = self.olm.lock().await;
@ -1430,7 +1443,7 @@ impl BaseClient {
pub(crate) async fn emit_timeline_event( pub(crate) async fn emit_timeline_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &RoomEvent, event: &AnyRoomEventStub,
room_state: RoomStateType, room_state: RoomStateType,
) { ) {
let lock = self.event_emitter.read().await; let lock = self.event_emitter.read().await;
@ -1464,42 +1477,58 @@ impl BaseClient {
} }
}; };
match event { match &event {
RoomEvent::RoomMember(mem) => event_emitter.on_room_member(room, &mem).await, AnyRoomEventStub::State(event) => match &event {
RoomEvent::RoomName(name) => event_emitter.on_room_name(room, &name).await, AnyStateEventStub::RoomMember(e) => event_emitter.on_room_member(room, &e).await,
RoomEvent::RoomCanonicalAlias(canonical) => { AnyStateEventStub::RoomName(e) => event_emitter.on_room_name(room, &e).await,
AnyStateEventStub::RoomCanonicalAlias(e) => {
event_emitter.on_room_canonical_alias(room, &e).await
}
AnyStateEventStub::RoomAliases(e) => event_emitter.on_room_aliases(room, &e).await,
AnyStateEventStub::RoomAvatar(e) => event_emitter.on_room_avatar(room, &e).await,
AnyStateEventStub::RoomPowerLevels(e) => {
event_emitter.on_room_power_levels(room, &e).await
}
AnyStateEventStub::RoomTombstone(e) => {
event_emitter.on_room_tombstone(room, &e).await
}
AnyStateEventStub::RoomJoinRules(_e) => {
// TODO is this needed ??
// event_emitter
// .on_room_join_rules(room, &e).await
}
AnyStateEventStub::Custom(e) => {
event_emitter event_emitter
.on_room_canonical_alias(room, &canonical) .on_unrecognized_event(room, &CustomOrRawEvent::State(&e))
.await
}
RoomEvent::RoomAliases(aliases) => event_emitter.on_room_aliases(room, &aliases).await,
RoomEvent::RoomAvatar(avatar) => event_emitter.on_room_avatar(room, &avatar).await,
RoomEvent::RoomMessage(msg) => event_emitter.on_room_message(room, &msg).await,
RoomEvent::RoomMessageFeedback(msg_feedback) => {
event_emitter
.on_room_message_feedback(room, &msg_feedback)
.await
}
RoomEvent::RoomRedaction(redaction) => {
event_emitter.on_room_redaction(room, &redaction).await
}
RoomEvent::RoomPowerLevels(power) => {
event_emitter.on_room_power_levels(room, &power).await
}
RoomEvent::RoomTombstone(tomb) => event_emitter.on_room_tombstone(room, &tomb).await,
RoomEvent::CustomRoom(custom) => {
event_emitter
.on_unrecognized_event(room, &CustomOrRawEvent::CustomRoom(custom))
.await .await
} }
_ => {} _ => {}
},
AnyRoomEventStub::Message(event) => match &event {
AnyMessageEventStub::RoomMessage(e) => {
event_emitter.on_room_message(room, &e).await
}
AnyMessageEventStub::RoomMessageFeedback(e) => {
event_emitter.on_room_message_feedback(room, &e).await
}
AnyMessageEventStub::RoomRedaction(e) => {
event_emitter.on_room_redaction(room, e).await
}
AnyMessageEventStub::Custom(e) => {
event_emitter
.on_unrecognized_event(room, &CustomOrRawEvent::Message(&e))
.await
}
_ => {}
},
} }
} }
pub(crate) async fn emit_state_event( pub(crate) async fn emit_state_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &StateEvent, event: &AnyStateEventStub,
room_state: RoomStateType, room_state: RoomStateType,
) { ) {
let lock = self.event_emitter.read().await; let lock = self.event_emitter.read().await;
@ -1534,27 +1563,34 @@ impl BaseClient {
}; };
match event { match event {
StateEvent::RoomMember(member) => event_emitter.on_state_member(room, &member).await, AnyStateEventStub::RoomMember(member) => {
StateEvent::RoomName(name) => event_emitter.on_state_name(room, &name).await, event_emitter.on_state_member(room, &member).await
StateEvent::RoomCanonicalAlias(canonical) => { }
AnyStateEventStub::RoomName(name) => event_emitter.on_state_name(room, &name).await,
AnyStateEventStub::RoomCanonicalAlias(canonical) => {
event_emitter event_emitter
.on_state_canonical_alias(room, &canonical) .on_state_canonical_alias(room, &canonical)
.await .await
} }
StateEvent::RoomAliases(aliases) => { AnyStateEventStub::RoomAliases(aliases) => {
event_emitter.on_state_aliases(room, &aliases).await event_emitter.on_state_aliases(room, &aliases).await
} }
StateEvent::RoomAvatar(avatar) => event_emitter.on_state_avatar(room, &avatar).await, AnyStateEventStub::RoomAvatar(avatar) => {
StateEvent::RoomPowerLevels(power) => { event_emitter.on_state_avatar(room, &avatar).await
}
AnyStateEventStub::RoomPowerLevels(power) => {
event_emitter.on_state_power_levels(room, &power).await event_emitter.on_state_power_levels(room, &power).await
} }
StateEvent::RoomJoinRules(rules) => { AnyStateEventStub::RoomJoinRules(rules) => {
event_emitter.on_state_join_rules(room, &rules).await event_emitter.on_state_join_rules(room, &rules).await
} }
StateEvent::RoomTombstone(tomb) => event_emitter.on_room_tombstone(room, &tomb).await, AnyStateEventStub::RoomTombstone(tomb) => {
StateEvent::CustomState(custom) => { // TODO make `on_state_tombstone` method
event_emitter.on_room_tombstone(room, &tomb).await
}
AnyStateEventStub::Custom(custom) => {
event_emitter event_emitter
.on_unrecognized_event(room, &CustomOrRawEvent::CustomState(custom)) .on_unrecognized_event(room, &CustomOrRawEvent::State(custom))
.await .await
} }
_ => {} _ => {}
@ -1564,7 +1600,7 @@ impl BaseClient {
pub(crate) async fn emit_stripped_state_event( pub(crate) async fn emit_stripped_state_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &AnyStrippedStateEvent, event: &AnyStrippedStateEventStub,
prev_content: Option<MemberEventContent>, prev_content: Option<MemberEventContent>,
room_state: RoomStateType, room_state: RoomStateType,
) { ) {
@ -1600,33 +1636,33 @@ impl BaseClient {
}; };
match event { match event {
AnyStrippedStateEvent::RoomMember(member) => { AnyStrippedStateEventStub::RoomMember(member) => {
event_emitter event_emitter
.on_stripped_state_member(room, &member, prev_content) .on_stripped_state_member(room, &member, prev_content)
.await .await
} }
AnyStrippedStateEvent::RoomName(name) => { AnyStrippedStateEventStub::RoomName(name) => {
event_emitter.on_stripped_state_name(room, &name).await event_emitter.on_stripped_state_name(room, &name).await
} }
AnyStrippedStateEvent::RoomCanonicalAlias(canonical) => { AnyStrippedStateEventStub::RoomCanonicalAlias(canonical) => {
event_emitter event_emitter
.on_stripped_state_canonical_alias(room, &canonical) .on_stripped_state_canonical_alias(room, &canonical)
.await .await
} }
AnyStrippedStateEvent::RoomAliases(aliases) => { AnyStrippedStateEventStub::RoomAliases(aliases) => {
event_emitter event_emitter
.on_stripped_state_aliases(room, &aliases) .on_stripped_state_aliases(room, &aliases)
.await .await
} }
AnyStrippedStateEvent::RoomAvatar(avatar) => { AnyStrippedStateEventStub::RoomAvatar(avatar) => {
event_emitter.on_stripped_state_avatar(room, &avatar).await event_emitter.on_stripped_state_avatar(room, &avatar).await
} }
AnyStrippedStateEvent::RoomPowerLevels(power) => { AnyStrippedStateEventStub::RoomPowerLevels(power) => {
event_emitter event_emitter
.on_stripped_state_power_levels(room, &power) .on_stripped_state_power_levels(room, &power)
.await .await
} }
AnyStrippedStateEvent::RoomJoinRules(rules) => { AnyStrippedStateEventStub::RoomJoinRules(rules) => {
event_emitter event_emitter
.on_stripped_state_join_rules(room, &rules) .on_stripped_state_join_rules(room, &rules)
.await .await
@ -1638,7 +1674,7 @@ impl BaseClient {
pub(crate) async fn emit_account_data_event( pub(crate) async fn emit_account_data_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &NonRoomEvent, event: &AnyBasicEvent,
room_state: RoomStateType, room_state: RoomStateType,
) { ) {
let lock = self.event_emitter.read().await; let lock = self.event_emitter.read().await;
@ -1673,21 +1709,17 @@ impl BaseClient {
}; };
match event { match event {
NonRoomEvent::Presence(presence) => { AnyBasicEvent::Presence(presence) => {
event_emitter.on_non_room_presence(room, &presence).await event_emitter.on_non_room_presence(room, &presence).await
} }
NonRoomEvent::IgnoredUserList(ignored) => { AnyBasicEvent::IgnoredUserList(ignored) => {
event_emitter event_emitter
.on_non_room_ignored_users(room, &ignored) .on_non_room_ignored_users(room, &ignored)
.await .await
} }
NonRoomEvent::PushRules(rules) => { AnyBasicEvent::PushRules(rules) => {
event_emitter.on_non_room_push_rules(room, &rules).await event_emitter.on_non_room_push_rules(room, &rules).await
} }
NonRoomEvent::FullyRead(full_read) => {
event_emitter.on_non_room_fully_read(room, &full_read).await
}
NonRoomEvent::Typing(typing) => event_emitter.on_non_room_typing(room, &typing).await,
_ => {} _ => {}
} }
} }
@ -1695,7 +1727,7 @@ impl BaseClient {
pub(crate) async fn emit_ephemeral_event( pub(crate) async fn emit_ephemeral_event(
&self, &self,
room_id: &RoomId, room_id: &RoomId,
event: &NonRoomEvent, event: &AnyEphemeralRoomEvent,
room_state: RoomStateType, room_state: RoomStateType,
) { ) {
let lock = self.event_emitter.read().await; let lock = self.event_emitter.read().await;
@ -1730,21 +1762,15 @@ impl BaseClient {
}; };
match event { match event {
NonRoomEvent::Presence(presence) => { AnyEphemeralRoomEvent::FullyRead(full_read) => {
event_emitter.on_non_room_presence(room, &presence).await
}
NonRoomEvent::IgnoredUserList(ignored) => {
event_emitter
.on_non_room_ignored_users(room, &ignored)
.await
}
NonRoomEvent::PushRules(rules) => {
event_emitter.on_non_room_push_rules(room, &rules).await
}
NonRoomEvent::FullyRead(full_read) => {
event_emitter.on_non_room_fully_read(room, &full_read).await event_emitter.on_non_room_fully_read(room, &full_read).await
} }
NonRoomEvent::Typing(typing) => event_emitter.on_non_room_typing(room, &typing).await, AnyEphemeralRoomEvent::Typing(typing) => {
event_emitter.on_non_room_typing(room, &typing).await
}
AnyEphemeralRoomEvent::Receipt(receipt) => {
event_emitter.on_non_room_receipt(room, &receipt).await
}
_ => {} _ => {}
} }
} }
@ -1822,12 +1848,9 @@ impl BaseClient {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::{ use crate::{events::AnyRoomEventStub, BaseClient, Session};
events::{collections::all::RoomEvent, stripped::AnyStrippedStateEvent},
BaseClient, Session,
};
use matrix_sdk_common_macros::async_trait; use matrix_sdk_common_macros::async_trait;
use matrix_sdk_test::{async_test, test_json, EventBuilder, EventsJson}; use matrix_sdk_test::{async_test, test_json, EventBuilder, EventsFile};
use serde_json::json; use serde_json::json;
use std::convert::TryFrom; use std::convert::TryFrom;
@ -1860,14 +1883,14 @@ mod test {
"origin_server_ts": 0, "origin_server_ts": 0,
"sender": "@example:localhost", "sender": "@example:localhost",
"state_key": "@example:localhost", "state_key": "@example:localhost",
"type": "m.room.member", "type": "m.room.member"
}) })
} }
#[async_test] #[async_test]
async fn test_joined_room_creation() { async fn test_joined_room_creation() {
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_room_event(EventsJson::Member, RoomEvent::RoomMember) .add_state_event(EventsFile::Member)
.build_sync_response(); .build_sync_response();
let client = get_client().await; let client = get_client().await;
let room_id = get_room_id(); let room_id = get_room_id();
@ -1887,7 +1910,7 @@ mod test {
assert!(room.is_some()); assert!(room.is_some());
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_custom_left_event(&room_id, member_event(), RoomEvent::RoomMember) .add_custom_left_event(&room_id, member_event(), AnyRoomEventStub::State)
.build_sync_response(); .build_sync_response();
sync_response.next_batch = "Hello".to_owned(); sync_response.next_batch = "Hello".to_owned();
@ -1908,7 +1931,7 @@ mod test {
async fn test_left_room_creation() { async fn test_left_room_creation() {
let room_id = RoomId::try_from("!left_room:localhost").unwrap(); let room_id = RoomId::try_from("!left_room:localhost").unwrap();
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_custom_left_event(&room_id, member_event(), RoomEvent::RoomMember) .add_custom_left_event(&room_id, member_event(), AnyRoomEventStub::State)
.build_sync_response(); .build_sync_response();
let client = get_client().await; let client = get_client().await;
@ -1925,7 +1948,7 @@ mod test {
assert!(room.is_some()); assert!(room.is_some());
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_custom_joined_event(&room_id, member_event(), RoomEvent::RoomMember) .add_custom_joined_event(&room_id, member_event(), AnyRoomEventStub::State)
.build_sync_response(); .build_sync_response();
sync_response.next_batch = "Hello".to_owned(); sync_response.next_batch = "Hello".to_owned();
@ -1946,7 +1969,7 @@ mod test {
async fn test_invited_room_creation() { async fn test_invited_room_creation() {
let room_id = RoomId::try_from("!invited_room:localhost").unwrap(); let room_id = RoomId::try_from("!invited_room:localhost").unwrap();
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_custom_invited_event(&room_id, member_event(), AnyStrippedStateEvent::RoomMember) .add_custom_invited_event(&room_id, member_event())
.build_sync_response(); .build_sync_response();
let client = get_client().await; let client = get_client().await;
@ -1963,7 +1986,7 @@ mod test {
assert!(room.is_some()); assert!(room.is_some());
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_custom_joined_event(&room_id, member_event(), RoomEvent::RoomMember) .add_custom_joined_event(&room_id, member_event(), AnyRoomEventStub::State)
.build_sync_response(); .build_sync_response();
sync_response.next_batch = "Hello".to_owned(); sync_response.next_batch = "Hello".to_owned();
@ -1985,7 +2008,10 @@ mod test {
use super::*; use super::*;
use crate::{EventEmitter, SyncRoom}; use crate::{EventEmitter, SyncRoom};
use matrix_sdk_common::events::room::member::{MemberEvent, MembershipChange}; use matrix_sdk_common::events::{
room::member::{MemberEventContent, MembershipChange},
StateEventStub,
};
use matrix_sdk_common::locks::RwLock; use matrix_sdk_common::locks::RwLock;
use std::sync::{ use std::sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
@ -1995,14 +2021,15 @@ 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_room_member(&self, room: SyncRoom, event: &MemberEvent) { async fn on_room_member(
&self,
room: SyncRoom,
event: &StateEventStub<MemberEventContent>,
) {
if let SyncRoom::Joined(_) = room { if let SyncRoom::Joined(_) = room {
match event.membership_change() { if let MembershipChange::Joined = event.membership_change() {
MembershipChange::Joined => {
self.0.swap(true, Ordering::SeqCst); self.0.swap(true, Ordering::SeqCst);
} }
_ => {}
};
} }
if event.prev_content.is_none() { if event.prev_content.is_none() {
self.0.swap(false, Ordering::SeqCst); self.0.swap(false, Ordering::SeqCst);
@ -2237,6 +2264,7 @@ mod test {
use super::*; use super::*;
use crate::{EventEmitter, SyncRoom}; use crate::{EventEmitter, SyncRoom};
use matrix_sdk_common::api::r0::sync::sync_events;
use matrix_sdk_common::locks::RwLock; use matrix_sdk_common::locks::RwLock;
use std::sync::{ use std::sync::{
atomic::{AtomicBool, Ordering}, atomic::{AtomicBool, Ordering},
@ -2248,9 +2276,9 @@ mod test {
impl EventEmitter for EE { impl EventEmitter for EE {
async fn on_unrecognized_event(&self, room: SyncRoom, event: &CustomOrRawEvent<'_>) { async fn on_unrecognized_event(&self, room: SyncRoom, event: &CustomOrRawEvent<'_>) {
if let SyncRoom::Joined(_) = room { if let SyncRoom::Joined(_) = room {
if let CustomOrRawEvent::CustomRoom(custom) = event { if let CustomOrRawEvent::Message(custom) = event {
if custom.event_type == "m.reaction" if custom.content.event_type == "m.reaction"
&& custom.content.get("m.relates_to").is_some() && custom.content.json.get("m.relates_to").is_some()
{ {
self.0.swap(true, Ordering::SeqCst); self.0.swap(true, Ordering::SeqCst);
} }
@ -2316,8 +2344,7 @@ mod test {
let response = http::Response::builder() let response = http::Response::builder()
.body(serde_json::to_vec(&body).unwrap()) .body(serde_json::to_vec(&body).unwrap())
.unwrap(); .unwrap();
let mut sync = let mut sync = sync_events::Response::try_from(response).unwrap();
matrix_sdk_common::api::r0::sync::sync_events::Response::try_from(response).unwrap();
client.receive_sync_response(&mut sync).await.unwrap(); client.receive_sync_response(&mut sync).await.unwrap();
@ -2331,7 +2358,7 @@ mod test {
let room_id = get_room_id(); let room_id = get_room_id();
let mut sync_response = EventBuilder::default() let mut sync_response = EventBuilder::default()
.add_room_event(EventsJson::Member, RoomEvent::RoomMember) .add_state_event(EventsFile::Member)
.build_sync_response(); .build_sync_response();
client client

View File

@ -18,29 +18,26 @@ use matrix_sdk_common::locks::RwLock;
use serde_json::value::RawValue as RawJsonValue; use serde_json::value::RawValue as RawJsonValue;
use crate::events::{ use crate::events::{
fully_read::FullyReadEvent, custom::CustomEventContent,
ignored_user_list::IgnoredUserListEvent, fully_read::FullyReadEventContent,
ignored_user_list::IgnoredUserListEventContent,
presence::PresenceEvent, presence::PresenceEvent,
push_rules::PushRulesEvent, push_rules::PushRulesEventContent,
receipt::ReceiptEvent, receipt::ReceiptEventContent,
room::{ room::{
aliases::AliasesEvent, aliases::AliasesEventContent,
avatar::AvatarEvent, avatar::AvatarEventContent,
canonical_alias::CanonicalAliasEvent, canonical_alias::CanonicalAliasEventContent,
join_rules::JoinRulesEvent, join_rules::JoinRulesEventContent,
member::{MemberEvent, MemberEventContent}, member::MemberEventContent,
message::{feedback::FeedbackEvent, MessageEvent}, message::{feedback::FeedbackEventContent, MessageEventContent as MsgEventContent},
name::NameEvent, name::NameEventContent,
power_levels::PowerLevelsEvent, power_levels::PowerLevelsEventContent,
redaction::RedactionEvent, redaction::RedactionEventStub,
tombstone::TombstoneEvent, tombstone::TombstoneEventContent,
}, },
stripped::{ typing::TypingEventContent,
StrippedRoomAliases, StrippedRoomAvatar, StrippedRoomCanonicalAlias, StrippedRoomJoinRules, BasicEvent, EphemeralRoomEvent, MessageEventStub, StateEventStub, StrippedStateEventStub,
StrippedRoomMember, StrippedRoomName, StrippedRoomPowerLevels,
},
typing::TypingEvent,
CustomEvent, CustomRoomEvent, CustomStateEvent,
}; };
use crate::{Room, RoomState}; use crate::{Room, RoomState};
use matrix_sdk_common_macros::async_trait; use matrix_sdk_common_macros::async_trait;
@ -52,15 +49,17 @@ pub type SyncRoom = RoomState<Arc<RwLock<Room>>>;
#[derive(Clone, Copy, Debug)] #[derive(Clone, Copy, Debug)]
pub enum CustomOrRawEvent<'c> { pub enum CustomOrRawEvent<'c> {
/// When an event can not be deserialized by ruma. /// When an event can not be deserialized by ruma.
///
/// This will be mostly obsolete when ruma-events is updated.
RawJson(&'c RawJsonValue), RawJson(&'c RawJsonValue),
/// A custom event. /// A custom basic event.
Custom(&'c CustomEvent), Basic(&'c BasicEvent<CustomEventContent>),
/// A custom basic event.
EphemeralRoom(&'c EphemeralRoomEvent<CustomEventContent>),
/// A custom room event. /// A custom room event.
CustomRoom(&'c CustomRoomEvent), Message(&'c MessageEventStub<CustomEventContent>),
/// A custom state event. /// A custom state event.
CustomState(&'c CustomStateEvent), State(&'c StateEventStub<CustomEventContent>),
/// A custom stripped state event.
StrippedState(&'c StrippedStateEventStub<CustomEventContent>),
} }
/// This trait allows any type implementing `EventEmitter` to specify event callbacks for each event. /// This trait allows any type implementing `EventEmitter` to specify event callbacks for each event.
@ -74,7 +73,8 @@ pub enum CustomOrRawEvent<'c> {
/// # use matrix_sdk_base::{ /// # use matrix_sdk_base::{
/// # self, /// # self,
/// # events::{ /// # events::{
/// # room::message::{MessageEvent, MessageEventContent, TextMessageEventContent}, /// # room::message::{MessageEventContent, TextMessageEventContent},
/// # MessageEventStub
/// # }, /// # },
/// # EventEmitter, SyncRoom /// # EventEmitter, SyncRoom
/// # }; /// # };
@ -85,9 +85,9 @@ pub enum CustomOrRawEvent<'c> {
/// ///
/// #[async_trait] /// #[async_trait]
/// impl EventEmitter for EventCallback { /// impl EventEmitter for EventCallback {
/// async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) { /// async fn on_room_message(&self, room: SyncRoom, event: &MessageEventStub<MessageEventContent>) {
/// if let SyncRoom::Joined(room) = room { /// if let SyncRoom::Joined(room) = room {
/// if let MessageEvent { /// if let MessageEventStub {
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), /// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
/// sender, /// sender,
/// .. /// ..
@ -112,80 +112,140 @@ pub enum CustomOrRawEvent<'c> {
pub trait EventEmitter: Send + Sync { pub trait EventEmitter: Send + Sync {
// ROOM EVENTS from `IncomingTimeline` // ROOM EVENTS from `IncomingTimeline`
/// Fires when `Client` receives a `RoomEvent::RoomMember` event. /// Fires when `Client` receives a `RoomEvent::RoomMember` event.
async fn on_room_member(&self, _: SyncRoom, _: &MemberEvent) {} async fn on_room_member(&self, _: SyncRoom, _: &StateEventStub<MemberEventContent>) {}
/// Fires when `Client` receives a `RoomEvent::RoomName` event. /// Fires when `Client` receives a `RoomEvent::RoomName` event.
async fn on_room_name(&self, _: SyncRoom, _: &NameEvent) {} async fn on_room_name(&self, _: SyncRoom, _: &StateEventStub<NameEventContent>) {}
/// Fires when `Client` receives a `RoomEvent::RoomCanonicalAlias` event. /// Fires when `Client` receives a `RoomEvent::RoomCanonicalAlias` event.
async fn on_room_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) {} async fn on_room_canonical_alias(
&self,
_: SyncRoom,
_: &StateEventStub<CanonicalAliasEventContent>,
) {
}
/// Fires when `Client` receives a `RoomEvent::RoomAliases` event. /// Fires when `Client` receives a `RoomEvent::RoomAliases` event.
async fn on_room_aliases(&self, _: SyncRoom, _: &AliasesEvent) {} async fn on_room_aliases(&self, _: SyncRoom, _: &StateEventStub<AliasesEventContent>) {}
/// Fires when `Client` receives a `RoomEvent::RoomAvatar` event. /// Fires when `Client` receives a `RoomEvent::RoomAvatar` event.
async fn on_room_avatar(&self, _: SyncRoom, _: &AvatarEvent) {} async fn on_room_avatar(&self, _: SyncRoom, _: &StateEventStub<AvatarEventContent>) {}
/// Fires when `Client` receives a `RoomEvent::RoomMessage` event. /// Fires when `Client` receives a `RoomEvent::RoomMessage` event.
async fn on_room_message(&self, _: SyncRoom, _: &MessageEvent) {} async fn on_room_message(&self, _: SyncRoom, _: &MessageEventStub<MsgEventContent>) {}
/// Fires when `Client` receives a `RoomEvent::RoomMessageFeedback` event. /// Fires when `Client` receives a `RoomEvent::RoomMessageFeedback` event.
async fn on_room_message_feedback(&self, _: SyncRoom, _: &FeedbackEvent) {} async fn on_room_message_feedback(
&self,
_: SyncRoom,
_: &MessageEventStub<FeedbackEventContent>,
) {
}
/// Fires when `Client` receives a `RoomEvent::RoomRedaction` event. /// Fires when `Client` receives a `RoomEvent::RoomRedaction` event.
async fn on_room_redaction(&self, _: SyncRoom, _: &RedactionEvent) {} async fn on_room_redaction(&self, _: SyncRoom, _: &RedactionEventStub) {}
/// Fires when `Client` receives a `RoomEvent::RoomPowerLevels` event. /// Fires when `Client` receives a `RoomEvent::RoomPowerLevels` event.
async fn on_room_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) {} async fn on_room_power_levels(&self, _: SyncRoom, _: &StateEventStub<PowerLevelsEventContent>) {
}
/// Fires when `Client` receives a `RoomEvent::Tombstone` event. /// Fires when `Client` receives a `RoomEvent::Tombstone` event.
async fn on_room_tombstone(&self, _: SyncRoom, _: &TombstoneEvent) {} async fn on_room_tombstone(&self, _: SyncRoom, _: &StateEventStub<TombstoneEventContent>) {}
// `RoomEvent`s from `IncomingState` // `RoomEvent`s from `IncomingState`
/// Fires when `Client` receives a `StateEvent::RoomMember` event. /// Fires when `Client` receives a `StateEvent::RoomMember` event.
async fn on_state_member(&self, _: SyncRoom, _: &MemberEvent) {} async fn on_state_member(&self, _: SyncRoom, _: &StateEventStub<MemberEventContent>) {}
/// Fires when `Client` receives a `StateEvent::RoomName` event. /// Fires when `Client` receives a `StateEvent::RoomName` event.
async fn on_state_name(&self, _: SyncRoom, _: &NameEvent) {} async fn on_state_name(&self, _: SyncRoom, _: &StateEventStub<NameEventContent>) {}
/// Fires when `Client` receives a `StateEvent::RoomCanonicalAlias` event. /// Fires when `Client` receives a `StateEvent::RoomCanonicalAlias` event.
async fn on_state_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) {} async fn on_state_canonical_alias(
&self,
_: SyncRoom,
_: &StateEventStub<CanonicalAliasEventContent>,
) {
}
/// Fires when `Client` receives a `StateEvent::RoomAliases` event. /// Fires when `Client` receives a `StateEvent::RoomAliases` event.
async fn on_state_aliases(&self, _: SyncRoom, _: &AliasesEvent) {} async fn on_state_aliases(&self, _: SyncRoom, _: &StateEventStub<AliasesEventContent>) {}
/// Fires when `Client` receives a `StateEvent::RoomAvatar` event. /// Fires when `Client` receives a `StateEvent::RoomAvatar` event.
async fn on_state_avatar(&self, _: SyncRoom, _: &AvatarEvent) {} async fn on_state_avatar(&self, _: SyncRoom, _: &StateEventStub<AvatarEventContent>) {}
/// Fires when `Client` receives a `StateEvent::RoomPowerLevels` event. /// Fires when `Client` receives a `StateEvent::RoomPowerLevels` event.
async fn on_state_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) {} async fn on_state_power_levels(
&self,
_: SyncRoom,
_: &StateEventStub<PowerLevelsEventContent>,
) {
}
/// Fires when `Client` receives a `StateEvent::RoomJoinRules` event. /// Fires when `Client` receives a `StateEvent::RoomJoinRules` event.
async fn on_state_join_rules(&self, _: SyncRoom, _: &JoinRulesEvent) {} async fn on_state_join_rules(&self, _: SyncRoom, _: &StateEventStub<JoinRulesEventContent>) {}
// `AnyStrippedStateEvent`s // `AnyStrippedStateEvent`s
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomMember` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
async fn on_stripped_state_member( async fn on_stripped_state_member(
&self, &self,
_: SyncRoom, _: SyncRoom,
_: &StrippedRoomMember, _: &StrippedStateEventStub<MemberEventContent>,
_: Option<MemberEventContent>, _: Option<MemberEventContent>,
) { ) {
} }
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomName` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
async fn on_stripped_state_name(&self, _: SyncRoom, _: &StrippedRoomName) {} async fn on_stripped_state_name(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<NameEventContent>,
) {
}
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
async fn on_stripped_state_canonical_alias(&self, _: SyncRoom, _: &StrippedRoomCanonicalAlias) { async fn on_stripped_state_canonical_alias(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<CanonicalAliasEventContent>,
) {
} }
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
async fn on_stripped_state_aliases(&self, _: SyncRoom, _: &StrippedRoomAliases) {} async fn on_stripped_state_aliases(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<AliasesEventContent>,
) {
}
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
async fn on_stripped_state_avatar(&self, _: SyncRoom, _: &StrippedRoomAvatar) {} async fn on_stripped_state_avatar(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<AvatarEventContent>,
) {
}
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
async fn on_stripped_state_power_levels(&self, _: SyncRoom, _: &StrippedRoomPowerLevels) {} async fn on_stripped_state_power_levels(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<PowerLevelsEventContent>,
) {
}
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event. /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
async fn on_stripped_state_join_rules(&self, _: SyncRoom, _: &StrippedRoomJoinRules) {} async fn on_stripped_state_join_rules(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<JoinRulesEventContent>,
) {
}
// `NonRoomEvent` (this is a type alias from ruma_events) // `NonRoomEvent` (this is a type alias from ruma_events)
/// Fires when `Client` receives a `NonRoomEvent::RoomPresence` event. /// Fires when `Client` receives a `NonRoomEvent::RoomPresence` event.
async fn on_non_room_presence(&self, _: SyncRoom, _: &PresenceEvent) {} async fn on_non_room_presence(&self, _: SyncRoom, _: &PresenceEvent) {}
/// Fires when `Client` receives a `NonRoomEvent::RoomName` event. /// Fires when `Client` receives a `NonRoomEvent::RoomName` event.
async fn on_non_room_ignored_users(&self, _: SyncRoom, _: &IgnoredUserListEvent) {} async fn on_non_room_ignored_users(
&self,
_: SyncRoom,
_: &BasicEvent<IgnoredUserListEventContent>,
) {
}
/// Fires when `Client` receives a `NonRoomEvent::RoomCanonicalAlias` event. /// Fires when `Client` receives a `NonRoomEvent::RoomCanonicalAlias` event.
async fn on_non_room_push_rules(&self, _: SyncRoom, _: &PushRulesEvent) {} async fn on_non_room_push_rules(&self, _: SyncRoom, _: &BasicEvent<PushRulesEventContent>) {}
/// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event. /// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event.
async fn on_non_room_fully_read(&self, _: SyncRoom, _: &FullyReadEvent) {} async fn on_non_room_fully_read(
&self,
_: SyncRoom,
_: &EphemeralRoomEvent<FullyReadEventContent>,
) {
}
/// Fires when `Client` receives a `NonRoomEvent::Typing` event. /// Fires when `Client` receives a `NonRoomEvent::Typing` event.
async fn on_non_room_typing(&self, _: SyncRoom, _: &TypingEvent) {} async fn on_non_room_typing(&self, _: SyncRoom, _: &EphemeralRoomEvent<TypingEventContent>) {}
/// Fires when `Client` receives a `NonRoomEvent::Receipt` event. /// Fires when `Client` receives a `NonRoomEvent::Receipt` event.
/// ///
/// This is always a read receipt. /// This is always a read receipt.
async fn on_non_room_receipt(&self, _: SyncRoom, _: &ReceiptEvent) {} async fn on_non_room_receipt(&self, _: SyncRoom, _: &EphemeralRoomEvent<ReceiptEventContent>) {}
// `PresenceEvent` is a struct so there is only the one method // `PresenceEvent` is a struct so there is only the one method
/// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event. /// Fires when `Client` receives a `NonRoomEvent::RoomAliases` event.
@ -214,63 +274,89 @@ mod test {
#[async_trait] #[async_trait]
impl EventEmitter for EvEmitterTest { impl EventEmitter for EvEmitterTest {
async fn on_room_member(&self, _: SyncRoom, _: &MemberEvent) { async fn on_room_member(&self, _: SyncRoom, _: &StateEventStub<MemberEventContent>) {
self.0.lock().await.push("member".to_string()) self.0.lock().await.push("member".to_string())
} }
async fn on_room_name(&self, _: SyncRoom, _: &NameEvent) { async fn on_room_name(&self, _: SyncRoom, _: &StateEventStub<NameEventContent>) {
self.0.lock().await.push("name".to_string()) self.0.lock().await.push("name".to_string())
} }
async fn on_room_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) { async fn on_room_canonical_alias(
&self,
_: SyncRoom,
_: &StateEventStub<CanonicalAliasEventContent>,
) {
self.0.lock().await.push("canonical".to_string()) self.0.lock().await.push("canonical".to_string())
} }
async fn on_room_aliases(&self, _: SyncRoom, _: &AliasesEvent) { async fn on_room_aliases(&self, _: SyncRoom, _: &StateEventStub<AliasesEventContent>) {
self.0.lock().await.push("aliases".to_string()) self.0.lock().await.push("aliases".to_string())
} }
async fn on_room_avatar(&self, _: SyncRoom, _: &AvatarEvent) { async fn on_room_avatar(&self, _: SyncRoom, _: &StateEventStub<AvatarEventContent>) {
self.0.lock().await.push("avatar".to_string()) self.0.lock().await.push("avatar".to_string())
} }
async fn on_room_message(&self, _: SyncRoom, _: &MessageEvent) { async fn on_room_message(&self, _: SyncRoom, _: &MessageEventStub<MsgEventContent>) {
self.0.lock().await.push("message".to_string()) self.0.lock().await.push("message".to_string())
} }
async fn on_room_message_feedback(&self, _: SyncRoom, _: &FeedbackEvent) { async fn on_room_message_feedback(
&self,
_: SyncRoom,
_: &MessageEventStub<FeedbackEventContent>,
) {
self.0.lock().await.push("feedback".to_string()) self.0.lock().await.push("feedback".to_string())
} }
async fn on_room_redaction(&self, _: SyncRoom, _: &RedactionEvent) { async fn on_room_redaction(&self, _: SyncRoom, _: &RedactionEventStub) {
self.0.lock().await.push("redaction".to_string()) self.0.lock().await.push("redaction".to_string())
} }
async fn on_room_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) { async fn on_room_power_levels(
&self,
_: SyncRoom,
_: &StateEventStub<PowerLevelsEventContent>,
) {
self.0.lock().await.push("power".to_string()) self.0.lock().await.push("power".to_string())
} }
async fn on_room_tombstone(&self, _: SyncRoom, _: &TombstoneEvent) { async fn on_room_tombstone(&self, _: SyncRoom, _: &StateEventStub<TombstoneEventContent>) {
self.0.lock().await.push("tombstone".to_string()) self.0.lock().await.push("tombstone".to_string())
} }
async fn on_state_member(&self, _: SyncRoom, _: &MemberEvent) { async fn on_state_member(&self, _: SyncRoom, _: &StateEventStub<MemberEventContent>) {
self.0.lock().await.push("state member".to_string()) self.0.lock().await.push("state member".to_string())
} }
async fn on_state_name(&self, _: SyncRoom, _: &NameEvent) { async fn on_state_name(&self, _: SyncRoom, _: &StateEventStub<NameEventContent>) {
self.0.lock().await.push("state name".to_string()) self.0.lock().await.push("state name".to_string())
} }
async fn on_state_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) { async fn on_state_canonical_alias(
&self,
_: SyncRoom,
_: &StateEventStub<CanonicalAliasEventContent>,
) {
self.0.lock().await.push("state canonical".to_string()) self.0.lock().await.push("state canonical".to_string())
} }
async fn on_state_aliases(&self, _: SyncRoom, _: &AliasesEvent) { async fn on_state_aliases(&self, _: SyncRoom, _: &StateEventStub<AliasesEventContent>) {
self.0.lock().await.push("state aliases".to_string()) self.0.lock().await.push("state aliases".to_string())
} }
async fn on_state_avatar(&self, _: SyncRoom, _: &AvatarEvent) { async fn on_state_avatar(&self, _: SyncRoom, _: &StateEventStub<AvatarEventContent>) {
self.0.lock().await.push("state avatar".to_string()) self.0.lock().await.push("state avatar".to_string())
} }
async fn on_state_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) { async fn on_state_power_levels(
&self,
_: SyncRoom,
_: &StateEventStub<PowerLevelsEventContent>,
) {
self.0.lock().await.push("state power".to_string()) self.0.lock().await.push("state power".to_string())
} }
async fn on_state_join_rules(&self, _: SyncRoom, _: &JoinRulesEvent) { async fn on_state_join_rules(
&self,
_: SyncRoom,
_: &StateEventStub<JoinRulesEventContent>,
) {
self.0.lock().await.push("state rules".to_string()) self.0.lock().await.push("state rules".to_string())
} }
// `AnyStrippedStateEvent`s
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
async fn on_stripped_state_member( async fn on_stripped_state_member(
&self, &self,
_: SyncRoom, _: SyncRoom,
_: &StrippedRoomMember, _: &StrippedStateEventStub<MemberEventContent>,
_: Option<MemberEventContent>, _: Option<MemberEventContent>,
) { ) {
self.0 self.0
@ -278,57 +364,103 @@ mod test {
.await .await
.push("stripped state member".to_string()) .push("stripped state member".to_string())
} }
async fn on_stripped_state_name(&self, _: SyncRoom, _: &StrippedRoomName) { /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
async fn on_stripped_state_name(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<NameEventContent>,
) {
self.0.lock().await.push("stripped state name".to_string()) self.0.lock().await.push("stripped state name".to_string())
} }
/// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
async fn on_stripped_state_canonical_alias( async fn on_stripped_state_canonical_alias(
&self, &self,
_: SyncRoom, _: SyncRoom,
_: &StrippedRoomCanonicalAlias, _: &StrippedStateEventStub<CanonicalAliasEventContent>,
) { ) {
self.0 self.0
.lock() .lock()
.await .await
.push("stripped state canonical".to_string()) .push("stripped state canonical".to_string())
} }
async fn on_stripped_state_aliases(&self, _: SyncRoom, _: &StrippedRoomAliases) { /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
async fn on_stripped_state_aliases(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<AliasesEventContent>,
) {
self.0 self.0
.lock() .lock()
.await .await
.push("stripped state aliases".to_string()) .push("stripped state aliases".to_string())
} }
async fn on_stripped_state_avatar(&self, _: SyncRoom, _: &StrippedRoomAvatar) { /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
async fn on_stripped_state_avatar(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<AvatarEventContent>,
) {
self.0 self.0
.lock() .lock()
.await .await
.push("stripped state avatar".to_string()) .push("stripped state avatar".to_string())
} }
async fn on_stripped_state_power_levels(&self, _: SyncRoom, _: &StrippedRoomPowerLevels) { /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
async fn on_stripped_state_power_levels(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<PowerLevelsEventContent>,
) {
self.0.lock().await.push("stripped state power".to_string()) self.0.lock().await.push("stripped state power".to_string())
} }
async fn on_stripped_state_join_rules(&self, _: SyncRoom, _: &StrippedRoomJoinRules) { /// Fires when `Client` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
async fn on_stripped_state_join_rules(
&self,
_: SyncRoom,
_: &StrippedStateEventStub<JoinRulesEventContent>,
) {
self.0.lock().await.push("stripped state rules".to_string()) self.0.lock().await.push("stripped state rules".to_string())
} }
async fn on_non_room_presence(&self, _: SyncRoom, _: &PresenceEvent) { async fn on_non_room_presence(&self, _: SyncRoom, _: &PresenceEvent) {
self.0.lock().await.push("account presence".to_string()) self.0.lock().await.push("presence".to_string())
} }
async fn on_non_room_ignored_users(&self, _: SyncRoom, _: &IgnoredUserListEvent) { async fn on_non_room_ignored_users(
&self,
_: SyncRoom,
_: &BasicEvent<IgnoredUserListEventContent>,
) {
self.0.lock().await.push("account ignore".to_string()) self.0.lock().await.push("account ignore".to_string())
} }
async fn on_non_room_push_rules(&self, _: SyncRoom, _: &PushRulesEvent) { async fn on_non_room_push_rules(&self, _: SyncRoom, _: &BasicEvent<PushRulesEventContent>) {
self.0.lock().await.push("account push rules".to_string()) self.0.lock().await.push("account push rules".to_string())
} }
async fn on_non_room_fully_read(&self, _: SyncRoom, _: &FullyReadEvent) { async fn on_non_room_fully_read(
&self,
_: SyncRoom,
_: &EphemeralRoomEvent<FullyReadEventContent>,
) {
self.0.lock().await.push("account read".to_string()) self.0.lock().await.push("account read".to_string())
} }
async fn on_non_room_typing(&self, _: SyncRoom, _: &TypingEvent) { async fn on_non_room_typing(
&self,
_: SyncRoom,
_: &EphemeralRoomEvent<TypingEventContent>,
) {
self.0.lock().await.push("typing event".to_string()) self.0.lock().await.push("typing event".to_string())
} }
async fn on_non_room_receipt(
&self,
_: SyncRoom,
_: &EphemeralRoomEvent<ReceiptEventContent>,
) {
self.0.lock().await.push("receipt event".to_string())
}
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, event: &CustomOrRawEvent<'_>) {
println!("{:#?}", event);
self.0.lock().await.push("unrecognized event".to_string()) self.0.lock().await.push("unrecognized event".to_string())
} }
} }
@ -373,9 +505,10 @@ mod test {
"state member", "state member",
"state member", "state member",
"message", "message",
"account read",
"account ignore", "account ignore",
"presence event" "presence event",
"receipt event",
"account read",
], ],
) )
} }
@ -448,6 +581,7 @@ mod test {
"redaction", "redaction",
"unrecognized event", "unrecognized event",
"unrecognized event", "unrecognized event",
"receipt event",
"typing event" "typing event"
], ],
) )

View File

@ -1,55 +0,0 @@
//! De-/serialization functions to and from json strings, allows the type to be used as a query string.
use serde::de::{Deserialize, Deserializer, Error as _};
use crate::events::collections::all::Event;
use crate::events::presence::PresenceEvent;
use crate::events::EventJson;
pub fn deserialize_events<'de, D>(deserializer: D) -> Result<Vec<Event>, D::Error>
where
D: Deserializer<'de>,
{
let mut events = vec![];
let ev = Vec::<EventJson<Event>>::deserialize(deserializer)?;
for event in ev {
events.push(event.deserialize().map_err(D::Error::custom)?);
}
Ok(events)
}
pub fn deserialize_presence<'de, D>(deserializer: D) -> Result<Vec<PresenceEvent>, D::Error>
where
D: Deserializer<'de>,
{
let mut events = vec![];
let ev = Vec::<EventJson<PresenceEvent>>::deserialize(deserializer)?;
for event in ev {
events.push(event.deserialize().map_err(D::Error::custom)?);
}
Ok(events)
}
#[cfg(test)]
mod test {
use crate::events::room::member::MemberEvent;
use crate::events::EventJson;
use crate::models::RoomMember;
use matrix_sdk_test::test_json;
#[test]
fn events_and_presence_deserialization() {
let ev_json = test_json::MEMBER.to_string();
let ev = serde_json::from_str::<EventJson<MemberEvent>>(&ev_json)
.unwrap()
.deserialize()
.unwrap();
let member = RoomMember::new(&ev);
let member_json = serde_json::to_string(&member).unwrap();
let mem = serde_json::from_str::<RoomMember>(&member_json).unwrap();
assert_eq!(member, mem);
}
}

View File

@ -7,11 +7,12 @@ use std::cmp::Ordering;
use std::ops::Deref; use std::ops::Deref;
use std::vec::IntoIter; use std::vec::IntoIter;
use crate::events::room::message::MessageEvent; use crate::events::room::message::MessageEventContent;
use crate::events::EventJson; use crate::events::MessageEventStub;
use serde::{de, ser, Serialize}; use serde::{de, ser, Serialize};
type MessageEvent = MessageEventStub<MessageEventContent>;
/// A queue that holds the 10 most recent messages received from the server. /// A queue that holds the 10 most recent messages received from the server.
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
pub struct MessageQueue { pub struct MessageQueue {
@ -115,13 +116,10 @@ pub(crate) mod ser_deser {
where where
D: de::Deserializer<'de>, D: de::Deserializer<'de>,
{ {
use serde::de::Error; let messages: Vec<MessageEvent> = de::Deserialize::deserialize(deserializer)?;
let messages: Vec<EventJson<MessageEvent>> = de::Deserialize::deserialize(deserializer)?;
let mut msgs = vec![]; let mut msgs = vec![];
for json in messages { for msg in messages {
let msg = json.deserialize().map_err(D::Error::custom)?;
msgs.push(MessageWrapper(msg)); msgs.push(MessageWrapper(msg));
} }
@ -160,17 +158,11 @@ mod test {
let mut room = Room::new(&id, &user); let mut room = Room::new(&id, &user);
let json: &serde_json::Value = &test_json::MESSAGE_TEXT; let json: &serde_json::Value = &test_json::MESSAGE_TEXT;
let event = serde_json::from_value::<EventJson<RoomEvent>>(json.clone()).unwrap(); let msg = serde_json::from_value::<MessageEvent>(json.clone()).unwrap();
let mut msgs = MessageQueue::new(); let mut msgs = MessageQueue::new();
let message = if let RoomEvent::RoomMessage(msg) = event.deserialize().unwrap() {
msgs.push(msg.clone()); msgs.push(msg.clone());
msg room.messages = msgs;
} else {
panic!("this should always be a RoomMessage")
};
room.messages = msgs.clone();
let mut joined_rooms = HashMap::new(); let mut joined_rooms = HashMap::new();
joined_rooms.insert(id, room); joined_rooms.insert(id, room);
@ -191,7 +183,7 @@ mod test {
"creator": null, "creator": null,
"joined_members": {}, "joined_members": {},
"invited_members": {}, "invited_members": {},
"messages": [ message ], "messages": [ msg ],
"typing_users": [], "typing_users": [],
"power_levels": null, "power_levels": null,
"encrypted": null, "encrypted": null,
@ -212,19 +204,14 @@ mod test {
let mut room = Room::new(&id, &user); let mut room = Room::new(&id, &user);
let json: &serde_json::Value = &test_json::MESSAGE_TEXT; let json: &serde_json::Value = &test_json::MESSAGE_TEXT;
let event = serde_json::from_value::<EventJson<RoomEvent>>(json.clone()).unwrap(); let msg = serde_json::from_value::<MessageEvent>(json.clone()).unwrap();
let mut msgs = MessageQueue::new(); let mut msgs = MessageQueue::new();
let message = if let RoomEvent::RoomMessage(msg) = event.deserialize().unwrap() {
msgs.push(msg.clone()); msgs.push(msg.clone());
msg
} else {
panic!("this should always be a RoomMessage")
};
room.messages = msgs; room.messages = msgs;
let mut joined_rooms = HashMap::new(); let mut joined_rooms = HashMap::new();
joined_rooms.insert(id, room.clone()); joined_rooms.insert(id, room);
let json = serde_json::json!({ let json = serde_json::json!({
"!roomid:example.com": { "!roomid:example.com": {
@ -242,7 +229,7 @@ mod test {
"creator": null, "creator": null,
"joined_members": {}, "joined_members": {},
"invited_members": {}, "invited_members": {},
"messages": [ message ], "messages": [ msg ],
"typing_users": [], "typing_users": [],
"power_levels": null, "power_levels": null,
"encrypted": null, "encrypted": null,

View File

@ -1,4 +1,3 @@
mod event_deser;
#[cfg(feature = "messages")] #[cfg(feature = "messages")]
#[cfg_attr(docsrs, doc(cfg(feature = "messages")))] #[cfg_attr(docsrs, doc(cfg(feature = "messages")))]
mod message; mod message;

View File

@ -22,28 +22,35 @@ use super::message::MessageQueue;
use super::RoomMember; use super::RoomMember;
use crate::api::r0::sync::sync_events::{RoomSummary, UnreadNotificationsCount}; use crate::api::r0::sync::sync_events::{RoomSummary, UnreadNotificationsCount};
use crate::events::collections::all::{RoomEvent, StateEvent};
use crate::events::presence::PresenceEvent; use crate::events::presence::PresenceEvent;
use crate::events::room::{ use crate::events::room::{
aliases::AliasesEvent, aliases::AliasesEventContent,
canonical_alias::CanonicalAliasEvent, canonical_alias::CanonicalAliasEventContent,
encryption::EncryptionEvent, encryption::EncryptionEventContent,
member::{MemberEvent, MembershipChange}, member::{MemberEventContent, MembershipChange},
name::NameEvent, name::NameEventContent,
power_levels::{NotificationPowerLevels, PowerLevelsEvent, PowerLevelsEventContent}, power_levels::{NotificationPowerLevels, PowerLevelsEventContent},
tombstone::TombstoneEvent, tombstone::TombstoneEventContent,
};
use crate::events::{
Algorithm, AnyMessageEventStub, AnyRoomEventStub, AnyStateEventStub, AnyStrippedStateEventStub,
EventType, StateEventStub, StrippedStateEventStub,
}; };
use crate::events::stripped::{AnyStrippedStateEvent, StrippedRoomName};
use crate::events::{Algorithm, EventType};
#[cfg(feature = "messages")] #[cfg(feature = "messages")]
use crate::events::room::message::MessageEvent; use crate::events::{room::message::MessageEventContent as MsgContent, MessageEventStub};
use crate::identifiers::{RoomAliasId, RoomId, UserId}; use crate::identifiers::{RoomAliasId, RoomId, UserId};
use crate::js_int::{Int, UInt}; use crate::js_int::{Int, UInt};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[cfg(feature = "messages")]
type SentMessageEvent = MessageEventStub<MsgContent>;
#[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)] #[derive(Debug, Default, PartialEq, Serialize, Deserialize, Clone)]
#[cfg_attr(test, derive(Clone))]
/// `RoomName` allows the calculation of a text room name. /// `RoomName` allows the calculation of a text room name.
pub struct RoomName { pub struct RoomName {
/// The displayed name of the room. /// The displayed name of the room.
@ -123,8 +130,8 @@ impl EncryptionInfo {
} }
} }
impl From<&EncryptionEvent> for EncryptionInfo { impl From<&StateEventStub<EncryptionEventContent>> for EncryptionInfo {
fn from(event: &EncryptionEvent) -> Self { fn from(event: &StateEventStub<EncryptionEventContent>) -> Self {
EncryptionInfo { EncryptionInfo {
algorithm: event.content.algorithm.clone(), algorithm: event.content.algorithm.clone(),
rotation_period_ms: event rotation_period_ms: event
@ -357,29 +364,15 @@ impl Room {
} }
} }
/// Process the member event of an entering user. fn add_member(&mut self, event: &StateEventStub<MemberEventContent>, room_id: &RoomId) -> bool {
/// if self
/// Returns true if this made a change to the room's state, false otherwise. .members
fn add_member(&mut self, event: &MemberEvent) -> bool { .contains_key(&UserId::try_from(event.state_key.as_str()).unwrap())
let new_member = RoomMember::new(event);
if self.joined_members.contains_key(&new_member.user_id)
|| self.invited_members.contains_key(&new_member.user_id)
{ {
return false; return false;
} }
match event.membership_change() { let member = RoomMember::new(event, room_id);
MembershipChange::Joined => self
.joined_members
.insert(new_member.user_id.clone(), new_member.clone()),
MembershipChange::Invited => self
.invited_members
.insert(new_member.user_id.clone(), new_member.clone()),
_ => {
panic!("Room::add_member called on an event that is neither a join nor an invite.")
}
};
// Perform display name disambiguations, if necessary. // Perform display name disambiguations, if necessary.
let disambiguations = self.disambiguation_updates(&new_member, MemberDirection::Entering); let disambiguations = self.disambiguation_updates(&new_member, MemberDirection::Entering);
@ -396,7 +389,7 @@ impl Room {
/// Process the member event of a leaving user. /// Process the member event of a leaving user.
/// ///
/// Returns true if this made a change to the room's state, false otherwise. /// Returns true if this made a change to the room's state, false otherwise.
fn remove_member(&mut self, event: &MemberEvent) -> bool { fn remove_member(&mut self, event: &StateEventStub<MemberEventContent>) -> bool {
let leaving_member = RoomMember::new(event); let leaving_member = RoomMember::new(event);
// Perform display name disambiguations, if necessary. // Perform display name disambiguations, if necessary.
@ -535,7 +528,7 @@ impl Room {
true true
} }
fn set_room_power_level(&mut self, event: &PowerLevelsEvent) -> bool { fn set_room_power_level(&mut self, event: &StateEventStub<PowerLevelsEventContent>) -> bool {
let PowerLevelsEventContent { let PowerLevelsEventContent {
ban, ban,
events, events,
@ -583,7 +576,11 @@ impl Room {
/// Handle a room.member updating the room state if necessary. /// Handle a room.member updating the room state if necessary.
/// ///
/// Returns true if the joined member list changed, false otherwise. /// Returns true if the joined member list changed, false otherwise.
pub fn handle_membership(&mut self, event: &MemberEvent) -> bool { pub fn handle_membership(
&mut self,
event: &StateEventStub<MemberEventContent>,
room_id: &RoomId,
) -> bool {
use MembershipChange::*; use MembershipChange::*;
// TODO: This would not be handled correctly as all the MemberEvents have the `prev_content` // TODO: This would not be handled correctly as all the MemberEvents have the `prev_content`
@ -594,7 +591,7 @@ impl Room {
self.remove_member(event) self.remove_member(event)
} }
ProfileChanged => { ProfileChanged => {
let user_id = if let Ok(id) = UserId::try_from(event.state_key.as_str()) { let user = if let Ok(id) = UserId::try_from(event.state_key.as_str()) {
id id
} else { } else {
return false; return false;
@ -617,14 +614,14 @@ impl Room {
/// Returns true if `MessageQueue` was added to. /// Returns true if `MessageQueue` was added to.
#[cfg(feature = "messages")] #[cfg(feature = "messages")]
#[cfg_attr(docsrs, doc(cfg(feature = "messages")))] #[cfg_attr(docsrs, doc(cfg(feature = "messages")))]
pub fn handle_message(&mut self, event: &MessageEvent) -> bool { pub fn handle_message(&mut self, event: &SentMessageEvent) -> bool {
self.messages.push(event.clone()) self.messages.push(event.clone())
} }
/// Handle a room.aliases event, updating the room state if necessary. /// Handle a room.aliases event, updating the room state if necessary.
/// ///
/// Returns true if the room name changed, false otherwise. /// Returns true if the room name changed, false otherwise.
pub fn handle_room_aliases(&mut self, event: &AliasesEvent) -> bool { pub fn handle_room_aliases(&mut self, event: &StateEventStub<AliasesEventContent>) -> bool {
match event.content.aliases.as_slice() { match event.content.aliases.as_slice() {
[alias] => self.push_room_alias(alias), [alias] => self.push_room_alias(alias),
[alias, ..] => self.push_room_alias(alias), [alias, ..] => self.push_room_alias(alias),
@ -635,7 +632,7 @@ impl Room {
/// Handle a room.canonical_alias event, updating the room state if necessary. /// Handle a room.canonical_alias event, updating the room state if necessary.
/// ///
/// Returns true if the room name changed, false otherwise. /// Returns true if the room name changed, false otherwise.
pub fn handle_canonical(&mut self, event: &CanonicalAliasEvent) -> bool { pub fn handle_canonical(&mut self, event: &StateEventStub<CanonicalAliasEventContent>) -> bool {
match &event.content.alias { match &event.content.alias {
Some(name) => self.canonical_alias(&name), Some(name) => self.canonical_alias(&name),
_ => false, _ => false,
@ -645,7 +642,7 @@ impl Room {
/// Handle a room.name event, updating the room state if necessary. /// Handle a room.name event, updating the room state if necessary.
/// ///
/// Returns true if the room name changed, false otherwise. /// Returns true if the room name changed, false otherwise.
pub fn handle_room_name(&mut self, event: &NameEvent) -> bool { pub fn handle_room_name(&mut self, event: &StateEventStub<NameEventContent>) -> bool {
match event.content.name() { match event.content.name() {
Some(name) => self.set_room_name(name), Some(name) => self.set_room_name(name),
_ => false, _ => false,
@ -655,7 +652,10 @@ impl Room {
/// Handle a room.name event, updating the room state if necessary. /// Handle a room.name event, updating the room state if necessary.
/// ///
/// Returns true if the room name changed, false otherwise. /// Returns true if the room name changed, false otherwise.
pub fn handle_stripped_room_name(&mut self, event: &StrippedRoomName) -> bool { pub fn handle_stripped_room_name(
&mut self,
event: &StrippedStateEventStub<NameEventContent>,
) -> bool {
match event.content.name() { match event.content.name() {
Some(name) => self.set_room_name(name), Some(name) => self.set_room_name(name),
_ => false, _ => false,
@ -665,7 +665,7 @@ impl Room {
/// Handle a room.power_levels event, updating the room state if necessary. /// Handle a room.power_levels event, updating the room state if necessary.
/// ///
/// Returns true if the room name changed, false otherwise. /// Returns true if the room name changed, false otherwise.
pub fn handle_power_level(&mut self, event: &PowerLevelsEvent) -> bool { pub fn handle_power_level(&mut self, event: &StateEventStub<PowerLevelsEventContent>) -> bool {
// NOTE: this is always true, we assume that if we get an event their is an update. // NOTE: this is always true, we assume that if we get an event their is an update.
let mut updated = self.set_room_power_level(event); let mut updated = self.set_room_power_level(event);
@ -684,7 +684,7 @@ impl Room {
updated updated
} }
fn handle_tombstone(&mut self, event: &TombstoneEvent) -> bool { fn handle_tombstone(&mut self, event: &StateEventStub<TombstoneEventContent>) -> bool {
self.tombstone = Some(Tombstone { self.tombstone = Some(Tombstone {
body: event.content.body.clone(), body: event.content.body.clone(),
replacement: event.content.replacement_room.clone(), replacement: event.content.replacement_room.clone(),
@ -692,7 +692,7 @@ impl Room {
true true
} }
fn handle_encryption_event(&mut self, event: &EncryptionEvent) -> bool { fn handle_encryption_event(&mut self, event: &StateEventStub<EncryptionEventContent>) -> bool {
self.encrypted = Some(event.into()); self.encrypted = Some(event.into());
true true
} }
@ -704,21 +704,28 @@ impl Room {
/// # Arguments /// # Arguments
/// ///
/// * `event` - The event of the room. /// * `event` - The event of the room.
pub fn receive_timeline_event(&mut self, event: &RoomEvent) -> bool { pub fn receive_timeline_event(&mut self, event: &AnyRoomEventStub, room_id: &RoomId) -> bool {
match event { match &event {
AnyRoomEventStub::State(event) => match &event {
// update to the current members of the room // update to the current members of the room
RoomEvent::RoomMember(member) => self.handle_membership(member), AnyStateEventStub::RoomMember(event) => self.handle_membership(&event, room_id),
// finds all events related to the name of the room for later use // finds all events related to the name of the room for later use
RoomEvent::RoomName(name) => self.handle_room_name(name), AnyStateEventStub::RoomName(event) => self.handle_room_name(&event),
RoomEvent::RoomCanonicalAlias(c_alias) => self.handle_canonical(c_alias), AnyStateEventStub::RoomCanonicalAlias(event) => self.handle_canonical(&event),
RoomEvent::RoomAliases(alias) => self.handle_room_aliases(alias), AnyStateEventStub::RoomAliases(event) => self.handle_room_aliases(&event),
// power levels of the room members // power levels of the room members
RoomEvent::RoomPowerLevels(power) => self.handle_power_level(power), AnyStateEventStub::RoomPowerLevels(event) => self.handle_power_level(&event),
RoomEvent::RoomTombstone(tomb) => self.handle_tombstone(tomb), AnyStateEventStub::RoomTombstone(event) => self.handle_tombstone(&event),
RoomEvent::RoomEncryption(encrypt) => self.handle_encryption_event(encrypt), AnyStateEventStub::RoomEncryption(event) => self.handle_encryption_event(&event),
#[cfg(feature = "messages")]
RoomEvent::RoomMessage(msg) => self.handle_message(msg),
_ => false, _ => false,
},
AnyRoomEventStub::Message(event) => match &event {
#[cfg(feature = "messages")]
AnyMessageEventStub::RoomMessage(event) => self.handle_message(&event),
// TODO if a redaction event deletes one of our saved messages delete it?
AnyMessageEventStub::RoomRedaction(_) => false,
_ => false,
},
} }
} }
@ -729,18 +736,18 @@ impl Room {
/// # Arguments /// # Arguments
/// ///
/// * `event` - The event of the room. /// * `event` - The event of the room.
pub fn receive_state_event(&mut self, event: &StateEvent) -> bool { pub fn receive_state_event(&mut self, event: &AnyStateEventStub, room_id: &RoomId) -> bool {
match event { match event {
// update to the current members of the room // update to the current members of the room
StateEvent::RoomMember(member) => self.handle_membership(member), AnyStateEventStub::RoomMember(member) => self.handle_membership(member, room_id),
// finds all events related to the name of the room for later use // finds all events related to the name of the room for later use
StateEvent::RoomName(name) => self.handle_room_name(name), AnyStateEventStub::RoomName(name) => self.handle_room_name(name),
StateEvent::RoomCanonicalAlias(c_alias) => self.handle_canonical(c_alias), AnyStateEventStub::RoomCanonicalAlias(c_alias) => self.handle_canonical(c_alias),
StateEvent::RoomAliases(alias) => self.handle_room_aliases(alias), AnyStateEventStub::RoomAliases(alias) => self.handle_room_aliases(alias),
// power levels of the room members // power levels of the room members
StateEvent::RoomPowerLevels(power) => self.handle_power_level(power), AnyStateEventStub::RoomPowerLevels(power) => self.handle_power_level(power),
StateEvent::RoomTombstone(tomb) => self.handle_tombstone(tomb), AnyStateEventStub::RoomTombstone(tomb) => self.handle_tombstone(tomb),
StateEvent::RoomEncryption(encrypt) => self.handle_encryption_event(encrypt), AnyStateEventStub::RoomEncryption(encrypt) => self.handle_encryption_event(encrypt),
_ => false, _ => false,
} }
} }
@ -753,9 +760,9 @@ impl Room {
/// ///
/// * `event` - The `AnyStrippedStateEvent` sent by the server for invited but not /// * `event` - The `AnyStrippedStateEvent` sent by the server for invited but not
/// joined rooms. /// joined rooms.
pub fn receive_stripped_state_event(&mut self, event: &AnyStrippedStateEvent) -> bool { pub fn receive_stripped_state_event(&mut self, event: &AnyStrippedStateEventStub) -> bool {
match event { match &event {
AnyStrippedStateEvent::RoomName(n) => self.handle_stripped_room_name(n), AnyStrippedStateEventStub::RoomName(event) => self.handle_stripped_room_name(event),
_ => false, _ => false,
} }
} }
@ -1025,8 +1032,8 @@ mod test {
let user_id = UserId::try_from("@example:localhost").unwrap(); let user_id = UserId::try_from("@example:localhost").unwrap();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_room_event(EventsJson::Member, RoomEvent::RoomMember) .add_state_event(EventsFile::Member)
.add_room_event(EventsJson::PowerLevels, RoomEvent::RoomPowerLevels) .add_state_event(EventsFile::PowerLevels)
.build_sync_response(); .build_sync_response();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();
@ -1054,7 +1061,7 @@ mod test {
let room_id = get_room_id(); let room_id = get_room_id();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_state_event(EventsJson::Aliases, StateEvent::RoomAliases) .add_state_event(EventsFile::Aliases)
.build_sync_response(); .build_sync_response();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();
@ -1072,7 +1079,7 @@ mod test {
let room_id = get_room_id(); let room_id = get_room_id();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_state_event(EventsJson::Alias, StateEvent::RoomCanonicalAlias) .add_state_event(EventsFile::Alias)
.build_sync_response(); .build_sync_response();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();
@ -1090,7 +1097,7 @@ mod test {
let room_id = get_room_id(); let room_id = get_room_id();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_state_event(EventsJson::Name, StateEvent::RoomName) .add_state_event(EventsFile::Name)
.build_sync_response(); .build_sync_response();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();
@ -1125,6 +1132,8 @@ mod test {
#[async_test] #[async_test]
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]
async fn encryption_info_test() { async fn encryption_info_test() {
let room_id = get_room_id();
let mut response = sync_response(SyncResponseFile::DefaultWithSummary); let mut response = sync_response(SyncResponseFile::DefaultWithSummary);
let user_id = UserId::try_from("@example:localhost").unwrap(); let user_id = UserId::try_from("@example:localhost").unwrap();
@ -1137,7 +1146,7 @@ mod test {
client.restore_login(session).await.unwrap(); client.restore_login(session).await.unwrap();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();
let event = EncryptionEvent { let event = StateEventStub {
event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(), event_id: EventId::try_from("$h29iv0s8:example.com").unwrap(),
origin_server_ts: SystemTime::now(), origin_server_ts: SystemTime::now(),
sender: user_id, sender: user_id,
@ -1149,10 +1158,8 @@ mod test {
rotation_period_msgs: Some(100u32.into()), rotation_period_msgs: Some(100u32.into()),
}, },
prev_content: None, prev_content: None,
room_id: None,
}; };
let room_id = get_room_id();
let room = client.get_joined_room(&room_id).await.unwrap(); let room = client.get_joined_room(&room_id).await.unwrap();
assert!(!room.read().await.is_encrypted()); assert!(!room.read().await.is_encrypted());

View File

@ -15,13 +15,13 @@
use std::convert::TryFrom; use std::convert::TryFrom;
use crate::events::collections::all::Event;
use crate::events::presence::{PresenceEvent, PresenceEventContent, PresenceState}; use crate::events::presence::{PresenceEvent, PresenceEventContent, PresenceState};
use crate::events::room::{ use crate::events::room::{
member::{MemberEvent, MembershipChange}, member::{MemberEventContent, MembershipChange, MembershipState},
power_levels::PowerLevelsEvent, power_levels::PowerLevelsEventContent,
}; };
use crate::identifiers::UserId; use crate::events::StateEventStub;
use crate::identifiers::{RoomId, UserId};
use crate::js_int::{Int, UInt}; use crate::js_int::{Int, UInt};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -29,7 +29,6 @@ use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
/// A Matrix room member. /// A Matrix room member.
///
pub struct RoomMember { pub struct RoomMember {
/// The unique MXID of the user. /// The unique MXID of the user.
pub user_id: UserId, pub user_id: UserId,
@ -42,7 +41,7 @@ pub struct RoomMember {
/// If the user should be considered active. /// If the user should be considered active.
pub currently_active: Option<bool>, pub currently_active: Option<bool>,
/// The unique id of the room. /// The unique id of the room.
pub room_id: Option<String>, pub room_id: Option<RoomId>,
/// If the member is typing. /// If the member is typing.
pub typing: Option<bool>, pub typing: Option<bool>,
/// The presence of the user, if found. /// The presence of the user, if found.
@ -53,13 +52,11 @@ pub struct RoomMember {
pub power_level: Option<Int>, pub power_level: Option<Int>,
/// The normalized power level of this `RoomMember` (0-100). /// The normalized power level of this `RoomMember` (0-100).
pub power_level_norm: Option<Int>, pub power_level_norm: Option<Int>,
/// The `MembershipState` of this `RoomMember`.
pub membership: MembershipState,
/// The human readable name of this room member. /// The human readable name of this room member.
pub name: String, pub name: String,
/// The events that created the state of this room member.
#[serde(deserialize_with = "super::event_deser::deserialize_events")]
pub events: Vec<Event>,
/// The `PresenceEvent`s connected to this user. /// The `PresenceEvent`s connected to this user.
#[serde(deserialize_with = "super::event_deser::deserialize_presence")]
pub presence_events: Vec<PresenceEvent>, pub presence_events: Vec<PresenceEvent>,
} }
@ -76,10 +73,10 @@ impl PartialEq for RoomMember {
} }
impl RoomMember { impl RoomMember {
pub fn new(event: &MemberEvent) -> Self { pub fn new(event: &StateEventStub<MemberEventContent>, room_id: &RoomId) -> Self {
Self { Self {
name: event.state_key.clone(), name: event.state_key.clone(),
room_id: event.room_id.as_ref().map(|id| id.to_string()), room_id: Some(room_id.clone()),
user_id: UserId::try_from(event.state_key.as_str()).unwrap(), user_id: UserId::try_from(event.state_key.as_str()).unwrap(),
display_name: event.content.displayname.clone(), display_name: event.content.displayname.clone(),
avatar_url: event.content.avatar_url.clone(), avatar_url: event.content.avatar_url.clone(),
@ -90,8 +87,8 @@ impl RoomMember {
typing: None, typing: None,
power_level: None, power_level: None,
power_level_norm: None, power_level_norm: None,
presence_events: Vec::default(), membership: event.content.membership,
events: vec![Event::RoomMember(event.clone())], presence_events: vec![],
} }
} }
@ -116,7 +113,7 @@ impl RoomMember {
} }
/// Handle profile updates. /// Handle profile updates.
pub(crate) fn update_profile(&mut self, event: &MemberEvent) -> bool { pub(crate) fn update_profile(&mut self, event: &StateEventStub<MemberEventContent>) -> bool {
use MembershipChange::*; use MembershipChange::*;
match event.membership_change() { match event.membership_change() {
@ -131,7 +128,11 @@ impl RoomMember {
} }
} }
pub fn update_power(&mut self, event: &PowerLevelsEvent, max_power: Int) -> bool { pub fn update_power(
&mut self,
event: &StateEventStub<PowerLevelsEventContent>,
max_power: Int,
) -> bool {
let changed; let changed;
if let Some(user_power) = event.content.users.get(&self.user_id) { if let Some(user_power) = event.content.users.get(&self.user_id) {
changed = self.power_level != Some(*user_power); changed = self.power_level != Some(*user_power);
@ -211,7 +212,7 @@ impl RoomMember {
mod test { mod test {
use matrix_sdk_test::{async_test, EventBuilder, EventsJson}; use matrix_sdk_test::{async_test, EventBuilder, EventsJson};
use crate::events::collections::all::RoomEvent; use crate::events::room::member::MembershipState;
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::{BaseClient, Session}; use crate::{BaseClient, Session};
@ -244,8 +245,8 @@ mod test {
let room_id = get_room_id(); let room_id = get_room_id();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_room_event(EventsJson::Member, RoomEvent::RoomMember) .add_state_event(EventsFile::Member)
.add_room_event(EventsJson::PowerLevels, RoomEvent::RoomPowerLevels) .add_state_event(EventsFile::PowerLevels)
.build_sync_response(); .build_sync_response();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();
@ -267,9 +268,9 @@ mod test {
let room_id = get_room_id(); let room_id = get_room_id();
let mut response = EventBuilder::default() let mut response = EventBuilder::default()
.add_room_event(EventsJson::Member, RoomEvent::RoomMember) .add_state_event(EventsFile::Member)
.add_room_event(EventsJson::PowerLevels, RoomEvent::RoomPowerLevels) .add_state_event(EventsFile::PowerLevels)
.add_presence_event(EventsJson::Presence) .add_presence_event(EventsFile::Presence)
.build_sync_response(); .build_sync_response();
client.receive_sync_response(&mut response).await.unwrap(); client.receive_sync_response(&mut response).await.unwrap();

View File

@ -201,6 +201,7 @@ mod test {
use tempfile::tempdir; use tempfile::tempdir;
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::push::Ruleset;
use crate::{BaseClient, BaseClientConfig, Session}; use crate::{BaseClient, BaseClientConfig, Session};
use matrix_sdk_test::{sync_response, SyncResponseFile}; use matrix_sdk_test::{sync_response, SyncResponseFile};
@ -221,7 +222,7 @@ mod test {
let state = ClientState { let state = ClientState {
sync_token: Some("hello".into()), sync_token: Some("hello".into()),
ignored_users: vec![user], ignored_users: vec![user],
push_ruleset: None, push_ruleset: None::<Ruleset>,
}; };
let mut path_with_user = PathBuf::from(path); let mut path_with_user = PathBuf::from(path);

View File

@ -23,8 +23,8 @@ mod json_store;
pub use json_store::JsonStore; pub use json_store::JsonStore;
use crate::client::{BaseClient, Token}; use crate::client::{BaseClient, Token};
use crate::events::push_rules::Ruleset;
use crate::identifiers::{RoomId, UserId}; use crate::identifiers::{RoomId, UserId};
use crate::push::Ruleset;
use crate::{Result, Room, RoomState, Session}; use crate::{Result, Room, RoomState, Session};
#[cfg(not(target_arch = "wasm32"))] #[cfg(not(target_arch = "wasm32"))]

View File

@ -1,5 +1,5 @@
[package] [package]
authors = ["Damir Jelić <poljar@termina.org.uk>"] authors = ["Damir Jelić <poljar@termina.org.uk"]
description = "Collection of common types used in the matrix-sdk" description = "Collection of common types used in the matrix-sdk"
edition = "2018" edition = "2018"
homepage = "https://github.com/matrix-org/matrix-rust-sdk" homepage = "https://github.com/matrix-org/matrix-rust-sdk"
@ -11,12 +11,16 @@ repository = "https://github.com/matrix-org/matrix-rust-sdk"
version = "0.1.0" version = "0.1.0"
[dependencies] [dependencies]
js_int = "0.1.8" js_int = "0.1.5"
ruma-api = "0.16.1" # ruma-api = "0.16.1"
ruma-client-api = "0.9.0" # ruma-client-api = "0.9.0"
ruma-events = "0.21.3" # ruma-events = "0.21.2"
ruma-identifiers = "0.16.2" # ruma-identifiers = "0.16.1"
instant = { version = "0.1.6", features = ["wasm-bindgen", "now"] }
ruma = { git = "https://github.com/DevinR528/ruma", features = ["client-api", "rand"], branch = "matrix-sdk2"}
# ruma = { path = "../../ruma/ruma", features = ["client-api", "rand"] }
instant = { version = "0.1.4", features = ["wasm-bindgen", "now"] }
[target.'cfg(not(target_arch = "wasm32"))'.dependencies] [target.'cfg(not(target_arch = "wasm32"))'.dependencies]
uuid = { version = "0.8.1", features = ["v4"] } uuid = { version = "0.8.1", features = ["v4"] }

View File

@ -1,12 +1,14 @@
pub use instant; pub use instant;
pub use js_int; pub use js_int;
pub use ruma_api::{
error::{FromHttpResponseError, IntoHttpError, ServerError}, pub use ruma::{
Endpoint, api::{
client as api,
error::{FromHttpRequestError, FromHttpResponseError, IntoHttpError, ServerError},
Endpoint, EndpointError,
},
events, identifiers, push,
}; };
pub use ruma_client_api as api;
pub use ruma_events as events;
pub use ruma_identifiers as identifiers;
pub use uuid; pub use uuid;

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
use std::collections::{BTreeMap, HashMap, HashSet}; use std::collections::{BTreeMap, HashMap, HashSet};
use std::convert::{TryFrom, TryInto}; use std::convert::TryInto;
use std::mem; use std::mem;
#[cfg(feature = "sqlite-cryptostore")] #[cfg(feature = "sqlite-cryptostore")]
use std::path::Path; use std::path::Path;
@ -32,17 +32,16 @@ use super::{device::Device, store::Result as StoreError, CryptoStore};
use matrix_sdk_common::api; use matrix_sdk_common::api;
use matrix_sdk_common::events::{ use matrix_sdk_common::events::{
collections::all::RoomEvent, forwarded_room_key::ForwardedRoomKeyEventContent,
room::encrypted::{ room::encrypted::{
CiphertextInfo, EncryptedEvent, EncryptedEventContent, MegolmV1AesSha2Content, CiphertextInfo, EncryptedEventContent, MegolmV1AesSha2Content,
OlmV1Curve25519AesSha2Content, OlmV1Curve25519AesSha2Content,
}, },
room::message::MessageEventContent, room::message::MessageEventContent,
to_device::{ room_key::RoomKeyEventContent,
AnyToDeviceEvent as ToDeviceEvent, ToDeviceEncrypted, ToDeviceForwardedRoomKey, room_key_request::RoomKeyRequestEventContent,
ToDeviceRoomKey, ToDeviceRoomKeyRequest, Algorithm, AnyRoomEventStub, AnyToDeviceEvent, EventJson, EventType, MessageEventStub,
}, ToDeviceEvent,
Algorithm, EventJson, EventType,
}; };
use matrix_sdk_common::identifiers::{DeviceId, RoomId, UserId}; use matrix_sdk_common::identifiers::{DeviceId, RoomId, UserId};
use matrix_sdk_common::uuid::Uuid; use matrix_sdk_common::uuid::Uuid;
@ -825,7 +824,7 @@ impl OlmMachine {
sender: &UserId, sender: &UserId,
sender_key: &str, sender_key: &str,
message: OlmMessage, message: OlmMessage,
) -> OlmResult<(EventJson<ToDeviceEvent>, String)> { ) -> OlmResult<(EventJson<AnyToDeviceEvent>, String)> {
// First try to decrypt using an existing session. // First try to decrypt using an existing session.
let plaintext = if let Some(p) = self let plaintext = if let Some(p) = self
.try_decrypt_olm_message(sender, sender_key, &message) .try_decrypt_olm_message(sender, sender_key, &message)
@ -894,7 +893,7 @@ impl OlmMachine {
&self, &self,
sender: &UserId, sender: &UserId,
plaintext: &str, plaintext: &str,
) -> OlmResult<(EventJson<ToDeviceEvent>, String)> { ) -> OlmResult<(EventJson<AnyToDeviceEvent>, String)> {
// TODO make the errors a bit more specific. // TODO make the errors a bit more specific.
let decrypted_json: Value = serde_json::from_str(&plaintext)?; let decrypted_json: Value = serde_json::from_str(&plaintext)?;
@ -939,7 +938,8 @@ impl OlmMachine {
.ok_or(EventError::MissingSigningKey)?; .ok_or(EventError::MissingSigningKey)?;
Ok(( Ok((
serde_json::from_value::<EventJson<ToDeviceEvent>>(decrypted_json)?, // FIXME EventJson<Any*Event> fails to deserialize still?
EventJson::from(serde_json::from_value::<AnyToDeviceEvent>(decrypted_json)?),
signing_key.to_owned(), signing_key.to_owned(),
)) ))
} }
@ -954,8 +954,8 @@ impl OlmMachine {
/// * `event` - The to-device event that should be decrypted. /// * `event` - The to-device event that should be decrypted.
async fn decrypt_to_device_event( async fn decrypt_to_device_event(
&mut self, &mut self,
event: &ToDeviceEncrypted, event: &ToDeviceEvent<EncryptedEventContent>,
) -> OlmResult<EventJson<ToDeviceEvent>> { ) -> OlmResult<EventJson<AnyToDeviceEvent>> {
info!("Decrypting to-device event"); info!("Decrypting to-device event");
let content = if let EncryptedEventContent::OlmV1Curve25519AesSha2(c) = &event.content { let content = if let EncryptedEventContent::OlmV1Curve25519AesSha2(c) = &event.content {
@ -1018,8 +1018,8 @@ impl OlmMachine {
&mut self, &mut self,
sender_key: &str, sender_key: &str,
signing_key: &str, signing_key: &str,
event: &mut ToDeviceRoomKey, event: &mut ToDeviceEvent<RoomKeyEventContent>,
) -> OlmResult<Option<EventJson<ToDeviceEvent>>> { ) -> OlmResult<Option<EventJson<AnyToDeviceEvent>>> {
match event.content.algorithm { match event.content.algorithm {
Algorithm::MegolmV1AesSha2 => { Algorithm::MegolmV1AesSha2 => {
let session_key = GroupSessionKey(mem::take(&mut event.content.session_key)); let session_key = GroupSessionKey(mem::take(&mut event.content.session_key));
@ -1031,16 +1031,8 @@ impl OlmMachine {
session_key, session_key,
)?; )?;
let _ = self.store.save_inbound_group_session(session).await?; let _ = self.store.save_inbound_group_session(session).await?;
// TODO ideally we would rewrap the event again just like so
// let event = EventJson::from(ToDeviceEvent::RoomKey(event.clone()));
// This saidly lacks a type once it's serialized again, fix
// this in Ruma.
let mut json = serde_json::to_value(event.clone())?;
json.as_object_mut()
.unwrap()
.insert("type".to_owned(), Value::String("m.room_key".to_owned()));
let event = serde_json::from_value::<EventJson<ToDeviceEvent>>(json)?;
let event = EventJson::from(AnyToDeviceEvent::RoomKey(event.clone()));
Ok(Some(event)) Ok(Some(event))
} }
_ => { _ => {
@ -1324,7 +1316,7 @@ impl OlmMachine {
&self, &self,
_sender_key: &str, _sender_key: &str,
_signing_key: &str, _signing_key: &str,
_event: &ToDeviceForwardedRoomKey, _event: &ToDeviceEvent<ForwardedRoomKeyEventContent>,
) -> OlmResult<()> { ) -> OlmResult<()> {
Ok(()) Ok(())
// TODO // TODO
@ -1343,8 +1335,8 @@ impl OlmMachine {
&mut self, &mut self,
sender_key: &str, sender_key: &str,
signing_key: &str, signing_key: &str,
event: &EventJson<ToDeviceEvent>, event: &EventJson<AnyToDeviceEvent>,
) -> OlmResult<Option<EventJson<ToDeviceEvent>>> { ) -> OlmResult<Option<EventJson<AnyToDeviceEvent>>> {
let event = if let Ok(e) = event.deserialize() { let event = if let Ok(e) = event.deserialize() {
e e
} else { } else {
@ -1353,10 +1345,10 @@ impl OlmMachine {
}; };
match event { match event {
ToDeviceEvent::RoomKey(mut e) => { AnyToDeviceEvent::RoomKey(mut e) => {
Ok(self.add_room_key(sender_key, signing_key, &mut e).await?) Ok(self.add_room_key(sender_key, signing_key, &mut e).await?)
} }
ToDeviceEvent::ForwardedRoomKey(e) => { AnyToDeviceEvent::ForwardedRoomKey(e) => {
self.add_forwarded_room_key(sender_key, signing_key, &e)?; self.add_forwarded_room_key(sender_key, signing_key, &e)?;
Ok(None) Ok(None)
} }
@ -1367,11 +1359,11 @@ impl OlmMachine {
} }
} }
fn handle_room_key_request(&self, _: &ToDeviceRoomKeyRequest) { fn handle_room_key_request(&self, _: &ToDeviceEvent<RoomKeyRequestEventContent>) {
// TODO handle room key requests here. // TODO handle room key requests here.
} }
fn handle_verification_event(&self, _: &ToDeviceEvent) { fn handle_verification_event(&self, _: &AnyToDeviceEvent) {
// TODO handle to-device verification events here. // TODO handle to-device verification events here.
} }
@ -1394,19 +1386,11 @@ impl OlmMachine {
let count: u64 = one_time_key_count.map_or(0, |c| (*c).into()); let count: u64 = one_time_key_count.map_or(0, |c| (*c).into());
self.update_key_count(count); self.update_key_count(count);
if let Some(device_list) = &response.device_lists { for user_id in &response.device_lists.changed {
for user_id in &device_list.changed {
let user_id = if let Ok(u) = UserId::try_from(user_id.to_owned()) {
u
} else {
continue;
};
if let Err(e) = self.mark_user_as_changed(&user_id).await { if let Err(e) = self.mark_user_as_changed(&user_id).await {
error!("Error marking a tracked user as changed {:?}", e); error!("Error marking a tracked user as changed {:?}", e);
} }
} }
}
for event_result in &mut response.to_device.events { for event_result in &mut response.to_device.events {
let event = if let Ok(e) = event_result.deserialize() { let event = if let Ok(e) = event_result.deserialize() {
@ -1420,8 +1404,8 @@ impl OlmMachine {
info!("Received a to-device event {:?}", event); info!("Received a to-device event {:?}", event);
match &event { match &event {
ToDeviceEvent::RoomEncrypted(e) => { AnyToDeviceEvent::RoomEncrypted(e) => {
let decrypted_event = match self.decrypt_to_device_event(e).await { let decrypted_event = match self.decrypt_to_device_event(&e).await {
Ok(e) => e, Ok(e) => e,
Err(err) => { Err(err) => {
warn!( warn!(
@ -1438,13 +1422,15 @@ impl OlmMachine {
// before we replace the result. // before we replace the result.
*event_result = decrypted_event; *event_result = decrypted_event;
} }
ToDeviceEvent::RoomKeyRequest(e) => self.handle_room_key_request(e), AnyToDeviceEvent::RoomKeyRequest(e) => self.handle_room_key_request(&e),
ToDeviceEvent::KeyVerificationAccept(..) AnyToDeviceEvent::KeyVerificationAccept(..)
| ToDeviceEvent::KeyVerificationCancel(..) | AnyToDeviceEvent::KeyVerificationCancel(..)
| ToDeviceEvent::KeyVerificationKey(..) | AnyToDeviceEvent::KeyVerificationKey(..)
| ToDeviceEvent::KeyVerificationMac(..) | AnyToDeviceEvent::KeyVerificationMac(..)
| ToDeviceEvent::KeyVerificationRequest(..) | AnyToDeviceEvent::KeyVerificationRequest(..)
| ToDeviceEvent::KeyVerificationStart(..) => self.handle_verification_event(&event), | AnyToDeviceEvent::KeyVerificationStart(..) => {
self.handle_verification_event(&event)
}
_ => continue, _ => continue,
} }
} }
@ -1457,18 +1443,17 @@ impl OlmMachine {
/// * `event` - The event that should be decrypted. /// * `event` - The event that should be decrypted.
pub async fn decrypt_room_event( pub async fn decrypt_room_event(
&mut self, &mut self,
event: &EncryptedEvent, event: &MessageEventStub<EncryptedEventContent>,
) -> MegolmResult<EventJson<RoomEvent>> { room_id: &RoomId,
) -> MegolmResult<EventJson<AnyRoomEventStub>> {
let content = match &event.content { let content = match &event.content {
EncryptedEventContent::MegolmV1AesSha2(c) => c, EncryptedEventContent::MegolmV1AesSha2(c) => c,
_ => return Err(EventError::UnsupportedAlgorithm.into()), _ => return Err(EventError::UnsupportedAlgorithm.into()),
}; };
let room_id = event.room_id.as_ref().unwrap();
let session = self let session = self
.store .store
.get_inbound_group_session(&room_id, &content.sender_key, &content.session_id) .get_inbound_group_session(room_id, &content.sender_key, &content.session_id)
.await?; .await?;
// TODO check if the Olm session is wedged and re-request the key. // TODO check if the Olm session is wedged and re-request the key.
let session = session.ok_or(MegolmError::MissingSession)?; let session = session.ok_or(MegolmError::MissingSession)?;
@ -1499,7 +1484,8 @@ impl OlmMachine {
serde_json::to_value(&event.unsigned).unwrap_or_default(), serde_json::to_value(&event.unsigned).unwrap_or_default(),
); );
let decrypted_event = serde_json::from_value::<EventJson<RoomEvent>>(decrypted_value)?; let decrypted_event =
serde_json::from_value::<EventJson<AnyRoomEventStub>>(decrypted_value)?;
trace!("Successfully decrypted Megolm event {:?}", decrypted_event); trace!("Successfully decrypted Megolm event {:?}", decrypted_event);
// TODO set the encryption info on the event (is it verified, was it // TODO set the encryption info on the event (is it verified, was it
// decrypted, sender key...) // decrypted, sender key...)
@ -1587,13 +1573,12 @@ mod test {
keys, to_device::send_event_to_device::Request as ToDeviceRequest, keys, to_device::send_event_to_device::Request as ToDeviceRequest,
}; };
use matrix_sdk_common::events::{ use matrix_sdk_common::events::{
collections::all::RoomEvent,
room::{ room::{
encrypted::{EncryptedEvent, EncryptedEventContent}, encrypted::EncryptedEventContent,
message::{MessageEventContent, TextMessageEventContent}, message::{MessageEventContent, TextMessageEventContent},
}, },
to_device::{AnyToDeviceEvent, ToDeviceEncrypted}, AnyMessageEventStub, AnyRoomEventStub, AnyToDeviceEvent, EventJson, EventType,
EventJson, EventType, UnsignedData, MessageEventStub, ToDeviceEvent, UnsignedData,
}; };
use matrix_sdk_common::identifiers::{DeviceId, EventId, RoomId, UserId}; use matrix_sdk_common::identifiers::{DeviceId, EventId, RoomId, UserId};
use matrix_sdk_test::test_json; use matrix_sdk_test::test_json;
@ -1732,7 +1717,7 @@ mod test {
.unwrap() .unwrap()
.unwrap(); .unwrap();
let event = ToDeviceEncrypted { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id.clone(),
content: alice content: alice
.olm_encrypt(session, &bob_device, EventType::Dummy, json!({})) .olm_encrypt(session, &bob_device, EventType::Dummy, json!({}))
@ -2025,7 +2010,7 @@ mod test {
.unwrap() .unwrap()
.unwrap(); .unwrap();
let event = ToDeviceEncrypted { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id.clone(),
content: alice content: alice
.olm_encrypt(session, &bob_device, EventType::Dummy, json!({})) .olm_encrypt(session, &bob_device, EventType::Dummy, json!({}))
@ -2033,12 +2018,17 @@ mod test {
.unwrap(), .unwrap(),
}; };
let event = bob.decrypt_to_device_event(&event).await.unwrap(); let event = bob
.decrypt_to_device_event(&event)
.await
.unwrap()
.deserialize()
.unwrap();
if let AnyToDeviceEvent::Dummy(e) = event.deserialize().unwrap() { if let AnyToDeviceEvent::Dummy(e) = event {
assert_eq!(e.sender, alice.user_id); assert_eq!(e.sender, alice.user_id);
} else { } else {
panic!("Event had the wrong type"); panic!("Wrong event type found {:?}", event);
} }
} }
@ -2053,20 +2043,25 @@ mod test {
.await .await
.unwrap(); .unwrap();
let event = ToDeviceEncrypted { let event = ToDeviceEvent {
sender: alice.user_id.clone(), sender: alice.user_id.clone(),
content: to_device_requests_to_content(to_device_requests), content: to_device_requests_to_content(to_device_requests),
}; };
let alice_session = alice.outbound_group_sessions.get(&room_id).unwrap(); let alice_session = alice.outbound_group_sessions.get(&room_id).unwrap();
let event = bob.decrypt_to_device_event(&event).await.unwrap(); let event = bob
.decrypt_to_device_event(&event)
.await
.unwrap()
.deserialize()
.unwrap();
if let AnyToDeviceEvent::RoomKey(e) = event.deserialize().unwrap() { if let AnyToDeviceEvent::RoomKey(event) = event {
assert_eq!(e.sender, alice.user_id); assert_eq!(event.sender, alice.user_id);
assert!(e.content.session_key.is_empty()) assert!(event.content.session_key.is_empty());
} else { } else {
panic!("Event had the wrong type"); panic!("expected RoomKeyEvent found {:?}", event);
} }
let session = bob let session = bob
@ -2091,8 +2086,8 @@ mod test {
.await .await
.unwrap(); .unwrap();
let event = ToDeviceEncrypted { let event = ToDeviceEvent {
sender: alice.user_id().clone(), sender: alice.user_id.clone(),
content: to_device_requests_to_content(to_device_requests), content: to_device_requests_to_content(to_device_requests),
}; };
@ -2104,33 +2099,35 @@ mod test {
let encrypted_content = alice.encrypt(&room_id, content.clone()).await.unwrap(); let encrypted_content = alice.encrypt(&room_id, content.clone()).await.unwrap();
let event = EncryptedEvent { let event = MessageEventStub {
event_id: EventId::new("example.org").unwrap(), event_id: EventId::try_from("$xxxxx:example.org").unwrap(),
origin_server_ts: SystemTime::now(), origin_server_ts: SystemTime::now(),
room_id: Some(room_id.clone()),
sender: alice.user_id().clone(), sender: alice.user_id().clone(),
content: encrypted_content, content: encrypted_content,
unsigned: UnsignedData::default(), unsigned: UnsignedData::default(),
}; };
let decrypted_event = bob let decrypted_event = bob
.decrypt_room_event(&event) .decrypt_room_event(&event, &room_id)
.await .await
.unwrap() .unwrap()
.deserialize() .deserialize()
.unwrap(); .unwrap();
let decrypted_event = match decrypted_event { match decrypted_event {
RoomEvent::RoomMessage(e) => e, AnyRoomEventStub::Message(AnyMessageEventStub::RoomMessage(MessageEventStub {
_ => panic!("Decrypted room event has the wrong type"), sender,
}; content,
..
assert_eq!(&decrypted_event.sender, alice.user_id()); })) => {
assert_eq!(&decrypted_event.room_id, &Some(room_id)); assert_eq!(&sender, alice.user_id());
if let MessageEventContent::Text(c) = &decrypted_event.content { if let MessageEventContent::Text(c) = &content {
assert_eq!(&c.body, plaintext); assert_eq!(&c.body, plaintext);
} else { } else {
panic!("Decrypted event has a missmatched content"); panic!("Decrypted event has a missmatched content");
} }
} }
_ => panic!("Decrypted room event has the wrong type"),
}
}
} }

View File

@ -16,3 +16,4 @@ http = "0.2.1"
matrix-sdk-common = { version = "0.1.0", path = "../matrix_sdk_common" } matrix-sdk-common = { version = "0.1.0", path = "../matrix_sdk_common" }
matrix-sdk-test-macros = { version = "0.1.0", path = "../matrix_sdk_test_macros" } matrix-sdk-test-macros = { version = "0.1.0", path = "../matrix_sdk_test_macros" }
lazy_static = "1.4.0" lazy_static = "1.4.0"
serde = "1.0.111"

View File

@ -6,13 +6,8 @@ use http::Response;
use matrix_sdk_common::api::r0::sync::sync_events::Response as SyncResponse; use matrix_sdk_common::api::r0::sync::sync_events::Response as SyncResponse;
use matrix_sdk_common::events::{ use matrix_sdk_common::events::{
collections::{ presence::PresenceEvent, AnyBasicEvent, AnyEphemeralRoomEventContent, AnyRoomEventStub,
all::{RoomEvent, StateEvent}, AnyStateEventStub, EphemeralRoomEventStub,
only::Event,
},
presence::PresenceEvent,
stripped::AnyStrippedStateEvent,
EventJson, TryFromRaw,
}; };
use matrix_sdk_common::identifiers::RoomId; use matrix_sdk_common::identifiers::RoomId;
use serde_json::Value as JsonValue; use serde_json::Value as JsonValue;
@ -22,6 +17,9 @@ pub use matrix_sdk_test_macros::async_test;
pub mod test_json; pub mod test_json;
/// Static `serde_json::Value`s /// Static `serde_json::Value`s
type AnyEphemeralRoomEventStub = EphemeralRoomEventStub<AnyEphemeralRoomEventContent>;
/// Embedded event files
#[derive(Debug)] #[derive(Debug)]
pub enum EventsJson { pub enum EventsJson {
Alias, Alias,
@ -51,19 +49,19 @@ pub enum EventsJson {
#[derive(Default)] #[derive(Default)]
pub struct EventBuilder { pub struct EventBuilder {
/// The events that determine the state of a `Room`. /// The events that determine the state of a `Room`.
joined_room_events: HashMap<RoomId, Vec<RoomEvent>>, joined_room_events: HashMap<RoomId, Vec<AnyRoomEventStub>>,
/// The events that determine the state of a `Room`. /// The events that determine the state of a `Room`.
invited_room_events: HashMap<RoomId, Vec<AnyStrippedStateEvent>>, invited_room_events: HashMap<RoomId, Vec<AnyStateEventStub>>,
/// The events that determine the state of a `Room`. /// The events that determine the state of a `Room`.
left_room_events: HashMap<RoomId, Vec<RoomEvent>>, left_room_events: HashMap<RoomId, Vec<AnyRoomEventStub>>,
/// The presence events that determine the presence state of a `RoomMember`. /// The presence events that determine the presence state of a `RoomMember`.
presence_events: Vec<PresenceEvent>, presence_events: Vec<PresenceEvent>,
/// The state events that determine the state of a `Room`. /// The state events that determine the state of a `Room`.
state_events: Vec<StateEvent>, state_events: Vec<AnyStateEventStub>,
/// The ephemeral room events that determine the state of a `Room`. /// The ephemeral room events that determine the state of a `Room`.
ephemeral: Vec<Event>, ephemeral: Vec<AnyEphemeralRoomEventStub>,
/// The account data events that determine the state of a `Room`. /// The account data events that determine the state of a `Room`.
account_data: Vec<Event>, account_data: Vec<AnyBasicEvent>,
/// Internal counter to enable the `prev_batch` and `next_batch` of each sync response to vary. /// Internal counter to enable the `prev_batch` and `next_batch` of each sync response to vary.
batch_counter: i64, batch_counter: i64,
} }
@ -75,11 +73,11 @@ impl EventBuilder {
} }
/// Add an event to the room events `Vec`. /// Add an event to the room events `Vec`.
pub fn add_ephemeral<Ev: TryFromRaw>( pub fn add_ephemeral<Ev: serde::de::DeserializeOwned>(
&mut self, mut self,
json: EventsJson, file: EventsFile,
variant: fn(Ev) -> Event, variant: fn(Ev) -> AnyEphemeralRoomEventStub,
) -> &mut Self { ) -> Self {
let val: &JsonValue = match json { let val: &JsonValue = match json {
EventsJson::Typing => &test_json::TYPING, EventsJson::Typing => &test_json::TYPING,
_ => panic!("unknown ephemeral event {:?}", json), _ => panic!("unknown ephemeral event {:?}", json),
@ -89,6 +87,7 @@ impl EventBuilder {
.unwrap() .unwrap()
.deserialize() .deserialize()
.unwrap(); .unwrap();
self.ephemeral.push(variant(event)); self.ephemeral.push(variant(event));
self self
} }
@ -112,77 +111,64 @@ impl EventBuilder {
self self
} }
/// Add an event to the room events `Vec`. // /// Add an event to the room events `Vec`.
pub fn add_room_event<Ev: TryFromRaw>( // pub fn add_room_event<Ev: TryFromRaw>(
&mut self, // &mut self,
json: EventsJson, // json: EventsJson,
variant: fn(Ev) -> RoomEvent, // variant: fn(Ev) -> AnyRoomEventStub,
) -> &mut Self { // ) -> &mut Self {
let val: &JsonValue = match json { // let val: &JsonValue = match json {
EventsJson::Member => &test_json::MEMBER, // EventsJson::Member => &test_json::MEMBER,
EventsJson::PowerLevels => &test_json::POWER_LEVELS, // EventsJson::PowerLevels => &test_json::POWER_LEVELS,
_ => panic!("unknown room event json {:?}", json), // _ => panic!("unknown room event json {:?}", json),
}; // };
let event = serde_json::from_value::<EventJson<Ev>>(val.clone()) // let event = serde_json::from_value::<EventJson<Ev>>(val.clone())
.unwrap() // .unwrap()
.deserialize() // .deserialize()
.unwrap(); // .unwrap();
self.add_joined_event(
&RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap(),
variant(event),
);
self
}
pub fn add_custom_joined_event<Ev: TryFromRaw>( // self.add_joined_event(
&mut self, // &RoomId::try_from("!SVkFJHzfwvuaIEawgC:localhost").unwrap(),
// variant(event),
// );
// self
// }
pub fn add_custom_joined_event<Ev: serde::de::DeserializeOwned>(
mut self,
room_id: &RoomId, room_id: &RoomId,
event: serde_json::Value, event: serde_json::Value,
variant: fn(Ev) -> RoomEvent, variant: fn(Ev) -> AnyRoomEventStub,
) -> &mut Self { ) -> Self {
let event = serde_json::from_value::<EventJson<Ev>>(event) let event = serde_json::from_value::<Ev>(event).unwrap();
.unwrap()
.deserialize()
.unwrap();
self.add_joined_event(room_id, variant(event)); self.add_joined_event(room_id, variant(event));
self self
} }
fn add_joined_event(&mut self, room_id: &RoomId, event: RoomEvent) { fn add_joined_event(&mut self, room_id: &RoomId, event: AnyRoomEventStub) {
self.joined_room_events self.joined_room_events
.entry(room_id.clone()) .entry(room_id.clone())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push(event); .push(event);
} }
pub fn add_custom_invited_event<Ev: TryFromRaw>( pub fn add_custom_invited_event(mut self, room_id: &RoomId, event: serde_json::Value) -> Self {
&mut self, let event = serde_json::from_value::<AnyStateEventStub>(event).unwrap();
room_id: &RoomId,
event: serde_json::Value,
variant: fn(Ev) -> AnyStrippedStateEvent,
) -> &mut Self {
let event = serde_json::from_value::<EventJson<Ev>>(event)
.unwrap()
.deserialize()
.unwrap();
self.invited_room_events self.invited_room_events
.entry(room_id.clone()) .entry(room_id.clone())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
.push(variant(event)); .push(event);
self self
} }
pub fn add_custom_left_event<Ev: TryFromRaw>( pub fn add_custom_left_event<Ev: serde::de::DeserializeOwned>(
&mut self, mut self,
room_id: &RoomId, room_id: &RoomId,
event: serde_json::Value, event: serde_json::Value,
variant: fn(Ev) -> RoomEvent, variant: fn(Ev) -> AnyRoomEventStub,
) -> &mut Self { ) -> Self {
let event = serde_json::from_value::<EventJson<Ev>>(event) let event = serde_json::from_value::<Ev>(event).unwrap();
.unwrap()
.deserialize()
.unwrap();
self.left_room_events self.left_room_events
.entry(room_id.clone()) .entry(room_id.clone())
.or_insert_with(Vec::new) .or_insert_with(Vec::new)
@ -194,7 +180,6 @@ impl EventBuilder {
pub fn add_state_event<Ev: TryFromRaw>( pub fn add_state_event<Ev: TryFromRaw>(
&mut self, &mut self,
json: EventsJson, json: EventsJson,
variant: fn(Ev) -> StateEvent,
) -> &mut Self { ) -> &mut Self {
let val: &JsonValue = match json { let val: &JsonValue = match json {
EventsJson::Alias => &test_json::ALIAS, EventsJson::Alias => &test_json::ALIAS,
@ -203,9 +188,7 @@ impl EventBuilder {
_ => panic!("unknown state event {:?}", json), _ => panic!("unknown state event {:?}", json),
}; };
let event = serde_json::from_value::<EventJson<Ev>>(val.clone()) let event = serde_json::from_value::<AnyStateEventStub>(val.clone())
.unwrap()
.deserialize()
.unwrap(); .unwrap();
self.state_events.push(variant(event)); self.state_events.push(variant(event));
self self
@ -218,9 +201,7 @@ impl EventBuilder {
_ => panic!("unknown presence event {:?}", json), _ => panic!("unknown presence event {:?}", json),
}; };
let event = serde_json::from_value::<EventJson<PresenceEvent>>(val.clone()) let event = serde_json::from_value::<PresenceEvent>(val.clone())
.unwrap()
.deserialize()
.unwrap(); .unwrap();
self.presence_events.push(event); self.presence_events.push(event);
self self