From b61dc18060dd958a770473ac0971ad218c7de5ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 30 Oct 2019 19:30:55 +0100 Subject: [PATCH] nio: Allow callbacks to borrow the room, sadly back to non async callbacks. --- examples/login.rs | 32 +++++++++++++--------- src/async_client.rs | 67 ++++++++++++++++++++------------------------- src/base_client.rs | 1 + src/lib.rs | 4 ++- 4 files changed, 53 insertions(+), 51 deletions(-) diff --git a/examples/login.rs b/examples/login.rs index 32af92d2..201698b2 100644 --- a/examples/login.rs +++ b/examples/login.rs @@ -9,9 +9,13 @@ use matrix_nio::{ room::message::{MessageEvent, MessageEventContent, TextMessageEventContent}, EventType, }, - AsyncClient, AsyncClientConfig, SyncSettings, + AsyncClient, AsyncClientConfig, SyncSettings, Room }; +fn callback(room: &Room, event: &RoomEvent) { + println!("{:?}", event); +} + async fn login( homeserver_url: String, username: String, @@ -22,18 +26,20 @@ async fn login( .disable_ssl_verification(); let mut client = AsyncClient::new_with_config(&homeserver_url, None, client_config).unwrap(); - client.add_event_callback(EventType::RoomMessage, |event| { - Box::pin(async { - if let RoomEvent::RoomMessage(MessageEvent { - content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), - sender, - .. - }) = event - { - println!("{}: {}", sender, msg_body); - } - }) - }); + client.add_event_callback(EventType::RoomMessage, Box::new(callback)); + + // client.add_event_callback(EventType::RoomMessage, Box::new(|event| { + // Box::pin(async { + // if let RoomEvent::RoomMessage(MessageEvent { + // content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }), + // sender, + // .. + // }) = event + // { + // println!("{}: {}", sender, msg_body); + // } + // }) + // })); client.login(username, password, None).await?; let response = client.sync(SyncSettings::new()).await?; diff --git a/src/async_client.rs b/src/async_client.rs index 92a9e27d..add8ed8b 100644 --- a/src/async_client.rs +++ b/src/async_client.rs @@ -1,4 +1,3 @@ -use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; use std::future::Future; use std::pin::Pin; @@ -16,9 +15,12 @@ pub use ruma_events::EventType; use crate::api; use crate::base_client::Client as BaseClient; +use crate::base_client::Room; use crate::error::{Error, InnerError}; use crate::session::Session; +type RoomEventCallback = Box::; + pub struct AsyncClient { /// The URL of the homeserver to connect to. homeserver: Url, @@ -27,8 +29,7 @@ pub struct AsyncClient { /// User session data. base_client: BaseClient, /// Event callbacks - event_callbacks: - HashMap Pin>>>>, + event_callbacks: Vec, } #[derive(Default, Debug)] @@ -160,16 +161,16 @@ impl AsyncClient { homeserver, http_client, base_client: BaseClient::new(session), - event_callbacks: HashMap::new(), + event_callbacks: Vec::new(), }) } pub fn add_event_callback( &mut self, event_type: EventType, - callback: impl FnMut(RoomEvent) -> Pin>> + 'static, + callback: RoomEventCallback, ) { - self.event_callbacks.insert(event_type, Box::new(callback)); + self.event_callbacks.push(callback); } pub async fn login>( @@ -187,7 +188,7 @@ impl AsyncClient { user: user.into(), }; - let response = self.send(request).await.unwrap(); + let response = self.send(request).await?; self.base_client.receive_login_response(&response); Ok(response) @@ -205,47 +206,39 @@ impl AsyncClient { timeout: sync_settings.timeout, }; - let response = self.send(request).await.unwrap(); + let response = self.send(request).await?; for (room_id, room) in &response.rooms.join { let room_id = room_id.to_string(); for event in &room.state.events { - self.base_client.receive_joined_state_event(&room_id, event); + let event = match event.clone().into_result() { + Ok(e) => e, + Err(e) => continue + }; + + self.base_client.receive_joined_state_event(&room_id, &event); } for event in &room.timeline.events { - self.base_client - .receive_joined_timeline_event(&room_id, event); - - let event_type = match &event { - RoomEvent::CallAnswer(e) => e.event_type(), - RoomEvent::CallCandidates(e) => e.event_type(), - RoomEvent::CallHangup(e) => e.event_type(), - RoomEvent::CallInvite(e) => e.event_type(), - RoomEvent::RoomAliases(e) => e.event_type(), - RoomEvent::RoomAvatar(e) => e.event_type(), - RoomEvent::RoomCanonicalAlias(e) => e.event_type(), - RoomEvent::RoomCreate(e) => e.event_type(), - RoomEvent::RoomGuestAccess(e) => e.event_type(), - RoomEvent::RoomHistoryVisibility(e) => e.event_type(), - RoomEvent::RoomJoinRules(e) => e.event_type(), - RoomEvent::RoomMember(e) => e.event_type(), - RoomEvent::RoomMessage(e) => e.event_type(), - RoomEvent::RoomName(e) => e.event_type(), - RoomEvent::RoomPinnedEvents(e) => e.event_type(), - RoomEvent::RoomPowerLevels(e) => e.event_type(), - RoomEvent::RoomRedaction(e) => e.event_type(), - RoomEvent::RoomThirdPartyInvite(e) => e.event_type(), - RoomEvent::RoomTopic(e) => e.event_type(), - RoomEvent::CustomRoom(e) => e.event_type(), - RoomEvent::CustomState(e) => e.event_type(), + let event = match event.clone().into_result() { + Ok(e) => e, + Err(e) => continue }; - if self.event_callbacks.contains_key(&event_type) { - let cb = self.event_callbacks.get_mut(&event_type).unwrap(); - cb(event.clone()).await; + self.base_client + .receive_joined_timeline_event(&room_id, &event); + + let room = self.base_client.joined_rooms.get(&room_id).unwrap(); + + for mut cb in &mut self.event_callbacks { + cb(&room, &event); } + + // if self.event_callbacks.contains_key(&event_type) { + // let cb = self.event_callbacks.get_mut(&event_type).unwrap(); + // cb(&event).await; + // } } } diff --git a/src/base_client.rs b/src/base_client.rs index b34f7d07..cf6ae6c5 100644 --- a/src/base_client.rs +++ b/src/base_client.rs @@ -105,6 +105,7 @@ impl Room { MembershipState::Ban => self.handle_leave(event), MembershipState::Invite => false, MembershipState::Knock => false, + _ => false, } } diff --git a/src/lib.rs b/src/lib.rs index fc4c0e4d..16c8b7af 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -13,4 +13,6 @@ mod error; mod session; pub use async_client::{AsyncClient, AsyncClientConfig, SyncSettings}; -pub use base_client::Client; +pub use base_client::{Client, Room}; + +pub const VERSION: &'static str = env!("CARGO_PKG_VERSION");