diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index f465ac36..069604ae 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -41,7 +41,7 @@ use tracing::{error, info, instrument}; use matrix_sdk_base::{ deserialized_responses::{MembersResponse, SyncResponse}, - BaseClient, BaseClientConfig, EventHandler, Room, RoomType, Session, Store, + BaseClient, BaseClientConfig, EventHandler, Session, Store, }; #[cfg(feature = "encryption")] @@ -121,7 +121,7 @@ use matrix_sdk_common::{ use crate::{ error::HttpError, http_client::{client_with_config, HttpClient, HttpSend}, - Error, OutgoingRequest, Result, + room, Error, OutgoingRequest, Result, }; #[cfg(feature = "encryption")] @@ -564,34 +564,38 @@ impl Client { /// Get all the rooms the client knows about. /// /// This will return the list of joined, invited, and left rooms. - pub fn rooms(&self) -> Vec { - self.store().get_rooms() - } - - /// Returns the joined rooms this client knows about. - pub fn joined_rooms(&self) -> Vec { + pub fn rooms(&self) -> Vec { self.store() .get_rooms() .into_iter() - .filter(|room| room.room_type() == RoomType::Joined) + .map(|room| room::Common::new(self.clone(), room)) + .collect() + } + + /// Returns the joined rooms this client knows about. + pub fn joined_rooms(&self) -> Vec { + self.store() + .get_rooms() + .into_iter() + .filter_map(|room| room::Joined::new(self.clone(), room)) .collect() } /// Returns the invited rooms this client knows about. - pub fn invited_rooms(&self) -> Vec { + pub fn invited_rooms(&self) -> Vec { self.store() .get_rooms() .into_iter() - .filter(|room| room.room_type() == RoomType::Invited) + .filter_map(|room| room::Invited::new(self.clone(), room)) .collect() } /// Returns the left rooms this client knows about. - pub fn left_rooms(&self) -> Vec { + pub fn left_rooms(&self) -> Vec { self.store() .get_rooms() .into_iter() - .filter(|room| room.room_type() == RoomType::Left) + .filter_map(|room| room::Left::new(self.clone(), room)) .collect() } @@ -600,10 +604,10 @@ impl Client { /// # Arguments /// /// `room_id` - The unique id of the room that should be fetched. - pub fn get_joined_room(&self, room_id: &RoomId) -> Option { + pub fn get_joined_room(&self, room_id: &RoomId) -> Option { self.store() .get_room(room_id) - .filter(|room| room.room_type() == RoomType::Joined) + .and_then(|room| room::Joined::new(self.clone(), room)) } /// Get an invited room with the given room id. @@ -611,10 +615,10 @@ impl Client { /// # Arguments /// /// `room_id` - The unique id of the room that should be fetched. - pub fn get_invited_room(&self, room_id: &RoomId) -> Option { + pub fn get_invited_room(&self, room_id: &RoomId) -> Option { self.store() .get_room(room_id) - .filter(|room| room.room_type() == RoomType::Invited) + .and_then(|room| room::Invited::new(self.clone(), room)) } /// Get a left room with the given room id. @@ -622,10 +626,10 @@ impl Client { /// # Arguments /// /// `room_id` - The unique id of the room that should be fetched. - pub fn get_left_room(&self, room_id: &RoomId) -> Option { + pub fn get_left_room(&self, room_id: &RoomId) -> Option { self.store() .get_room(room_id) - .filter(|room| room.room_type() == RoomType::Left) + .and_then(|room| room::Left::new(self.clone(), room)) } /// Login to the server. diff --git a/matrix_sdk/src/lib.rs b/matrix_sdk/src/lib.rs index 9b70e874..9d90c72e 100644 --- a/matrix_sdk/src/lib.rs +++ b/matrix_sdk/src/lib.rs @@ -78,6 +78,8 @@ pub use reqwest; mod client; mod error; mod http_client; +/// High-level room API +pub mod room; #[cfg(feature = "encryption")] mod device; diff --git a/matrix_sdk/src/room/common.rs b/matrix_sdk/src/room/common.rs new file mode 100644 index 00000000..f31b3767 --- /dev/null +++ b/matrix_sdk/src/room/common.rs @@ -0,0 +1,34 @@ +use crate::{Client, Room}; +use std::ops::Deref; + +/// A struct containing methodes that are common for Joined, Invited and Left Rooms +#[derive(Debug, Clone)] +pub struct Common { + inner: Room, + client: Client, +} + +impl Deref for Common { + type Target = Room; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl Common { + /// Create a new `room::Common` + /// + /// # Arguments + /// * `client` - The client used to make requests. + /// + /// * `room` - The underlaying room. + pub fn new(client: Client, room: Room) -> Self { + Self { + inner: room, + client, + } + } + + // TODO: add common mehtods e.g forget_room() +} diff --git a/matrix_sdk/src/room/invited.rs b/matrix_sdk/src/room/invited.rs new file mode 100644 index 00000000..404b652a --- /dev/null +++ b/matrix_sdk/src/room/invited.rs @@ -0,0 +1,37 @@ +use crate::{room::Common, Client, Room, RoomType}; +use std::ops::Deref; + +/// A room in the invited state. +/// +/// This struct contains all methodes specific to a `Room` with type `RoomType::Invited`. +/// Operations may fail once the underlaying `Room` changes `RoomType`. +#[derive(Debug, Clone)] +pub struct Invited { + inner: Common, +} + +impl Invited { + /// Create a new `room::Invited` if the underlaying `Room` has type `RoomType::Invited`. + /// + /// # Arguments + /// * `client` - The client used to make requests. + /// + /// * `room` - The underlaying room. + pub fn new(client: Client, room: Room) -> Option { + if room.room_type() == RoomType::Invited { + Some(Self { + inner: Common::new(client, room), + }) + } else { + None + } + } +} + +impl Deref for Invited { + type Target = Common; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} diff --git a/matrix_sdk/src/room/joined.rs b/matrix_sdk/src/room/joined.rs new file mode 100644 index 00000000..bcc91372 --- /dev/null +++ b/matrix_sdk/src/room/joined.rs @@ -0,0 +1,37 @@ +use crate::{room::Common, Client, Room, RoomType}; +use std::ops::Deref; + +/// A room in the joined state. +/// +/// The `JoinedRoom` contains all methodes specific to a `Room` with type `RoomType::Joined`. +/// Operations may fail once the underlaying `Room` changes `RoomType`. +#[derive(Debug, Clone)] +pub struct Joined { + inner: Common, +} + +impl Deref for Joined { + type Target = Common; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} + +impl Joined { + /// Create a new `room::Joined` if the underlaying `Room` has type `RoomType::Joined`. + /// + /// # Arguments + /// * `client` - The client used to make requests. + /// + /// * `room` - The underlaying room. + pub fn new(client: Client, room: Room) -> Option { + if room.room_type() == RoomType::Joined { + Some(Self { + inner: Common::new(client, room), + }) + } else { + None + } + } +} diff --git a/matrix_sdk/src/room/left.rs b/matrix_sdk/src/room/left.rs new file mode 100644 index 00000000..0c360dbf --- /dev/null +++ b/matrix_sdk/src/room/left.rs @@ -0,0 +1,37 @@ +use crate::{room::Common, Client, Room, RoomType}; +use std::ops::Deref; + +/// A room in the left state. +/// +/// This struct contains all methodes specific to a `Room` with type `RoomType::Left`. +/// Operations may fail once the underlaying `Room` changes `RoomType`. +#[derive(Debug, Clone)] +pub struct Left { + inner: Common, +} + +impl Left { + /// Create a new `room::Left` if the underlaying `Room` has type `RoomType::Left`. + /// + /// # Arguments + /// * `client` - The client used to make requests. + /// + /// * `room` - The underlaying room. + pub fn new(client: Client, room: Room) -> Option { + if room.room_type() == RoomType::Left { + Some(Self { + inner: Common::new(client, room), + }) + } else { + None + } + } +} + +impl Deref for Left { + type Target = Common; + + fn deref(&self) -> &Self::Target { + &self.inner + } +} diff --git a/matrix_sdk/src/room/mod.rs b/matrix_sdk/src/room/mod.rs new file mode 100644 index 00000000..906500b1 --- /dev/null +++ b/matrix_sdk/src/room/mod.rs @@ -0,0 +1,9 @@ +mod common; +mod invited; +mod joined; +mod left; + +pub use self::common::Common; +pub use self::invited::Invited; +pub use self::joined::Joined; +pub use self::left::Left;