state_store: load/store each room type (invite, join, left), add type for returning 3 room maps
parent
22c4a1f2e7
commit
21712d0930
|
@ -3,7 +3,7 @@ use std::{env, process::exit};
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
self,
|
self,
|
||||||
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
Client, ClientConfig, EventEmitter, JsonStore, RoomState, SyncSettings,
|
Client, ClientConfig, EventEmitter, JsonStore, SyncRoom, SyncSettings,
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
@ -21,8 +21,8 @@ impl CommandBot {
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl EventEmitter for CommandBot {
|
impl EventEmitter for CommandBot {
|
||||||
async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) {
|
||||||
if let RoomState::Joined(room) = room {
|
if let SyncRoom::Joined(room) = room {
|
||||||
let msg_body = if let MessageEvent {
|
let msg_body = if let MessageEvent {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
..
|
..
|
||||||
|
|
|
@ -4,15 +4,15 @@ use url::Url;
|
||||||
use matrix_sdk::{
|
use matrix_sdk::{
|
||||||
self,
|
self,
|
||||||
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
events::room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
Client, ClientConfig, EventEmitter, RoomState, SyncSettings,
|
Client, ClientConfig, EventEmitter, SyncRoom, SyncSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EventCallback;
|
struct EventCallback;
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
impl EventEmitter for EventCallback {
|
impl EventEmitter for EventCallback {
|
||||||
async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) {
|
||||||
if let RoomState::Joined(room) = room {
|
if let SyncRoom::Joined(room) = room {
|
||||||
if let MessageEvent {
|
if let MessageEvent {
|
||||||
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
sender,
|
sender,
|
||||||
|
|
|
@ -26,8 +26,8 @@
|
||||||
//! destroyed.
|
//! destroyed.
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
pub use matrix_sdk_base::{EventEmitter, Room, Session};
|
pub use matrix_sdk_base::{AllRooms, JsonStore, RoomState, StateStore};
|
||||||
pub use matrix_sdk_base::{JsonStore, RoomState, StateStore};
|
pub use matrix_sdk_base::{EventEmitter, Room, Session, SyncRoom};
|
||||||
pub use matrix_sdk_common::*;
|
pub use matrix_sdk_common::*;
|
||||||
pub use reqwest::header::InvalidHeaderValue;
|
pub use reqwest::header::InvalidHeaderValue;
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ use crate::events::EventJson;
|
||||||
use crate::identifiers::{RoomId, UserId};
|
use crate::identifiers::{RoomId, UserId};
|
||||||
use crate::models::Room;
|
use crate::models::Room;
|
||||||
use crate::session::Session;
|
use crate::session::Session;
|
||||||
use crate::state::{ClientState, StateStore};
|
use crate::state::{AllRooms, ClientState, StateStore};
|
||||||
use crate::EventEmitter;
|
use crate::EventEmitter;
|
||||||
|
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
@ -73,14 +73,15 @@ pub enum RoomStateType {
|
||||||
/// An enum that represents the state of the given `Room`.
|
/// An enum that represents the state of the given `Room`.
|
||||||
///
|
///
|
||||||
/// If the event came from the `join`, `invite` or `leave` rooms map from the server
|
/// If the event came from the `join`, `invite` or `leave` rooms map from the server
|
||||||
/// the variant that holds the corresponding room is used.
|
/// the variant that holds the corresponding room is used. `RoomState` is generic
|
||||||
pub enum RoomState {
|
/// so it can be used to represent a `Room` or an `Arc<RwLock<Room>>`
|
||||||
|
pub enum RoomState<R> {
|
||||||
/// A room from the `join` section of a sync response.
|
/// A room from the `join` section of a sync response.
|
||||||
Joined(Arc<RwLock<Room>>),
|
Joined(R),
|
||||||
/// A room from the `leave` section of a sync response.
|
/// A room from the `leave` section of a sync response.
|
||||||
Left(Arc<RwLock<Room>>),
|
Left(R),
|
||||||
/// A room from the `invite` section of a sync response.
|
/// A room from the `invite` section of a sync response.
|
||||||
Invited(Arc<RwLock<Room>>),
|
Invited(R),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A no IO Client implementation.
|
/// A no IO Client implementation.
|
||||||
|
@ -229,8 +230,20 @@ impl BaseClient {
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut rooms = store.load_all_rooms().await?;
|
let AllRooms {
|
||||||
*self.joined_rooms.write().await = rooms
|
mut joined,
|
||||||
|
mut invited,
|
||||||
|
mut left,
|
||||||
|
} = store.load_all_rooms().await?;
|
||||||
|
*self.joined_rooms.write().await = joined
|
||||||
|
.drain()
|
||||||
|
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||||
|
.collect();
|
||||||
|
*self.invited_rooms.write().await = invited
|
||||||
|
.drain()
|
||||||
|
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||||
|
.collect();
|
||||||
|
*self.left_rooms.write().await = left
|
||||||
.drain()
|
.drain()
|
||||||
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
.map(|(k, room)| (k, Arc::new(RwLock::new(room))))
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -248,7 +261,21 @@ impl BaseClient {
|
||||||
if let Some(store) = self.state_store.read().await.as_ref() {
|
if let Some(store) = self.state_store.read().await.as_ref() {
|
||||||
if let Some(room) = self.get_joined_room(room_id).await {
|
if let Some(room) = self.get_joined_room(room_id).await {
|
||||||
let room = room.read().await;
|
let room = room.read().await;
|
||||||
store.store_room_state(room.deref()).await?;
|
store
|
||||||
|
.store_room_state(RoomState::Joined(room.deref()))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
if let Some(room) = self.get_invited_room(room_id).await {
|
||||||
|
let room = room.read().await;
|
||||||
|
store
|
||||||
|
.store_room_state(RoomState::Invited(room.deref()))
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
if let Some(room) = self.get_left_room(room_id).await {
|
||||||
|
let room = room.read().await;
|
||||||
|
store
|
||||||
|
.store_room_state(RoomState::Left(room.deref()))
|
||||||
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -754,7 +781,7 @@ impl BaseClient {
|
||||||
if updated {
|
if updated {
|
||||||
if let Some(store) = self.state_store.read().await.as_ref() {
|
if let Some(store) = self.state_store.read().await.as_ref() {
|
||||||
store
|
store
|
||||||
.store_room_state(matrix_room.read().await.deref())
|
.store_room_state(RoomState::Joined(matrix_room.read().await.deref()))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -801,7 +828,7 @@ impl BaseClient {
|
||||||
if updated {
|
if updated {
|
||||||
if let Some(store) = self.state_store.read().await.as_ref() {
|
if let Some(store) = self.state_store.read().await.as_ref() {
|
||||||
store
|
store
|
||||||
.store_room_state(matrix_room.read().await.deref())
|
.store_room_state(RoomState::Left(matrix_room.read().await.deref()))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -837,7 +864,7 @@ impl BaseClient {
|
||||||
if updated {
|
if updated {
|
||||||
if let Some(store) = self.state_store.read().await.as_ref() {
|
if let Some(store) = self.state_store.read().await.as_ref() {
|
||||||
store
|
store
|
||||||
.store_room_state(matrix_room.read().await.deref())
|
.store_room_state(RoomState::Invited(matrix_room.read().await.deref()))
|
||||||
.await?;
|
.await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
// See the License for the specific language governing permissions and
|
// See the License for the specific language governing permissions and
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use tokio::sync::RwLock;
|
||||||
|
|
||||||
use crate::events::{
|
use crate::events::{
|
||||||
fully_read::FullyReadEvent,
|
fully_read::FullyReadEvent,
|
||||||
|
@ -37,7 +40,10 @@ use crate::events::{
|
||||||
},
|
},
|
||||||
typing::TypingEvent,
|
typing::TypingEvent,
|
||||||
};
|
};
|
||||||
use crate::RoomState;
|
use crate::{Room, RoomState};
|
||||||
|
|
||||||
|
/// Type alias for `RoomState` enum when passed to `EventEmitter` methods.
|
||||||
|
pub type SyncRoom = RoomState<Arc<RwLock<Room>>>;
|
||||||
|
|
||||||
/// 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.
|
||||||
/// The `AsyncClient` calls each method when the corresponding event is received.
|
/// The `AsyncClient` calls each method when the corresponding event is received.
|
||||||
|
@ -52,7 +58,7 @@ use crate::RoomState;
|
||||||
/// # events::{
|
/// # events::{
|
||||||
/// # room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
/// # room::message::{MessageEvent, MessageEventContent, TextMessageEventContent},
|
||||||
/// # },
|
/// # },
|
||||||
/// # EventEmitter, RoomState
|
/// # EventEmitter, SyncRoom
|
||||||
/// # };
|
/// # };
|
||||||
/// use tokio::sync::RwLock;
|
/// use tokio::sync::RwLock;
|
||||||
///
|
///
|
||||||
|
@ -60,8 +66,8 @@ use crate::RoomState;
|
||||||
///
|
///
|
||||||
/// #[async_trait::async_trait]
|
/// #[async_trait::async_trait]
|
||||||
/// impl EventEmitter for EventCallback {
|
/// impl EventEmitter for EventCallback {
|
||||||
/// async fn on_room_message(&self, room: RoomState, event: &MessageEvent) {
|
/// async fn on_room_message(&self, room: SyncRoom, event: &MessageEvent) {
|
||||||
/// if let RoomState::Joined(room) = room {
|
/// if let SyncRoom::Joined(room) = room {
|
||||||
/// if let MessageEvent {
|
/// if let MessageEvent {
|
||||||
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
/// content: MessageEventContent::Text(TextMessageEventContent { body: msg_body, .. }),
|
||||||
/// sender,
|
/// sender,
|
||||||
|
@ -87,82 +93,78 @@ use crate::RoomState;
|
||||||
pub trait EventEmitter: Send + Sync {
|
pub trait EventEmitter: Send + Sync {
|
||||||
// ROOM EVENTS from `IncomingTimeline`
|
// ROOM EVENTS from `IncomingTimeline`
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMember` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMember` event.
|
||||||
async fn on_room_member(&self, _: RoomState, _: &MemberEvent) {}
|
async fn on_room_member(&self, _: SyncRoom, _: &MemberEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomName` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomName` event.
|
||||||
async fn on_room_name(&self, _: RoomState, _: &NameEvent) {}
|
async fn on_room_name(&self, _: SyncRoom, _: &NameEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomCanonicalAlias` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomCanonicalAlias` event.
|
||||||
async fn on_room_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {}
|
async fn on_room_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomAliases` event.
|
||||||
async fn on_room_aliases(&self, _: RoomState, _: &AliasesEvent) {}
|
async fn on_room_aliases(&self, _: SyncRoom, _: &AliasesEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomAvatar` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomAvatar` event.
|
||||||
async fn on_room_avatar(&self, _: RoomState, _: &AvatarEvent) {}
|
async fn on_room_avatar(&self, _: SyncRoom, _: &AvatarEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMessage` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMessage` event.
|
||||||
async fn on_room_message(&self, _: RoomState, _: &MessageEvent) {}
|
async fn on_room_message(&self, _: SyncRoom, _: &MessageEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMessageFeedback` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomMessageFeedback` event.
|
||||||
async fn on_room_message_feedback(&self, _: RoomState, _: &FeedbackEvent) {}
|
async fn on_room_message_feedback(&self, _: SyncRoom, _: &FeedbackEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomRedaction` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomRedaction` event.
|
||||||
async fn on_room_redaction(&self, _: RoomState, _: &RedactionEvent) {}
|
async fn on_room_redaction(&self, _: SyncRoom, _: &RedactionEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::RoomPowerLevels` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::RoomPowerLevels` event.
|
||||||
async fn on_room_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {}
|
async fn on_room_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `RoomEvent::Tombstone` event.
|
/// Fires when `AsyncClient` receives a `RoomEvent::Tombstone` event.
|
||||||
async fn on_room_tombstone(&self, _: RoomState, _: &TombstoneEvent) {}
|
async fn on_room_tombstone(&self, _: SyncRoom, _: &TombstoneEvent) {}
|
||||||
|
|
||||||
// `RoomEvent`s from `IncomingState`
|
// `RoomEvent`s from `IncomingState`
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomMember` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomMember` event.
|
||||||
async fn on_state_member(&self, _: RoomState, _: &MemberEvent) {}
|
async fn on_state_member(&self, _: SyncRoom, _: &MemberEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomName` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomName` event.
|
||||||
async fn on_state_name(&self, _: RoomState, _: &NameEvent) {}
|
async fn on_state_name(&self, _: SyncRoom, _: &NameEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomCanonicalAlias` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomCanonicalAlias` event.
|
||||||
async fn on_state_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {}
|
async fn on_state_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomAliases` event.
|
||||||
async fn on_state_aliases(&self, _: RoomState, _: &AliasesEvent) {}
|
async fn on_state_aliases(&self, _: SyncRoom, _: &AliasesEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomAvatar` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomAvatar` event.
|
||||||
async fn on_state_avatar(&self, _: RoomState, _: &AvatarEvent) {}
|
async fn on_state_avatar(&self, _: SyncRoom, _: &AvatarEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomPowerLevels` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomPowerLevels` event.
|
||||||
async fn on_state_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {}
|
async fn on_state_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `StateEvent::RoomJoinRules` event.
|
/// Fires when `AsyncClient` receives a `StateEvent::RoomJoinRules` event.
|
||||||
async fn on_state_join_rules(&self, _: RoomState, _: &JoinRulesEvent) {}
|
async fn on_state_join_rules(&self, _: SyncRoom, _: &JoinRulesEvent) {}
|
||||||
|
|
||||||
// `AnyStrippedStateEvent`s
|
// `AnyStrippedStateEvent`s
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomMember` event.
|
||||||
async fn on_stripped_state_member(&self, _: RoomState, _: &StrippedRoomMember) {}
|
async fn on_stripped_state_member(&self, _: SyncRoom, _: &StrippedRoomMember) {}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomName` event.
|
||||||
async fn on_stripped_state_name(&self, _: RoomState, _: &StrippedRoomName) {}
|
async fn on_stripped_state_name(&self, _: SyncRoom, _: &StrippedRoomName) {}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomCanonicalAlias` event.
|
||||||
async fn on_stripped_state_canonical_alias(
|
async fn on_stripped_state_canonical_alias(&self, _: SyncRoom, _: &StrippedRoomCanonicalAlias) {
|
||||||
&self,
|
|
||||||
_: RoomState,
|
|
||||||
_: &StrippedRoomCanonicalAlias,
|
|
||||||
) {
|
|
||||||
}
|
}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAliases` event.
|
||||||
async fn on_stripped_state_aliases(&self, _: RoomState, _: &StrippedRoomAliases) {}
|
async fn on_stripped_state_aliases(&self, _: SyncRoom, _: &StrippedRoomAliases) {}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomAvatar` event.
|
||||||
async fn on_stripped_state_avatar(&self, _: RoomState, _: &StrippedRoomAvatar) {}
|
async fn on_stripped_state_avatar(&self, _: SyncRoom, _: &StrippedRoomAvatar) {}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomPowerLevels` event.
|
||||||
async fn on_stripped_state_power_levels(&self, _: RoomState, _: &StrippedRoomPowerLevels) {}
|
async fn on_stripped_state_power_levels(&self, _: SyncRoom, _: &StrippedRoomPowerLevels) {}
|
||||||
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
/// Fires when `AsyncClient` receives a `AnyStrippedStateEvent::StrippedRoomJoinRules` event.
|
||||||
async fn on_stripped_state_join_rules(&self, _: RoomState, _: &StrippedRoomJoinRules) {}
|
async fn on_stripped_state_join_rules(&self, _: SyncRoom, _: &StrippedRoomJoinRules) {}
|
||||||
|
|
||||||
// `NonRoomEvent` (this is a type alias from ruma_events)
|
// `NonRoomEvent` (this is a type alias from ruma_events)
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomMember` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomMember` event.
|
||||||
async fn on_account_presence(&self, _: RoomState, _: &PresenceEvent) {}
|
async fn on_account_presence(&self, _: SyncRoom, _: &PresenceEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomName` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomName` event.
|
||||||
async fn on_account_ignored_users(&self, _: RoomState, _: &IgnoredUserListEvent) {}
|
async fn on_account_ignored_users(&self, _: SyncRoom, _: &IgnoredUserListEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomCanonicalAlias` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomCanonicalAlias` event.
|
||||||
async fn on_account_push_rules(&self, _: RoomState, _: &PushRulesEvent) {}
|
async fn on_account_push_rules(&self, _: SyncRoom, _: &PushRulesEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||||
async fn on_account_data_fully_read(&self, _: RoomState, _: &FullyReadEvent) {}
|
async fn on_account_data_fully_read(&self, _: SyncRoom, _: &FullyReadEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::Typing` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::Typing` event.
|
||||||
async fn on_account_data_typing(&self, _: RoomState, _: &TypingEvent) {}
|
async fn on_account_data_typing(&self, _: SyncRoom, _: &TypingEvent) {}
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::Receipt` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::Receipt` event.
|
||||||
///
|
///
|
||||||
/// This is always a read receipt.
|
/// This is always a read receipt.
|
||||||
async fn on_account_data_receipt(&self, _: RoomState, _: &ReceiptEvent) {}
|
async fn on_account_data_receipt(&self, _: SyncRoom, _: &ReceiptEvent) {}
|
||||||
|
|
||||||
// `PresenceEvent` is a struct so there is only the one method
|
// `PresenceEvent` is a struct so there is only the one method
|
||||||
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
/// Fires when `AsyncClient` receives a `NonRoomEvent::RoomAliases` event.
|
||||||
async fn on_presence_event(&self, _: RoomState, _: &PresenceEvent) {}
|
async fn on_presence_event(&self, _: SyncRoom, _: &PresenceEvent) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -174,72 +176,74 @@ mod test {
|
||||||
pub struct EvEmitterTest(Arc<Mutex<Vec<String>>>);
|
pub struct EvEmitterTest(Arc<Mutex<Vec<String>>>);
|
||||||
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
|
// we don't need to test our tests right?
|
||||||
|
#[cfg_attr(tarpaulin, skip)]
|
||||||
impl EventEmitter for EvEmitterTest {
|
impl EventEmitter for EvEmitterTest {
|
||||||
async fn on_room_member(&self, _: RoomState, _: &MemberEvent) {
|
async fn on_room_member(&self, _: SyncRoom, _: &MemberEvent) {
|
||||||
self.0.lock().await.push("member".to_string())
|
self.0.lock().await.push("member".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_name(&self, _: RoomState, _: &NameEvent) {
|
async fn on_room_name(&self, _: SyncRoom, _: &NameEvent) {
|
||||||
self.0.lock().await.push("name".to_string())
|
self.0.lock().await.push("name".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_canonical_alias(&self, _: RoomState, _: &CanonicalAliasEvent) {
|
async fn on_room_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) {
|
||||||
self.0.lock().await.push("canonical".to_string())
|
self.0.lock().await.push("canonical".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_aliases(&self, _: RoomState, _: &AliasesEvent) {
|
async fn on_room_aliases(&self, _: SyncRoom, _: &AliasesEvent) {
|
||||||
self.0.lock().await.push("aliases".to_string())
|
self.0.lock().await.push("aliases".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_avatar(&self, _: RoomState, _: &AvatarEvent) {
|
async fn on_room_avatar(&self, _: SyncRoom, _: &AvatarEvent) {
|
||||||
self.0.lock().await.push("avatar".to_string())
|
self.0.lock().await.push("avatar".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_message(&self, _: RoomState, _: &MessageEvent) {
|
async fn on_room_message(&self, _: SyncRoom, _: &MessageEvent) {
|
||||||
self.0.lock().await.push("message".to_string())
|
self.0.lock().await.push("message".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_message_feedback(&self, _: RoomState, _: &FeedbackEvent) {
|
async fn on_room_message_feedback(&self, _: SyncRoom, _: &FeedbackEvent) {
|
||||||
self.0.lock().await.push("feedback".to_string())
|
self.0.lock().await.push("feedback".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_redaction(&self, _: RoomState, _: &RedactionEvent) {
|
async fn on_room_redaction(&self, _: SyncRoom, _: &RedactionEvent) {
|
||||||
self.0.lock().await.push("redaction".to_string())
|
self.0.lock().await.push("redaction".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_power_levels(&self, _: RoomState, _: &PowerLevelsEvent) {
|
async fn on_room_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) {
|
||||||
self.0.lock().await.push("power".to_string())
|
self.0.lock().await.push("power".to_string())
|
||||||
}
|
}
|
||||||
async fn on_room_tombstone(&self, _: RoomState, _: &TombstoneEvent) {
|
async fn on_room_tombstone(&self, _: SyncRoom, _: &TombstoneEvent) {
|
||||||
self.0.lock().await.push("tombstone".to_string())
|
self.0.lock().await.push("tombstone".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_state_member(&self, _: RoomState, _: &MemberEvent) {
|
async fn on_state_member(&self, _: SyncRoom, _: &MemberEvent) {
|
||||||
self.0.lock().await.push("state member".to_string())
|
self.0.lock().await.push("state member".to_string())
|
||||||
}
|
}
|
||||||
async fn on_state_name(&self, _: RoomState, _: &NameEvent) {
|
async fn on_state_name(&self, _: SyncRoom, _: &NameEvent) {
|
||||||
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, _: RoomState, _: &CanonicalAliasEvent) {
|
async fn on_state_canonical_alias(&self, _: SyncRoom, _: &CanonicalAliasEvent) {
|
||||||
self.0.lock().await.push("state canonical".to_string())
|
self.0.lock().await.push("state canonical".to_string())
|
||||||
}
|
}
|
||||||
async fn on_state_aliases(&self, _: RoomState, _: &AliasesEvent) {
|
async fn on_state_aliases(&self, _: SyncRoom, _: &AliasesEvent) {
|
||||||
self.0.lock().await.push("state aliases".to_string())
|
self.0.lock().await.push("state aliases".to_string())
|
||||||
}
|
}
|
||||||
async fn on_state_avatar(&self, _: RoomState, _: &AvatarEvent) {
|
async fn on_state_avatar(&self, _: SyncRoom, _: &AvatarEvent) {
|
||||||
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, _: RoomState, _: &PowerLevelsEvent) {
|
async fn on_state_power_levels(&self, _: SyncRoom, _: &PowerLevelsEvent) {
|
||||||
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, _: RoomState, _: &JoinRulesEvent) {
|
async fn on_state_join_rules(&self, _: SyncRoom, _: &JoinRulesEvent) {
|
||||||
self.0.lock().await.push("state rules".to_string())
|
self.0.lock().await.push("state rules".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_stripped_state_member(&self, _: RoomState, _: &StrippedRoomMember) {
|
async fn on_stripped_state_member(&self, _: SyncRoom, _: &StrippedRoomMember) {
|
||||||
self.0
|
self.0
|
||||||
.lock()
|
.lock()
|
||||||
.await
|
.await
|
||||||
.push("stripped state member".to_string())
|
.push("stripped state member".to_string())
|
||||||
}
|
}
|
||||||
async fn on_stripped_state_name(&self, _: RoomState, _: &StrippedRoomName) {
|
async fn on_stripped_state_name(&self, _: SyncRoom, _: &StrippedRoomName) {
|
||||||
self.0.lock().await.push("stripped state name".to_string())
|
self.0.lock().await.push("stripped state name".to_string())
|
||||||
}
|
}
|
||||||
async fn on_stripped_state_canonical_alias(
|
async fn on_stripped_state_canonical_alias(
|
||||||
&self,
|
&self,
|
||||||
_: RoomState,
|
_: SyncRoom,
|
||||||
_: &StrippedRoomCanonicalAlias,
|
_: &StrippedRoomCanonicalAlias,
|
||||||
) {
|
) {
|
||||||
self.0
|
self.0
|
||||||
|
@ -247,38 +251,38 @@ mod test {
|
||||||
.await
|
.await
|
||||||
.push("stripped state canonical".to_string())
|
.push("stripped state canonical".to_string())
|
||||||
}
|
}
|
||||||
async fn on_stripped_state_aliases(&self, _: RoomState, _: &StrippedRoomAliases) {
|
async fn on_stripped_state_aliases(&self, _: SyncRoom, _: &StrippedRoomAliases) {
|
||||||
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, _: RoomState, _: &StrippedRoomAvatar) {
|
async fn on_stripped_state_avatar(&self, _: SyncRoom, _: &StrippedRoomAvatar) {
|
||||||
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, _: RoomState, _: &StrippedRoomPowerLevels) {
|
async fn on_stripped_state_power_levels(&self, _: SyncRoom, _: &StrippedRoomPowerLevels) {
|
||||||
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, _: RoomState, _: &StrippedRoomJoinRules) {
|
async fn on_stripped_state_join_rules(&self, _: SyncRoom, _: &StrippedRoomJoinRules) {
|
||||||
self.0.lock().await.push("stripped state rules".to_string())
|
self.0.lock().await.push("stripped state rules".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn on_account_presence(&self, _: RoomState, _: &PresenceEvent) {
|
async fn on_account_presence(&self, _: SyncRoom, _: &PresenceEvent) {
|
||||||
self.0.lock().await.push("account presence".to_string())
|
self.0.lock().await.push("account presence".to_string())
|
||||||
}
|
}
|
||||||
async fn on_account_ignored_users(&self, _: RoomState, _: &IgnoredUserListEvent) {
|
async fn on_account_ignored_users(&self, _: SyncRoom, _: &IgnoredUserListEvent) {
|
||||||
self.0.lock().await.push("account ignore".to_string())
|
self.0.lock().await.push("account ignore".to_string())
|
||||||
}
|
}
|
||||||
async fn on_account_push_rules(&self, _: RoomState, _: &PushRulesEvent) {
|
async fn on_account_push_rules(&self, _: SyncRoom, _: &PushRulesEvent) {
|
||||||
self.0.lock().await.push("account push rules".to_string())
|
self.0.lock().await.push("account push rules".to_string())
|
||||||
}
|
}
|
||||||
async fn on_account_data_fully_read(&self, _: RoomState, _: &FullyReadEvent) {
|
async fn on_account_data_fully_read(&self, _: SyncRoom, _: &FullyReadEvent) {
|
||||||
self.0.lock().await.push("account read".to_string())
|
self.0.lock().await.push("account read".to_string())
|
||||||
}
|
}
|
||||||
async fn on_presence_event(&self, _: RoomState, _: &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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,8 +37,8 @@ mod session;
|
||||||
mod state;
|
mod state;
|
||||||
|
|
||||||
pub use client::{BaseClient, RoomState, RoomStateType};
|
pub use client::{BaseClient, RoomState, RoomStateType};
|
||||||
pub use event_emitter::EventEmitter;
|
pub use event_emitter::{EventEmitter, SyncRoom};
|
||||||
#[cfg(feature = "encryption")]
|
#[cfg(feature = "encryption")]
|
||||||
pub use matrix_sdk_crypto::{Device, TrustState};
|
pub use matrix_sdk_crypto::{Device, TrustState};
|
||||||
pub use models::Room;
|
pub use models::Room;
|
||||||
pub use state::{JsonStore, StateStore};
|
pub use state::{AllRooms, JsonStore, StateStore};
|
||||||
|
|
|
@ -167,7 +167,9 @@ mod test {
|
||||||
|
|
||||||
let mut joined_rooms = HashMap::new();
|
let mut joined_rooms = HashMap::new();
|
||||||
joined_rooms.insert(id, room);
|
joined_rooms.insert(id, room);
|
||||||
println!("{}", serde_json::to_string_pretty(&joined_rooms).unwrap());
|
|
||||||
|
// println!("{}", serde_json::to_string_pretty(&joined_rooms).unwrap());
|
||||||
|
|
||||||
// this is the correct JSON string changes to `ruma-events` have not been released
|
// this is the correct JSON string changes to `ruma-events` have not been released
|
||||||
// that would fix the doubling of fields
|
// that would fix the doubling of fields
|
||||||
// TODO uncomment when fixed
|
// TODO uncomment when fixed
|
||||||
|
|
|
@ -14,15 +14,14 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::HashMap;
|
|
||||||
|
|
||||||
pub mod state_store;
|
pub mod state_store;
|
||||||
pub use state_store::JsonStore;
|
pub use state_store::{AllRooms, JsonStore};
|
||||||
|
|
||||||
use crate::client::{BaseClient, Token};
|
use crate::client::{BaseClient, Token};
|
||||||
use crate::events::push_rules::Ruleset;
|
use crate::events::push_rules::Ruleset;
|
||||||
use crate::identifiers::{RoomId, UserId};
|
use crate::identifiers::UserId;
|
||||||
use crate::{Result, Room, Session};
|
use crate::{Result, Room, RoomState, Session};
|
||||||
|
|
||||||
/// `ClientState` holds all the information to restore a `BaseClient`
|
/// `ClientState` holds all the information to restore a `BaseClient`
|
||||||
/// except the `access_token` as the default store is not secure.
|
/// except the `access_token` as the default store is not secure.
|
||||||
|
@ -73,11 +72,11 @@ pub trait StateStore: Send + Sync {
|
||||||
/// Load the state of all `Room`s.
|
/// Load the state of all `Room`s.
|
||||||
///
|
///
|
||||||
/// This will be mapped over in the client in order to store `Room`s in an async safe way.
|
/// This will be mapped over in the client in order to store `Room`s in an async safe way.
|
||||||
async fn load_all_rooms(&self) -> Result<HashMap<RoomId, Room>>;
|
async fn load_all_rooms(&self) -> Result<AllRooms>;
|
||||||
/// Save the current state of the `BaseClient` using the `StateStore::Store` type.
|
/// Save the current state of the `BaseClient` using the `StateStore::Store` type.
|
||||||
async fn store_client_state(&self, _: ClientState) -> Result<()>;
|
async fn store_client_state(&self, _: ClientState) -> Result<()>;
|
||||||
/// Save the state a single `Room`.
|
/// Save the state a single `Room`.
|
||||||
async fn store_room_state(&self, _: &Room) -> Result<()>;
|
async fn store_room_state(&self, _: RoomState<&Room>) -> Result<()>;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -87,6 +86,8 @@ mod test {
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
|
use crate::identifiers::RoomId;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn serialize() {
|
fn serialize() {
|
||||||
let id = RoomId::try_from("!roomid:example.com").unwrap();
|
let id = RoomId::try_from("!roomid:example.com").unwrap();
|
||||||
|
|
|
@ -12,7 +12,20 @@ use tokio::sync::RwLock;
|
||||||
|
|
||||||
use super::{ClientState, StateStore};
|
use super::{ClientState, StateStore};
|
||||||
use crate::identifiers::RoomId;
|
use crate::identifiers::RoomId;
|
||||||
use crate::{Error, Result, Room, Session};
|
use crate::{Error, Result, Room, RoomState, Session};
|
||||||
|
|
||||||
|
/// `JsonStore::load_all_rooms` returns `AllRooms`.
|
||||||
|
///
|
||||||
|
/// `AllRooms` is made of the `joined`, `invited` and `left` room maps.
|
||||||
|
pub struct AllRooms {
|
||||||
|
/// The joined room mapping of `RoomId` to `Room`.
|
||||||
|
pub joined: HashMap<RoomId, Room>,
|
||||||
|
/// The invited room mapping of `RoomId` to `Room`.
|
||||||
|
pub invited: HashMap<RoomId, Room>,
|
||||||
|
/// The left room mapping of `RoomId` to `Room`.
|
||||||
|
pub left: HashMap<RoomId, Room>,
|
||||||
|
}
|
||||||
|
|
||||||
/// A default `StateStore` implementation that serializes state as json
|
/// A default `StateStore` implementation that serializes state as json
|
||||||
/// and saves it to disk.
|
/// and saves it to disk.
|
||||||
///
|
///
|
||||||
|
@ -60,11 +73,21 @@ impl StateStore for JsonStore {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn load_all_rooms(&self) -> Result<HashMap<RoomId, Room>> {
|
async fn load_all_rooms(&self) -> Result<AllRooms> {
|
||||||
let mut path = self.path.read().await.clone();
|
let mut path = self.path.read().await.clone();
|
||||||
path.push("rooms");
|
path.push("rooms");
|
||||||
|
|
||||||
let mut rooms_map = HashMap::new();
|
let mut joined = HashMap::new();
|
||||||
|
let mut left = HashMap::new();
|
||||||
|
let mut invited = HashMap::new();
|
||||||
|
for room_state_type in &["joined", "invited", "left"] {
|
||||||
|
path.push(room_state_type);
|
||||||
|
// don't load rooms that aren't saved yet
|
||||||
|
if !path.exists() {
|
||||||
|
path.pop();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
for file in fs::read_dir(&path)? {
|
for file in fs::read_dir(&path)? {
|
||||||
let file = file?.path();
|
let file = file?.path();
|
||||||
|
|
||||||
|
@ -77,17 +100,28 @@ impl StateStore for JsonStore {
|
||||||
let room = serde_json::from_str::<Room>(&json).map_err(Error::from)?;
|
let room = serde_json::from_str::<Room>(&json).map_err(Error::from)?;
|
||||||
let room_id = room.room_id.clone();
|
let room_id = room.room_id.clone();
|
||||||
|
|
||||||
rooms_map.insert(room_id, room);
|
match *room_state_type {
|
||||||
|
"joined" => joined.insert(room_id, room),
|
||||||
|
"invited" => invited.insert(room_id, room),
|
||||||
|
"left" => left.insert(room_id, room),
|
||||||
|
_ => unreachable!("an array with 3 const elements was altered in JsonStore"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
path.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(rooms_map)
|
Ok(AllRooms {
|
||||||
|
joined,
|
||||||
|
left,
|
||||||
|
invited,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn store_client_state(&self, state: ClientState) -> Result<()> {
|
async fn store_client_state(&self, state: ClientState) -> Result<()> {
|
||||||
let mut path = self.path.read().await.clone();
|
let mut path = self.path.read().await.clone();
|
||||||
path.push("client.json");
|
path.push("client.json");
|
||||||
|
|
||||||
if !Path::new(&path).exists() {
|
if !path.exists() {
|
||||||
let mut dir = path.clone();
|
let mut dir = path.clone();
|
||||||
dir.pop();
|
dir.pop();
|
||||||
async_fs::create_dir_all(dir).await?;
|
async_fs::create_dir_all(dir).await?;
|
||||||
|
@ -104,16 +138,23 @@ impl StateStore for JsonStore {
|
||||||
file.write_all(json.as_bytes()).await.map_err(Error::from)
|
file.write_all(json.as_bytes()).await.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn store_room_state(&self, room: &Room) -> Result<()> {
|
async fn store_room_state(&self, room: RoomState<&Room>) -> Result<()> {
|
||||||
|
let (room, room_state) = match room {
|
||||||
|
RoomState::Joined(room) => (room, "joined"),
|
||||||
|
RoomState::Invited(room) => (room, "invited"),
|
||||||
|
RoomState::Left(room) => (room, "left"),
|
||||||
|
};
|
||||||
|
|
||||||
if !self.user_path_set.load(Ordering::SeqCst) {
|
if !self.user_path_set.load(Ordering::SeqCst) {
|
||||||
self.user_path_set.swap(true, Ordering::SeqCst);
|
self.user_path_set.swap(true, Ordering::SeqCst);
|
||||||
self.path.write().await.push(room.own_user_id.localpart())
|
self.path.write().await.push(room.own_user_id.localpart())
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut path = self.path.read().await.clone();
|
let mut path = self.path.read().await.clone();
|
||||||
path.push(&format!("rooms/{}.json", room.room_id));
|
path.push("rooms");
|
||||||
|
path.push(&format!("{}/{}.json", room_state, room.room_id));
|
||||||
|
|
||||||
if !Path::new(&path).exists() {
|
if !path.exists() {
|
||||||
let mut dir = path.clone();
|
let mut dir = path.clone();
|
||||||
dir.pop();
|
dir.pop();
|
||||||
async_fs::create_dir_all(dir).await?;
|
async_fs::create_dir_all(dir).await?;
|
||||||
|
@ -187,7 +228,7 @@ mod test {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_store_room_state() {
|
async fn test_store_load_joined_room_state() {
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
let path: &Path = dir.path();
|
let path: &Path = dir.path();
|
||||||
let store = JsonStore::open(path).unwrap();
|
let store = JsonStore::open(path).unwrap();
|
||||||
|
@ -196,13 +237,16 @@ mod test {
|
||||||
let user = UserId::try_from("@example:example.com").unwrap();
|
let user = UserId::try_from("@example:example.com").unwrap();
|
||||||
|
|
||||||
let room = Room::new(&id, &user);
|
let room = Room::new(&id, &user);
|
||||||
store.store_room_state(&room).await.unwrap();
|
store
|
||||||
let loaded = store.load_all_rooms().await.unwrap();
|
.store_room_state(RoomState::Joined(&room))
|
||||||
assert_eq!(loaded.get(&id), Some(&Room::new(&id, &user)));
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let AllRooms { joined, .. } = store.load_all_rooms().await.unwrap();
|
||||||
|
assert_eq!(joined.get(&id), Some(&Room::new(&id, &user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_load_rooms() {
|
async fn test_store_load_left_room_state() {
|
||||||
let dir = tempdir().unwrap();
|
let dir = tempdir().unwrap();
|
||||||
let path: &Path = dir.path();
|
let path: &Path = dir.path();
|
||||||
let store = JsonStore::open(path).unwrap();
|
let store = JsonStore::open(path).unwrap();
|
||||||
|
@ -211,9 +255,30 @@ mod test {
|
||||||
let user = UserId::try_from("@example:example.com").unwrap();
|
let user = UserId::try_from("@example:example.com").unwrap();
|
||||||
|
|
||||||
let room = Room::new(&id, &user);
|
let room = Room::new(&id, &user);
|
||||||
store.store_room_state(&room).await.unwrap();
|
store
|
||||||
let loaded = store.load_all_rooms().await.unwrap();
|
.store_room_state(RoomState::Left(&room))
|
||||||
assert_eq!(&room, loaded.get(&id).unwrap());
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let AllRooms { left, .. } = store.load_all_rooms().await.unwrap();
|
||||||
|
assert_eq!(left.get(&id), Some(&Room::new(&id, &user)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn test_store_load_invited_room_state() {
|
||||||
|
let dir = tempdir().unwrap();
|
||||||
|
let path: &Path = dir.path();
|
||||||
|
let store = JsonStore::open(path).unwrap();
|
||||||
|
|
||||||
|
let id = RoomId::try_from("!roomid:example.com").unwrap();
|
||||||
|
let user = UserId::try_from("@example:example.com").unwrap();
|
||||||
|
|
||||||
|
let room = Room::new(&id, &user);
|
||||||
|
store
|
||||||
|
.store_room_state(RoomState::Invited(&room))
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let AllRooms { invited, .. } = store.load_all_rooms().await.unwrap();
|
||||||
|
assert_eq!(invited.get(&id), Some(&Room::new(&id, &user)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
|
|
Loading…
Reference in New Issue