async_client: impl kick, join, leave, invite, create for
This commit is contained in:
parent
7c20c79f32
commit
c69d54e2d4
3 changed files with 372 additions and 1 deletions
|
@ -37,7 +37,7 @@ use ruma_api::{Endpoint, Outgoing};
|
|||
use ruma_events::room::message::MessageEventContent;
|
||||
use ruma_events::EventResult;
|
||||
pub use ruma_events::EventType;
|
||||
use ruma_identifiers::RoomId;
|
||||
use ruma_identifiers::{RoomId, RoomIdOrAliasId, UserId};
|
||||
|
||||
#[cfg(feature = "encryption")]
|
||||
use ruma_identifiers::{DeviceId, UserId};
|
||||
|
@ -181,7 +181,16 @@ impl SyncSettings {
|
|||
use api::r0::client_exchange::send_event_to_device;
|
||||
#[cfg(feature = "encryption")]
|
||||
use api::r0::keys::{claim_keys, get_keys, upload_keys, KeyAlgorithm};
|
||||
use api::r0::membership::join_room_by_id;
|
||||
use api::r0::membership::join_room_by_id_or_alias;
|
||||
use api::r0::membership::kick_user;
|
||||
use api::r0::membership::leave_room;
|
||||
use api::r0::membership::{
|
||||
invite_user::{self, InvitationRecipient},
|
||||
Invite3pid,
|
||||
};
|
||||
use api::r0::message::create_message_event;
|
||||
use api::r0::room::create_room;
|
||||
use api::r0::session::login;
|
||||
use api::r0::sync::sync_events;
|
||||
|
||||
|
@ -333,6 +342,162 @@ impl AsyncClient {
|
|||
Ok(response)
|
||||
}
|
||||
|
||||
/// Join a room by `RoomId`.
|
||||
///
|
||||
/// Returns a `join_room_by_id::Response` consisting of the
|
||||
/// joined rooms `RoomId`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * room_id - A valid RoomId otherwise sending will fail.
|
||||
///
|
||||
pub async fn join_room_by_id(&mut self, room_id: &RoomId) -> Result<join_room_by_id::Response> {
|
||||
let request = join_room_by_id::Request {
|
||||
room_id: room_id.clone(),
|
||||
third_party_signed: None,
|
||||
};
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// Join a room by `RoomId`.
|
||||
///
|
||||
/// Returns a `join_room_by_id_or_alias::Response` consisting of the
|
||||
/// joined rooms `RoomId`.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * alias - A valid `RoomIdOrAliasId` otherwise sending will fail.
|
||||
///
|
||||
pub async fn join_room_by_id_or_alias(
|
||||
&mut self,
|
||||
alias: &RoomIdOrAliasId,
|
||||
) -> Result<join_room_by_id_or_alias::Response> {
|
||||
let request = join_room_by_id_or_alias::Request {
|
||||
room_id_or_alias: alias.clone(),
|
||||
third_party_signed: None,
|
||||
};
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// Kick a user out of the specified room.
|
||||
///
|
||||
/// Returns a `kick_user::Response`, an empty response.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * room_id - A valid `RoomId` otherwise sending will fail.
|
||||
///
|
||||
/// * user_id - A valid `UserId`.
|
||||
///
|
||||
/// * reason - Optional reason why the room member is being kicked out.
|
||||
///
|
||||
pub async fn kick_user(
|
||||
&mut self,
|
||||
room_id: &RoomId,
|
||||
user_id: &UserId,
|
||||
reason: Option<String>,
|
||||
) -> Result<kick_user::Response> {
|
||||
let request = kick_user::Request {
|
||||
reason,
|
||||
room_id: room_id.clone(),
|
||||
user_id: user_id.clone(),
|
||||
};
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// Leave the specified room.
|
||||
///
|
||||
/// Returns a `leave_room::Response`, an empty response.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * room_id - A valid `RoomId`.
|
||||
///
|
||||
pub async fn leave_room(&mut self, room_id: &RoomId) -> Result<leave_room::Response> {
|
||||
let request = leave_room::Request {
|
||||
room_id: room_id.clone(),
|
||||
};
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// Invite the specified user by `UserId` to the given room.
|
||||
///
|
||||
/// Returns a `invite_user::Response`, an empty response.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * room_id - A valid `RoomId`.
|
||||
///
|
||||
/// * user_id - A valid `UserId`.
|
||||
///
|
||||
pub async fn invite_user_by_id(
|
||||
&mut self,
|
||||
room_id: &RoomId,
|
||||
user_id: &UserId,
|
||||
) -> Result<invite_user::Response> {
|
||||
let request = invite_user::Request {
|
||||
room_id: room_id.clone(),
|
||||
recipient: InvitationRecipient::UserId {
|
||||
user_id: user_id.clone(),
|
||||
},
|
||||
};
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// Invite the specified user by third party id to the given room.
|
||||
///
|
||||
/// Returns a `invite_user::Response`, an empty response.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * room_id - A valid `RoomId`.
|
||||
///
|
||||
/// * invite_id - A valid `UserId`.
|
||||
///
|
||||
pub async fn invite_user_by_3pid(
|
||||
&mut self,
|
||||
room_id: &RoomId,
|
||||
invite_id: &Invite3pid,
|
||||
) -> Result<invite_user::Response> {
|
||||
let request = invite_user::Request {
|
||||
room_id: room_id.clone(),
|
||||
recipient: InvitationRecipient::ThirdPartyId(invite_id.clone()),
|
||||
};
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// A builder to create a room and send the request.
|
||||
///
|
||||
/// Returns a `create_room::Response`, an empty response.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * room - the easiest way to create this request is using `RoomBuilder` struct.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```ignore
|
||||
/// use matrix_sdk::{AsyncClient, RoomBuilder};
|
||||
///
|
||||
/// let mut bldr = RoomBuilder::default();
|
||||
/// bldr.creation_content(false)
|
||||
/// .initial_state(vec![])
|
||||
/// .visibility(Visibility::Public)
|
||||
/// .name("name")
|
||||
/// .room_version("v1.0");
|
||||
///
|
||||
/// let mut cli = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||
///
|
||||
/// assert!(cli.create_room(bldr).await.is_ok());
|
||||
/// ```
|
||||
///
|
||||
pub async fn create_room<R: Into<create_room::Request>>(
|
||||
&mut self,
|
||||
room: R,
|
||||
) -> Result<create_room::Response> {
|
||||
let request = room.into();
|
||||
self.send(request).await
|
||||
}
|
||||
|
||||
/// Synchronize the client's state with the latest state on the server.
|
||||
///
|
||||
/// # Arguments
|
||||
|
|
|
@ -38,6 +38,7 @@ mod base_client;
|
|||
mod error;
|
||||
mod event_emitter;
|
||||
mod models;
|
||||
mod request_builder;
|
||||
mod session;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -50,5 +51,6 @@ pub use async_client::{AsyncClient, AsyncClientConfig, SyncSettings};
|
|||
pub use base_client::Client;
|
||||
pub use event_emitter::EventEmitter;
|
||||
pub use models::Room;
|
||||
pub use request_builder::RoomBuilder;
|
||||
|
||||
pub(crate) const VERSION: &str = env!("CARGO_PKG_VERSION");
|
||||
|
|
204
src/request_builder.rs
Normal file
204
src/request_builder.rs
Normal file
|
@ -0,0 +1,204 @@
|
|||
use crate::events::room::power_levels::PowerLevelsEventContent;
|
||||
use crate::identifiers::UserId;
|
||||
use crate::api;
|
||||
use api::r0::membership::Invite3pid;
|
||||
use api::r0::room::{
|
||||
create_room::{self, CreationContent, InitialStateEvent, RoomPreset},
|
||||
Visibility,
|
||||
};
|
||||
|
||||
/// A builder used to create rooms.
|
||||
///
|
||||
/// # Examples
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
#[derive(Default)]
|
||||
pub struct RoomBuilder {
|
||||
/// Extra keys to be added to the content of the `m.room.create`.
|
||||
creation_content: Option<CreationContent>,
|
||||
/// List of state events to send to the new room.
|
||||
///
|
||||
/// Takes precedence over events set by preset, but gets overriden by
|
||||
/// name and topic keys.
|
||||
initial_state: Vec<InitialStateEvent>,
|
||||
/// A list of user IDs to invite to the room.
|
||||
///
|
||||
/// This will tell the server to invite everyone in the list to the newly created room.
|
||||
invite: Vec<UserId>,
|
||||
/// List of third party IDs of users to invite.
|
||||
invite_3pid: Vec<Invite3pid>,
|
||||
/// If set, this sets the `is_direct` flag on room invites.
|
||||
is_direct: Option<bool>,
|
||||
/// If this is included, an `m.room.name` event will be sent into the room to indicate
|
||||
/// the name of the room.
|
||||
name: Option<String>,
|
||||
/// Power level content to override in the default power level event.
|
||||
power_level_content_override: Option<PowerLevelsEventContent>,
|
||||
/// Convenience parameter for setting various default state events based on a preset.
|
||||
preset: Option<RoomPreset>,
|
||||
/// The desired room alias local part.
|
||||
room_alias_name: Option<String>,
|
||||
/// Room version to set for the room. Defaults to homeserver's default if not specified.
|
||||
room_version: Option<String>,
|
||||
/// If this is included, an `m.room.topic` event will be sent into the room to indicate
|
||||
/// the topic for the room.
|
||||
topic: Option<String>,
|
||||
/// A public visibility indicates that the room will be shown in the published room
|
||||
/// list. A private visibility will hide the room from the published room list. Rooms
|
||||
/// default to private visibility if this key is not included.
|
||||
visibility: Option<Visibility>,
|
||||
}
|
||||
|
||||
impl RoomBuilder {
|
||||
/// Returns an empty `RoomBuilder` for creating rooms.
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
/// Set the `CreationContent`.
|
||||
///
|
||||
/// Weather users on other servers can join this room.
|
||||
pub fn creation_content(&mut self, federate: bool) -> &mut Self {
|
||||
let federate = Some(federate);
|
||||
self.creation_content = Some(CreationContent { federate });
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the `InitialStateEvent` vector.
|
||||
///
|
||||
pub fn initial_state(&mut self, state: Vec<InitialStateEvent>) -> &mut Self {
|
||||
self.initial_state = state;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the vec of `UserId`s.
|
||||
///
|
||||
pub fn invite(&mut self, invite: Vec<UserId>) -> &mut Self {
|
||||
self.invite = invite;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the vec of `Invite3pid`s.
|
||||
///
|
||||
pub fn invite_3pid(&mut self, invite: Vec<Invite3pid>) -> &mut Self {
|
||||
self.invite_3pid = invite;
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the vec of `Invite3pid`s.
|
||||
///
|
||||
pub fn is_direct(&mut self, direct: bool) -> &mut Self {
|
||||
self.is_direct = Some(direct);
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the room name. A `m.room.name` event will be sent to the room.
|
||||
///
|
||||
pub fn name<S: Into<String>>(&mut self, name: S) -> &mut Self {
|
||||
self.name = Some(name.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Set the room's power levels.
|
||||
///
|
||||
pub fn power_level_override(&mut self, power: PowerLevelsEventContent) -> &mut Self {
|
||||
self.power_level_content_override = Some(power);
|
||||
self
|
||||
}
|
||||
|
||||
/// Convenience for setting various default state events based on a preset.
|
||||
///
|
||||
pub fn preset(&mut self, preset: RoomPreset) -> &mut Self {
|
||||
self.preset = Some(preset);
|
||||
self
|
||||
}
|
||||
|
||||
/// The local part of a room alias.
|
||||
///
|
||||
pub fn room_alias_name<S: Into<String>>(&mut self, alias: S) -> &mut Self {
|
||||
self.room_alias_name = Some(alias.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// Room version, defaults to homeserver's version if left unspecified.
|
||||
///
|
||||
pub fn room_version<S: Into<String>>(&mut self, version: S) -> &mut Self {
|
||||
self.room_version = Some(version.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// If included, a `m.room.topic` event will be sent to the room.
|
||||
///
|
||||
pub fn topic<S: Into<String>>(&mut self, topic: S) -> &mut Self {
|
||||
self.topic = Some(topic.into());
|
||||
self
|
||||
}
|
||||
|
||||
/// A public visibility indicates that the room will be shown in the published
|
||||
/// room list. A private visibility will hide the room from the published room list.
|
||||
/// Rooms default to private visibility if this key is not included.
|
||||
///
|
||||
pub fn visibility(&mut self, vis: Visibility) -> &mut Self {
|
||||
self.visibility = Some(vis);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl Into<create_room::Request> for RoomBuilder {
|
||||
fn into(self) -> create_room::Request {
|
||||
create_room::Request {
|
||||
creation_content: self.creation_content,
|
||||
initial_state: self.initial_state,
|
||||
invite: self.invite,
|
||||
invite_3pid: self.invite_3pid,
|
||||
is_direct: self.is_direct,
|
||||
name: self.name,
|
||||
power_level_content_override: self.power_level_content_override,
|
||||
preset: self.preset,
|
||||
room_alias_name: self.room_alias_name,
|
||||
room_version: self.room_version,
|
||||
topic: self.topic,
|
||||
visibility: self.visibility,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
use crate::{AsyncClient, Session};
|
||||
|
||||
use mockito::mock;
|
||||
use url::Url;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
|
||||
#[tokio::test]
|
||||
async fn create_room_builder() {
|
||||
let homeserver = Url::parse(&mockito::server_url()).unwrap();
|
||||
|
||||
let _m = mock("POST", "/_matrix/client/r0/createRoom")
|
||||
.with_status(200)
|
||||
.with_body_from_file("./tests/data/room_id.json")
|
||||
.create();
|
||||
|
||||
let session = Session {
|
||||
access_token: "1234".to_owned(),
|
||||
user_id: UserId::try_from("@example:localhost").unwrap(),
|
||||
device_id: "DEVICEID".to_owned(),
|
||||
};
|
||||
|
||||
let mut bldr = RoomBuilder::default();
|
||||
bldr.creation_content(false)
|
||||
.initial_state(vec![])
|
||||
.visibility(Visibility::Public)
|
||||
.name("name")
|
||||
.room_version("v1.0");
|
||||
|
||||
let mut cli = AsyncClient::new(homeserver, Some(session)).unwrap();
|
||||
|
||||
assert!(cli.create_room(bldr).await.is_ok());
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue