diff --git a/CONVENTIONAL_COMMITS.md b/CONVENTIONAL_COMMITS.md new file mode 100644 index 000000000..c6a83fb1c --- /dev/null +++ b/CONVENTIONAL_COMMITS.md @@ -0,0 +1,120 @@ +# Conventional Commits + +This project uses [Conventional +Commits](https://www.conventionalcommits.org/). Read the +[Summary](https://www.conventionalcommits.org/en/v1.0.0/#summary) or +the [Full +Specification](https://www.conventionalcommits.org/en/v1.0.0/#specification) +to learn more. + +## Types + +Conventional Commits defines _type_ (as in `type(scope): +message`). This section aims at listing the types used inside this +project: + +| Type | Definition | +|-|-| +| `feat` | About a new feature. | +| `fix` | About a bug fix. | +| `test` | About a test (suite, case, runner…). | +| `doc` | About a documentation modification. | +| `refactor` | About a refactoring. | +| `ci` | About a Continuous Integration modification. | +| `chore` | About some cleanup, or regular tasks. | + +## Scopes + +Conventional Commits defines _scope_ (as in `type(scope): message`). This +section aims at listing all the scopes used inside this project: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
GroupScopeDefinition
CratessdkAbout the matrix-sdk crate.
appserviceAbout the matrix-sdk-appservice crate.
baseAbout the matrix-sdk-base crate.
commonAbout the matrix-sdk-common crate.
cryptoAbout the matrix-sdk-crypto crate.
indexeddbAbout the matrix-sdk-indexeddb crate.
qrcodeAbout the matrix-sdk-qrcode crate.
sledAbout the matrix-sdk-sled crate.
store-encryptionAbout the matrix-sdk-store-encryption crate.
testAbout the matrix-sdk-test and matrix-sdk-test-macros crate.
BindingsappleAbout the matrix-rust-components-swift binding.
crypto-nodejsAbout the matrix-sdk-crypto-nodejs binding.
crypto-jsAbout the matrix-sdk-crypto-js binding.
crypto-ffiAbout the matrix-sdk-crypto-ffi binding.
Labssled-state-inspectorAbout the sled-state-inspector project.
Continuous IntegrationxtaskAbout the xtask project.
+ +## Generating `CHANGELOG.md` + +The [`git-cliff`](https://github.com/orhun/git-cliff) project is used +to generate `CHANGELOG.md` automatically. Hence the various +`cliff.toml` files that are present in this project, or the +`package.metadata.git-cliff` sections in various `Cargo.toml` files. + +Its companion, +[`git-cliff-action`](https://github.com/orhun/git-cliff-action) +project, is used inside Github Action workflows. diff --git a/benchmarks/benches/crypto_bench.rs b/benchmarks/benches/crypto_bench.rs index 8b0c929d2..66fd7081d 100644 --- a/benchmarks/benches/crypto_bench.rs +++ b/benchmarks/benches/crypto_bench.rs @@ -63,7 +63,7 @@ pub fn keys_query(c: &mut Criterion) { let mut group = c.benchmark_group("Keys querying"); group.throughput(Throughput::Elements(count as u64)); - let name = format!("{} device and cross signing keys", count); + let name = format!("{count} device and cross signing keys"); group.bench_with_input(BenchmarkId::new("memory store", &name), &response, |b, response| { b.to_async(&runtime) @@ -96,7 +96,7 @@ pub fn keys_claiming(c: &mut Criterion) { let mut group = c.benchmark_group("Olm session creation"); group.throughput(Throughput::Elements(count as u64)); - let name = format!("{} one-time keys", count); + let name = format!("{count} one-time keys"); group.bench_with_input(BenchmarkId::new("memory store", &name), &response, |b, response| { b.iter_batched( @@ -158,7 +158,7 @@ pub fn room_key_sharing(c: &mut Criterion) { let mut group = c.benchmark_group("Room key sharing"); group.throughput(Throughput::Elements(count as u64)); - let name = format!("{} devices", count); + let name = format!("{count} devices"); group.bench_function(BenchmarkId::new("memory store", &name), |b| { b.to_async(&runtime).iter(|| async { @@ -225,7 +225,7 @@ pub fn devices_missing_sessions_collecting(c: &mut Criterion) { let mut group = c.benchmark_group("Devices missing sessions collecting"); group.throughput(Throughput::Elements(count as u64)); - let name = format!("{} devices", count); + let name = format!("{count} devices"); runtime.block_on(machine.mark_request_as_sent(&txn_id, &response)).unwrap(); diff --git a/bindings/matrix-sdk-crypto-ffi/Cargo.toml b/bindings/matrix-sdk-crypto-ffi/Cargo.toml index 3b200e82a..53cd6d866 100644 --- a/bindings/matrix-sdk-crypto-ffi/Cargo.toml +++ b/bindings/matrix-sdk-crypto-ffi/Cargo.toml @@ -2,7 +2,7 @@ name = "matrix-sdk-crypto-ffi" version = "0.1.0" authors = ["Damir Jelić "] -edition = "2018" +edition = "2021" rust-version = "1.60" description = "Uniffi based bindings for the Rust SDK crypto crate" repository = "https://github.com/matrix-org/matrix-rust-sdk" diff --git a/bindings/matrix-sdk-crypto-ffi/src/lib.rs b/bindings/matrix-sdk-crypto-ffi/src/lib.rs index ce1f22d1e..e2ee5860f 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/lib.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/lib.rs @@ -14,7 +14,7 @@ mod responses; mod users; mod verification; -use std::{borrow::Borrow, collections::HashMap, convert::TryFrom, str::FromStr, sync::Arc}; +use std::{borrow::Borrow, collections::HashMap, str::FromStr, sync::Arc}; pub use backup_recovery_key::{ BackupRecoveryKey, DecodeError, MegolmV1BackupKey, PassphraseInfo, PkDecryptionError, diff --git a/bindings/matrix-sdk-crypto-ffi/src/machine.rs b/bindings/matrix-sdk-crypto-ffi/src/machine.rs index 79c595450..1da6d0938 100644 --- a/bindings/matrix-sdk-crypto-ffi/src/machine.rs +++ b/bindings/matrix-sdk-crypto-ffi/src/machine.rs @@ -1,6 +1,5 @@ use std::{ collections::{BTreeMap, HashMap}, - convert::TryInto, io::Cursor, ops::Deref, sync::Arc, diff --git a/bindings/matrix-sdk-crypto-js/src/lib.rs b/bindings/matrix-sdk-crypto-js/src/lib.rs index b927fedca..4b22a69d9 100644 --- a/bindings/matrix-sdk-crypto-js/src/lib.rs +++ b/bindings/matrix-sdk-crypto-js/src/lib.rs @@ -62,8 +62,7 @@ where Ok(unsafe { T::ref_from_abi(pointer) }) } else { Err(JsError::new(&format!( - "Expect an `{}` instance, received `{}` instead", - classname, constructor_name, + "Expect an `{classname}` instance, received `{constructor_name}` instead", ))) } } diff --git a/bindings/matrix-sdk-crypto-js/src/tracing.rs b/bindings/matrix-sdk-crypto-js/src/tracing.rs index 75a7801aa..3d5ca7f9f 100644 --- a/bindings/matrix-sdk-crypto-js/src/tracing.rs +++ b/bindings/matrix-sdk-crypto-js/src/tracing.rs @@ -207,7 +207,7 @@ mod inner { let origin = metadata .file() - .and_then(|file| metadata.line().map(|ln| format!("{}:{}", file, ln))) + .and_then(|file| metadata.line().map(|ln| format!("{file}:{ln}"))) .unwrap_or_default(); let message = format!("{level} {origin}{recorder}"); @@ -240,11 +240,11 @@ mod inner { self.string.push('\n'); } - let _ = write!(self.string, "{:?}", value); + let _ = write!(self.string, "{value:?}"); } field_name => { - let _ = write!(self.string, "\n{} = {:?}", field_name, value); + let _ = write!(self.string, "\n{field_name} = {value:?}"); } } } diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index 76d2ada9f..3622b76fe 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -159,6 +159,7 @@ interface MediaSource { [Error] enum AuthenticationError { "ClientMissing", + "SessionMissing", "Generic", }; @@ -178,6 +179,9 @@ interface AuthenticationService { [Throws=AuthenticationError] Client login(string username, string password); + + [Throws=AuthenticationError] + Client restore_with_access_token(string token, string device_id); }; interface SessionVerificationEmoji { diff --git a/bindings/matrix-sdk-ffi/src/authentication_service.rs b/bindings/matrix-sdk-ffi/src/authentication_service.rs index 0c3df8f12..426fa6476 100644 --- a/bindings/matrix-sdk-ffi/src/authentication_service.rs +++ b/bindings/matrix-sdk-ffi/src/authentication_service.rs @@ -1,6 +1,10 @@ use std::sync::Arc; use futures_util::future::join3; +use matrix_sdk::{ + ruma::{OwnedDeviceId, UserId}, + Session, +}; use parking_lot::RwLock; use super::{client::Client, client_builder::ClientBuilder, RUNTIME}; @@ -15,6 +19,8 @@ pub struct AuthenticationService { pub enum AuthenticationError { #[error("A successful call to use_server must be made first.")] ClientMissing, + #[error("Login was successful but is missing a valid Session to configure the file store.")] + SessionMissing, #[error("An error occurred: {message}")] Generic { message: String }, } @@ -66,14 +72,12 @@ impl AuthenticationService { /// Updates the service to authenticate with the homeserver for the /// specified address. pub fn configure_homeserver(&self, server_name: String) -> Result<(), AuthenticationError> { - // Construct a username as the builder currently requires one. - let username = format!("@auth:{}", server_name); - - let mut builder = - Arc::new(ClientBuilder::new()).base_path(self.base_path.clone()).username(username); + let mut builder = Arc::new(ClientBuilder::new()).base_path(self.base_path.clone()); if server_name.starts_with("http://") || server_name.starts_with("https://") { builder = builder.homeserver_url(server_name) + } else { + builder = builder.server_name(server_name); } let client = builder.build().map_err(AuthenticationError::from)?; @@ -96,18 +100,74 @@ impl AuthenticationService { ) -> Result, AuthenticationError> { match self.client.read().as_ref() { Some(client) => { - let homeserver_url = client.homeserver(); + // Login and ask the server for the full user ID as this could be different from + // the username that was entered. + client.login(username, password).map_err(AuthenticationError::from)?; + let whoami = client.whoami()?; - // Create a new client to setup the store path for the username + // Create a new client to setup the store path now the user ID is known. + let homeserver_url = client.homeserver(); + let session = client.session().ok_or(AuthenticationError::SessionMissing)?; let client = Arc::new(ClientBuilder::new()) .base_path(self.base_path.clone()) .homeserver_url(homeserver_url) - .username(username.clone()) + .username(whoami.user_id.to_string()) .build() .map_err(AuthenticationError::from)?; + // Restore the client using the session from the login request. client - .login(username, password) + .restore_session(session.clone()) + .map(|_| client.clone()) + .map_err(AuthenticationError::from) + } + None => Err(AuthenticationError::ClientMissing), + } + } + + /// Restore an existing session on the current homeserver using an access + /// token issued by an authentication server. + /// # Arguments + /// + /// * `token` - The access token issued by the authentication server. + /// + /// * `device_id` - The device ID that the access token was scoped for. + pub fn restore_with_access_token( + &self, + token: String, + device_id: String, + ) -> Result, AuthenticationError> { + match self.client.read().as_ref() { + Some(client) => { + // Restore the client and ask the server for the full user ID as this + // could be different from the username that was entered. + let discovery_user_id = UserId::parse("@unknown:unknown") + .map_err(|e| AuthenticationError::Generic { message: e.to_string() })?; + let device_id: OwnedDeviceId = device_id.as_str().into(); + + let discovery_session = Session { + access_token: token.clone(), + user_id: discovery_user_id, + device_id: device_id.clone(), + }; + + client.restore_session(discovery_session).map_err(AuthenticationError::from)?; + let whoami = client.whoami()?; + + // Create the actual client with a store path from the user ID. + let homeserver_url = client.homeserver(); + let session = + Session { access_token: token, user_id: whoami.user_id.clone(), device_id }; + let client = Arc::new(ClientBuilder::new()) + .base_path(self.base_path.clone()) + .homeserver_url(homeserver_url) + .username(whoami.user_id.to_string()) + .build() + .map_err(AuthenticationError::from)?; + + // Restore the client using the session. + client + .restore_session(session) .map(|_| client.clone()) .map_err(AuthenticationError::from) } diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 35538cb84..d6ae64819 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -1,10 +1,12 @@ use std::sync::Arc; +use anyhow::anyhow; use matrix_sdk::{ config::SyncSettings, media::{MediaFormat, MediaRequest}, ruma::{ api::client::{ + account::whoami, filter::{FilterDefinition, LazyLoadOptions, RoomEventFilter, RoomFilter}, session::get_login_types, sync::sync_events::v3::Filter, @@ -12,7 +14,7 @@ use matrix_sdk::{ events::room::MediaSource, TransactionId, }, - Client as MatrixClient, LoopCtrl, + Client as MatrixClient, LoopCtrl, Session, }; use parking_lot::RwLock; @@ -51,6 +53,7 @@ impl Client { } } + /// Login using a username and password. pub fn login(&self, username: String, password: String) -> anyhow::Result<()> { RUNTIME.block_on(async move { self.client.login_username(&username, &password).send().await?; @@ -58,10 +61,16 @@ impl Client { }) } + /// Restores the client from a `RestoreToken`. pub fn restore_login(&self, restore_token: String) -> anyhow::Result<()> { let RestoreToken { session, homeurl: _, is_guest: _ } = serde_json::from_str(&restore_token)?; + self.restore_session(session) + } + + /// Restores the client from a `Session`. + pub fn restore_session(&self, session: Session) -> anyhow::Result<()> { RUNTIME.block_on(async move { self.client.restore_login(session).await?; Ok(()) @@ -97,6 +106,12 @@ impl Client { Ok(supports_password) } + /// Gets information about the owner of a given access token. + pub fn whoami(&self) -> anyhow::Result { + RUNTIME + .block_on(async move { self.client.whoami().await.map_err(|e| anyhow!(e.to_string())) }) + } + pub fn start_sync(&self) { let client = self.client.clone(); let state = self.state.clone(); diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 786fbdf18..0b677d5d1 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -1,9 +1,10 @@ use std::{fs, path::PathBuf, sync::Arc}; -use anyhow::Context; +use anyhow::anyhow; use matrix_sdk::{ - ruma::UserId, store::make_store_config, Client as MatrixClient, - ClientBuilder as MatrixClientBuilder, + ruma::{ServerName, UserId}, + store::make_store_config, + Client as MatrixClient, ClientBuilder as MatrixClientBuilder, }; use sanitize_filename_reader_friendly::sanitize; @@ -13,6 +14,7 @@ use super::{client::Client, ClientState, RUNTIME}; pub struct ClientBuilder { base_path: Option, username: Option, + server_name: Option, homeserver_url: Option, inner: MatrixClientBuilder, } @@ -22,6 +24,7 @@ impl ClientBuilder { Self { base_path: None, username: None, + server_name: None, homeserver_url: None, inner: MatrixClient::builder().user_agent("rust-sdk-ios"), } @@ -39,6 +42,12 @@ impl ClientBuilder { Arc::new(builder) } + pub fn server_name(self: Arc, server_name: String) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.server_name = Some(server_name); + Arc::new(builder) + } + pub fn homeserver_url(self: Arc, url: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.homeserver_url = Some(url); @@ -47,25 +56,30 @@ impl ClientBuilder { pub fn build(self: Arc) -> anyhow::Result> { let builder = unwrap_or_clone_arc(self); + let mut inner_builder = builder.inner; - let base_path = builder.base_path.context("Base path was not set")?; - let username = builder - .username - .context("Username to determine homeserver and home path was not set")?; + if let (Some(base_path), Some(username)) = (builder.base_path, &builder.username) { + // Determine store path + let data_path = PathBuf::from(base_path).join(sanitize(username)); + fs::create_dir_all(&data_path)?; + let store_config = make_store_config(&data_path, None)?; - // Determine store path - let data_path = PathBuf::from(base_path).join(sanitize(&username)); - fs::create_dir_all(&data_path)?; - let store_config = make_store_config(&data_path, None)?; + inner_builder = inner_builder.store_config(store_config); + } - let mut inner_builder = builder.inner.store_config(store_config); - - // Determine server either from explicitly set homeserver or from userId + // Determine server either from URL, server name or user ID. if let Some(homeserver_url) = builder.homeserver_url { inner_builder = inner_builder.homeserver_url(homeserver_url); - } else { + } else if let Some(server_name) = builder.server_name { + let server_name = ServerName::parse(server_name)?; + inner_builder = inner_builder.server_name(&server_name); + } else if let Some(username) = builder.username { let user = UserId::parse(username)?; inner_builder = inner_builder.server_name(user.server_name()); + } else { + return Err(anyhow!( + "Failed to build: One of homeserver_url, server_name or username must be called." + )); } RUNTIME.block_on(async move { diff --git a/crates/matrix-sdk-appservice/Cargo.toml b/crates/matrix-sdk-appservice/Cargo.toml index 258591231..d4fd58ef7 100644 --- a/crates/matrix-sdk-appservice/Cargo.toml +++ b/crates/matrix-sdk-appservice/Cargo.toml @@ -1,6 +1,6 @@ [package] authors = ["Johannes Becker "] -edition = "2018" +edition = "2021" homepage = "https://github.com/matrix-org/matrix-rust-sdk" repository = "https://github.com/matrix-org/matrix-rust-sdk" description = "Appservice SDK based on the matrix-sdk" diff --git a/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs b/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs index 8835449e4..171e6e44f 100644 --- a/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs +++ b/crates/matrix-sdk-appservice/examples/appservice_autojoin.rs @@ -60,10 +60,11 @@ pub async fn main() -> Result<(), Box> { let appservice = AppService::new(homeserver_url, server_name, registration).await?; appservice.register_user_query(Box::new(|_, _| Box::pin(async { true }))).await; - appservice - .virtual_user(None) - .await? - .register_event_handler_context(appservice.clone()) + + let virtual_user = appservice.virtual_user(None).await?; + + virtual_user.register_event_handler_context(appservice.clone()); + virtual_user .register_event_handler( move |event: OriginalSyncRoomMemberEvent, room: Room, diff --git a/crates/matrix-sdk-appservice/src/lib.rs b/crates/matrix-sdk-appservice/src/lib.rs index 7fb2519c8..2dbd404d5 100644 --- a/crates/matrix-sdk-appservice/src/lib.rs +++ b/crates/matrix-sdk-appservice/src/lib.rs @@ -84,7 +84,7 @@ //! [matrix-org/matrix-rust-sdk#228]: https://github.com/matrix-org/matrix-rust-sdk/issues/228 //! [examples directory]: https://github.com/matrix-org/matrix-rust-sdk/tree/main/crates/matrix-sdk-appservice/examples -use std::{convert::TryInto, sync::Arc}; +use std::sync::Arc; use dashmap::DashMap; pub use error::Error; @@ -122,7 +122,7 @@ pub use virtual_user::VirtualUserBuilder; pub type Result = std::result::Result; const USER_KEY: &[u8] = b"appservice.users."; -pub const USER_MEMBER: &[u8] = b"appservice.users.membership."; +const USER_MEMBER: &[u8] = b"appservice.users.membership."; type Localpart = String; @@ -492,7 +492,7 @@ impl AppService { } for task in tasks { if let Err(e) = task.await { - warn!("Joining sync task failed: {}", e); + warn!("Joining sync task failed: {e}"); } } Ok(()) @@ -505,7 +505,7 @@ impl AppService { pub async fn run(&self, host: impl Into, port: impl Into) -> Result<()> { let host = host.into(); let port = port.into(); - info!("Starting AppService on {}:{}", &host, &port); + info!("Starting AppService on {host}:{port}"); webserver::run_server(self.clone(), host, port).await?; Ok(()) diff --git a/crates/matrix-sdk-appservice/src/registration.rs b/crates/matrix-sdk-appservice/src/registration.rs index 2c581d28f..4da736588 100644 --- a/crates/matrix-sdk-appservice/src/registration.rs +++ b/crates/matrix-sdk-appservice/src/registration.rs @@ -14,7 +14,7 @@ //! AppService Registration. -use std::{convert::TryFrom, fs::File, ops::Deref, path::PathBuf}; +use std::{fs::File, ops::Deref, path::PathBuf}; use http::Uri; use regex::Regex; diff --git a/crates/matrix-sdk-appservice/src/webserver.rs b/crates/matrix-sdk-appservice/src/webserver.rs index 9e29a08a9..49fa38894 100644 --- a/crates/matrix-sdk-appservice/src/webserver.rs +++ b/crates/matrix-sdk-appservice/src/webserver.rs @@ -145,7 +145,7 @@ mod filters { .and(warp::body::bytes()) .and_then(|method, path: FullPath, query, headers, bytes| async move { let uri = http::uri::Builder::new() - .path_and_query(format!("{}?{}", path.as_str(), query)) + .path_and_query(format!("{}?{query}", path.as_str())) .build() .map_err(Error::from)?; @@ -164,9 +164,13 @@ mod filters { mod handlers { use percent_encoding::percent_decode_str; + use serde::Serialize; use super::*; + #[derive(Serialize)] + struct EmptyObject {} + pub async fn user( user_id: String, appservice: AppService, @@ -177,12 +181,12 @@ mod handlers { let request = query_user::IncomingRequest::try_from_http_request(request, &[user_id]) .map_err(Error::from)?; return if user_exists(appservice.clone(), request).await { - Ok(warp::reply::json(&String::from("{}"))) + Ok(warp::reply::json(&EmptyObject {})) } else { Err(warp::reject::not_found()) }; } - Ok(warp::reply::json(&String::from("{}"))) + Ok(warp::reply::json(&EmptyObject {})) } pub async fn room( @@ -195,12 +199,12 @@ mod handlers { let request = query_room::IncomingRequest::try_from_http_request(request, &[room_id]) .map_err(Error::from)?; return if room_exists(appservice.clone(), request).await { - Ok(warp::reply::json(&String::from("{}"))) + Ok(warp::reply::json(&EmptyObject {})) } else { Err(warp::reject::not_found()) }; } - Ok(warp::reply::json(&String::from("{}"))) + Ok(warp::reply::json(&EmptyObject {})) } pub async fn transaction( @@ -213,7 +217,7 @@ mod handlers { .map_err(Error::from)?; appservice.receive_transaction(incoming_transaction).await?; - Ok(warp::reply::json(&String::from("{}"))) + Ok(warp::reply::json(&EmptyObject {})) } } diff --git a/crates/matrix-sdk-base/src/client.rs b/crates/matrix-sdk-base/src/client.rs index 5d58c040a..ad4ee33e3 100644 --- a/crates/matrix-sdk-base/src/client.rs +++ b/crates/matrix-sdk-base/src/client.rs @@ -400,8 +400,8 @@ impl BaseClient { } Err(err) => { warn!( - "Couldn't deserialize stripped state event for room {}: {:?}", - room_info.room_id, err + "Couldn't deserialize stripped state event for room {}: {err:?}", + room_info.room_id, ); } } @@ -430,8 +430,8 @@ impl BaseClient { Ok(e) => e, Err(e) => { warn!( - "Couldn't deserialize state event for room {}: {:?} {:#?}", - room_id, e, raw_event + "Couldn't deserialize state event for room {room_id}: \ + {e:?} {raw_event:#?}", ); continue; } @@ -831,7 +831,7 @@ impl BaseClient { .filter_map(|event| match event.deserialize() { Ok(ev) => Some(ev), Err(e) => { - debug!(?event, "Failed to deserialize m.room.member event: {}", e); + debug!(?event, "Failed to deserialize m.room.member event: {e}"); None } }) diff --git a/crates/matrix-sdk-base/src/rooms/mod.rs b/crates/matrix-sdk-base/src/rooms/mod.rs index 049854a09..3d3e4d7c5 100644 --- a/crates/matrix-sdk-base/src/rooms/mod.rs +++ b/crates/matrix-sdk-base/src/rooms/mod.rs @@ -47,9 +47,9 @@ impl fmt::Display for DisplayName { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match self { DisplayName::Named(s) | DisplayName::Calculated(s) | DisplayName::Aliased(s) => { - write!(f, "{}", s) + write!(f, "{s}") } - DisplayName::EmptyWas(s) => write!(f, "Empty Room (was {})", s), + DisplayName::EmptyWas(s) => write!(f, "Empty Room (was {s})"), DisplayName::Empty => write!(f, "Empty Room"), } } diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index fe286f965..e830673b5 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -44,6 +44,7 @@ use ruma::{ RoomVersionId, UserId, }; use serde::{Deserialize, Serialize}; +use tracing::debug; use super::{BaseRoomInfo, DisplayName, RoomMember}; use crate::{ @@ -396,7 +397,7 @@ impl Room { _ => (summary.joined_member_count, summary.invited_member_count), }; - tracing::debug!( + debug!( room_id = self.room_id().as_str(), own_user = self.own_user_id.as_str(), joined, invited, @@ -589,6 +590,8 @@ impl Room { /// Add a new timeline slice to the timeline streams. #[cfg(feature = "experimental-timeline")] pub async fn add_timeline_slice(&self, timeline: &TimelineSlice) { + use tracing::warn; + if timeline.sync { let mut streams = self.forward_timeline_streams.lock().await; let mut remaining_streams = Vec::with_capacity(streams.len()); @@ -596,7 +599,7 @@ impl Room { if !forward.is_closed() { if let Err(error) = forward.try_send(timeline.clone()) { if error.is_full() { - tracing::warn!("Drop timeline slice because the limit of the buffer for the forward stream is reached"); + warn!("Drop timeline slice because the limit of the buffer for the forward stream is reached"); } } else { remaining_streams.push(forward); @@ -611,7 +614,7 @@ impl Room { if !backward.is_closed() { if let Err(error) = backward.try_send(timeline.clone()) { if error.is_full() { - tracing::warn!("Drop timeline slice because the limit of the buffer for the backward stream is reached"); + warn!("Drop timeline slice because the limit of the buffer for the backward stream is reached"); } } else { remaining_streams.push(backward); diff --git a/crates/matrix-sdk-base/src/store/ambiguity_map.rs b/crates/matrix-sdk-base/src/store/ambiguity_map.rs index 57e8b18b0..d4b876f58 100644 --- a/crates/matrix-sdk-base/src/store/ambiguity_map.rs +++ b/crates/matrix-sdk-base/src/store/ambiguity_map.rs @@ -123,7 +123,7 @@ impl AmbiguityCache { member_ambiguous: ambiguous, }; - trace!("Handling display name ambiguity for {}: {:#?}", member_event.state_key(), change); + trace!("Handling display name ambiguity for {}: {change:#?}", member_event.state_key()); self.add_change(room_id, member_event.event_id().to_owned(), change); diff --git a/crates/matrix-sdk-base/src/store/integration_tests.rs b/crates/matrix-sdk-base/src/store/integration_tests.rs index 0af39b2b8..1a423fc28 100644 --- a/crates/matrix-sdk-base/src/store/integration_tests.rs +++ b/crates/matrix-sdk-base/src/store/integration_tests.rs @@ -775,13 +775,14 @@ macro_rules! statestore_integration_tests { .zip(stored_events.iter()) .enumerate() { - assert_eq!(a.expect("not a value").event_id(), b.event_id(), "pos {} not equal - expected: {:#?}, but found {:#?}", idx, expected, found); - + assert_eq!( + a.expect("not a value").event_id(), + b.event_id(), + "pos {idx} not equal - expected: {expected:#?}, but found {found:#?}", + ); } } - } - )* } } diff --git a/crates/matrix-sdk-base/src/store/memory_store.rs b/crates/matrix-sdk-base/src/store/memory_store.rs index a0321fad8..03187a5c1 100644 --- a/crates/matrix-sdk-base/src/store/memory_store.rs +++ b/crates/matrix-sdk-base/src/store/memory_store.rs @@ -43,6 +43,7 @@ use ruma::{ serde::Raw, EventId, MxcUri, OwnedEventId, OwnedRoomId, OwnedUserId, RoomId, UserId, }; +use tracing::info; #[cfg(feature = "experimental-timeline")] use super::BoxStream; @@ -343,25 +344,24 @@ impl MemoryStore { #[cfg(feature = "experimental-timeline")] for (room, timeline) in &changes.timeline { + use tracing::warn; + if timeline.sync { - tracing::info!("Save new timeline batch from sync response for {}", room); + info!("Save new timeline batch from sync response for {room}"); } else { - tracing::info!("Save new timeline batch from messages response for {}", room); + info!("Save new timeline batch from messages response for {room}"); } let mut delete_timeline = false; if timeline.limited { - tracing::info!( - "Delete stored timeline for {} because the sync response was limited", - room - ); + info!("Delete stored timeline for {room} because the sync response was limited"); delete_timeline = true; } else if let Some(mut data) = self.room_timeline.get_mut(room) { if !timeline.sync && Some(&timeline.start) != data.end.as_ref() { // This should only happen when a developer adds a wrong timeline // batch to the `StateChanges` or the server returns a wrong response // to our request. - tracing::warn!("Drop unexpected timeline batch for {}", room); + warn!("Drop unexpected timeline batch for {room}"); return Ok(()); } @@ -385,7 +385,7 @@ impl MemoryStore { } if delete_timeline { - tracing::info!("Delete stored timeline for {} because of duplicated events", room); + info!("Delete stored timeline for {room} because of duplicated events"); self.room_timeline.remove(room); } @@ -401,10 +401,7 @@ impl MemoryStore { .get(room) .and_then(|info| info.room_version().cloned()) .unwrap_or_else(|| { - tracing::warn!( - "Unable to find the room version for {}, assume version 9", - room - ); + warn!("Unable to find the room version for {room}, assume version 9"); RoomVersionId::V9 }) }; @@ -455,7 +452,7 @@ impl MemoryStore { } } - tracing::info!("Saved changes in {:?}", now.elapsed()); + info!("Saved changes in {:?}", now.elapsed()); Ok(()) } @@ -676,7 +673,7 @@ impl MemoryStore { let (events, end_token) = if let Some(data) = self.room_timeline.get(room_id) { (data.events.clone(), data.end.clone()) } else { - tracing::info!("No timeline for {} was previously stored", room_id); + info!("No timeline for {room_id} was previously stored"); return Ok(None); }; @@ -686,11 +683,7 @@ impl MemoryStore { } }; - tracing::info!( - "Found previously stored timeline for {}, with end token {:?}", - room_id, - end_token - ); + info!("Found previously stored timeline for {room_id}, with end token {end_token:?}"); Ok(Some((Box::pin(stream), end_token))) } diff --git a/crates/matrix-sdk-crypto/README.md b/crates/matrix-sdk-crypto/README.md index 9891105ba..b8dc9ad80 100644 --- a/crates/matrix-sdk-crypto/README.md +++ b/crates/matrix-sdk-crypto/README.md @@ -17,7 +17,7 @@ The state machine works in a push/pull manner: state machine ```rust,no_run -use std::{collections::BTreeMap, convert::TryFrom}; +use std::collections::BTreeMap; use matrix_sdk_crypto::{OlmMachine, OlmError}; use ruma::{ diff --git a/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs b/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs index 42ef34259..4af89fe1b 100644 --- a/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs +++ b/crates/matrix-sdk-crypto/src/backups/keys/recovery.rs @@ -13,7 +13,6 @@ // limitations under the License. use std::{ - convert::TryFrom, io::{Cursor, Read}, ops::DerefMut, }; diff --git a/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs b/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs index f5adde9b0..0a4a7cb2c 100644 --- a/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs +++ b/crates/matrix-sdk-crypto/src/file_encryption/key_export.rs @@ -369,7 +369,7 @@ mod tests { )]), ); - assert_eq!(machine.import_keys(export, false, |_, _| {}).await?, keys,); + assert_eq!(machine.import_keys(export, false, |_, _| {}).await?, keys); let export = vec![session.export_at_index(10).await]; assert_eq!( @@ -379,7 +379,7 @@ mod tests { let better_export = vec![session.export().await]; - assert_eq!(machine.import_keys(better_export, false, |_, _| {}).await?, keys,); + assert_eq!(machine.import_keys(better_export, false, |_, _| {}).await?, keys); let another_session = machine.create_inbound_session(room_id).await?; let export = vec![another_session.export_at_index(10).await]; @@ -396,7 +396,7 @@ mod tests { )]), ); - assert_eq!(machine.import_keys(export, false, |_, _| {}).await?, keys,); + assert_eq!(machine.import_keys(export, false, |_, _| {}).await?, keys); Ok(()) } diff --git a/crates/matrix-sdk-crypto/src/identities/manager.rs b/crates/matrix-sdk-crypto/src/identities/manager.rs index dd566c3b7..11a35cb7d 100644 --- a/crates/matrix-sdk-crypto/src/identities/manager.rs +++ b/crates/matrix-sdk-crypto/src/identities/manager.rs @@ -14,7 +14,6 @@ use std::{ collections::{BTreeMap, BTreeSet, HashSet}, - convert::TryFrom, ops::Deref, sync::Arc, time::Duration, @@ -623,7 +622,7 @@ impl IdentityManager { } if let Err(e) = self.store.update_tracked_user(user, true).await { - warn!("Error storing users for tracking {}", e); + warn!("Error storing users for tracking: {e}"); } } } diff --git a/crates/matrix-sdk-crypto/src/machine.rs b/crates/matrix-sdk-crypto/src/machine.rs index ada12d5b8..8dab2334e 100644 --- a/crates/matrix-sdk-crypto/src/machine.rs +++ b/crates/matrix-sdk-crypto/src/machine.rs @@ -1211,7 +1211,6 @@ impl OlmMachine { /// # Example /// /// ``` - /// # use std::convert::TryFrom; /// # use matrix_sdk_crypto::OlmMachine; /// # use ruma::{device_id, user_id}; /// # use futures::executor::block_on; @@ -1269,7 +1268,6 @@ impl OlmMachine { /// # Example /// /// ``` - /// # use std::convert::TryFrom; /// # use matrix_sdk_crypto::OlmMachine; /// # use ruma::{device_id, user_id}; /// # use futures::executor::block_on; @@ -1554,7 +1552,7 @@ pub(crate) mod testing { #[cfg(test)] pub(crate) mod tests { - use std::{collections::BTreeMap, convert::TryInto, iter, sync::Arc}; + use std::{collections::BTreeMap, iter, sync::Arc}; use matrix_sdk_test::{async_test, test_json}; use ruma::{ diff --git a/crates/matrix-sdk-crypto/src/olm/account.rs b/crates/matrix-sdk-crypto/src/olm/account.rs index 2c12ef75b..cc6acc482 100644 --- a/crates/matrix-sdk-crypto/src/olm/account.rs +++ b/crates/matrix-sdk-crypto/src/olm/account.rs @@ -14,7 +14,6 @@ use std::{ collections::{BTreeMap, HashMap}, - convert::TryInto, fmt, ops::Deref, sync::{ @@ -577,9 +576,8 @@ impl ReadOnlyAccount { // so. if count != old_count { debug!( - "Updated uploaded one-time key count {} -> {}.", + "Updated uploaded one-time key count {} -> {count}.", self.uploaded_key_count(), - count ); } diff --git a/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs b/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs index d5b7b7543..d47466e1a 100644 --- a/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs +++ b/crates/matrix-sdk-crypto/src/olm/group_sessions/mod.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::BTreeMap, convert::TryInto}; +use std::collections::BTreeMap; use ruma::{ events::forwarded_room_key::{ diff --git a/crates/matrix-sdk-crypto/src/olm/signing/mod.rs b/crates/matrix-sdk-crypto/src/olm/signing/mod.rs index 1b6ddb3ea..c5c2191c0 100644 --- a/crates/matrix-sdk-crypto/src/olm/signing/mod.rs +++ b/crates/matrix-sdk-crypto/src/olm/signing/mod.rs @@ -717,12 +717,12 @@ mod tests { assert!(master_key .public_key - .verify_subkey(&identity.self_signing_key.lock().await.as_ref().unwrap().public_key,) + .verify_subkey(&identity.self_signing_key.lock().await.as_ref().unwrap().public_key) .is_ok()); assert!(master_key .public_key - .verify_subkey(&identity.user_signing_key.lock().await.as_ref().unwrap().public_key,) + .verify_subkey(&identity.user_signing_key.lock().await.as_ref().unwrap().public_key) .is_ok()); } diff --git a/crates/matrix-sdk-crypto/src/olm/utility.rs b/crates/matrix-sdk-crypto/src/olm/utility.rs index dcca398d5..64c23b60c 100644 --- a/crates/matrix-sdk-crypto/src/olm/utility.rs +++ b/crates/matrix-sdk-crypto/src/olm/utility.rs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::convert::TryInto; - use ruma::{CanonicalJsonValue, DeviceKeyAlgorithm, DeviceKeyId, UserId}; use serde::Serialize; use serde_json::Value; diff --git a/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs b/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs index 25f24799d..41b6d345a 100644 --- a/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs +++ b/crates/matrix-sdk-crypto/src/session_manager/group_sessions.rs @@ -445,7 +445,7 @@ impl GroupSessionManager { users: impl Iterator, encryption_settings: impl Into, ) -> OlmResult>> { - trace!(room_id = room_id.as_str(), "Checking if a room key needs to be shared",); + trace!(room_id = room_id.as_str(), "Checking if a room key needs to be shared"); let encryption_settings = encryption_settings.into(); let history_visibility = encryption_settings.history_visibility.clone(); diff --git a/crates/matrix-sdk-crypto/src/session_manager/sessions.rs b/crates/matrix-sdk-crypto/src/session_manager/sessions.rs index 5c275ac4d..0676feaaf 100644 --- a/crates/matrix-sdk-crypto/src/session_manager/sessions.rs +++ b/crates/matrix-sdk-crypto/src/session_manager/sessions.rs @@ -338,10 +338,7 @@ impl SessionManager { self.key_request_machine.retry_keyshare(user_id, device_id); if let Err(e) = self.check_if_unwedged(user_id, device_id).await { - error!( - "Error while treating an unwedged device {} {} {:?}", - user_id, device_id, e - ); + error!("Error while treating an unwedged device {user_id} {device_id} {e:?}"); } changes.sessions.push(session); diff --git a/crates/matrix-sdk-crypto/src/verification/event_enums.rs b/crates/matrix-sdk-crypto/src/verification/event_enums.rs index 340050c9f..aa4bfdc3a 100644 --- a/crates/matrix-sdk-crypto/src/verification/event_enums.rs +++ b/crates/matrix-sdk-crypto/src/verification/event_enums.rs @@ -753,7 +753,7 @@ impl TryFrom for OutgoingContent { serde_json::from_value(json).map_err(|e| e.to_string())?, ) } - e => return Err(format!("Unsupported event type {}", e)), + e => return Err(format!("Unsupported event type {e}")), }; Ok(content.into()) diff --git a/crates/matrix-sdk-crypto/src/verification/machine.rs b/crates/matrix-sdk-crypto/src/verification/machine.rs index b5def1845..3f2f8714a 100644 --- a/crates/matrix-sdk-crypto/src/verification/machine.rs +++ b/crates/matrix-sdk-crypto/src/verification/machine.rs @@ -506,7 +506,7 @@ impl VerificationMachine { #[cfg(test)] mod tests { - use std::{convert::TryFrom, sync::Arc, time::Duration}; + use std::{sync::Arc, time::Duration}; use matrix_sdk_common::{instant::Instant, locks::Mutex}; use matrix_sdk_test::async_test; diff --git a/crates/matrix-sdk-crypto/src/verification/mod.rs b/crates/matrix-sdk-crypto/src/verification/mod.rs index 6a296a3ec..dcdf4eaf3 100644 --- a/crates/matrix-sdk-crypto/src/verification/mod.rs +++ b/crates/matrix-sdk-crypto/src/verification/mod.rs @@ -501,10 +501,9 @@ impl IdentitiesBeingVerified { } Err(e) => { error!( - "Error signing device keys for {} {} {:?}", + "Error signing device keys for {} {}: {e:?}", device.user_id(), device.device_id(), - e ); None } @@ -535,9 +534,8 @@ impl IdentitiesBeingVerified { } Err(e) => { error!( - "Error signing the public cross signing keys for {} {:?}", + "Error signing the public cross signing keys for {} {e:?}", i.user_id(), - e ); None } @@ -707,7 +705,6 @@ impl IdentitiesBeingVerified { #[cfg(test)] pub(crate) mod tests { - use std::convert::TryInto; use ruma::{ events::{AnyToDeviceEventContent, ToDeviceEvent}, diff --git a/crates/matrix-sdk-crypto/src/verification/qrcode.rs b/crates/matrix-sdk-crypto/src/verification/qrcode.rs index 8969df1fa..d0eaf9e7a 100644 --- a/crates/matrix-sdk-crypto/src/verification/qrcode.rs +++ b/crates/matrix-sdk-crypto/src/verification/qrcode.rs @@ -787,7 +787,7 @@ impl QrState { #[cfg(test)] mod tests { - use std::{convert::TryFrom, sync::Arc}; + use std::sync::Arc; use matrix_sdk_common::locks::Mutex; use matrix_sdk_qrcode::QrVerificationData; diff --git a/crates/matrix-sdk-crypto/src/verification/sas/helpers.rs b/crates/matrix-sdk-crypto/src/verification/sas/helpers.rs index 3ce340747..77d4837a6 100644 --- a/crates/matrix-sdk-crypto/src/verification/sas/helpers.rs +++ b/crates/matrix-sdk-crypto/src/verification/sas/helpers.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{collections::BTreeMap, convert::TryInto}; +use std::collections::BTreeMap; use ruma::{ events::{ @@ -196,19 +196,14 @@ pub fn receive_mac_event( let info = extra_mac_info_receive(ids, flow_id); - trace!( - "Received a key.verification.mac event from {} {}", - sender, - ids.other_device.device_id() - ); + trace!("Received a key.verification.mac event from {sender} {}", ids.other_device.device_id()); let mut keys = content.mac().keys().map(|k| k.as_str()).collect::>(); keys.sort_unstable(); - let keys = Base64::parse( - sas.calculate_mac_invalid_base64(&keys.join(","), &format!("{}KEY_IDS", &info)), - ) - .expect("Can't base64-decode SAS MAC"); + let keys = + Base64::parse(sas.calculate_mac_invalid_base64(&keys.join(","), &format!("{info}KEY_IDS"))) + .expect("Can't base64-decode SAS MAC"); if keys != *content.keys() { return Err(CancelCode::KeyMismatch); @@ -216,9 +211,7 @@ pub fn receive_mac_event( for (key_id, key_mac) in content.mac() { trace!( - "Checking MAC for the key id {} from {} {}", - key_id, - sender, + "Checking MAC for the key id {key_id} from {sender} {}", ids.other_device.device_id() ); @@ -234,7 +227,7 @@ pub fn receive_mac_event( .expect("Can't base64-decode SAS MAC"); if *key_mac == calculated_mac { - trace!("Successfully verified the device key {} from {}", key_id, sender); + trace!("Successfully verified the device key {key_id} from {sender}"); verified_devices.push(ids.other_device.clone()); } else { return Err(CancelCode::KeyMismatch); @@ -243,14 +236,13 @@ pub fn receive_mac_event( if let Some(key) = identity.master_key().get_key(&key_id) { // TODO we should check that the master key signs the device, // this way we know the master key also trusts the device - let calculated_mac = Base64::parse(sas.calculate_mac_invalid_base64( - &key.to_base64(), - &format!("{}{}", info, key_id), - )) + let calculated_mac = Base64::parse( + sas.calculate_mac_invalid_base64(&key.to_base64(), &format!("{info}{key_id}")), + ) .expect("Can't base64-decode SAS MAC"); if *key_mac == calculated_mac { - trace!("Successfully verified the master key {} from {}", key_id, sender); + trace!("Successfully verified the master key {key_id} from {sender}"); verified_identities.push(identity.clone()) } else { return Err(CancelCode::KeyMismatch); @@ -258,10 +250,8 @@ pub fn receive_mac_event( } } else { warn!( - "Key ID {} in MAC event from {} {} doesn't belong to any device \ + "Key ID {key_id} in MAC event from {sender} {} doesn't belong to any device \ or user identity", - key_id, - sender, ids.other_device.device_id() ); } @@ -312,7 +302,7 @@ pub fn get_mac_content(sas: &EstablishedSas, ids: &SasIds, flow_id: &FlowId) -> mac.insert( key_id.to_string(), - Base64::parse(sas.calculate_mac_invalid_base64(&key, &format!("{}{}", info, key_id))) + Base64::parse(sas.calculate_mac_invalid_base64(&key, &format!("{info}{key_id}"))) .expect("Can't base64-decode SAS MAC"), ); @@ -321,10 +311,9 @@ pub fn get_mac_content(sas: &EstablishedSas, ids: &SasIds, flow_id: &FlowId) -> if let Some(key) = own_identity.master_key().get_first_key() { let key_id = format!("{}:{}", DeviceKeyAlgorithm::Ed25519, key.to_base64()); - let calculated_mac = Base64::parse(sas.calculate_mac_invalid_base64( - &key.to_base64(), - &format!("{}{}", info, &key_id), - )) + let calculated_mac = Base64::parse( + sas.calculate_mac_invalid_base64(&key.to_base64(), &format!("{info}{key_id}")), + ) .expect("Can't base64-decode SAS Master key MAC"); mac.insert(key_id, calculated_mac); diff --git a/crates/matrix-sdk-crypto/src/verification/sas/mod.rs b/crates/matrix-sdk-crypto/src/verification/sas/mod.rs index 12aacdb2e..52681c84b 100644 --- a/crates/matrix-sdk-crypto/src/verification/sas/mod.rs +++ b/crates/matrix-sdk-crypto/src/verification/sas/mod.rs @@ -508,7 +508,7 @@ impl AcceptSettings { #[cfg(test)] mod tests { - use std::{convert::TryFrom, sync::Arc}; + use std::sync::Arc; use matrix_sdk_common::locks::Mutex; use matrix_sdk_test::async_test; diff --git a/crates/matrix-sdk-crypto/src/verification/sas/sas_state.rs b/crates/matrix-sdk-crypto/src/verification/sas/sas_state.rs index e9133eb50..0e19884a4 100644 --- a/crates/matrix-sdk-crypto/src/verification/sas/sas_state.rs +++ b/crates/matrix-sdk-crypto/src/verification/sas/sas_state.rs @@ -13,7 +13,6 @@ // limitations under the License. use std::{ - convert::{TryFrom, TryInto}, matches, sync::{Arc, Mutex}, time::Duration, @@ -546,10 +545,8 @@ impl SasState { let commitment = calculate_commitment(our_public_key, content); info!( - "Calculated commitment for pubkey {} and content {:?} {}", + "Calculated commitment for pubkey {} and content {content:?} {commitment}", our_public_key.to_base64(), - content, - commitment ); if let Ok(accepted_protocols) = AcceptedProtocols::try_from(method_content) { @@ -1224,8 +1221,6 @@ impl SasState { #[cfg(test)] mod tests { - use std::convert::TryFrom; - use matrix_sdk_test::async_test; use ruma::{ device_id, diff --git a/crates/matrix-sdk-indexeddb/src/safe_encode.rs b/crates/matrix-sdk-indexeddb/src/safe_encode.rs index 081c1a35a..55bfe4df4 100644 --- a/crates/matrix-sdk-indexeddb/src/safe_encode.rs +++ b/crates/matrix-sdk-indexeddb/src/safe_encode.rs @@ -72,8 +72,7 @@ pub trait SafeEncode { store_cipher: &StoreCipher, i: usize, ) -> JsValue { - format!("{}{}{:016x}", self.as_secure_string(table_name, store_cipher), KEY_SEPARATOR, i,) - .into() + format!("{}{KEY_SEPARATOR}{i:016x}", self.as_secure_string(table_name, store_cipher)).into() } /// Encode self into a IdbKeyRange for searching all keys that are diff --git a/crates/matrix-sdk-indexeddb/src/state_store.rs b/crates/matrix-sdk-indexeddb/src/state_store.rs index 0508fa391..2e94d2631 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store.rs @@ -54,6 +54,8 @@ use ruma::{ RoomVersionId, }; use serde::{de::DeserializeOwned, Deserialize, Serialize}; +#[cfg(feature = "experimental-timeline")] +use tracing::{info, warn}; use wasm_bindgen::JsValue; use web_sys::IdbKeyRange; @@ -111,12 +113,10 @@ impl From for StoreError { EncryptionError::Serialization(e) => StoreError::Json(e), EncryptionError::Encryption(e) => StoreError::Encryption(e.to_string()), EncryptionError::Version(found, expected) => StoreError::Encryption(format!( - "Bad Database Encryption Version: expected {} found {}", - expected, found + "Bad Database Encryption Version: expected {expected}, found {found}", )), EncryptionError::Length(found, expected) => StoreError::Encryption(format!( - "The database key an invalid length: expected {} found {}", - expected, found + "The database key an invalid length: expected {expected}, found {found}", )), }, _ => StoreError::backend(e), @@ -274,9 +274,11 @@ async fn backup(source: &IdbDatabase, meta: &IdbDatabase) -> Result<()> { pub struct IndexeddbStoreBuilderConfig { /// The name for the indexeddb store to use, `state` is none given name: String, - /// The password the indexeddb should be encrypted with. If not given, the DB is not encrypted + /// The password the indexeddb should be encrypted with. If not given, the + /// DB is not encrypted passphrase: String, - /// The strategy to use when a merge conflict is found, see [`MigrationConflictStrategy`] for details + /// The strategy to use when a merge conflict is found, see + /// [`MigrationConflictStrategy`] for details #[builder(default = "MigrationConflictStrategy::BackupAndDrop")] migration_conflict_strategy: MigrationConflictStrategy, } @@ -851,17 +853,14 @@ impl IndexeddbStore { for (room_id, timeline) in &changes.timeline { if timeline.sync { - tracing::info!("Save new timeline batch from sync response for {}", room_id); + info!("Save new timeline batch from sync response for {room_id}"); } else { - tracing::info!( - "Save new timeline batch from messages response for {}", - room_id - ); + info!("Save new timeline batch from messages response for {room_id}"); } let metadata: Option = if timeline.limited { - tracing::info!( - "Delete stored timeline for {} because the sync response was limited", - room_id + info!( + "Delete stored timeline for {room_id} because the sync response was \ + limited", ); let stores = &[ @@ -888,7 +887,7 @@ impl IndexeddbStore { // This should only happen when a developer adds a wrong timeline // batch to the `StateChanges` or the server returns a wrong response // to our request. - tracing::warn!("Drop unexpected timeline batch for {}", room_id); + warn!("Drop unexpected timeline batch for {room_id}"); return Ok(()); } @@ -912,9 +911,8 @@ impl IndexeddbStore { } if delete_timeline { - tracing::info!( - "Delete stored timeline for {} because of duplicated events", - room_id + info!( + "Delete stored timeline for {room_id} because of duplicated events", ); let stores = &[ @@ -961,9 +959,8 @@ impl IndexeddbStore { .transpose()? .and_then(|info| info.room_version().cloned()) .unwrap_or_else(|| { - tracing::warn!( - "Unable to find the room version for {}, assume version 9", - room_id + warn!( + "Unable to find the room version for {room_id}, assume version 9", ); RoomVersionId::V9 }); @@ -1466,7 +1463,7 @@ impl IndexeddbStore { { Some(tl) => tl, _ => { - tracing::info!("No timeline for {} was previously stored", room_id); + info!("No timeline for {room_id} was previously stored"); return Ok(None); } }; @@ -1482,11 +1479,7 @@ impl IndexeddbStore { let stream = Box::pin(stream::iter(timeline.into_iter())); - tracing::info!( - "Found previously stored timeline for {}, with end token {:?}", - room_id, - end_token - ); + info!("Found previously stored timeline for {room_id}, with end token {end_token:?}"); Ok(Some((stream, end_token))) } @@ -1682,7 +1675,7 @@ mod tests { use super::{IndexeddbStore, IndexeddbStoreBuilder, Result}; async fn get_store() -> Result { - let db_name = format!("test-state-plain-{}", Uuid::new_v4().as_hyphenated().to_string()); + let db_name = format!("test-state-plain-{}", Uuid::new_v4().as_hyphenated()); Ok(IndexeddbStoreBuilder::default().name(db_name).build().await?) } @@ -1700,9 +1693,8 @@ mod encrypted_tests { use super::{IndexeddbStore, IndexeddbStoreBuilder, Result}; async fn get_store() -> Result { - let db_name = - format!("test-state-encrypted-{}", Uuid::new_v4().as_hyphenated().to_string()); - let passphrase = format!("some_passphrase-{}", Uuid::new_v4().as_hyphenated().to_string()); + let db_name = format!("test-state-encrypted-{}", Uuid::new_v4().as_hyphenated()); + let passphrase = format!("some_passphrase-{}", Uuid::new_v4().as_hyphenated()); Ok(IndexeddbStoreBuilder::default().name(db_name).passphrase(passphrase).build().await?) } diff --git a/crates/matrix-sdk-qrcode/src/lib.rs b/crates/matrix-sdk-qrcode/src/lib.rs index 28fbe9d59..a9f261f60 100644 --- a/crates/matrix-sdk-qrcode/src/lib.rs +++ b/crates/matrix-sdk-qrcode/src/lib.rs @@ -33,7 +33,7 @@ pub use types::{ #[cfg(test)] mod tests { #[cfg(feature = "decode_image")] - use std::{convert::TryFrom, io::Cursor}; + use std::io::Cursor; #[cfg(feature = "decode_image")] use image::{ImageFormat, Luma}; diff --git a/crates/matrix-sdk-qrcode/src/utils.rs b/crates/matrix-sdk-qrcode/src/utils.rs index 14812cabc..5c819b259 100644 --- a/crates/matrix-sdk-qrcode/src/utils.rs +++ b/crates/matrix-sdk-qrcode/src/utils.rs @@ -12,8 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::convert::TryInto; - #[cfg(feature = "decode_image")] use image::{GenericImage, GenericImageView, Luma}; use qrcode::{bits::Bits, EcLevel, QrCode, Version}; diff --git a/crates/matrix-sdk-sled/src/cryptostore.rs b/crates/matrix-sdk-sled/src/cryptostore.rs index 871c2d2e0..2b936e76d 100644 --- a/crates/matrix-sdk-sled/src/cryptostore.rs +++ b/crates/matrix-sdk-sled/src/cryptostore.rs @@ -14,7 +14,6 @@ use std::{ collections::{HashMap, HashSet}, - convert::TryInto, path::{Path, PathBuf}, sync::{Arc, RwLock}, }; diff --git a/crates/matrix-sdk-sled/src/state_store.rs b/crates/matrix-sdk-sled/src/state_store.rs index 533c58b31..3f9f94eaa 100644 --- a/crates/matrix-sdk-sled/src/state_store.rs +++ b/crates/matrix-sdk-sled/src/state_store.rs @@ -59,6 +59,7 @@ use sled::{ Config, Db, Transactional, Tree, }; use tokio::task::spawn_blocking; +use tracing::{debug, info}; #[cfg(feature = "crypto-store")] use super::OpenStoreError; @@ -126,12 +127,10 @@ impl Into for SledStoreError { KeyEncryptionError::Serialization(e) => StoreError::Json(e), KeyEncryptionError::Encryption(e) => StoreError::Encryption(e.to_string()), KeyEncryptionError::Version(found, expected) => StoreError::Encryption(format!( - "Bad Database Encryption Version: expected {} found {}", - expected, found + "Bad Database Encryption Version: expected {expected}, found {found}", )), KeyEncryptionError::Length(found, expected) => StoreError::Encryption(format!( - "The database key an invalid length: expected {} found {}", - expected, found + "The database key an invalid length: expected {expected}, found {found}", )), }, SledStoreError::StoreError(e) => e, @@ -215,7 +214,8 @@ pub struct SledStoreBuilderConfig { path: PathBuf, /// Set the password the sled store is encrypted with (if any) passphrase: String, - /// The strategy to use when a merge conflict is found, see [`MigrationConflictStrategy`] for details + /// The strategy to use when a merge conflict is found, see + /// [`MigrationConflictStrategy`] for details #[builder(default = "MigrationConflictStrategy::BackupAndDrop")] migration_conflict_strategy: MigrationConflictStrategy, } @@ -476,11 +476,7 @@ impl SledStore { Some(version) => version, }; - tracing::debug!( - old_version, - new_version = DATABASE_VERSION, - "Upgrading the Sled state store" - ); + debug!(old_version, new_version = DATABASE_VERSION, "Upgrading the Sled state store"); if old_version == 1 { if self.store_cipher.is_some() { @@ -839,7 +835,7 @@ impl SledStore { self.inner.flush_async().await?; - tracing::info!("Saved changes in {:?}", now.elapsed()); + info!("Saved changes in {:?}", now.elapsed()); Ok(()) } @@ -1308,7 +1304,7 @@ impl SledStore { let metadata = match metadata { Some(m) => m, None => { - tracing::info!("No timeline for {} was previously stored", r_id); + info!("No timeline for {r_id} was previously stored"); return Ok(None); } }; @@ -1316,16 +1312,14 @@ impl SledStore { let mut position = metadata.start_position; let end_token = metadata.end; - tracing::info!( - "Found previously stored timeline for {}, with end token {:?}", - r_id, - end_token - ); + info!("Found previously stored timeline for {r_id}, with end token {end_token:?}"); let stream = stream! { - while let Ok(Some(item)) = db.room_timeline.get(&db.encode_key_with_counter(TIMELINE, &r_id, position)) { + while let Ok(Some(item)) = + db.room_timeline.get(&db.encode_key_with_counter(TIMELINE, &r_id, position)) + { position += 1; - yield db.deserialize_value(&item).map_err(SledStoreError::from).map_err(|e| e.into()); + yield db.deserialize_value(&item).map_err(|e| SledStoreError::from(e).into()); } }; @@ -1334,7 +1328,7 @@ impl SledStore { #[cfg(feature = "experimental-timeline")] async fn remove_room_timeline(&self, room_id: &RoomId) -> Result<()> { - tracing::info!("Remove stored timeline for {}", room_id); + info!("Remove stored timeline for {room_id}"); let mut timeline_batch = sled::Batch::default(); for key in self.room_timeline.scan_prefix(self.encode_key(TIMELINE, &room_id)).keys() { @@ -1371,22 +1365,21 @@ impl SledStore { #[cfg(feature = "experimental-timeline")] async fn save_room_timeline(&self, changes: &StateChanges) -> Result<()> { + use tracing::warn; + let mut timeline_batch = sled::Batch::default(); let mut event_id_to_position_batch = sled::Batch::default(); let mut timeline_metadata_batch = sled::Batch::default(); for (room_id, timeline) in &changes.timeline { if timeline.sync { - tracing::info!("Save new timeline batch from sync response for {}", room_id); + info!("Save new timeline batch from sync response for {room_id}"); } else { - tracing::info!("Save new timeline batch from messages response for {}", room_id); + info!("Save new timeline batch from messages response for {room_id}"); } let metadata: Option = if timeline.limited { - tracing::info!( - "Delete stored timeline for {} because the sync response was limited", - room_id - ); + info!("Delete stored timeline for {room_id} because the sync response was limited"); self.remove_room_timeline(room_id).await?; None } else { @@ -1400,7 +1393,7 @@ impl SledStore { // This should only happen when a developer adds a wrong timeline // batch to the `StateChanges` or the server returns a wrong response // to our request. - tracing::warn!("Drop unexpected timeline batch for {}", room_id); + warn!("Drop unexpected timeline batch for {room_id}"); return Ok(()); } @@ -1418,10 +1411,7 @@ impl SledStore { } if delete_timeline { - tracing::info!( - "Delete stored timeline for {} because of duplicated events", - room_id - ); + info!("Delete stored timeline for {room_id} because of duplicated events"); self.remove_room_timeline(room_id).await?; None } else if timeline.sync { @@ -1453,10 +1443,7 @@ impl SledStore { .transpose()? .and_then(|info| info.room_version().cloned()) .unwrap_or_else(|| { - tracing::warn!( - "Unable to find the room version for {}, assume version 9", - room_id - ); + warn!("Unable to find the room version for {room_id}, assume version 9"); RoomVersionId::V9 }); diff --git a/crates/matrix-sdk-test/src/appservice.rs b/crates/matrix-sdk-test/src/appservice.rs index 29244f00f..cd3c3fdb8 100644 --- a/crates/matrix-sdk-test/src/appservice.rs +++ b/crates/matrix-sdk-test/src/appservice.rs @@ -1,5 +1,3 @@ -use std::convert::TryFrom; - use ruma::{events::AnyRoomEvent, serde::Raw}; use serde_json::Value; diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index 1b511b14b..a7b0da4c7 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -19,7 +19,7 @@ rustdoc-args = ["--cfg", "docsrs"] default = [ "e2e-encryption", "sled", - "native-tls" + "native-tls", ] e2e-encryption = [ diff --git a/crates/matrix-sdk/README.md b/crates/matrix-sdk/README.md index f8e99151c..58d694bbd 100644 --- a/crates/matrix-sdk/README.md +++ b/crates/matrix-sdk/README.md @@ -25,7 +25,6 @@ some event handlers and then syncing. This is demonstrated in the example below. ```rust,no_run -use std::convert::TryFrom; use matrix_sdk::{ Client, config::SyncSettings, ruma::{user_id, events::room::message::SyncRoomMessageEvent}, diff --git a/crates/matrix-sdk/examples/autojoin.rs b/crates/matrix-sdk/examples/autojoin.rs index 5f7296278..978fb3340 100644 --- a/crates/matrix-sdk/examples/autojoin.rs +++ b/crates/matrix-sdk/examples/autojoin.rs @@ -22,13 +22,13 @@ async fn on_stripped_state_member( // retry autojoin due to synapse sending invites, before the // invited user can join for more information see // https://github.com/matrix-org/synapse/issues/4345 - eprintln!("Failed to join room {} ({:?}), retrying in {}s", room.room_id(), err, delay); + eprintln!("Failed to join room {} ({err:?}), retrying in {delay}s", room.room_id()); sleep(Duration::from_secs(delay)).await; delay *= 2; if delay > 3600 { - eprintln!("Can't join room {} ({:?})", room.room_id(), err); + eprintln!("Can't join room {} ({err:?})", room.room_id()); break; } } @@ -67,7 +67,7 @@ async fn login_and_sync( .send() .await?; - println!("logged in as {}", username); + println!("logged in as {username}"); client.register_event_handler(on_stripped_state_member).await; diff --git a/crates/matrix-sdk/examples/command_bot.rs b/crates/matrix-sdk/examples/command_bot.rs index e49b2381c..e05125236 100644 --- a/crates/matrix-sdk/examples/command_bot.rs +++ b/crates/matrix-sdk/examples/command_bot.rs @@ -61,7 +61,7 @@ async fn login_and_sync( .send() .await?; - println!("logged in as {}", username); + println!("logged in as {username}"); // An initial sync to set up state and so our bot doesn't respond to old // messages. If the `StateStore` finds saved state in the location given the diff --git a/crates/matrix-sdk/examples/image_bot.rs b/crates/matrix-sdk/examples/image_bot.rs index b6aab0931..b423d566d 100644 --- a/crates/matrix-sdk/examples/image_bot.rs +++ b/crates/matrix-sdk/examples/image_bot.rs @@ -92,7 +92,7 @@ async fn main() -> anyhow::Result<()> { } }; - println!("helloooo {} {} {} {:#?}", homeserver_url, username, password, image_path); + println!("helloooo {homeserver_url} {username} {password} {image_path:#?}"); let path = PathBuf::from(image_path); let image = File::open(path).expect("Can't open image file."); diff --git a/crates/matrix-sdk/examples/login.rs b/crates/matrix-sdk/examples/login.rs index c935dc206..d7cdb2357 100644 --- a/crates/matrix-sdk/examples/login.rs +++ b/crates/matrix-sdk/examples/login.rs @@ -25,7 +25,7 @@ async fn on_room_message(event: OriginalSyncRoomMessageEvent, room: Room) { { let member = room.get_member(&sender).await.unwrap().unwrap(); let name = member.display_name().unwrap_or_else(|| member.user_id().as_str()); - println!("{}: {}", name, msg_body); + println!("{name}: {msg_body}"); } } } diff --git a/crates/matrix-sdk/examples/timeline.rs b/crates/matrix-sdk/examples/timeline.rs index eb1c7b39d..ccb759d0b 100644 --- a/crates/matrix-sdk/examples/timeline.rs +++ b/crates/matrix-sdk/examples/timeline.rs @@ -54,7 +54,7 @@ async fn print_timeline(room: Room) { while let Some(event) = backward_stream.next().await { let event = event.unwrap(); if let Some(content) = event_content(event.event.deserialize().unwrap()) { - println!("{}", content); + println!("{content}"); } } } diff --git a/crates/matrix-sdk/src/account.rs b/crates/matrix-sdk/src/account.rs index 97a805381..60c493343 100644 --- a/crates/matrix-sdk/src/account.rs +++ b/crates/matrix-sdk/src/account.rs @@ -65,7 +65,7 @@ impl Account { /// client.login(user, "password", None, None).await?; /// /// if let Some(name) = client.account().get_display_name().await? { - /// println!("Logged in as user '{}' with display name '{}'", user, name); + /// println!("Logged in as user '{user}' with display name '{name}'"); /// } /// # anyhow::Ok(()) }); /// ``` @@ -113,7 +113,7 @@ impl Account { /// client.login(user, "password", None, None).await?; /// /// if let Some(url) = client.account().get_avatar_url().await? { - /// println!("Your avatar's mxc url is {}", url); + /// println!("Your avatar's mxc url is {url}"); /// } /// # anyhow::Ok(()) }); /// ``` @@ -258,7 +258,6 @@ impl Account { /// /// # Example /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::Client; /// # use matrix_sdk::ruma::{ /// # api::client::{ @@ -307,7 +306,6 @@ impl Account { /// /// # Example /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::Client; /// # use matrix_sdk::ruma::{ /// # api::client::{ diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index fa9b17c1f..f49e928c4 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -342,6 +342,7 @@ impl ClientBuilder { typing_notice_times: Default::default(), event_handlers: Default::default(), event_handler_data: Default::default(), + event_handler_counter: Default::default(), notification_handlers: Default::default(), appservice_mode: self.appservice_mode, respect_login_well_known: self.respect_login_well_known, @@ -354,12 +355,12 @@ impl ClientBuilder { fn homeserver_from_name(server_name: &ServerName) -> String { #[cfg(not(test))] - return format!("https://{}", server_name); + return format!("https://{server_name}"); // Wiremock only knows how to test http endpoints: // https://github.com/LukeMathWalker/wiremock-rs/issues/58 #[cfg(test)] - return format!("http://{}", server_name); + return format!("http://{server_name}"); } #[derive(Clone, Debug)] diff --git a/crates/matrix-sdk/src/client/login_builder.rs b/crates/matrix-sdk/src/client/login_builder.rs index e01b8d90d..9e610615a 100644 --- a/crates/matrix-sdk/src/client/login_builder.rs +++ b/crates/matrix-sdk/src/client/login_builder.rs @@ -224,7 +224,7 @@ where const SSO_SERVER_BIND_TRIES: u8 = 10; let homeserver = self.client.homeserver().await; - info!("Logging in to {}", homeserver); + info!("Logging in to {homeserver}"); let (signal_tx, signal_rx) = oneshot::channel(); let (data_tx, data_rx) = oneshot::channel(); diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index 61840003c..912ff262f 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -1,5 +1,6 @@ // Copyright 2020 Damir Jelić // Copyright 2020 The Matrix.org Foundation C.I.C. +// Copyright 2022 Famedly GmbH // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -19,7 +20,10 @@ use std::{ future::Future, io::Read, pin::Pin, - sync::{Arc, RwLock as StdRwLock}, + sync::{ + atomic::{AtomicU64, Ordering::SeqCst}, + Arc, RwLock as StdRwLock, + }, }; use anymap2::any::CloneAnySendSync; @@ -80,7 +84,10 @@ use crate::{ attachment::{AttachmentInfo, Thumbnail}, config::RequestConfig, error::{HttpError, HttpResult}, - event_handler::{EventHandler, EventHandlerData, EventHandlerResult, EventKind, SyncEvent}, + event_handler::{ + EventHandler, EventHandlerData, EventHandlerHandle, EventHandlerResult, + EventHandlerWrapper, EventKind, SyncEvent, + }, http_client::HttpClient, room, Account, Error, Result, }; @@ -101,8 +108,8 @@ const DEFAULT_UPLOAD_SPEED: u64 = 125_000; const MIN_UPLOAD_REQUEST_TIMEOUT: Duration = Duration::from_secs(60 * 5); type EventHandlerFut = Pin + Send>>; -type EventHandlerFn = Box) -> EventHandlerFut + Send + Sync>; -type EventHandlerMap = BTreeMap<(EventKind, &'static str), Vec>; +pub(crate) type EventHandlerFn = dyn Fn(EventHandlerData<'_>) -> EventHandlerFut + Send + Sync; +type EventHandlerMap = BTreeMap<(EventKind, &'static str), Vec>; type NotificationHandlerFut = EventHandlerFut; type NotificationHandlerFn = @@ -156,6 +163,9 @@ pub(crate) struct ClientInner { event_handlers: RwLock, /// Custom event handler context. See `register_event_handler_context`. event_handler_data: StdRwLock, + /// When registering a event handler, the current value is used for the + /// handlers identification, then the counter is incremented. + event_handler_counter: AtomicU64, /// Notification handlers. See `register_notification_handler`. notification_handlers: RwLock>, /// Whether the client should operate in application service style mode. @@ -346,9 +356,11 @@ impl Client { /// "context" arguments: They have to implement [`EventHandlerContext`]. /// This trait is named that way because most of the types implementing it /// give additional context about an event: The room it was in, its raw form - /// and other similar things. As an exception to this, - /// [`Client`] also implements the `EventHandlerContext` trait - /// so you don't have to clone your client into the event handler manually. + /// and other similar things. As two exceptions to this, + /// [`Client`] and [`EventHandlerHandle`] also implement the + /// `EventHandlerContext` trait so you don't have to clone your client + /// into the event handler manually and a handler can decide to remove + /// itself. /// /// Some context arguments are not universally applicable. A context /// argument that isn't available for the given event type will result in @@ -388,13 +400,15 @@ impl Client { /// # .build() /// # .await /// # .unwrap(); + /// /// client /// .register_event_handler( /// |ev: SyncRoomMessageEvent, room: Room, client: Client| async move { /// // Common usage: Room event plus room and client. /// }, /// ) - /// .await + /// .await; + /// client /// .register_event_handler( /// |ev: SyncRoomMessageEvent, room: Room, encryption_info: Option| { /// async move { @@ -403,7 +417,8 @@ impl Client { /// } /// }, /// ) - /// .await + /// .await; + /// client /// .register_event_handler(|ev: SyncRoomTopicEvent| async move { /// // You can omit any or all arguments after the first. /// }) @@ -431,54 +446,118 @@ impl Client { /// move |ev: SyncRoomMessageEvent | { /// let data = data.clone(); /// async move { - /// println!("Calling the handler with identifier {}", data); + /// println!("Calling the handler with identifier {data}"); /// } /// } /// }).await; /// # }); /// ``` - pub async fn register_event_handler(&self, handler: H) -> &Self + pub async fn register_event_handler(&self, handler: H) -> EventHandlerHandle where Ev: SyncEvent + DeserializeOwned + Send + 'static, H: EventHandler, ::Output: EventHandlerResult, { - let event_type = H::ID.1; - self.inner.event_handlers.write().await.entry(H::ID).or_default().push(Box::new( - move |data| { - let maybe_fut = serde_json::from_str(data.raw.get()) - .map(|ev| handler.clone().handle_event(ev, data)); + let event_type = Ev::TYPE; + let key = (Ev::KIND, Ev::TYPE); - Box::pin(async move { - match maybe_fut { - Ok(Some(fut)) => { - fut.await.print_error(event_type); - } - Ok(None) => { - error!( - "Event handler for {} has an invalid context argument", - event_type - ); - } - Err(e) => { - warn!( - "Failed to deserialize `{}` event, skipping event handler.\n\ - Deserialization error: {}", - event_type, e, - ); - } + let handler_fn: Box = Box::new(move |data| { + let maybe_fut = serde_json::from_str(data.raw.get()) + .map(|ev| handler.clone().handle_event(ev, data)); + + Box::pin(async move { + match maybe_fut { + Ok(Some(fut)) => { + fut.await.print_error(event_type); } - }) - }, - )); + Ok(None) => { + error!("Event handler for {} has an invalid context argument", event_type); + } + Err(e) => { + warn!( + "Failed to deserialize `{}` event, skipping event handler.\n\ + Deserialization error: {}", + event_type, e, + ); + } + } + }) + }); - self + let handler_id = self.inner.event_handler_counter.fetch_add(1, SeqCst); + + let handle = EventHandlerHandle { handler_id, ev_id: key }; + + self.inner + .event_handlers + .write() + .await + .entry(key) + .or_default() + .push(EventHandlerWrapper { handler_fn, handle }); + + handle } pub(crate) async fn event_handlers(&self) -> RwLockReadGuard<'_, EventHandlerMap> { self.inner.event_handlers.read().await } + /// Remove the event handler associated with the handle. + /// + /// Note that handlers that remove themselves will still execute + /// with events received in the same sync cycle. + /// + /// # Arguments + /// + /// `handle` - The [`EventHandlerHandle`] that is returned when + /// registering the event handler with [`Client::register_event_handler`]. + /// + /// # Examples + /// + /// ``` + /// # use futures::executor::block_on; + /// # use url::Url; + /// # use tokio::sync::mpsc; + /// # + /// # let homeserver = Url::parse("http://localhost:8080").unwrap(); + /// # + /// use matrix_sdk::{ + /// ruma::events::room::member::SyncRoomMemberEvent, + /// Client, event_handler::EventHandlerHandle + /// }; + /// # + /// # block_on(async { + /// # let client = matrix_sdk::Client::builder() + /// # .homeserver_url(homeserver) + /// # .server_versions([ruma::api::MatrixVersion::V1_0]) + /// # .build() + /// # .await + /// # .unwrap(); + /// + /// client + /// .register_event_handler( + /// |ev: SyncRoomMemberEvent, client: Client, handle: EventHandlerHandle| async move { + /// // Common usage: Check arriving Event is the expected one + /// println!("Expected RoomMemberEvent received!"); + /// client.remove_event_handler(handle); + /// }, + /// ) + /// .await; + /// # }); + /// ``` + pub async fn remove_event_handler(&self, handle: EventHandlerHandle) { + let mut event_handlers = self.inner.event_handlers.write().await; + + if let Some(v) = event_handlers.get_mut(&handle.ev_id) { + v.retain(|e| e.handle.handler_id != handle.handler_id); + + if v.is_empty() { + event_handlers.remove(&handle.ev_id); + } + } + } + /// Add an arbitrary value for use as event handler context. /// /// The value can be obtained in an event handler by adding an argument of @@ -511,8 +590,8 @@ impl Client { /// // Handle used to send messages to the UI part of the app /// let my_gui_handle: SomeType = obtain_gui_handle(); /// + /// client.register_event_handler_context(my_gui_handle.clone()); /// client - /// .register_event_handler_context(my_gui_handle.clone()) /// .register_event_handler( /// |ev: SyncRoomMessageEvent, room: Room, gui_handle: Ctx| async move { /// // gui_handle.send(DisplayMessage { message: ev }); @@ -521,12 +600,11 @@ impl Client { /// .await; /// # }); /// ``` - pub fn register_event_handler_context(&self, ctx: T) -> &Self + pub fn register_event_handler_context(&self, ctx: T) where T: Clone + Send + Sync + 'static, { self.inner.event_handler_data.write().unwrap().insert(ctx); - self } pub(crate) fn event_handler_context(&self) -> Option @@ -725,7 +803,6 @@ impl Client { /// # Example /// /// ```no_run - /// # use std::convert::TryFrom; /// # use futures::executor::block_on; /// # use url::Url; /// # let homeserver = Url::parse("http://example.com").unwrap(); @@ -742,8 +819,8 @@ impl Client { /// .await?; /// /// println!( - /// "Logged in as {}, got device_id {} and access_token {}", - /// user, response.device_id, response.access_token, + /// "Logged in as {user}, got device_id {} and access_token {}", + /// response.device_id, response.access_token, /// ); /// # anyhow::Ok(()) }); /// ``` @@ -792,7 +869,6 @@ impl Client { /// # Example /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::Client; /// # use matrix_sdk::ruma::{assign, DeviceId}; /// # use futures::executor::block_on; @@ -1061,7 +1137,6 @@ impl Client { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::Client; /// # use matrix_sdk::ruma::{ /// # api::client::{ @@ -1092,7 +1167,7 @@ impl Client { registration: impl Into>, ) -> HttpResult { let homeserver = self.homeserver().await; - info!("Registering to {}", homeserver); + info!("Registering to {homeserver}"); let config = if self.inner.appservice_mode { Some(RequestConfig::short_retry().force_auth()) @@ -1224,7 +1299,6 @@ impl Client { /// # Examples /// ```no_run /// use matrix_sdk::Client; - /// # use std::convert::TryInto; /// # use url::Url; /// # let homeserver = Url::parse("http://example.com").unwrap(); /// # let limit = Some(10); @@ -1300,7 +1374,6 @@ impl Client { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use url::Url; /// # use matrix_sdk::Client; /// # use futures::executor::block_on; @@ -1415,7 +1488,6 @@ impl Client { /// # use matrix_sdk::{Client, config::SyncSettings}; /// # use futures::executor::block_on; /// # use url::Url; - /// # use std::convert::TryFrom; /// # block_on(async { /// # let homeserver = Url::parse("http://localhost:8080")?; /// # let mut client = Client::new(homeserver).await?; @@ -1498,7 +1570,6 @@ impl Client { /// # use matrix_sdk::{Client, config::SyncSettings}; /// # use futures::executor::block_on; /// # use url::Url; - /// # use std::convert::TryFrom; /// # block_on(async { /// # let homeserver = Url::parse("http://localhost:8080")?; /// # let mut client = Client::new(homeserver).await?; @@ -1546,7 +1617,7 @@ impl Client { /// # use futures::executor::block_on; /// # use serde_json::json; /// # use url::Url; - /// # use std::{collections::BTreeMap, convert::TryFrom}; + /// # use std::collections::BTreeMap; /// # block_on(async { /// # let homeserver = Url::parse("http://localhost:8080")?; /// # let mut client = Client::new(homeserver).await?; @@ -1838,8 +1909,6 @@ impl Client { if callback(r).await == LoopCtrl::Break { return; } - } else { - continue; } Client::delay_sync(&mut last_sync_time).await diff --git a/crates/matrix-sdk/src/encryption/identities/devices.rs b/crates/matrix-sdk/src/encryption/identities/devices.rs index e03427b5b..f0a106f05 100644 --- a/crates/matrix-sdk/src/encryption/identities/devices.rs +++ b/crates/matrix-sdk/src/encryption/identities/devices.rs @@ -81,7 +81,6 @@ impl Device { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::{device_id, user_id}}; /// # use url::Url; /// # use futures::executor::block_on; @@ -123,7 +122,6 @@ impl Device { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ @@ -171,7 +169,6 @@ impl Device { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::{device_id, user_id}}; /// # use url::Url; /// # use futures::executor::block_on; @@ -229,7 +226,6 @@ impl Device { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ @@ -344,7 +340,6 @@ impl Device { /// Let's check if a device is verified: /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ diff --git a/crates/matrix-sdk/src/encryption/identities/mod.rs b/crates/matrix-sdk/src/encryption/identities/mod.rs index 220c3c3d3..594a115cb 100644 --- a/crates/matrix-sdk/src/encryption/identities/mod.rs +++ b/crates/matrix-sdk/src/encryption/identities/mod.rs @@ -35,7 +35,6 @@ //! Verifying a device is pretty straightforward: //! //! ```no_run -//! # use std::convert::TryFrom; //! # use matrix_sdk::{Client, ruma::{device_id, user_id}}; //! # use url::Url; //! # use futures::executor::block_on; @@ -61,7 +60,6 @@ //! Verifying a user identity works largely the same: //! //! ```no_run -//! # use std::convert::TryFrom; //! # use matrix_sdk::{Client, ruma::user_id}; //! # use url::Url; //! # use futures::executor::block_on; diff --git a/crates/matrix-sdk/src/encryption/identities/users.rs b/crates/matrix-sdk/src/encryption/identities/users.rs index ae85e5054..9269da0cc 100644 --- a/crates/matrix-sdk/src/encryption/identities/users.rs +++ b/crates/matrix-sdk/src/encryption/identities/users.rs @@ -91,7 +91,6 @@ impl UserIdentity { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::user_id}; /// # use url::Url; /// # let alice = user_id!("@alice:example.org"); @@ -143,7 +142,6 @@ impl UserIdentity { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::user_id}; /// # use url::Url; /// # let alice = user_id!("@alice:example.org"); @@ -195,7 +193,6 @@ impl UserIdentity { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ @@ -274,7 +271,6 @@ impl UserIdentity { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ @@ -318,7 +314,6 @@ impl UserIdentity { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ @@ -358,7 +353,6 @@ impl UserIdentity { /// # Examples /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{ /// # Client, /// # ruma::{ diff --git a/crates/matrix-sdk/src/encryption/mod.rs b/crates/matrix-sdk/src/encryption/mod.rs index fd597437b..420cfd812 100644 --- a/crates/matrix-sdk/src/encryption/mod.rs +++ b/crates/matrix-sdk/src/encryption/mod.rs @@ -555,7 +555,6 @@ impl Encryption { /// # Example /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::{device_id, user_id}}; /// # use url::Url; /// # use futures::executor::block_on; @@ -600,7 +599,6 @@ impl Encryption { /// # Example /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::user_id}; /// # use url::Url; /// # use futures::executor::block_on; @@ -640,7 +638,6 @@ impl Encryption { /// # Example /// /// ```no_run - /// # use std::convert::TryFrom; /// # use matrix_sdk::{Client, ruma::user_id}; /// # use url::Url; /// # use futures::executor::block_on; @@ -691,7 +688,7 @@ impl Encryption { /// /// # Examples /// ```no_run - /// # use std::{convert::TryFrom, collections::BTreeMap}; + /// # use std::collections::BTreeMap; /// # use matrix_sdk::{ruma::api::client::uiaa, Client}; /// # use url::Url; /// # use futures::executor::block_on; diff --git a/crates/matrix-sdk/src/encryption/verification/sas.rs b/crates/matrix-sdk/src/encryption/verification/sas.rs index c9dc3928a..828d274fc 100644 --- a/crates/matrix-sdk/src/encryption/verification/sas.rs +++ b/crates/matrix-sdk/src/encryption/verification/sas.rs @@ -147,7 +147,7 @@ impl SasVerification { /// .collect::>() /// .join(""); /// - /// println!("Do the emojis match?\n{}\n{}", emoji_string, description); + /// println!("Do the emojis match?\n{emoji_string}\n{description}"); /// } /// # anyhow::Ok(()) }); /// ``` diff --git a/crates/matrix-sdk/src/event_handler.rs b/crates/matrix-sdk/src/event_handler.rs index fec80128d..48d4ba0e4 100644 --- a/crates/matrix-sdk/src/event_handler.rs +++ b/crates/matrix-sdk/src/event_handler.rs @@ -1,4 +1,5 @@ // Copyright 2021 Jonas Platte +// Copyright 2022 Famedly GmbH // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -38,8 +39,9 @@ use matrix_sdk_base::deserialized_responses::{EncryptionInfo, SyncRoomEvent}; use ruma::{events::AnySyncStateEvent, serde::Raw}; use serde::Deserialize; use serde_json::value::RawValue as RawJsonValue; +use tracing::error; -use crate::{room, Client}; +use crate::{client::EventHandlerFn, room, Client}; #[doc(hidden)] #[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)] @@ -80,7 +82,28 @@ impl EventKind { /// A statically-known event kind/type that can be retrieved from an event sync. pub trait SyncEvent { #[doc(hidden)] - const ID: (EventKind, &'static str); + const KIND: EventKind; + #[doc(hidden)] + const TYPE: &'static str; +} + +pub(crate) struct EventHandlerWrapper { + pub handler_fn: Box, + pub handle: EventHandlerHandle, +} + +/// Handle to remove a registered event handler by passing it to +/// [`Client::remove_event_handler`]. +#[derive(Clone, Copy, Debug)] +pub struct EventHandlerHandle { + pub(crate) ev_id: (EventKind, &'static str), + pub(crate) handler_id: u64, +} + +impl EventHandlerContext for EventHandlerHandle { + fn from_data(data: &EventHandlerData<'_>) -> Option { + Some(data.handle) + } } /// Interface for event handlers. @@ -121,11 +144,6 @@ pub trait EventHandler: Clone + Send + Sync + 'static { #[doc(hidden)] type Future: Future + Send + 'static; - /// The event type being handled, for example a message event of type - /// `m.room.message`. - #[doc(hidden)] - const ID: (EventKind, &'static str); - /// Create a future for handling the given event. /// /// `data` provides additional data about the event, for example the room it @@ -143,6 +161,7 @@ pub struct EventHandlerData<'a> { pub room: Option, pub raw: &'a RawJsonValue, pub encryption_info: Option<&'a EncryptionInfo>, + pub handle: EventHandlerHandle, } /// Context for an event handler. @@ -237,14 +256,14 @@ impl EventHandlerResult for Result<(), E match self { #[cfg(feature = "anyhow")] Err(e) if TypeId::of::() == TypeId::of::() => { - tracing::error!("Event handler for `{}` failed: {:?}", event_type, e); + error!("Event handler for `{event_type}` failed: {e:?}"); } #[cfg(feature = "eyre")] Err(e) if TypeId::of::() == TypeId::of::() => { - tracing::error!("Event handler for `{}` failed: {:?}", event_type, e); + error!("Event handler for `{event_type}` failed: {e:?}"); } Err(e) => { - tracing::error!("Event handler for `{}` failed: {}", event_type, e); + error!("Event handler for `{event_type}` failed: {e}"); } Ok(_) => {} } @@ -383,14 +402,15 @@ impl Client { .get(&event_handler_id) .into_iter() .flatten() - .map(|handler| { + .map(|handler_wrapper| { let data = EventHandlerData { client: self.clone(), room: room.clone(), raw: raw_event.json(), encryption_info, + handle: handler_wrapper.handle, }; - (handler)(data) + (handler_wrapper.handler_fn)(data) }) .collect(); @@ -416,7 +436,6 @@ macro_rules! impl_event_handler { $($ty: EventHandlerContext),* { type Future = Fut; - const ID: (EventKind, &'static str) = Ev::ID; fn handle_event(&self, ev: Ev, _d: EventHandlerData<'_>) -> Option { Some((self)(ev, $($ty::from_data(&_d)?),*)) @@ -450,21 +469,24 @@ mod static_events { where C: StaticEventContent + GlobalAccountDataEventContent, { - const ID: (EventKind, &'static str) = (EventKind::GlobalAccountData, C::TYPE); + const KIND: EventKind = EventKind::GlobalAccountData; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::RoomAccountDataEvent where C: StaticEventContent + RoomAccountDataEventContent, { - const ID: (EventKind, &'static str) = (EventKind::RoomAccountData, C::TYPE); + const KIND: EventKind = EventKind::RoomAccountData; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::SyncEphemeralRoomEvent where C: StaticEventContent + EphemeralRoomEventContent, { - const ID: (EventKind, &'static str) = (EventKind::EphemeralRoomData, C::TYPE); + const KIND: EventKind = EventKind::EphemeralRoomData; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::SyncMessageLikeEvent @@ -472,40 +494,39 @@ mod static_events { C: StaticEventContent + MessageLikeEventContent + RedactContent, C::Redacted: MessageLikeEventContent + RedactedEventContent, { - const ID: (EventKind, &'static str) = (EventKind::MessageLike, C::TYPE); + const KIND: EventKind = EventKind::MessageLike; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::OriginalSyncMessageLikeEvent where C: StaticEventContent + MessageLikeEventContent, { - const ID: (EventKind, &'static str) = (EventKind::OriginalMessageLike, C::TYPE); + const KIND: EventKind = EventKind::OriginalMessageLike; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::RedactedSyncMessageLikeEvent where C: StaticEventContent + MessageLikeEventContent + RedactedEventContent, { - const ID: (EventKind, &'static str) = (EventKind::RedactedMessageLike, C::TYPE); + const KIND: EventKind = EventKind::RedactedMessageLike; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::room::redaction::SyncRoomRedactionEvent { - const ID: (EventKind, &'static str) = - (EventKind::MessageLike, events::room::redaction::RoomRedactionEventContent::TYPE); + const KIND: EventKind = EventKind::MessageLike; + const TYPE: &'static str = events::room::redaction::RoomRedactionEventContent::TYPE; } impl SyncEvent for events::room::redaction::OriginalSyncRoomRedactionEvent { - const ID: (EventKind, &'static str) = ( - EventKind::OriginalMessageLike, - events::room::redaction::RoomRedactionEventContent::TYPE, - ); + const KIND: EventKind = EventKind::OriginalMessageLike; + const TYPE: &'static str = events::room::redaction::RoomRedactionEventContent::TYPE; } impl SyncEvent for events::room::redaction::RedactedSyncRoomRedactionEvent { - const ID: (EventKind, &'static str) = ( - EventKind::RedactedMessageLike, - events::room::redaction::RoomRedactionEventContent::TYPE, - ); + const KIND: EventKind = EventKind::RedactedMessageLike; + const TYPE: &'static str = events::room::redaction::RoomRedactionEventContent::TYPE; } impl SyncEvent for events::SyncStateEvent @@ -513,46 +534,53 @@ mod static_events { C: StaticEventContent + StateEventContent + RedactContent, C::Redacted: StateEventContent + RedactedEventContent, { - const ID: (EventKind, &'static str) = (EventKind::State, C::TYPE); + const KIND: EventKind = EventKind::State; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::OriginalSyncStateEvent where C: StaticEventContent + StateEventContent, { - const ID: (EventKind, &'static str) = (EventKind::OriginalState, C::TYPE); + const KIND: EventKind = EventKind::OriginalState; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::RedactedSyncStateEvent where C: StaticEventContent + StateEventContent + RedactedEventContent, { - const ID: (EventKind, &'static str) = (EventKind::RedactedState, C::TYPE); + const KIND: EventKind = EventKind::RedactedState; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::StrippedStateEvent where C: StaticEventContent + StateEventContent, { - const ID: (EventKind, &'static str) = (EventKind::StrippedState, C::TYPE); + const KIND: EventKind = EventKind::StrippedState; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::InitialStateEvent where C: StaticEventContent + StateEventContent, { - const ID: (EventKind, &'static str) = (EventKind::InitialState, C::TYPE); + const KIND: EventKind = EventKind::InitialState; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for events::ToDeviceEvent where C: StaticEventContent + ToDeviceEventContent, { - const ID: (EventKind, &'static str) = (EventKind::ToDevice, C::TYPE); + const KIND: EventKind = EventKind::ToDevice; + const TYPE: &'static str = C::TYPE; } impl SyncEvent for PresenceEvent { - const ID: (EventKind, &'static str) = (EventKind::Presence, PresenceEventContent::TYPE); + const KIND: EventKind = EventKind::Presence; + const TYPE: &'static str = PresenceEventContent::TYPE; } } @@ -567,7 +595,13 @@ mod tests { EphemeralTestEvent, EventBuilder, StateTestEvent, StrippedStateTestEvent, TimelineTestEvent, }; use ruma::{ - events::room::member::{OriginalSyncRoomMemberEvent, StrippedRoomMemberEvent}, + events::{ + room::{ + member::{OriginalSyncRoomMemberEvent, StrippedRoomMemberEvent}, + power_levels::OriginalSyncRoomPowerLevelsEvent, + }, + typing::SyncTypingEvent, + }, room_id, }; use serde_json::json; @@ -575,7 +609,7 @@ mod tests { use crate::{room, Client}; #[async_test] - async fn event_handler() -> crate::Result<()> { + async fn register_event_handler() -> crate::Result<()> { use std::sync::atomic::{AtomicU8, Ordering::SeqCst}; let client = crate::client::tests::logged_in_client(None).await; @@ -593,23 +627,26 @@ mod tests { future::ready(()) } }) - .await + .await; + client .register_event_handler({ let typing_count = typing_count.clone(); - move |_ev: OriginalSyncRoomMemberEvent| { + move |_ev: SyncTypingEvent| { typing_count.fetch_add(1, SeqCst); future::ready(()) } }) - .await + .await; + client .register_event_handler({ let power_levels_count = power_levels_count.clone(); - move |_ev: OriginalSyncRoomMemberEvent, _client: Client, _room: room::Room| { + move |_ev: OriginalSyncRoomPowerLevelsEvent, _client: Client, _room: room::Room| { power_levels_count.fetch_add(1, SeqCst); future::ready(()) } }) - .await + .await; + client .register_event_handler({ let invited_member_count = invited_member_count.clone(); move |_ev: StrippedRoomMemberEvent| { @@ -674,4 +711,57 @@ mod tests { Ok(()) } + + #[async_test] + async fn remove_event_handler() -> crate::Result<()> { + use std::sync::atomic::{AtomicU8, Ordering::SeqCst}; + + let client = crate::client::tests::logged_in_client(None).await; + + let member_count = Arc::new(AtomicU8::new(0)); + + client + .register_event_handler({ + let member_count = member_count.clone(); + move |_ev: OriginalSyncRoomMemberEvent| { + member_count.fetch_add(1, SeqCst); + future::ready(()) + } + }) + .await; + + let handle = client + .register_event_handler({ + move |_ev: OriginalSyncRoomMemberEvent| { + panic!("handler should have been removed"); + #[allow(unreachable_code)] + future::ready(()) + } + }) + .await; + + client + .register_event_handler({ + let member_count = member_count.clone(); + move |_ev: OriginalSyncRoomMemberEvent| { + member_count.fetch_add(1, SeqCst); + future::ready(()) + } + }) + .await; + + let response = EventBuilder::default() + .add_joined_room( + JoinedRoomBuilder::default().add_timeline_event(TimelineTestEvent::Member), + ) + .build_sync_response(); + + client.remove_event_handler(handle).await; + + client.process_sync(response).await?; + + assert_eq!(member_count.load(SeqCst), 2); + + Ok(()) + } } diff --git a/crates/matrix-sdk/src/http_client.rs b/crates/matrix-sdk/src/http_client.rs index 13b4fe25f..b4bc4e7b0 100644 --- a/crates/matrix-sdk/src/http_client.rs +++ b/crates/matrix-sdk/src/http_client.rs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -use std::{any::type_name, convert::TryFrom, fmt::Debug, sync::Arc, time::Duration}; +use std::{any::type_name, fmt::Debug, sync::Arc, time::Duration}; use async_trait::async_trait; use bytes::{Bytes, BytesMut}; @@ -50,7 +50,6 @@ pub trait HttpSend: AsyncTraitDeps { /// # Examples /// /// ``` - /// use std::convert::TryFrom; /// use matrix_sdk::{HttpSend, async_trait, HttpError, config::RequestConfig, bytes::Bytes}; /// /// #[derive(Debug)] diff --git a/crates/matrix-sdk/src/lib.rs b/crates/matrix-sdk/src/lib.rs index 5303dfe01..34fb3010a 100644 --- a/crates/matrix-sdk/src/lib.rs +++ b/crates/matrix-sdk/src/lib.rs @@ -17,10 +17,10 @@ #![warn(missing_debug_implementations, missing_docs)] #![cfg_attr(docsrs, feature(doc_auto_cfg))] -#[cfg(not(any(feature = "native-tls", feature = "rustls-tls",)))] +#[cfg(not(any(feature = "native-tls", feature = "rustls-tls")))] compile_error!("one of 'native-tls' or 'rustls-tls' features must be enabled"); -#[cfg(all(feature = "native-tls", feature = "rustls-tls",))] +#[cfg(all(feature = "native-tls", feature = "rustls-tls"))] compile_error!("only one of 'native-tls' or 'rustls-tls' features can be enabled"); #[cfg(all(feature = "sso-login", target_arch = "wasm32"))] diff --git a/crates/matrix-sdk/src/room/common.rs b/crates/matrix-sdk/src/room/common.rs index 9e740a9e2..08f379eff 100644 --- a/crates/matrix-sdk/src/room/common.rs +++ b/crates/matrix-sdk/src/room/common.rs @@ -165,7 +165,6 @@ impl Common { /// /// # Examples /// ```no_run - /// # use std::convert::TryFrom; /// use matrix_sdk::{room::MessagesOptions, Client}; /// # use matrix_sdk::ruma::{ /// # api::client::filter::RoomEventFilter, @@ -263,7 +262,6 @@ impl Common { /// /// # Examples /// ```no_run - /// # use std::convert::TryFrom; /// use matrix_sdk::Client; /// # use matrix_sdk::ruma::{ /// # api::client::filter::RoomEventFilter, @@ -315,8 +313,10 @@ impl Common { for await item in backward_store { match item { Ok(event) => yield Ok(event), - Err(TimelineStreamError::EndCache { fetch_more_token }) => if let Err(error) = room.request_messages(&fetch_more_token).await { - yield Err(error); + Err(TimelineStreamError::EndCache { fetch_more_token }) => { + if let Err(error) = room.request_messages(&fetch_more_token).await { + yield Err(error); + } }, Err(TimelineStreamError::Store(error)) => yield Err(error.into()), } @@ -343,7 +343,6 @@ impl Common { /// /// # Examples /// ```no_run - /// # use std::convert::TryFrom; /// use matrix_sdk::Client; /// # use matrix_sdk::ruma::{ /// # api::client::filter::RoomEventFilter, @@ -402,7 +401,6 @@ impl Common { /// /// # Examples /// ```no_run - /// # use std::convert::TryFrom; /// use matrix_sdk::Client; /// # use matrix_sdk::ruma::{ /// # api::client::filter::RoomEventFilter, @@ -445,8 +443,10 @@ impl Common { for await item in backward_store { match item { Ok(event) => yield Ok(event), - Err(TimelineStreamError::EndCache { fetch_more_token }) => if let Err(error) = room.request_messages(&fetch_more_token).await { - yield Err(error); + Err(TimelineStreamError::EndCache { fetch_more_token }) => { + if let Err(error) = room.request_messages(&fetch_more_token).await { + yield Err(error); + } }, Err(TimelineStreamError::Store(error)) => yield Err(error.into()), } @@ -1075,7 +1075,9 @@ impl Common { /// Options for [`messages`][Common::messages]. /// -/// See that method and for details. +/// See that method and +/// +/// for details. #[derive(Debug)] #[non_exhaustive] pub struct MessagesOptions<'a> { diff --git a/crates/matrix-sdk/src/room/joined.rs b/crates/matrix-sdk/src/room/joined.rs index 5ffad481e..d1f1ce477 100644 --- a/crates/matrix-sdk/src/room/joined.rs +++ b/crates/matrix-sdk/src/room/joined.rs @@ -416,7 +416,6 @@ impl Joined { /// # use url::Url; /// # use futures::executor::block_on; /// # use matrix_sdk::ruma::room_id; - /// # use std::convert::TryFrom; /// # use serde::{Deserialize, Serialize}; /// use matrix_sdk::ruma::{ /// events::{ @@ -513,7 +512,6 @@ impl Joined { /// # use url::Url; /// # use futures::executor::block_on; /// # use matrix_sdk::ruma::room_id; - /// # use std::convert::TryFrom; /// # block_on(async { /// # let homeserver = Url::parse("http://localhost:8080")?; /// # let mut client = Client::new(homeserver).await?; @@ -557,7 +555,7 @@ impl Joined { if event_type == "m.reaction" { debug!( room_id = %self.room_id(), - "Sending plaintext event because the event type is {}", event_type + "Sending plaintext event because the event type is {event_type}", ); (Raw::new(&content)?.cast(), event_type) } else { diff --git a/crates/matrix-sdk/src/sync.rs b/crates/matrix-sdk/src/sync.rs index a580e56c5..93b477565 100644 --- a/crates/matrix-sdk/src/sync.rs +++ b/crates/matrix-sdk/src/sync.rs @@ -36,7 +36,7 @@ impl Client { for (room_id, room_info) in &rooms.join { let room = self.get_room(room_id); if room.is_none() { - error!("Can't call event handler, room {} not found", room_id); + error!("Can't call event handler, room {room_id} not found"); continue; } @@ -53,7 +53,7 @@ impl Client { for (room_id, room_info) in &rooms.leave { let room = self.get_room(room_id); if room.is_none() { - error!("Can't call event handler, room {} not found", room_id); + error!("Can't call event handler, room {room_id} not found"); continue; } @@ -68,7 +68,7 @@ impl Client { for (room_id, room_info) in &rooms.invite { let room = self.get_room(room_id); if room.is_none() { - error!("Can't call event handler, room {} not found", room_id); + error!("Can't call event handler, room {room_id} not found"); continue; } @@ -88,7 +88,7 @@ impl Client { let room = match self.get_room(room_id) { Some(room) => room, None => { - warn!("Can't call notification handler, room {} not found", room_id); + warn!("Can't call notification handler, room {room_id} not found"); continue; } }; @@ -128,9 +128,7 @@ impl Client { Ok(r) } Err(e) => { - error!("Received an invalid response: {}", e); - Self::sleep().await; - + error!("Received an invalid response: {e}"); Err(e) } } diff --git a/labs/sled-state-inspector/src/main.rs b/labs/sled-state-inspector/src/main.rs index e36908cf8..97cd9aac4 100644 --- a/labs/sled-state-inspector/src/main.rs +++ b/labs/sled-state-inspector/src/main.rs @@ -1,4 +1,4 @@ -use std::{convert::TryFrom, fmt::Debug, sync::Arc}; +use std::{fmt::Debug, sync::Arc}; use atty::Stream; use clap::{Arg, ArgMatches, Command as Argparse}; @@ -66,7 +66,7 @@ impl InspectorHelper { fn complete_event_types(&self, arg: Option<&&str>) -> Vec { Self::EVENT_TYPES .iter() - .map(|&t| Pair { display: t.to_owned(), replacement: format!("{} ", t) }) + .map(|&t| Pair { display: t.to_owned(), replacement: format!("{t} ") }) .filter(|r| if let Some(arg) = arg { r.replacement.starts_with(arg) } else { true }) .collect() } @@ -105,7 +105,7 @@ impl Completer for InspectorHelper { ("get-members", "get all the membership events in the given room"), ] .iter() - .map(|(r, d)| Pair { display: format!("{} ({})", r, d), replacement: format!("{} ", r) }) + .map(|(r, d)| Pair { display: format!("{r} ({d})"), replacement: format!("{r} ") }) .collect(); if args.is_empty() { @@ -188,13 +188,13 @@ impl Printer { for line in LinesWithEndings::from(&data) { let ranges: Vec<(Style, &str)> = h.highlight(line, &self.ps); let escaped = as_24_bit_terminal_escaped(&ranges[..], false); - print!("{}", escaped); + print!("{escaped}"); } // Clear the formatting println!("\x1b[0m"); } else { - println!("{}", data); + println!("{data}"); } } } @@ -318,7 +318,7 @@ impl Inspector { self.run(m).await; } Err(e) => { - println!("{}", e); + println!("{e}"); } } } diff --git a/xtask/src/ci.rs b/xtask/src/ci.rs index 0b34f0858..baa991a2d 100644 --- a/xtask/src/ci.rs +++ b/xtask/src/ci.rs @@ -300,7 +300,7 @@ fn run_wasm_pack_tests(cmd: Option) -> Result<()> { ]); let run = |(folder, arg_set): (&str, &str)| { - let _p = pushd(format!("crates/{}", folder)); + let _p = pushd(format!("crates/{folder}")); cmd!("pwd").run()?; // print dir so we know what might have failed cmd!("wasm-pack test --node -- ").args(arg_set.split_whitespace()).run()?; cmd!("wasm-pack test --firefox --headless --").args(arg_set.split_whitespace()).run()