From 6760f81498284c8fb0a2c3fca3a6938520773ffd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Wed, 26 Aug 2020 13:40:38 +0200 Subject: [PATCH] matrix-sdk: Update Ruma. --- matrix_sdk/src/client.rs | 210 +++++----- matrix_sdk/src/lib.rs | 4 - matrix_sdk/src/request_builder.rs | 549 --------------------------- matrix_sdk_base/src/models/room.rs | 1 + matrix_sdk_common/Cargo.toml | 2 +- matrix_sdk_crypto/src/device.rs | 26 +- matrix_sdk_crypto/src/olm/account.rs | 11 +- 7 files changed, 105 insertions(+), 698 deletions(-) delete mode 100644 matrix_sdk/src/request_builder.rs diff --git a/matrix_sdk/src/client.rs b/matrix_sdk/src/client.rs index 7c6f27f7..be0db356 100644 --- a/matrix_sdk/src/client.rs +++ b/matrix_sdk/src/client.rs @@ -53,7 +53,9 @@ use matrix_sdk_common::{ room::create_room, session::login, sync::sync_events, - typing::create_typing_event, + typing::create_typing_event::{ + Request as TypingRequest, Response as TypingResponse, Typing, + }, }, assign, identifiers::ServerName, @@ -226,7 +228,7 @@ impl ClientConfig { /// implementations for the crypto store and the state store. It will use /// the given path to open the stores. If no path is provided no store will /// be opened - pub fn store_path>(mut self, path: P) -> Self { + pub fn store_path(mut self, path: impl AsRef) -> Self { self.base_config = self.base_config.store_path(path); self } @@ -280,7 +282,7 @@ impl<'a> SyncSettings<'a> { /// # Arguments /// /// * `token` - The sync token that should be used for the sync call. - pub fn token>(mut self, token: S) -> Self { + pub fn token(mut self, token: impl Into) -> Self { self.token = Some(token.into()); self } @@ -326,7 +328,7 @@ impl Client { /// # Arguments /// /// * `homeserver_url` - The homeserver that the client should connect to. - pub fn new>(homeserver_url: U) -> Result { + pub fn new(homeserver_url: impl TryInto) -> Result { let config = ClientConfig::new(); Client::new_with_config(homeserver_url, config) } @@ -338,8 +340,8 @@ impl Client { /// * `homeserver_url` - The homeserver that the client should connect to. /// /// * `config` - Configuration for the client. - pub fn new_with_config>( - homeserver_url: U, + pub fn new_with_config( + homeserver_url: impl TryInto, config: ClientConfig, ) -> Result { let homeserver = if let Ok(u) = homeserver_url.try_into() { @@ -518,31 +520,33 @@ impl Client { /// # Examples /// ```no_run /// # use std::convert::TryFrom; - /// # use matrix_sdk::{Client, RegistrationBuilder}; - /// # use matrix_sdk::api::r0::account::register::RegistrationKind; + /// # use matrix_sdk::Client; + /// # use matrix_sdk::api::r0::account::register::{Request as RegistrationRequest, RegistrationKind}; /// # use matrix_sdk::api::r0::uiaa::AuthData; /// # use matrix_sdk::identifiers::DeviceId; + /// # use matrix_sdk_common::assign; /// # use futures::executor::block_on; /// # use url::Url; /// # let homeserver = Url::parse("http://example.com").unwrap(); /// # block_on(async { - /// let mut builder = RegistrationBuilder::default(); - /// builder.password("pass") - /// .username("user") - /// .auth(AuthData::DirectRequest { - /// kind: "m.login.dummy", - /// session: None, - /// auth_parameters: Default::default(), - /// }) - /// .kind(RegistrationKind::User); - /// let mut client = Client::new(homeserver).unwrap(); - /// client.register_user(builder).await; + /// + /// let request = assign!(RegistrationRequest::new(), { + /// username: Some("user"), + /// password: Some("password"), + /// auth: Some(AuthData::FallbackAcknowledgement { session: "foobar" }), + /// kind: RegistrationKind::User, + /// device_id: None, + /// initial_device_display_name: None, + /// inhibit_login: false, + /// }); + /// let client = Client::new(homeserver).unwrap(); + /// client.register(request).await; /// # }) /// ``` #[instrument(skip(registration))] - pub async fn register_user<'a, R: Into>>( + pub async fn register( &self, - registration: R, + registration: impl Into>, ) -> Result { info!("Registering to {}", self.homeserver); @@ -577,11 +581,9 @@ impl Client { alias: &RoomIdOrAliasId, server_names: &[Box], ) -> Result { - let request = join_room_by_id_or_alias::Request { - room_id_or_alias: alias.clone(), + let request = assign!(join_room_by_id_or_alias::Request::new(alias), { server_name: server_names, - third_party_signed: None, - }; + }); self.send(request).await } @@ -665,12 +667,9 @@ impl Client { room_id: &RoomId, user_id: &UserId, ) -> Result { - let request = invite_user::Request { - room_id: room_id.clone(), - recipient: InvitationRecipient::UserId { - user_id: user_id.clone(), - }, - }; + let recipient = InvitationRecipient::UserId { user_id }; + + let request = invite_user::Request::new(room_id, recipient); self.send(request).await } @@ -686,12 +685,10 @@ impl Client { pub async fn invite_user_by_3pid( &self, room_id: &RoomId, - invite_id: &Invite3pid, + invite_id: Invite3pid<'_>, ) -> Result { - let request = invite_user::Request { - room_id: room_id.clone(), - recipient: InvitationRecipient::ThirdPartyId(invite_id.clone()), - }; + let recipient = InvitationRecipient::ThirdPartyId(invite_id); + let request = invite_user::Request::new(room_id, recipient); self.send(request).await } @@ -750,31 +747,28 @@ impl Client { /// * `room_search` - The easiest way to create this request is using the `RoomListFilterBuilder`. /// /// # Examples - /// ``` + /// ```no_run /// # use std::convert::TryFrom; - /// # use matrix_sdk::{Client, RoomListFilterBuilder}; + /// # use matrix_sdk::Client; /// # use matrix_sdk::directory::{Filter, RoomNetwork}; - /// # use matrix_sdk::api::r0::directory::get_public_rooms_filtered; + /// # use matrix_sdk::api::r0::directory::get_public_rooms_filtered::Request as PublicRoomsFilterRequest; + /// # use matrix_sdk_common::assign; /// # use url::Url; /// # use futures::executor::block_on; /// # let homeserver = Url::parse("http://example.com").unwrap(); /// # block_on(async { - /// # let last_sync_token = "".to_string(); /// let mut client = Client::new(homeserver).unwrap(); /// - /// let generic_search_term = Some("matrix-rust-sdk".to_string()); - /// let mut builder = RoomListFilterBuilder::new(); - /// builder - /// .filter(Filter { generic_search_term, }) - /// .since(&last_sync_token) - /// .room_network(RoomNetwork::Matrix); + /// let generic_search_term = Some("matrix-rust-sdk"); + /// let filter = Some(assign!(Filter::new(), { generic_search_term })); + /// let request = assign!(PublicRoomsFilterRequest::new(), { filter }); /// - /// client.public_rooms_filtered(builder).await; + /// client.public_rooms_filtered(request).await; /// # }) /// ``` - pub async fn public_rooms_filtered<'a, R: Into>>( + pub async fn public_rooms_filtered( &self, - room_search: R, + room_search: impl Into>, ) -> Result { let request = room_search.into(); self.send(request).await @@ -791,27 +785,21 @@ impl Client { /// /// # Examples /// ```no_run - /// use matrix_sdk::{Client, RoomBuilder}; - /// # use matrix_sdk::api::r0::room::Visibility; + /// use matrix_sdk::Client; + /// # use matrix_sdk::api::r0::room::{create_room::Request as CreateRoomRequest, Visibility}; /// # use url::Url; /// /// # let homeserver = Url::parse("http://example.com").unwrap(); - /// let mut builder = RoomBuilder::new(); - /// builder.federate(false) - /// .initial_state(vec![]) - /// .visibility(Visibility::Public) - /// .name("name") - /// .room_version("v1.0"); - /// - /// let mut client = Client::new(homeserver).unwrap(); + /// let request = CreateRoomRequest::new(); + /// let client = Client::new(homeserver).unwrap(); /// # use futures::executor::block_on; /// # block_on(async { - /// assert!(client.create_room(builder).await.is_ok()); + /// assert!(client.create_room(request).await.is_ok()); /// # }); /// ``` - pub async fn create_room>( + pub async fn create_room( &self, - room: R, + room: impl Into>, ) -> Result { let request = room.into(); self.send(request).await @@ -832,30 +820,26 @@ impl Client { /// # Examples /// ```no_run /// # use std::convert::TryFrom; - /// use matrix_sdk::{Client, MessagesRequestBuilder}; + /// use matrix_sdk::Client; /// # use matrix_sdk::identifiers::room_id; /// # use matrix_sdk::api::r0::filter::RoomEventFilter; - /// # use matrix_sdk::api::r0::message::get_message_events::Direction; + /// # use matrix_sdk::api::r0::message::get_message_events::Request as MessagesRequest; /// # use url::Url; /// # use matrix_sdk::js_int::UInt; /// /// # let homeserver = Url::parse("http://example.com").unwrap(); /// let room_id = room_id!("!roomid:example.com"); - /// let mut builder = MessagesRequestBuilder::new(&room_id, "t47429-4392820_219380_26003_2265"); - /// - /// builder.to("t4357353_219380_26003_2265") - /// .direction(Direction::Backward) - /// .limit(10); + /// let request = MessagesRequest::backward(&room_id, "t47429-4392820_219380_26003_2265"); /// /// let mut client = Client::new(homeserver).unwrap(); /// # use futures::executor::block_on; /// # block_on(async { - /// assert!(client.room_messages(builder).await.is_ok()); + /// assert!(client.room_messages(request).await.is_ok()); /// # }); /// ``` - pub async fn room_messages<'a, R: Into>>( + pub async fn room_messages( &self, - request: R, + request: impl Into>, ) -> Result { let req = request.into(); self.send(req).await @@ -878,14 +862,12 @@ impl Client { &self, room_id: &RoomId, user_id: &UserId, - typing: bool, - timeout: Option, - ) -> Result { - let request = create_typing_event::Request { + typing: impl Into, + ) -> Result { + let request = TypingRequest { room_id: room_id.clone(), user_id: user_id.clone(), - timeout, - typing, + state: typing.into(), }; self.send(request).await } @@ -929,11 +911,9 @@ impl Client { fully_read: &EventId, read_receipt: Option<&EventId>, ) -> Result { - let request = set_read_marker::Request { - room_id: room_id.clone(), - fully_read: fully_read.clone(), - read_receipt: read_receipt.cloned(), - }; + let request = assign!(set_read_marker::Request::new(room_id, fully_read), { + read_receipt + }); self.send(request).await } @@ -1135,13 +1115,13 @@ impl Client { /// * `sync_settings` - Settings for the sync call. #[instrument] pub async fn sync(&self, sync_settings: SyncSettings<'_>) -> Result { - let request = sync_events::Request { + let request = assign!(sync_events::Request::new(), { filter: sync_settings.filter, since: sync_settings.token.as_deref(), full_state: sync_settings.full_state, set_presence: PresenceState::Online, timeout: sync_settings.timeout, - }; + }); let mut response = self.send(request).await?; @@ -1505,15 +1485,17 @@ impl Client { #[cfg(test)] mod test { use super::{ - create_typing_event, get_public_rooms, get_public_rooms_filtered, - register::RegistrationKind, Client, ClientConfig, Invite3pid, MessageEventContent, Session, - SyncSettings, Url, + get_public_rooms, get_public_rooms_filtered, register::RegistrationKind, Client, + ClientConfig, Invite3pid, MessageEventContent, Session, SyncSettings, Url, }; - use crate::{RegistrationBuilder, RoomListFilterBuilder}; - use matrix_sdk_base::JsonStore; use matrix_sdk_common::{ - api::r0::uiaa::AuthData, + api::r0::{ + account::register::Request as RegistrationRequest, + directory::get_public_rooms_filtered::Request as PublicRoomsFilterRequest, + typing::create_typing_event::Typing, uiaa::AuthData, + }, + assign, directory::Filter, events::room::message::TextMessageEventContent, identifiers::{event_id, room_id, user_id}, @@ -1720,14 +1702,17 @@ mod test { .with_body(test_json::REGISTRATION_RESPONSE_ERR.to_string()) .create(); - let mut user = RegistrationBuilder::default(); + let user = assign!(RegistrationRequest::new(), { + username: Some("user"), + password: Some("password"), + auth: Some(AuthData::FallbackAcknowledgement { session: "foobar" }), + kind: RegistrationKind::User, + device_id: None, + initial_device_display_name: None, + inhibit_login: false, + }); - user.username("user") - .password("password") - .auth(AuthData::FallbackAcknowledgement { session: "foobar" }) - .kind(RegistrationKind::User); - - if let Err(err) = client.register_user(user).await { + if let Err(err) = client.register(user).await { if let crate::Error::UiaaError(crate::FromHttpResponseError::Http( // TODO this should be a UiaaError need to investigate crate::ServerError::Unknown(e), @@ -1831,11 +1816,11 @@ mod test { client .invite_user_by_3pid( &room_id, - &Invite3pid { - id_server: "example.org".to_string(), - id_access_token: "IdToken".to_string(), + Invite3pid { + id_server: "example.org", + id_access_token: "IdToken", medium: thirdparty::Medium::Email, - address: "address".to_string(), + address: "address", }, ) .await @@ -1873,11 +1858,9 @@ mod test { .match_header("authorization", "Bearer 1234") .create(); - let generic_search_term = Some("cheese".to_string()); - let mut request = RoomListFilterBuilder::default(); - request.filter(Filter { - generic_search_term, - }); + let generic_search_term = Some("cheese"); + let filter = Some(assign!(Filter::new(), { generic_search_term })); + let request = assign!(PublicRoomsFilterRequest::new(), { filter }); let get_public_rooms_filtered::Response { chunk, .. } = client.public_rooms_filtered(request).await.unwrap(); @@ -2002,7 +1985,6 @@ mod test { } #[tokio::test] - #[allow(irrefutable_let_patterns)] async fn typing_notice() { let client = logged_in_client().await; @@ -2018,22 +2000,14 @@ mod test { let room_id = room_id!("!testroom:example.org"); - let response = client + client .typing_notice( &room_id, &client.user_id().await.unwrap(), - true, - Some(std::time::Duration::from_secs(1)), + Typing::Yes(std::time::Duration::from_secs(1)), ) .await .unwrap(); - if let create_typing_event::Response = response { - } else { - panic!( - "expected `ruma_client_api::create_typing_event::Response` found {:?}", - response - ) - } } #[tokio::test] diff --git a/matrix_sdk/src/lib.rs b/matrix_sdk/src/lib.rs index 622c7cc5..6877a99c 100644 --- a/matrix_sdk/src/lib.rs +++ b/matrix_sdk/src/lib.rs @@ -62,7 +62,6 @@ pub use reqwest::header::InvalidHeaderValue; mod client; mod error; mod http_client; -mod request_builder; #[cfg(feature = "encryption")] mod device; @@ -75,9 +74,6 @@ pub use client::{Client, ClientConfig, SyncSettings}; pub use device::Device; pub use error::{Error, Result}; pub use http_client::HttpSend; -pub use request_builder::{ - MessagesRequestBuilder, RegistrationBuilder, RoomBuilder, RoomListFilterBuilder, -}; #[cfg(feature = "encryption")] #[cfg_attr(feature = "docs", doc(cfg(encryption)))] pub use sas::Sas; diff --git a/matrix_sdk/src/request_builder.rs b/matrix_sdk/src/request_builder.rs deleted file mode 100644 index 7ec31036..00000000 --- a/matrix_sdk/src/request_builder.rs +++ /dev/null @@ -1,549 +0,0 @@ -use matrix_sdk_common::{ - api::r0::{ - account::register::{self, RegistrationKind}, - directory::get_public_rooms_filtered, - filter::RoomEventFilter, - membership::Invite3pid, - message::get_message_events::{self, Direction}, - room::{ - create_room::{self, CreationContent, InitialStateEvent, RoomPreset}, - Visibility, - }, - uiaa::AuthData, - }, - directory::{Filter, RoomNetwork}, - events::room::{create::PreviousRoom, power_levels::PowerLevelsEventContent}, - identifiers::{DeviceId, RoomId, UserId}, - js_int::UInt, -}; - -/// A builder used to create rooms. -/// -/// # Examples -/// ``` -/// # use std::convert::TryFrom; -/// # use matrix_sdk::{Client, RoomBuilder}; -/// # use matrix_sdk::api::r0::room::Visibility; -/// # use matrix_sdk::identifiers::UserId; -/// # use url::Url; -/// # let homeserver = Url::parse("http://example.com").unwrap(); -/// # let mut rt = tokio::runtime::Runtime::new().unwrap(); -/// # rt.block_on(async { -/// let mut builder = RoomBuilder::new(); -/// builder.federate(false) -/// .initial_state(vec![]) -/// .visibility(Visibility::Public) -/// .name("name") -/// .room_version("v1.0"); -/// let mut client = Client::new(homeserver).unwrap(); -/// client.create_room(builder).await; -/// # }) -/// ``` -#[derive(Clone, Debug)] -pub struct RoomBuilder { - req: create_room::Request, - creation_content: CreationContent, -} - -impl RoomBuilder { - /// Returns an empty `RoomBuilder` for creating rooms. - pub fn new() -> Self { - Self { - req: create_room::Request::new(), - creation_content: CreationContent { - federate: true, - predecessor: None, - }, - } - } - - /// A reference to the room this room replaces, if the previous room was upgraded. - /// - /// Note: this is used to create the `CreationContent`. - pub fn previous_room(&mut self, previous_room: PreviousRoom) -> &mut Self { - self.creation_content.predecessor = Some(previous_room); - self - } - - /// Whether users on other servers can join this room. - /// - /// Defaults to `true` if key does not exist. - /// Note: this is used to create the `CreationContent`. - pub fn federate(&mut self, federate: bool) -> &mut Self { - self.creation_content.federate = federate; - self - } - - /// Sets a 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. - pub fn initial_state(&mut self, state: Vec) -> &mut Self { - self.req.initial_state = state; - self - } - - /// Sets 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. - pub fn invite(&mut self, invite: Vec) -> &mut Self { - self.req.invite = invite; - self - } - - /// Sets a list of third party IDs of users to invite. - pub fn invite_3pid(&mut self, invite: Vec) -> &mut Self { - self.req.invite_3pid = invite; - self - } - - /// If set, this sets the `is_direct` flag on room invites. - pub fn is_direct(&mut self, direct: bool) -> &mut Self { - self.req.is_direct = Some(direct); - self - } - - /// If this is included, an `m.room.name` event will be sent into the room to indicate - /// the name of the room. - pub fn name>(&mut self, name: S) -> &mut Self { - self.req.name = Some(name.into()); - self - } - - /// Power level content to override in the default power level event. - pub fn power_level_override(&mut self, power: PowerLevelsEventContent) -> &mut Self { - self.req.power_level_content_override = Some(power.into()); - self - } - - /// Convenience parameter for setting various default state events based on a preset. - pub fn preset(&mut self, preset: RoomPreset) -> &mut Self { - self.req.preset = Some(preset); - self - } - - /// The desired room alias local part. - pub fn room_alias_name>(&mut self, alias: S) -> &mut Self { - self.req.room_alias_name = Some(alias.into()); - self - } - - /// Room version to set for the room. Defaults to homeserver's default if not specified. - pub fn room_version>(&mut self, version: S) -> &mut Self { - self.req.room_version = Some(version.into()); - self - } - - /// If this is included, an `m.room.topic` event will be sent into the room to indicate - /// the topic for the room. - pub fn topic>(&mut self, topic: S) -> &mut Self { - self.req.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.req.visibility = Some(vis); - self - } -} - -impl Default for RoomBuilder { - fn default() -> Self { - Self::new() - } -} - -impl Into for RoomBuilder { - fn into(mut self) -> create_room::Request { - self.req.creation_content = Some(self.creation_content); - self.req - } -} - -/// Create a builder for making get_message_event requests. -/// -/// # Examples -/// ``` -/// # use std::convert::TryFrom; -/// # use matrix_sdk::{Client, MessagesRequestBuilder}; -/// # use matrix_sdk::api::r0::message::get_message_events::{self, Direction}; -/// # use matrix_sdk::identifiers::room_id; -/// # use url::Url; -/// # let homeserver = Url::parse("http://example.com").unwrap(); -/// # let mut rt = tokio::runtime::Runtime::new().unwrap(); -/// # rt.block_on(async { -/// # let room_id = room_id!("!test:localhost"); -/// # let last_sync_token = "".to_string(); -/// let mut client = Client::new(homeserver).unwrap(); -/// -/// let room_id = room_id!("!roomid:example.com"); -/// let mut builder = MessagesRequestBuilder::new(&room_id, "t47429-4392820_219380_26003_2265"); -/// -/// builder.to("t4357353_219380_26003_2265") -/// .direction(Direction::Backward) -/// .limit(10); -/// -/// client.room_messages(builder).await.is_err(); -/// # }) -/// ``` -#[derive(Clone, Debug)] -pub struct MessagesRequestBuilder<'a>(get_message_events::Request<'a>); - -impl<'a> MessagesRequestBuilder<'a> { - /// Create a `MessagesRequestBuilder` builder to make a `get_message_events::Request`. - /// - /// # Arguments - /// - /// * `room_id` - The id of the room that is being requested. - /// - /// * `from` - The token to start returning events from. This token can be obtained from - /// a `prev_batch` token from a sync response, or a start or end token from a previous request - /// to this endpoint. - pub fn new(room_id: &'a RoomId, from: &'a str) -> Self { - Self(get_message_events::Request::new( - room_id, - from, - Direction::Backward, - )) - } - - /// A `next_batch` token or `start` or `end` from a previous `get_message_events` request. - /// - /// This token signals when to stop receiving events. - pub fn to(&mut self, to: &'a str) -> &mut Self { - self.0.to = Some(to); - self - } - - /// The direction to return events from. - /// - /// If not specified `Direction::Backward` is used. - pub fn direction(&mut self, direction: Direction) -> &mut Self { - self.0.dir = direction; - self - } - - /// The maximum number of events to return. - /// - /// The default is 10. - pub fn limit(&mut self, limit: u32) -> &mut Self { - self.0.limit = UInt::from(limit); - self - } - - /// Filter events by the given `RoomEventFilter`. - pub fn filter(&mut self, filter: RoomEventFilter) -> &mut Self { - self.0.filter = Some(filter); - self - } -} - -impl<'a> Into> for MessagesRequestBuilder<'a> { - fn into(self) -> get_message_events::Request<'a> { - self.0 - } -} - -/// A builder used to register users. -/// -/// # Examples -/// ``` -/// # use std::convert::TryFrom; -/// # use matrix_sdk::{Client, RegistrationBuilder}; -/// # use matrix_sdk::api::r0::account::register::RegistrationKind; -/// # use matrix_sdk::identifiers::DeviceId; -/// # use url::Url; -/// # let homeserver = Url::parse("http://example.com").unwrap(); -/// # let mut rt = tokio::runtime::Runtime::new().unwrap(); -/// # rt.block_on(async { -/// let mut builder = RegistrationBuilder::default(); -/// builder.password("pass") -/// .username("user") -/// .kind(RegistrationKind::User); -/// let mut client = Client::new(homeserver).unwrap(); -/// client.register_user(builder).await; -/// # }) -/// ``` -#[derive(Clone, Debug, Default)] -pub struct RegistrationBuilder<'a> { - password: Option<&'a str>, - username: Option<&'a str>, - device_id: Option<&'a DeviceId>, - initial_device_display_name: Option<&'a str>, - auth: Option>, - kind: Option, - inhibit_login: bool, -} - -impl<'a> RegistrationBuilder<'a> { - /// Create a `RegistrationBuilder` builder to make a `register::Request`. - pub fn new() -> Self { - Self::default() - } - - /// The desired password for the account. - /// - /// May be empty for accounts that should not be able to log in again - /// with a password, e.g., for guest or application service accounts. - pub fn password(&mut self, password: &'a str) -> &mut Self { - self.password = Some(password); - self - } - - /// local part of the desired Matrix ID. - /// - /// If omitted, the homeserver MUST generate a Matrix ID local part. - pub fn username(&mut self, username: &'a str) -> &mut Self { - self.username = Some(username); - self - } - - /// ID of the client device. - /// - /// If this does not correspond to a known client device, a new device will be created. - /// The server will auto-generate a device_id if this is not specified. - pub fn device_id(&mut self, device_id: &'a DeviceId) -> &mut Self { - self.device_id = Some(device_id); - self - } - - /// A display name to assign to the newly-created device. - /// - /// Ignored if `device_id` corresponds to a known device. - pub fn initial_device_display_name( - &mut self, - initial_device_display_name: &'a str, - ) -> &mut Self { - self.initial_device_display_name = Some(initial_device_display_name); - self - } - - /// Additional authentication information for the user-interactive authentication API. - /// - /// Note that this information is not used to define how the registered user should be - /// authenticated, but is instead used to authenticate the register call itself. - /// It should be left empty, or omitted, unless an earlier call returned an response - /// with status code 401. - pub fn auth(&mut self, auth: AuthData<'a>) -> &mut Self { - self.auth = Some(auth); - self - } - - /// Kind of account to register - /// - /// Defaults to `User` if omitted. - pub fn kind(&mut self, kind: RegistrationKind) -> &mut Self { - self.kind = Some(kind); - self - } - - /// If `true`, an `access_token` and `device_id` should not be returned - /// from this call, therefore preventing an automatic login. - pub fn inhibit_login(&mut self, inhibit_login: bool) -> &mut Self { - self.inhibit_login = inhibit_login; - self - } -} - -impl<'a> Into> for RegistrationBuilder<'a> { - fn into(self) -> register::Request<'a> { - register::Request { - password: self.password, - username: self.username, - device_id: self.device_id, - initial_device_display_name: self.initial_device_display_name, - auth: self.auth, - kind: self.kind, - inhibit_login: self.inhibit_login, - } - } -} - -/// Create a builder for making get_public_rooms_filtered requests. -/// -/// # Examples -/// ``` -/// # use std::convert::TryFrom; -/// # use matrix_sdk::{Client, RoomListFilterBuilder}; -/// # use matrix_sdk::directory::{Filter, RoomNetwork}; -/// # use matrix_sdk::api::r0::directory::get_public_rooms_filtered; -/// # use url::Url; -/// # let homeserver = Url::parse("http://example.com").unwrap(); -/// # let mut rt = tokio::runtime::Runtime::new().unwrap(); -/// # rt.block_on(async { -/// # let last_sync_token = "".to_string(); -/// let mut client = Client::new(homeserver).unwrap(); -/// -/// let generic_search_term = Some("matrix-rust-sdk".to_string()); -/// let mut builder = RoomListFilterBuilder::new(); -/// builder -/// .filter(Filter { generic_search_term }) -/// .since(&last_sync_token) -/// .room_network(RoomNetwork::Matrix); -/// -/// client.public_rooms_filtered(builder).await.is_err(); -/// # }) -/// ``` -#[derive(Clone, Debug, Default)] -pub struct RoomListFilterBuilder<'a> { - server: Option<&'a str>, - limit: Option, - since: Option<&'a str>, - filter: Option, - room_network: Option, -} - -impl<'a> RoomListFilterBuilder<'a> { - /// Create a `RoomListFilterBuilder` builder to make a `get_message_events::Request`. - pub fn new() -> Self { - Self::default() - } - - /// The server to fetch the public room lists from. - /// - /// `None` means the server this request is sent to. - pub fn server(&mut self, server: &'a str) -> &mut Self { - self.server = Some(server); - self - } - - /// Limit for the number of results to return. - pub fn limit(&mut self, limit: u32) -> &mut Self { - self.limit = Some(limit); - self - } - - /// Pagination token from a previous request. - pub fn since(&mut self, since: &'a str) -> &mut Self { - self.since = Some(since); - self - } - - /// Filter to apply to the results. - pub fn filter(&mut self, filter: Filter) -> &mut Self { - self.filter = Some(filter); - self - } - - /// Network to fetch the public room lists from. - /// - /// Defaults to the Matrix network. - pub fn room_network(&mut self, room_network: RoomNetwork) -> &mut Self { - self.room_network = Some(room_network); - self - } -} - -impl<'a> Into> for RoomListFilterBuilder<'a> { - fn into(self) -> get_public_rooms_filtered::Request<'a> { - get_public_rooms_filtered::Request { - room_network: self.room_network.unwrap_or_default(), - limit: self.limit.map(UInt::from), - server: self.server, - since: self.since, - filter: self.filter, - } - } -} - -#[cfg(test)] -mod test { - use std::collections::BTreeMap; - - use super::*; - use crate::{ - api::r0::filter::{LazyLoadOptions, RoomEventFilter}, - events::room::power_levels::NotificationPowerLevels, - identifiers::{room_id, user_id}, - js_int::Int, - Client, Session, - }; - - use matrix_sdk_test::test_json; - use mockito::{mock, Matcher}; - use url::Url; - - #[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(test_json::ROOM_ID.to_string()) - .create(); - - let session = Session { - access_token: "1234".to_owned(), - user_id: user_id!("@example:localhost"), - device_id: "DEVICEID".into(), - }; - - let mut builder = RoomBuilder::new(); - builder - .federate(false) - .initial_state(vec![]) - .visibility(Visibility::Public) - .name("room_name") - .room_version("v1.0") - .invite_3pid(vec![]) - .is_direct(true) - .power_level_override(PowerLevelsEventContent { - ban: Int::MAX, - events: BTreeMap::default(), - events_default: Int::MIN, - invite: Int::MIN, - kick: Int::MIN, - redact: Int::MAX, - state_default: Int::MIN, - users_default: Int::MIN, - notifications: NotificationPowerLevels { room: Int::MIN }, - users: BTreeMap::default(), - }) - .preset(RoomPreset::PrivateChat) - .room_alias_name("room_alias") - .topic("room topic") - .visibility(Visibility::Private); - let cli = Client::new(homeserver).unwrap(); - cli.restore_login(session).await.unwrap(); - assert!(cli.create_room(builder).await.is_ok()); - } - - #[tokio::test] - async fn get_message_events() { - let homeserver = Url::parse(&mockito::server_url()).unwrap(); - - let _m = mock( - "GET", - Matcher::Regex(r"^/_matrix/client/r0/rooms/.*/messages".to_string()), - ) - .with_status(200) - .with_body(test_json::ROOM_MESSAGES.to_string()) - .create(); - - let session = Session { - access_token: "1234".to_owned(), - user_id: user_id!("@example:localhost"), - device_id: "DEVICEID".into(), - }; - - let room_id = room_id!("!roomid:example.com"); - let mut builder = MessagesRequestBuilder::new(&room_id, "t47429-4392820_219380_26003_2265"); - builder - .to("t4357353_219380_26003_2265") - .direction(Direction::Backward) - .limit(10) - .filter(RoomEventFilter { - lazy_load_options: LazyLoadOptions::Enabled { - include_redundant_members: false, - }, - ..Default::default() - }); - - let cli = Client::new(homeserver).unwrap(); - cli.restore_login(session).await.unwrap(); - assert!(cli.room_messages(builder).await.is_ok()); - } -} diff --git a/matrix_sdk_base/src/models/room.rs b/matrix_sdk_base/src/models/room.rs index 0149a3a3..e109bd9d 100644 --- a/matrix_sdk_base/src/models/room.rs +++ b/matrix_sdk_base/src/models/room.rs @@ -601,6 +601,7 @@ impl Room { heroes, joined_member_count, invited_member_count, + .. } = summary; self.room_name.heroes = heroes.clone(); self.room_name.invited_member_count = *invited_member_count; diff --git a/matrix_sdk_common/Cargo.toml b/matrix_sdk_common/Cargo.toml index 29060896..f22776ad 100644 --- a/matrix_sdk_common/Cargo.toml +++ b/matrix_sdk_common/Cargo.toml @@ -18,7 +18,7 @@ js_int = "0.1.9" [dependencies.ruma] version = "0.0.1" git = "https://github.com/ruma/ruma" -rev = "e74158b2626186ce23d4d3c07782e60b3be39434" +rev = "e4cd59e7e5f8ce4c8b90948155c3d031e45f9c54" features = ["client-api", "unstable-pre-spec"] [target.'cfg(not(target_arch = "wasm32"))'.dependencies] diff --git a/matrix_sdk_crypto/src/device.rs b/matrix_sdk_crypto/src/device.rs index 47589595..bfbaface 100644 --- a/matrix_sdk_crypto/src/device.rs +++ b/matrix_sdk_crypto/src/device.rs @@ -348,13 +348,7 @@ impl ReadOnlyDevice { pub(crate) fn update_device(&mut self, device_keys: &DeviceKeys) -> Result<(), SignatureError> { self.verify_device_keys(device_keys)?; - let display_name = Arc::new( - device_keys - .unsigned - .as_ref() - .map(|d| d.device_display_name.clone()) - .flatten(), - ); + let display_name = Arc::new(device_keys.unsigned.device_display_name.clone()); self.algorithms = Arc::new(device_keys.algorithms.clone()); self.keys = Arc::new(device_keys.keys.clone()); @@ -428,13 +422,7 @@ impl TryFrom<&DeviceKeys> for ReadOnlyDevice { algorithms: Arc::new(device_keys.algorithms.clone()), signatures: Arc::new(device_keys.signatures.clone()), keys: Arc::new(device_keys.keys.clone()), - display_name: Arc::new( - device_keys - .unsigned - .as_ref() - .map(|d| d.device_display_name.clone()) - .flatten(), - ), + display_name: Arc::new(device_keys.unsigned.device_display_name.clone()), deleted: Arc::new(AtomicBool::new(false)), trust_state: Arc::new(Atomic::new(LocalTrust::Unset)), }; @@ -525,15 +513,13 @@ pub(crate) mod test { device.display_name().as_ref().unwrap() ); + let display_name = "Alice's work computer".to_owned(); + let mut device_keys = device_keys(); - device_keys.unsigned.as_mut().unwrap().device_display_name = - Some("Alice's work computer".to_owned()); + device_keys.unsigned.device_display_name = Some(display_name.clone()); device.update_device(&device_keys).unwrap(); - assert_eq!( - "Alice's work computer", - device.display_name().as_ref().unwrap() - ); + assert_eq!(&display_name, device.display_name().as_ref().unwrap()); } #[test] diff --git a/matrix_sdk_crypto/src/olm/account.rs b/matrix_sdk_crypto/src/olm/account.rs index 86cd7d54..595a8ad0 100644 --- a/matrix_sdk_crypto/src/olm/account.rs +++ b/matrix_sdk_crypto/src/olm/account.rs @@ -309,17 +309,16 @@ impl Account { ); signatures.insert((*self.user_id).clone(), signature); - DeviceKeys { - user_id: (*self.user_id).clone(), - device_id: (*self.device_id).clone(), - algorithms: vec![ + DeviceKeys::new( + (*self.user_id).clone(), + (*self.device_id).clone(), + vec![ EventEncryptionAlgorithm::OlmV1Curve25519AesSha2, EventEncryptionAlgorithm::MegolmV1AesSha2, ], keys, signatures, - unsigned: None, - } + ) } /// Convert a JSON value to the canonical representation and sign the JSON