From 5c1827fee6a85a3f2be0c63cec83220036fe9097 Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Tue, 3 Jun 2025 09:29:37 -0400 Subject: [PATCH 1/8] Send/Sync bounds --- crates/matrix-sdk-base/src/room/mod.rs | 2 ++ crates/matrix-sdk-common/src/deserialized_responses.rs | 2 ++ crates/matrix-sdk/src/sliding_sync/list/builder.rs | 9 +++++++++ 3 files changed, 13 insertions(+) diff --git a/crates/matrix-sdk-base/src/room/mod.rs b/crates/matrix-sdk-base/src/room/mod.rs index 5cb3c232a65..2c49e9f75c2 100644 --- a/crates/matrix-sdk-base/src/room/mod.rs +++ b/crates/matrix-sdk-base/src/room/mod.rs @@ -41,6 +41,8 @@ use eyeball::{AsyncLock, SharedObservable}; use futures_util::{Stream, StreamExt}; #[cfg(feature = "e2e-encryption")] use matrix_sdk_common::ring_buffer::RingBuffer; +#[cfg(feature = "test-send-sync")] +use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm}; pub use members::{RoomMember, RoomMembersUpdate, RoomMemberships}; pub(crate) use room_info::SyncInfo; pub use room_info::{ diff --git a/crates/matrix-sdk-common/src/deserialized_responses.rs b/crates/matrix-sdk-common/src/deserialized_responses.rs index ea72259b9bc..0f22fa713b0 100644 --- a/crates/matrix-sdk-common/src/deserialized_responses.rs +++ b/crates/matrix-sdk-common/src/deserialized_responses.rs @@ -34,6 +34,8 @@ use crate::{ debug::{DebugRawEvent, DebugStructExt}, serde_helpers::extract_bundled_thread_summary, }; +#[cfg(feature = "test-send-sync")] +use crate::{SendOutsideWasm, SyncOutsideWasm}; const AUTHENTICITY_NOT_GUARANTEED: &str = "The authenticity of this encrypted message can't be guaranteed on this device."; diff --git a/crates/matrix-sdk/src/sliding_sync/list/builder.rs b/crates/matrix-sdk/src/sliding_sync/list/builder.rs index 93a202ef38f..a07c2822a9d 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/builder.rs @@ -111,6 +111,15 @@ impl SlidingSyncListBuilder { self } + #[cfg(target_family = "wasm")] + pub fn once_built(mut self, callback: C) -> Self + where + C: Fn(SlidingSyncList) -> SlidingSyncList + 'static, + { + self.once_built = Arc::new(Box::new(callback)); + self + } + /// Which SlidingSyncMode to start this list under. pub fn sync_mode(mut self, value: impl Into) -> Self { self.sync_mode = value.into(); From f3a3ef3db58eac501c99fd6246cd5fdf44c3476d Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Wed, 28 May 2025 12:48:24 -0400 Subject: [PATCH 2/8] target_arch to target_family --- Cargo.lock | 39 +++++++++++++++++++-------------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 38bf49c3f90..8de3651c1af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -159,9 +159,9 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" [[package]] name = "anymap2" @@ -5824,12 +5824,13 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "uniffi" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31bff6daf87277a9014bcdefbc2842b0553392919d1096843c5aad899ca4588" +checksum = "4cb08c58c7ed7033150132febe696bef553f891b1ede57424b40d87a89e3c170" dependencies = [ "anyhow", "camino", + "cargo_metadata", "clap", "uniffi_bindgen", "uniffi_build", @@ -5846,9 +5847,9 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96061d7e01b185aa405f7c9b134741ab3e50cc6796a47d6fd8ab9a5364b5feed" +checksum = "cade167af943e189a55020eda2c314681e223f1e42aca7c4e52614c2b627698f" dependencies = [ "anyhow", "askama", @@ -5864,15 +5865,14 @@ dependencies = [ "textwrap", "toml 0.5.11", "uniffi_meta", - "uniffi_testing", "uniffi_udl", ] [[package]] name = "uniffi_build" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6b86f9b221046af0c533eafe09ece04e2f1ded04ccdc9bba0ec09aec1c52bd" +checksum = "4c7cf32576e08104b7dc2a6a5d815f37616e66c6866c2a639fe16e6d2286b75b" dependencies = [ "anyhow", "camino", @@ -5891,14 +5891,13 @@ dependencies = [ [[package]] name = "uniffi_core" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3210d57d6ab6065ab47a2898dacdb7c606fd6a4156196831fa3bf82e34ac58a6" +checksum = "bc7687007d2546c454d8ae609b105daceb88175477dac280707ad6d95bcd6f1f" dependencies = [ "anyhow", "async-compat", "bytes", - "camino", "log", "once_cell", "paste", @@ -5907,9 +5906,9 @@ dependencies = [ [[package]] name = "uniffi_macros" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b58691741080935437dc862122e68d7414432a11824ac1137868de46181a0bd2" +checksum = "12c65a5b12ec544ef136693af8759fb9d11aefce740fb76916721e876639033b" dependencies = [ "bincode", "camino", @@ -5925,9 +5924,9 @@ dependencies = [ [[package]] name = "uniffi_meta" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7663eacdbd9fbf4a88907ddcfe2e6fa85838eb6dc2418a7d91eebb3786f8e20b" +checksum = "4a74ed96c26882dac1ca9b93ca23c827e284bacbd7ec23c6f0b0372f747d59e4" dependencies = [ "anyhow", "bytes", @@ -5937,9 +5936,9 @@ dependencies = [ [[package]] name = "uniffi_testing" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f922465f7566f25f8fe766920205fdfa9a3fcdc209c6bfb7557f0b5bf45b04dd" +checksum = "6a6f984f0781f892cc864a62c3a5c60361b1ccbd68e538e6c9fbced5d82268ac" dependencies = [ "anyhow", "camino", @@ -5950,9 +5949,9 @@ dependencies = [ [[package]] name = "uniffi_udl" -version = "0.28.0" +version = "0.28.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cef408229a3a407fafa4c36dc4f6ece78a6fb258ab28d2b64bddd49c8cb680f6" +checksum = "037820a4cfc4422db1eaa82f291a3863c92c7d1789dc513489c36223f9b4cdfc" dependencies = [ "anyhow", "textwrap", From 6f2730c9ab048941b393dd1294a6d4b8017541ff Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Wed, 28 May 2025 13:04:21 -0400 Subject: [PATCH 3/8] Update matrix-sdk-common utils that are in existing PRs already --- bindings/matrix-sdk-ffi/Cargo.toml | 2 +- crates/matrix-sdk-common/Cargo.toml | 1 + crates/matrix-sdk-common/src/stream.rs | 1 - 3 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index 19854168745..c4bc9587cbe 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -24,7 +24,7 @@ unstable-msc4274 = ["matrix-sdk-ui/unstable-msc4274"] [dependencies] anyhow.workspace = true as_variant.workspace = true -async-compat = "0.2.4" +async-compat.workspace = true extension-trait = "1.0.1" eyeball-im.workspace = true futures-util.workspace = true diff --git a/crates/matrix-sdk-common/Cargo.toml b/crates/matrix-sdk-common/Cargo.toml index 6c424fd4cf6..f5a3e7a7ae1 100644 --- a/crates/matrix-sdk-common/Cargo.toml +++ b/crates/matrix-sdk-common/Cargo.toml @@ -38,6 +38,7 @@ uniffi = { workspace = true, optional = true } [target.'cfg(not(target_family = "wasm"))'.dependencies] # Enable the test macro. +async-compat.workspace = true tokio = { workspace = true, features = ["rt", "time", "macros"] } [target.'cfg(target_family = "wasm")'.dependencies] diff --git a/crates/matrix-sdk-common/src/stream.rs b/crates/matrix-sdk-common/src/stream.rs index 4eefe41dd5d..3427e9ee917 100644 --- a/crates/matrix-sdk-common/src/stream.rs +++ b/crates/matrix-sdk-common/src/stream.rs @@ -18,7 +18,6 @@ //! with boxed streams across different platforms. On native platforms, //! streams can be `Send`, but on Wasm they cannot. This module abstracts //! over that difference. - #[cfg(not(target_family = "wasm"))] mod sys { // On native platforms, just re-export everything from futures_util From d9fe0e4a2b4a77bafd77571610bf7ddc704db8f4 Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Wed, 28 May 2025 13:14:45 -0400 Subject: [PATCH 4/8] Move to uniffi 29.2 --- Cargo.lock | 168 +++++++++++++--------------- Cargo.toml | 5 +- bindings/matrix-sdk-ffi/Cargo.toml | 62 +++++----- bindings/matrix-sdk-ffi/src/api.udl | 2 + bindings/matrix-sdk-ffi/uniffi.toml | 12 +- xtask/Cargo.toml | 3 + xtask/src/config_supplier.rs | 74 ++++++++++++ xtask/src/kotlin.rs | 22 +++- xtask/src/main.rs | 1 + xtask/src/swift.rs | 22 +++- 10 files changed, 245 insertions(+), 126 deletions(-) create mode 100644 xtask/src/config_supplier.rs diff --git a/Cargo.lock b/Cargo.lock index 8de3651c1af..28565c78b3a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -212,43 +212,44 @@ checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a" [[package]] name = "askama" -version = "0.12.1" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +checksum = "5d4744ed2eef2645831b441d8f5459689ade2ab27c854488fbab1fbe94fce1a7" dependencies = [ "askama_derive", - "askama_escape", + "itoa", + "percent-encoding", + "serde", + "serde_json", ] [[package]] name = "askama_derive" -version = "0.12.5" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +checksum = "d661e0f57be36a5c14c48f78d09011e67e0cb618f269cca9f2fd8d15b68c46ac" dependencies = [ "askama_parser", "basic-toml", - "mime", - "mime_guess", + "memchr", "proc-macro2", "quote", + "rustc-hash 2.0.0", "serde", + "serde_derive", "syn", ] -[[package]] -name = "askama_escape" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" - [[package]] name = "askama_parser" -version = "0.2.1" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +checksum = "cf315ce6524c857bb129ff794935cf6d42c82a6cff60526fe2a63593de4d0d4f" dependencies = [ - "nom", + "memchr", + "serde", + "serde_derive", + "winnow 0.7.10", ] [[package]] @@ -498,15 +499,6 @@ dependencies = [ "wiremock", ] -[[package]] -name = "bincode" -version = "1.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" -dependencies = [ - "serde", -] - [[package]] name = "bitflags" version = "1.3.2" @@ -635,16 +627,16 @@ dependencies = [ [[package]] name = "cargo_metadata" -version = "0.15.4" +version = "0.19.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +checksum = "dd5eb614ed4c27c5d706420e4320fbe3216ab31fa1c33cd8246ac36dae4479ba" dependencies = [ "camino", "cargo-platform", "semver", "serde", "serde_json", - "thiserror 1.0.63", + "thiserror 2.0.11", ] [[package]] @@ -3100,6 +3092,7 @@ dependencies = [ "language-tags", "log-panics", "matrix-sdk", + "matrix-sdk-base", "matrix-sdk-common", "matrix-sdk-ffi-macros", "matrix-sdk-ui", @@ -3369,16 +3362,6 @@ version = "0.1.53" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "515a63dc9666c865e848b043ab52fe9a5c713ae89cde4b5fbaae67cfd614b93a" -[[package]] -name = "mime_guess" -version = "2.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" -dependencies = [ - "mime", - "unicase", -] - [[package]] name = "minicov" version = "0.3.7" @@ -4660,7 +4643,6 @@ version = "0.23.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321" dependencies = [ - "log", "once_cell", "ring", "rustls-pki-types", @@ -4796,7 +4778,6 @@ dependencies = [ "httpdate", "native-tls", "reqwest", - "rustls", "sentry-backtrace", "sentry-contexts", "sentry-core", @@ -4804,7 +4785,6 @@ dependencies = [ "sentry-tracing", "tokio", "ureq", - "webpki-roots", ] [[package]] @@ -5576,7 +5556,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.20", ] [[package]] @@ -5824,9 +5804,8 @@ checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" [[package]] name = "uniffi" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cb08c58c7ed7033150132febe696bef553f891b1ede57424b40d87a89e3c170" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", "camino", @@ -5836,6 +5815,7 @@ dependencies = [ "uniffi_build", "uniffi_core", "uniffi_macros", + "uniffi_pipeline", ] [[package]] @@ -5847,9 +5827,8 @@ dependencies = [ [[package]] name = "uniffi_bindgen" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cade167af943e189a55020eda2c314681e223f1e42aca7c4e52614c2b627698f" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", "askama", @@ -5859,58 +5838,57 @@ dependencies = [ "glob", "goblin", "heck", + "indexmap", "once_cell", - "paste", "serde", + "tempfile", "textwrap", "toml 0.5.11", + "uniffi_internal_macros", "uniffi_meta", + "uniffi_pipeline", "uniffi_udl", ] [[package]] name = "uniffi_build" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7cf32576e08104b7dc2a6a5d815f37616e66c6866c2a639fe16e6d2286b75b" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", "camino", "uniffi_bindgen", ] -[[package]] -name = "uniffi_checksum_derive" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "802d2051a700e3ec894c79f80d2705b69d85844dafbbe5d1a92776f8f48b563a" -dependencies = [ - "quote", - "syn", -] - [[package]] name = "uniffi_core" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc7687007d2546c454d8ae609b105daceb88175477dac280707ad6d95bcd6f1f" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", "async-compat", "bytes", - "log", "once_cell", - "paste", "static_assertions", ] +[[package]] +name = "uniffi_internal_macros" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" +dependencies = [ + "anyhow", + "indexmap", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "uniffi_macros" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12c65a5b12ec544ef136693af8759fb9d11aefce740fb76916721e876639033b" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ - "bincode", "camino", "fs-err", "once_cell", @@ -5924,39 +5902,35 @@ dependencies = [ [[package]] name = "uniffi_meta" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a74ed96c26882dac1ca9b93ca23c827e284bacbd7ec23c6f0b0372f747d59e4" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", - "bytes", "siphasher", - "uniffi_checksum_derive", + "uniffi_internal_macros", + "uniffi_pipeline", ] [[package]] -name = "uniffi_testing" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a6f984f0781f892cc864a62c3a5c60361b1ccbd68e538e6c9fbced5d82268ac" +name = "uniffi_pipeline" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", - "camino", - "cargo_metadata", - "fs-err", - "once_cell", + "heck", + "indexmap", + "tempfile", + "uniffi_internal_macros", ] [[package]] name = "uniffi_udl" -version = "0.28.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "037820a4cfc4422db1eaa82f291a3863c92c7d1789dc513489c36223f9b4cdfc" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "anyhow", "textwrap", "uniffi_meta", - "uniffi_testing", "weedle2", ] @@ -5986,10 +5960,7 @@ dependencies = [ "log", "native-tls", "once_cell", - "rustls", - "rustls-pki-types", "url", - "webpki-roots", ] [[package]] @@ -6279,8 +6250,7 @@ dependencies = [ [[package]] name = "weedle2" version = "5.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "998d2c24ec099a87daf9467808859f9d82b61f1d9c9701251aea037f514eae0e" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" dependencies = [ "nom", ] @@ -6587,6 +6557,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +dependencies = [ + "memchr", +] + [[package]] name = "wiremock" version = "0.6.2" @@ -6663,11 +6642,14 @@ checksum = "88301b56c26dd9bf5c43d858538f82d6f3f7764767defbc5d34e59459901c41a" name = "xtask" version = "0.1.0" dependencies = [ + "anyhow", "camino", + "cargo_metadata", "clap", "fs_extra", "serde", "serde_json", + "toml 0.5.11", "uniffi_bindgen", "xshell", ] diff --git a/Cargo.toml b/Cargo.toml index 7d902ec41bd..98305ee5943 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -94,8 +94,9 @@ tracing = { version = "0.1.40", default-features = false, features = ["std"] } tracing-core = "0.1.32" tracing-subscriber = "0.3.18" unicode-normalization = "0.1.24" -uniffi = { version = "0.28.0" } -uniffi_bindgen = { version = "0.28.0" } +uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" } +uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" } +uniffi_core = { git = "https://github.com/mozilla/uniffi-rs", rev = "c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" } url = "2.5.4" uuid = "1.12.1" vodozemac = { version = "0.9.0", features = ["insecure-pk-encryption"] } diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index c4bc9587cbe..ba0e387a10d 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -20,6 +20,7 @@ crate-type = ["cdylib", "staticlib"] default = ["bundled-sqlite", "unstable-msc4274"] bundled-sqlite = ["matrix-sdk/bundled-sqlite"] unstable-msc4274 = ["matrix-sdk-ui/unstable-msc4274"] +wasm = [] [dependencies] anyhow.workspace = true @@ -30,6 +31,7 @@ eyeball-im.workspace = true futures-util.workspace = true language-tags = "0.3.2" log-panics = { version = "2", features = ["with-backtrace"] } +matrix-sdk-base.workspace = true matrix-sdk-common.workspace = true matrix-sdk-ffi-macros.workspace = true matrix-sdk-ui = { workspace = true, features = ["uniffi"] } @@ -40,7 +42,6 @@ sentry-tracing = "0.36.0" serde.workspace = true serde_json.workspace = true thiserror.workspace = true -tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } tracing.workspace = true tracing-appender = { version = "0.2.2" } tracing-core.workspace = true @@ -50,21 +51,7 @@ url.workspace = true uuid = { version = "1.4.1", features = ["v4"] } zeroize.workspace = true -[target.'cfg(not(target_os = "android"))'.dependencies.matrix-sdk] -workspace = true -features = [ - "anyhow", - "e2e-encryption", - "experimental-widgets", - "markdown", - # note: differ from block below - "native-tls", - "socks", - "sqlite", - "uniffi", -] - -[target.'cfg(not(target_os = "android"))'.dependencies.sentry] +[target.'cfg(all(not(target_os = "android"), not(target_family = "wasm")))'.dependencies.sentry] version = "0.36.0" default-features = false features = [ @@ -80,6 +67,14 @@ features = [ [target.'cfg(target_os = "android")'.dependencies] paranoid-android = "0.2.1" +[target.'cfg(target_family = "wasm")'.dependencies] +tokio = { workspace = true, features = ["sync", "macros"] } +uniffi = { workspace = true, features = ["tokio", "wasm-unstable-single-threaded"] } + +[target.'cfg(not(target_family = "wasm"))'.dependencies] +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } +uniffi = { workspace = true, features = ["tokio"] } + [target.'cfg(target_os = "android")'.dependencies.matrix-sdk] workspace = true features = [ @@ -94,19 +89,34 @@ features = [ "uniffi", ] -[target.'cfg(target_os = "android")'.dependencies.sentry] -version = "0.36.0" -default-features = false +[target.'cfg(all(not(target_os = "android"), not(target_family = "wasm")))'.dependencies.matrix-sdk] +workspace = true features = [ - # TLS lib specific for Android. - "rustls", - # Most default features enabled otherwise. - "backtrace", - "contexts", - "panic", - "reqwest", + "anyhow", + "e2e-encryption", + "experimental-widgets", + "markdown", + # note: differ from block above + "native-tls", + "socks", + "sqlite", + "uniffi", ] +[target.'cfg(target_family = "wasm")'.dependencies.matrix-sdk] +workspace = true +features = [ + "anyhow", + "e2e-encryption", + "experimental-widgets", + "markdown", + "native-tls", # note: differ from block below + "socks", + "indexeddb", # note: differ from block below + "uniffi", +] + + [build-dependencies] uniffi = { workspace = true, features = ["build"] } vergen = { version = "8.1.3", features = ["build", "git", "gitcl"] } diff --git a/bindings/matrix-sdk-ffi/src/api.udl b/bindings/matrix-sdk-ffi/src/api.udl index c7caa1afb0b..c5fa1c1ffbb 100644 --- a/bindings/matrix-sdk-ffi/src/api.udl +++ b/bindings/matrix-sdk-ffi/src/api.udl @@ -1,10 +1,12 @@ namespace matrix_sdk_ffi {}; +[Remote] dictionary Mentions { sequence user_ids; boolean room; }; +[Remote] interface RoomMessageEventContentWithoutRelation { RoomMessageEventContentWithoutRelation with_mentions(Mentions mentions); }; diff --git a/bindings/matrix-sdk-ffi/uniffi.toml b/bindings/matrix-sdk-ffi/uniffi.toml index 92ed4de9c63..0284aee488f 100644 --- a/bindings/matrix-sdk-ffi/uniffi.toml +++ b/bindings/matrix-sdk-ffi/uniffi.toml @@ -1,4 +1,14 @@ [bindings.kotlin] package_name = "org.matrix.rustcomponents.sdk" cdylib_name = "matrix_sdk_ffi" -android_cleaner = true \ No newline at end of file +android_cleaner = true + +[bindings.typescript] +[bindings.typescript.customTypes.Date64] +typeName = "Date" +intoCustom = """((v: FfiType) => { + return new Date(Number(v)); +})({})""" +fromCustom = """((v: TsType) => { + return BigInt(v.getTime()); +})({})""" diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index 3e4f689c9aa..c94790abab9 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -13,10 +13,13 @@ name = "xtask" test = false [dependencies] +anyhow = "1.0.96" camino = "1.0.8" +cargo_metadata = "0.19.2" clap = { version = "4.0.18", features = ["derive"] } fs_extra = "1" serde = { workspace = true, features = ["derive"] } serde_json.workspace = true +toml = "0.5.11" uniffi_bindgen.workspace = true xshell = "0.2.2" diff --git a/xtask/src/config_supplier.rs b/xtask/src/config_supplier.rs new file mode 100644 index 00000000000..c85edbb6a77 --- /dev/null +++ b/xtask/src/config_supplier.rs @@ -0,0 +1,74 @@ +use std::{collections::HashMap, fs}; + +use anyhow::{bail, Context}; +use camino::Utf8PathBuf; +use cargo_metadata::Metadata; +use toml::value::Table; +use uniffi_bindgen::BindgenCrateConfigSupplier; + +#[derive(Debug, Clone, Default)] +pub struct CrateConfigSupplier { + paths: HashMap, +} + +fn load_toml_file(path: Option<&Utf8PathBuf>) -> anyhow::Result> { + if let Some(path) = path { + if path.exists() { + let contents = fs::read_to_string(path)?; + let table: Table = toml::from_str(&contents)?; + Ok(Some(table)) + } else { + Ok(None) + } + } else { + Ok(None) + } +} + +impl BindgenCrateConfigSupplier for CrateConfigSupplier { + fn get_toml(&self, crate_name: &str) -> anyhow::Result> { + load_toml_file(self.get_toml_path(crate_name).as_ref()) + } + + fn get_toml_path(&self, crate_name: &str) -> Option { + self.paths.get(crate_name).map(|p| p.join("uniffi.toml")) + } + + fn get_udl(&self, crate_name: &str, udl_name: &str) -> anyhow::Result { + let path = self + .paths + .get(crate_name) + .context(format!("No path known to UDL files for '{crate_name}'"))? + .join("src") + .join(format!("{udl_name}.udl")); + if path.exists() { + Ok(fs::read_to_string(path)?) + } else { + bail!(format!("No UDL file found at '{path}'")); + } + } +} + +impl From for CrateConfigSupplier { + fn from(metadata: Metadata) -> Self { + let paths: HashMap = metadata + .packages + .iter() + .flat_map(|p| { + p.targets + .iter() + .filter(|t| { + !t.is_bin() + && !t.is_example() + && !t.is_test() + && !t.is_bench() + && !t.is_custom_build() + }) + .filter_map(|t| { + p.manifest_path.parent().map(|p| (t.name.replace('-', "_"), p.to_owned())) + }) + }) + .collect(); + Self { paths } + } +} diff --git a/xtask/src/kotlin.rs b/xtask/src/kotlin.rs index 6ee768bce17..e13a5e3ddc0 100644 --- a/xtask/src/kotlin.rs +++ b/xtask/src/kotlin.rs @@ -1,11 +1,12 @@ use std::fs::create_dir_all; use camino::{Utf8Path, Utf8PathBuf}; +use cargo_metadata::MetadataCommand; use clap::{Args, Subcommand, ValueEnum}; use uniffi_bindgen::{bindings::KotlinBindingGenerator, library_mode::generate_bindings}; use xshell::cmd; -use crate::{sh, workspace, Result}; +use crate::{config_supplier::CrateConfigSupplier, sh, workspace, Result}; struct PackageValues { name: &'static str, @@ -121,7 +122,24 @@ fn build_android_library( fn generate_uniffi_bindings(library_path: &Utf8Path, ffi_generated_dir: &Utf8Path) -> Result<()> { println!("-- library_path = {library_path}"); - generate_bindings(library_path, None, &KotlinBindingGenerator, None, ffi_generated_dir, false)?; + let manifest_path = std::env::current_dir()?.join("Cargo.toml"); + println!("manifest path {:?}", manifest_path); + + // Get metadata using cargo_metadata + let metadata = MetadataCommand::new().manifest_path(&manifest_path).exec()?; + + // Convert the Metadata into a CrateConfigSupplier using From + let config_supplier = CrateConfigSupplier::from(metadata); + + generate_bindings( + library_path, + None, + &KotlinBindingGenerator, + &config_supplier, + None, + ffi_generated_dir, + false, + )?; Ok(()) } diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 12f29df96c2..7254c951a3a 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -1,6 +1,7 @@ #![allow(unexpected_cfgs)] mod ci; +mod config_supplier; mod fixup; mod kotlin; mod release; diff --git a/xtask/src/swift.rs b/xtask/src/swift.rs index cf41e2600a6..f712fb46e6f 100644 --- a/xtask/src/swift.rs +++ b/xtask/src/swift.rs @@ -4,11 +4,12 @@ use std::{ }; use camino::{Utf8Path, Utf8PathBuf}; +use cargo_metadata::MetadataCommand; use clap::{Args, Subcommand}; use uniffi_bindgen::{bindings::SwiftBindingGenerator, library_mode::generate_bindings}; use xshell::cmd; -use crate::{sh, workspace, Result}; +use crate::{config_supplier::CrateConfigSupplier, sh, workspace, Result}; /// Builds the SDK for Swift as a Static Library or XCFramework. #[derive(Args)] @@ -168,7 +169,24 @@ fn build_library() -> Result<()> { } fn generate_uniffi(library_path: &Utf8Path, ffi_directory: &Utf8Path) -> Result<()> { - generate_bindings(library_path, None, &SwiftBindingGenerator, None, ffi_directory, false)?; + let manifest_path = std::env::current_dir()?.join("Cargo.toml"); + println!("manifest path {:?}", manifest_path); + + // Get metadata using cargo_metadata + let metadata = MetadataCommand::new().manifest_path(&manifest_path).exec()?; + + // Convert the Metadata into a CrateConfigSupplier using From + let config_supplier = CrateConfigSupplier::from(metadata); + + generate_bindings( + library_path, + None, + &SwiftBindingGenerator, + &config_supplier, + None, + ffi_directory, + false, + )?; Ok(()) } From 9f117ca2a99ff8893baa9e443deea99ca236935c Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Wed, 4 Jun 2025 10:25:27 -0400 Subject: [PATCH 5/8] Flatten changes to support matrix-sdk-ffi with wasm --- Cargo.lock | 38 ++- Cargo.toml | 1 + bindings/matrix-sdk-ffi-web/Cargo.toml | 17 ++ bindings/matrix-sdk-ffi-web/src/lib.rs | 1 + bindings/matrix-sdk-ffi/Cargo.toml | 18 +- bindings/matrix-sdk-ffi/src/client.rs | 248 +++++++++++------- bindings/matrix-sdk-ffi/src/client_builder.rs | 152 ++++++----- bindings/matrix-sdk-ffi/src/platform.rs | 44 +++- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 15 +- crates/matrix-sdk-base/src/room/mod.rs | 2 - crates/matrix-sdk-common/Cargo.toml | 1 - .../src/deserialized_responses.rs | 2 - crates/matrix-sdk-common/src/stream.rs | 1 + .../src/sliding_sync/list/builder.rs | 9 - xtask/src/swift.rs | 2 +- 15 files changed, 337 insertions(+), 214 deletions(-) create mode 100644 bindings/matrix-sdk-ffi-web/Cargo.toml create mode 100644 bindings/matrix-sdk-ffi-web/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 28565c78b3a..e7a97156bf3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -249,7 +249,7 @@ dependencies = [ "memchr", "serde", "serde_derive", - "winnow 0.7.10", + "winnow 0.7.11", ] [[package]] @@ -869,6 +869,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "console_error_panic_hook" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06aeb73f470f66dcdbf7223caeebb85984942f22f1adb2a088cf9668146bbbc" +dependencies = [ + "cfg-if", + "wasm-bindgen", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -3086,6 +3096,7 @@ dependencies = [ "anyhow", "as_variant", "async-compat", + "console_error_panic_hook", "extension-trait", "eyeball-im", "futures-util", @@ -3126,6 +3137,14 @@ dependencies = [ "syn", ] +[[package]] +name = "matrix-sdk-ffi-web" +version = "0.1.0" +dependencies = [ + "matrix-sdk-ffi", + "uniffi", +] + [[package]] name = "matrix-sdk-indexeddb" version = "0.12.0" @@ -5847,6 +5866,7 @@ dependencies = [ "uniffi_internal_macros", "uniffi_meta", "uniffi_pipeline", + "uniffi_testing", "uniffi_udl", ] @@ -5923,6 +5943,18 @@ dependencies = [ "uniffi_internal_macros", ] +[[package]] +name = "uniffi_testing" +version = "0.29.1" +source = "git+https://github.com/mozilla/uniffi-rs?rev=c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f#c7f6caa3d1bf20f934346cefd8e82b5093f0dc6f" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + [[package]] name = "uniffi_udl" version = "0.29.1" @@ -6559,9 +6591,9 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] diff --git a/Cargo.toml b/Cargo.toml index 98305ee5943..cf685de77dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -3,6 +3,7 @@ members = [ "benchmarks", "bindings/matrix-sdk-crypto-ffi", "bindings/matrix-sdk-ffi", + "bindings/matrix-sdk-ffi-web", "crates/*", "examples/*", "labs/*", diff --git a/bindings/matrix-sdk-ffi-web/Cargo.toml b/bindings/matrix-sdk-ffi-web/Cargo.toml new file mode 100644 index 00000000000..d8f11e8bfd5 --- /dev/null +++ b/bindings/matrix-sdk-ffi-web/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "matrix-sdk-ffi-web" +version = "0.1.0" +edition = "2021" + +[dependencies] +matrix-sdk-ffi = { path = "../matrix-sdk-ffi/", features = ["js"] } +uniffi = { workspace = true } + +[build-dependencies] +uniffi = { workspace = true, features = ["build"] } + +[dev-dependencies] +uniffi = { workspace = true, features = ["bindgen-tests"] } + +[lib] +crate-type = ["lib", "staticlib", "cdylib"] diff --git a/bindings/matrix-sdk-ffi-web/src/lib.rs b/bindings/matrix-sdk-ffi-web/src/lib.rs new file mode 100644 index 00000000000..76861103124 --- /dev/null +++ b/bindings/matrix-sdk-ffi-web/src/lib.rs @@ -0,0 +1 @@ +pub use matrix_sdk_ffi; diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index ba0e387a10d..2e5c0ba2954 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -14,18 +14,17 @@ publish = false release = true [lib] -crate-type = ["cdylib", "staticlib"] +crate-type = ["lib", "cdylib", "staticlib"] [features] default = ["bundled-sqlite", "unstable-msc4274"] bundled-sqlite = ["matrix-sdk/bundled-sqlite"] unstable-msc4274 = ["matrix-sdk-ui/unstable-msc4274"] -wasm = [] +js = [] [dependencies] anyhow.workspace = true as_variant.workspace = true -async-compat.workspace = true extension-trait = "1.0.1" eyeball-im.workspace = true futures-util.workspace = true @@ -38,7 +37,6 @@ matrix-sdk-ui = { workspace = true, features = ["uniffi"] } mime = "0.3.16" once_cell.workspace = true ruma = { workspace = true, features = ["html", "unstable-unspecified", "unstable-msc3488", "compat-unset-avatar", "unstable-msc3245-v1-compat", "unstable-msc4278"] } -sentry-tracing = "0.36.0" serde.workspace = true serde_json.workspace = true thiserror.workspace = true @@ -46,7 +44,6 @@ tracing.workspace = true tracing-appender = { version = "0.2.2" } tracing-core.workspace = true tracing-subscriber = { workspace = true, features = ["env-filter"] } -uniffi = { workspace = true, features = ["tokio"] } url.workspace = true uuid = { version = "1.4.1", features = ["v4"] } zeroize.workspace = true @@ -68,10 +65,13 @@ features = [ paranoid-android = "0.2.1" [target.'cfg(target_family = "wasm")'.dependencies] +console_error_panic_hook = "0.1.7" tokio = { workspace = true, features = ["sync", "macros"] } -uniffi = { workspace = true, features = ["tokio", "wasm-unstable-single-threaded"] } +uniffi = { workspace = true, features = ["wasm-unstable-single-threaded"] } [target.'cfg(not(target_family = "wasm"))'.dependencies] +async-compat.workspace = true +sentry-tracing = "0.36.0" tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } uniffi = { workspace = true, features = ["tokio"] } @@ -108,11 +108,11 @@ workspace = true features = [ "anyhow", "e2e-encryption", - "experimental-widgets", + "experimental-widgets", "markdown", - "native-tls", # note: differ from block below + "rustls-tls", "socks", - "indexeddb", # note: differ from block below + "indexeddb", "uniffi", ] diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index cb6dac3c7ed..55a141785d1 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -6,17 +6,18 @@ use std::{ time::Duration, }; -use anyhow::{anyhow, Context as _}; +use anyhow::anyhow; use futures_util::pin_mut; +#[cfg(not(any(target_family = "wasm", feature = "js")))] +use matrix_sdk::media::MediaFileHandle as SdkMediaFileHandle; +#[cfg(not(target_family = "wasm"))] +use matrix_sdk::STATE_STORE_DATABASE_NAME; use matrix_sdk::{ authentication::oauth::{ AccountManagementActionFull, ClientId, OAuthAuthorizationData, OAuthSession, }, event_cache::EventCacheError, - media::{ - MediaFileHandle as SdkMediaFileHandle, MediaFormat, MediaRequestParameters, - MediaRetentionPolicy, MediaThumbnailSettings, - }, + media::{MediaFormat, MediaRequestParameters, MediaRetentionPolicy, MediaThumbnailSettings}, ruma::{ api::client::{ discovery::get_authorization_server_metadata::msc2965::Prompt as RumaOidcPrompt, @@ -38,7 +39,6 @@ use matrix_sdk::{ sliding_sync::Version as SdkSlidingSyncVersion, store::RoomLoadSettings as SdkRoomLoadSettings, AuthApi, AuthSession, Client as MatrixClient, SessionChange, SessionTokens, - STATE_STORE_DATABASE_NAME, }; use matrix_sdk_common::{stream::StreamExt, SendOutsideWasm, SyncOutsideWasm}; use matrix_sdk_ui::{ @@ -299,7 +299,8 @@ impl Client { let session_delegate = session_delegate.clone(); Box::new(move |client| { let session_delegate = session_delegate.clone(); - let user_id = client.user_id().context("user isn't logged in")?; + let user_id = + client.user_id().ok_or_else(|| anyhow!("user isn't logged in"))?; Ok(Self::retrieve_session(session_delegate, user_id)?) }) }, @@ -498,22 +499,35 @@ impl Client { use_cache: bool, temp_dir: Option, ) -> Result, ClientError> { - let source = (*media_source).clone(); - let mime_type: mime::Mime = mime_type.parse()?; + #[cfg(any(target_family = "wasm", feature = "js"))] + { + return Err(ClientError::Generic { + msg: "get_media_file is not supported on wasm32".to_string(), + details: None, + }); + } + #[cfg(not(any(target_family = "wasm", feature = "js")))] + { + let source = (*media_source).clone(); + let mime_type: mime::Mime = mime_type.parse()?; - let handle = self - .inner - .media() - .get_media_file( - &MediaRequestParameters { source: source.media_source, format: MediaFormat::File }, - filename, - &mime_type, - use_cache, - temp_dir, - ) - .await?; + let handle = self + .inner + .media() + .get_media_file( + &MediaRequestParameters { + source: source.media_source, + format: MediaFormat::File, + }, + filename, + &mime_type, + use_cache, + temp_dir, + ) + .await?; - Ok(Arc::new(MediaFileHandle::new(handle))) + Ok(Arc::new(MediaFileHandle::new(handle))) + } } /// Restores the client from a `Session`. @@ -735,7 +749,7 @@ impl Client { impl Client { /// Whether or not the client's homeserver supports the password login flow. - pub(crate) async fn supports_password_login(&self) -> anyhow::Result { + pub(crate) async fn supports_password_login(&self) -> Result { let login_types = self.inner.matrix_auth().get_login_types().await?; let supports_password = login_types .flows @@ -861,19 +875,23 @@ impl Client { } pub fn user_id(&self) -> Result { - let user_id = self.inner.user_id().context("No User ID found")?; + let user_id = self.inner.user_id().ok_or_else(|| anyhow!("No User ID found"))?; Ok(user_id.to_string()) } /// The server name part of the current user ID pub fn user_id_server_name(&self) -> Result { - let user_id = self.inner.user_id().context("No User ID found")?; + let user_id = self.inner.user_id().ok_or_else(|| anyhow!("No User ID found"))?; Ok(user_id.server_name().to_string()) } pub async fn display_name(&self) -> Result { - let display_name = - self.inner.account().get_display_name().await?.context("No User ID found")?; + let display_name = self + .inner + .account() + .get_display_name() + .await? + .ok_or_else(|| anyhow!("No User ID found"))?; Ok(display_name) } @@ -882,7 +900,7 @@ impl Client { .account() .set_display_name(Some(name.as_str())) .await - .context("Unable to set display name")?; + .map_err(|e| anyhow!("Unable to set display name: {}", e))?; Ok(()) } @@ -911,7 +929,7 @@ impl Client { } pub fn device_id(&self) -> Result { - let device_id = self.inner.device_id().context("No Device ID found")?; + let device_id = self.inner.device_id().ok_or_else(|| anyhow!("No Device ID found"))?; Ok(device_id.to_string()) } @@ -948,7 +966,8 @@ impl Client { data: Vec, progress_watcher: Option>, ) -> Result { - let mime_type: mime::Mime = mime_type.parse().context("Parsing mime type")?; + let mime_type: mime::Mime = + mime_type.parse().map_err(|e| anyhow!("Parsing mime type: {}", e))?; let request = self.inner.media().upload(&mime_type, data, None); if let Some(progress_watcher) = progress_watcher { @@ -1012,13 +1031,14 @@ impl Client { { return Ok(Arc::new(session_verification_controller.clone())); } - let user_id = self.inner.user_id().context("Failed retrieving current user_id")?; + let user_id = + self.inner.user_id().ok_or_else(|| anyhow!("Failed retrieving current user_id"))?; let user_identity = self .inner .encryption() .get_user_identity(user_id) .await? - .context("Failed retrieving user identity")?; + .ok_or_else(|| anyhow!("Failed retrieving user identity"))?; let session_verification_controller = SessionVerificationController::new( self.inner.encryption(), @@ -1314,13 +1334,14 @@ impl Client { room_id: String, via_servers: Vec, ) -> Result, ClientError> { - let room_id = RoomId::parse(&room_id).context("room_id is not a valid room id")?; + let room_id = RoomId::parse(&room_id) + .map_err(|e| anyhow!("room_id is not a valid room id: {}", e))?; let via_servers = via_servers .into_iter() .map(ServerName::parse) .collect::, _>>() - .context("at least one `via` server name is invalid")?; + .map_err(|e| anyhow!("at least one `via` server name is invalid: {}", e))?; // The `into()` call below doesn't work if I do `(&room_id).into()`, so I let // rustc win that one fight. @@ -1336,8 +1357,8 @@ impl Client { &self, room_alias: String, ) -> Result, ClientError> { - let room_alias = - RoomAliasId::parse(&room_alias).context("room_alias is not a valid room alias")?; + let room_alias = RoomAliasId::parse(&room_alias) + .map_err(|e| anyhow!("room_alias is not a valid room alias: {}", e))?; // The `into()` call below doesn't work if I do `(&room_id).into()`, so I let // rustc win that one fight. @@ -1432,56 +1453,62 @@ impl Client { /// - This will empty the media cache according to the current media /// retention policy. pub async fn clear_caches(&self) -> Result<(), ClientError> { - let closure = async || -> Result<_, ClientError> { - // Clean up the media cache according to the current media retention policy. - self.inner - .event_cache_store() - .lock() - .await - .map_err(EventCacheError::from)? - .clean_up_media_cache() - .await - .map_err(EventCacheError::from)?; - - // Clear all the room chunks. It's important to *not* call - // `EventCacheStore::clear_all_linked_chunks` here, because there might be live - // observers of the linked chunks, and that would cause some very bad state - // mismatch. - self.inner.event_cache().clear_all_rooms().await?; - - // Delete the state store file, if it exists. - if let Some(store_path) = &self.store_path { - debug!("Removing the state store: {}", store_path.display()); - - // The state store and the crypto store both live in the same store path, so we - // can't blindly delete the directory. - // - // Delete the state store SQLite file, as well as the write-ahead log (WAL) and - // shared-memory (SHM) files, if they exist. - - for file_name in [ - PathBuf::from(STATE_STORE_DATABASE_NAME), - PathBuf::from(format!("{STATE_STORE_DATABASE_NAME}.wal")), - PathBuf::from(format!("{STATE_STORE_DATABASE_NAME}.shm")), - ] { - let file_path = store_path.join(file_name); - if file_path.exists() { - debug!("Removing file: {}", file_path.display()); - std::fs::remove_file(&file_path).map_err(|err| ClientError::Generic { - msg: format!( - "couldn't delete the state store file {}: {err}", - file_path.display() - ), - details: None, - })?; + #[cfg(not(target_family = "wasm"))] + { + let closure = async || -> Result<_, ClientError> { + // Clean up the media cache according to the current media retention policy. + self.inner + .event_cache_store() + .lock() + .await + .map_err(EventCacheError::from)? + .clean_up_media_cache() + .await + .map_err(EventCacheError::from)?; + + // Clear all the room chunks. It's important to *not* call + // `EventCacheStore::clear_all_rooms_chunks` here, because there might be live + // observers of the linked chunks, and that would cause some very bad state + // mismatch. + self.inner.event_cache().clear_all_rooms().await?; + + // Delete the state store file, if it exists. + if let Some(store_path) = &self.store_path { + debug!("Removing the state store: {}", store_path.display()); + + // The state store and the crypto store both live in the same store path, so we + // can't blindly delete the directory. + // + // Delete the state store SQLite file, as well as the write-ahead log (WAL) and + // shared-memory (SHM) files, if they exist. + + for file_name in [ + PathBuf::from(STATE_STORE_DATABASE_NAME), + PathBuf::from(format!("{STATE_STORE_DATABASE_NAME}.wal")), + PathBuf::from(format!("{STATE_STORE_DATABASE_NAME}.shm")), + ] { + let file_path = store_path.join(file_name); + if file_path.exists() { + debug!("Removing file: {}", file_path.display()); + std::fs::remove_file(&file_path).map_err(|err| { + ClientError::Generic { + msg: format!( + "couldn't delete the state store file {}: {err}", + file_path.display() + ), + details: None, + } + })?; + } } } - } - Ok(()) - }; + Ok(()) + }; - closure().await + return closure().await; + } + Ok(()) } /// Checks if the server supports the report room API. @@ -1710,7 +1737,7 @@ impl Client { } fn session_inner(client: matrix_sdk::Client) -> Result { - let auth_api = client.auth_api().context("Missing authentication API")?; + let auth_api = client.auth_api().ok_or_else(|| anyhow!("Missing authentication API"))?; let homeserver_url = client.homeserver().into(); let sliding_sync_version = client.sliding_sync_version(); @@ -2028,7 +2055,7 @@ impl Session { let matrix_sdk::authentication::matrix::MatrixSession { meta: matrix_sdk::SessionMeta { user_id, device_id }, tokens: matrix_sdk::SessionTokens { access_token, refresh_token }, - } = a.session().context("Missing session")?; + } = a.session().ok_or_else(|| anyhow!("Missing session"))?; Ok(Session { access_token, @@ -2045,8 +2072,9 @@ impl Session { let matrix_sdk::authentication::oauth::UserSession { meta: matrix_sdk::SessionMeta { user_id, device_id }, tokens: matrix_sdk::SessionTokens { access_token, refresh_token }, - } = api.user_session().context("Missing session")?; - let client_id = api.client_id().context("OIDC client ID is missing.")?.clone(); + } = api.user_session().ok_or_else(|| anyhow!("Missing session"))?; + let client_id = + api.client_id().ok_or_else(|| anyhow!("OIDC client ID is missing."))?.clone(); let oidc_data = OidcSessionData { client_id }; let oidc_data = serde_json::to_string(&oidc_data).ok(); @@ -2155,10 +2183,12 @@ fn gen_transaction_id() -> String { /// is dropped, the file will be removed from the disk. #[derive(uniffi::Object)] pub struct MediaFileHandle { + #[cfg(not(any(target_family = "wasm", feature = "js")))] inner: RwLock>, } impl MediaFileHandle { + #[cfg(not(any(target_family = "wasm", feature = "js")))] fn new(handle: SdkMediaFileHandle) -> Self { Self { inner: RwLock::new(Some(handle)) } } @@ -2168,33 +2198,47 @@ impl MediaFileHandle { impl MediaFileHandle { /// Get the media file's path. pub fn path(&self) -> Result { - Ok(self + #[cfg(not(any(target_family = "wasm", feature = "js")))] + return Ok(self .inner .read() .unwrap() .as_ref() - .context("MediaFileHandle must not be used after calling persist")? + .ok_or_else(|| anyhow!("MediaFileHandle must not be used after calling persist"))? .path() .to_str() .unwrap() - .to_owned()) + .to_owned()); + #[cfg(any(target_family = "wasm", feature = "js"))] + return Err(ClientError::Generic { + msg: "MediaFileHandle is not supported on wasm".to_string(), + details: None, + }); } pub fn persist(&self, path: String) -> Result { - let mut guard = self.inner.write().unwrap(); - Ok( - match guard - .take() - .context("MediaFileHandle was already persisted")? - .persist(path.as_ref()) - { - Ok(_) => true, - Err(e) => { - *guard = Some(e.file); - false - } - }, - ) + #[cfg(not(any(target_family = "wasm", feature = "js")))] + { + let mut guard = self.inner.write().unwrap(); + return Ok( + match guard + .take() + .ok_or_else(|| anyhow!("MediaFileHandle was already persisted"))? + .persist(path.as_ref()) + { + Ok(_) => true, + Err(e) => { + *guard = Some(e.file); + false + } + }, + ); + } + #[cfg(any(target_family = "wasm", feature = "js"))] + return Err(ClientError::Generic { + msg: "MediaFileHandle is not supported on wasm".to_string(), + details: None, + }); } } diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 460bc2edbc6..e764ce5509c 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -9,16 +9,20 @@ use matrix_sdk::{ }, encryption::{BackupDownloadStrategy, EncryptionSettings}, event_cache::EventCacheError, - reqwest::Certificate, ruma::{ServerName, UserId}, sliding_sync::{ Error as MatrixSlidingSyncError, VersionBuilder as MatrixSlidingSyncVersionBuilder, VersionBuilderError, }, Client as MatrixClient, ClientBuildError as MatrixClientBuildError, HttpError, IdParseError, - RumaApiError, SqliteStoreConfig, + RumaApiError, SendOutsideWasm, SyncOutsideWasm, }; -use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm}; +#[cfg(not(target_family = "wasm"))] +use matrix_sdk::{ + reqwest::{Certificate, Proxy}, + SqliteStoreConfig, +}; +use matrix_sdk_common::runtime::get_runtime_handle; use ruma::api::error::{DeserializationError, FromHttpResponseError}; use tracing::{debug, error}; use zeroize::Zeroizing; @@ -577,56 +581,61 @@ impl ClientBuilder { pub async fn build(self: Arc) -> Result, ClientBuildError> { let builder = unwrap_or_clone_arc(self); let mut inner_builder = MatrixClient::builder(); + let store_path; if let Some(holder_name) = &builder.cross_process_store_locks_holder_name { inner_builder = inner_builder.cross_process_store_locks_holder_name(holder_name.clone()); } - let store_path = if let Some(session_paths) = &builder.session_paths { - // This is the path where both the state store and the crypto store will live. - let data_path = Path::new(&session_paths.data_path); - // This is the path where the event cache store will live. - let cache_path = Path::new(&session_paths.cache_path); - - debug!( - data_path = %data_path.to_string_lossy(), - event_cache_path = %cache_path.to_string_lossy(), - "Creating directories for data (state and crypto) and cache stores.", - ); - - fs::create_dir_all(data_path)?; - fs::create_dir_all(cache_path)?; + if let Some(session_paths) = &builder.session_paths { + #[cfg(target_family = "wasm")] + { + panic!("Session paths are not supported on wasm32."); + } + #[cfg(not(target_family = "wasm"))] + { + let data_path = Path::new(&session_paths.data_path); + store_path = Some(data_path.to_path_buf()); + let cache_path = Path::new(&session_paths.cache_path); + + debug!( + data_path = %data_path.to_string_lossy(), + cache_path = %cache_path.to_string_lossy(), + "Creating directories for data and cache stores.", + ); + + fs::create_dir_all(data_path)?; + fs::create_dir_all(cache_path)?; + + let mut sqlite_store_config = if builder.system_is_memory_constrained { + SqliteStoreConfig::with_low_memory_config(data_path) + } else { + SqliteStoreConfig::new(data_path) + }; - let mut sqlite_store_config = if builder.system_is_memory_constrained { - SqliteStoreConfig::with_low_memory_config(data_path) - } else { - SqliteStoreConfig::new(data_path) - }; + sqlite_store_config = + sqlite_store_config.passphrase(builder.session_passphrase.as_deref()); - sqlite_store_config = - sqlite_store_config.passphrase(builder.session_passphrase.as_deref()); + if let Some(size) = builder.session_pool_max_size { + sqlite_store_config = sqlite_store_config.pool_max_size(size); + } - if let Some(size) = builder.session_pool_max_size { - sqlite_store_config = sqlite_store_config.pool_max_size(size); - } + if let Some(size) = builder.session_cache_size { + sqlite_store_config = sqlite_store_config.cache_size(size); + } - if let Some(size) = builder.session_cache_size { - sqlite_store_config = sqlite_store_config.cache_size(size); - } + if let Some(limit) = builder.session_journal_size_limit { + sqlite_store_config = sqlite_store_config.journal_size_limit(limit); + } - if let Some(limit) = builder.session_journal_size_limit { - sqlite_store_config = sqlite_store_config.journal_size_limit(limit); + inner_builder = inner_builder + .sqlite_store_with_config_and_cache_path(sqlite_store_config, Some(cache_path)); } - - inner_builder = inner_builder - .sqlite_store_with_config_and_cache_path(sqlite_store_config, Some(cache_path)); - - Some(data_path.to_owned()) } else { debug!("Not using a store path."); - None - }; + store_path = None; + } // Determine server either from URL, server name or user ID. inner_builder = match builder.homeserver_cfg { @@ -650,48 +659,59 @@ impl ClientBuilder { } }; - let mut certificates = Vec::new(); + #[cfg(not(target_family = "wasm"))] + { + let mut certificates = Vec::new(); - for certificate in builder.additional_root_certificates { - // We don't really know what type of certificate we may get here, so let's try - // first one type, then the other. - match Certificate::from_der(&certificate) { - Ok(cert) => { - certificates.push(cert); - } - Err(der_error) => { - let cert = Certificate::from_pem(&certificate).map_err(|pem_error| { + for certificate in builder.additional_root_certificates { + // We don't really know what type of certificate we may get here, so let's try + // first one type, then the other. + match Certificate::from_der(&certificate) { + Ok(cert) => { + certificates.push(cert); + } + Err(der_error) => { + let cert = Certificate::from_pem(&certificate).map_err(|pem_error| { ClientBuildError::Generic { message: format!("Failed to add a root certificate as DER ({der_error:?}) or PEM ({pem_error:?})"), } })?; - certificates.push(cert); + certificates.push(cert); + } } } - } - inner_builder = inner_builder.add_root_certificates(certificates); - - if builder.disable_built_in_root_certificates { - inner_builder = inner_builder.disable_built_in_root_certificates(); - } - - if let Some(proxy) = builder.proxy { - inner_builder = inner_builder.proxy(proxy); - } + inner_builder = inner_builder.add_root_certificates(certificates); + if builder.disable_built_in_root_certificates { + inner_builder = inner_builder.disable_built_in_root_certificates(); + } + if let Some(proxy) = builder.proxy { + let Ok(proxy) = Proxy::all(proxy) else { + return Err(ClientBuildError::Generic { + message: "Proxy configuration is invalid.".to_owned(), + }); + }; + let Ok(http_client) = matrix_sdk::reqwest::Client::builder().proxy(proxy).build() + else { + return Err(ClientBuildError::Generic { + message: "Http client for proxy is invalid.".to_owned(), + }); + }; + inner_builder = inner_builder.http_client(http_client); + } + if builder.disable_ssl_verification { + inner_builder = inner_builder.disable_ssl_verification(); + } - if builder.disable_ssl_verification { - inner_builder = inner_builder.disable_ssl_verification(); + if let Some(user_agent) = builder.user_agent { + inner_builder = inner_builder.user_agent(user_agent); + } } if !builder.disable_automatic_token_refresh { inner_builder = inner_builder.handle_refresh_tokens(); } - if let Some(user_agent) = builder.user_agent { - inner_builder = inner_builder.user_agent(user_agent); - } - inner_builder = inner_builder .with_encryption_settings(builder.encryption_settings) .with_room_key_recipient_strategy(builder.room_key_recipient_strategy) diff --git a/bindings/matrix-sdk-ffi/src/platform.rs b/bindings/matrix-sdk-ffi/src/platform.rs index bf36b0c2491..f2759589734 100644 --- a/bindings/matrix-sdk-ffi/src/platform.rs +++ b/bindings/matrix-sdk-ffi/src/platform.rs @@ -340,6 +340,7 @@ impl TraceLogPacks { } } +#[cfg(not(target_family = "wasm"))] struct SentryLoggingCtx { /// The Sentry client guard, which keeps the Sentry context alive. _guard: sentry::ClientInitGuard, @@ -349,6 +350,7 @@ struct SentryLoggingCtx { } struct LoggingCtx { + #[cfg(not(target_family = "wasm"))] sentry: Option, } @@ -390,6 +392,7 @@ impl TracingConfiguration { log_panics::init(); // Prepare the Sentry layer, if a DSN is provided. + #[cfg(not(target_family = "wasm"))] let (sentry_layer, sentry_logging_ctx) = if let Some(sentry_dsn) = self.sentry_dsn.take() { // Initialize the Sentry client with the given options. let sentry_guard = sentry::init(( @@ -446,16 +449,21 @@ impl TracingConfiguration { let env_filter = build_tracing_filter(&self); - tracing_subscriber::registry() + let registry = tracing_subscriber::registry() .with(tracing_subscriber::EnvFilter::new(&env_filter)) - .with(crate::platform::text_layers(self)) - .with(sentry_layer) - .init(); + .with(crate::platform::text_layers(self)); + #[cfg(not(target_family = "wasm"))] + registry.with(sentry_layer).init(); + #[cfg(target_family = "wasm")] + registry.init(); // Log the log levels 🧠. tracing::info!(env_filter, "Logging has been set up"); - LoggingCtx { sentry: sentry_logging_ctx } + #[cfg(not(target_family = "wasm"))] + return LoggingCtx { sentry: sentry_logging_ctx }; + #[cfg(target_family = "wasm")] + LoggingCtx {} } } @@ -505,15 +513,22 @@ pub fn init_platform( config: TracingConfiguration, use_lightweight_tokio_runtime: bool, ) -> Result<(), ClientError> { - LOGGING.set(config.build()).map_err(|_| ClientError::Generic { - msg: "logger already initialized".to_owned(), - details: None, - })?; + #[cfg(target_family = "wasm")] + { + console_error_panic_hook::set_once(); + } - if use_lightweight_tokio_runtime { - setup_lightweight_tokio_runtime(); - } else { - setup_multithreaded_tokio_runtime(); + #[cfg(not(target_family = "wasm"))] + { + LOGGING.set(config.build()).map_err(|_| ClientError::Generic { + msg: "logger already initialized".to_owned(), + details: None, + })?; + if use_lightweight_tokio_runtime { + setup_lightweight_tokio_runtime(); + } else { + setup_multithreaded_tokio_runtime(); + } } Ok(()) @@ -524,6 +539,7 @@ pub fn init_platform( #[matrix_sdk_ffi_macros::export] pub fn enable_sentry_logging(enabled: bool) { if let Some(ctx) = LOGGING.get() { + #[cfg(not(target_family = "wasm"))] if let Some(sentry_ctx) = &ctx.sentry { sentry_ctx.enabled.store(enabled, std::sync::atomic::Ordering::SeqCst); } else { @@ -535,6 +551,7 @@ pub fn enable_sentry_logging(enabled: bool) { }; } +#[cfg(not(target_family = "wasm"))] fn setup_multithreaded_tokio_runtime() { async_compat::set_runtime_builder(Box::new(|| { eprintln!("spawning a multithreaded tokio runtime"); @@ -545,6 +562,7 @@ fn setup_multithreaded_tokio_runtime() { })); } +#[cfg(not(target_family = "wasm"))] fn setup_lightweight_tokio_runtime() { async_compat::set_runtime_builder(Box::new(|| { eprintln!("spawning a lightweight tokio runtime"); diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index d84e10efa88..7ad42e15e55 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -378,7 +378,7 @@ impl Timeline { Ok(handle) => Ok(Arc::new(SendHandle::new(handle))), Err(err) => { error!("error when sending a message: {err}"); - Err(anyhow::anyhow!(err).into()) + Err(err.into()) } } } @@ -531,10 +531,7 @@ impl Timeline { msg: Arc, reply_params: ReplyParameters, ) -> Result<(), ClientError> { - self.inner - .send_reply((*msg).clone(), reply_params.try_into()?) - .await - .map_err(|err| anyhow::anyhow!(err))?; + self.inner.send_reply((*msg).clone(), reply_params.try_into()?).await?; Ok(()) } @@ -634,7 +631,10 @@ impl Timeline { pub async fn fetch_details_for_event(&self, event_id: String) -> Result<(), ClientError> { let event_id = <&EventId>::try_from(event_id.as_str())?; - self.inner.fetch_details_for_event(event_id).await.context("Fetching event details")?; + self.inner + .fetch_details_for_event(event_id) + .await + .map_err(|_| ClientError::from_str("Fetching event details".to_string(), None))?; Ok(()) } @@ -1233,7 +1233,10 @@ impl SendAttachmentJoinHandle { return Ok(()); } error!("task panicked! resuming panic from here."); + #[cfg(not(target_family = "wasm"))] panic::resume_unwind(err.into_panic()); + #[cfg(target_family = "wasm")] + panic!("task panicked! {err}"); } } } diff --git a/crates/matrix-sdk-base/src/room/mod.rs b/crates/matrix-sdk-base/src/room/mod.rs index 2c49e9f75c2..5cb3c232a65 100644 --- a/crates/matrix-sdk-base/src/room/mod.rs +++ b/crates/matrix-sdk-base/src/room/mod.rs @@ -41,8 +41,6 @@ use eyeball::{AsyncLock, SharedObservable}; use futures_util::{Stream, StreamExt}; #[cfg(feature = "e2e-encryption")] use matrix_sdk_common::ring_buffer::RingBuffer; -#[cfg(feature = "test-send-sync")] -use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm}; pub use members::{RoomMember, RoomMembersUpdate, RoomMemberships}; pub(crate) use room_info::SyncInfo; pub use room_info::{ diff --git a/crates/matrix-sdk-common/Cargo.toml b/crates/matrix-sdk-common/Cargo.toml index f5a3e7a7ae1..6c424fd4cf6 100644 --- a/crates/matrix-sdk-common/Cargo.toml +++ b/crates/matrix-sdk-common/Cargo.toml @@ -38,7 +38,6 @@ uniffi = { workspace = true, optional = true } [target.'cfg(not(target_family = "wasm"))'.dependencies] # Enable the test macro. -async-compat.workspace = true tokio = { workspace = true, features = ["rt", "time", "macros"] } [target.'cfg(target_family = "wasm")'.dependencies] diff --git a/crates/matrix-sdk-common/src/deserialized_responses.rs b/crates/matrix-sdk-common/src/deserialized_responses.rs index 0f22fa713b0..ea72259b9bc 100644 --- a/crates/matrix-sdk-common/src/deserialized_responses.rs +++ b/crates/matrix-sdk-common/src/deserialized_responses.rs @@ -34,8 +34,6 @@ use crate::{ debug::{DebugRawEvent, DebugStructExt}, serde_helpers::extract_bundled_thread_summary, }; -#[cfg(feature = "test-send-sync")] -use crate::{SendOutsideWasm, SyncOutsideWasm}; const AUTHENTICITY_NOT_GUARANTEED: &str = "The authenticity of this encrypted message can't be guaranteed on this device."; diff --git a/crates/matrix-sdk-common/src/stream.rs b/crates/matrix-sdk-common/src/stream.rs index 3427e9ee917..4eefe41dd5d 100644 --- a/crates/matrix-sdk-common/src/stream.rs +++ b/crates/matrix-sdk-common/src/stream.rs @@ -18,6 +18,7 @@ //! with boxed streams across different platforms. On native platforms, //! streams can be `Send`, but on Wasm they cannot. This module abstracts //! over that difference. + #[cfg(not(target_family = "wasm"))] mod sys { // On native platforms, just re-export everything from futures_util diff --git a/crates/matrix-sdk/src/sliding_sync/list/builder.rs b/crates/matrix-sdk/src/sliding_sync/list/builder.rs index a07c2822a9d..93a202ef38f 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/builder.rs @@ -111,15 +111,6 @@ impl SlidingSyncListBuilder { self } - #[cfg(target_family = "wasm")] - pub fn once_built(mut self, callback: C) -> Self - where - C: Fn(SlidingSyncList) -> SlidingSyncList + 'static, - { - self.once_built = Arc::new(Box::new(callback)); - self - } - /// Which SlidingSyncMode to start this list under. pub fn sync_mode(mut self, value: impl Into) -> Self { self.sync_mode = value.into(); diff --git a/xtask/src/swift.rs b/xtask/src/swift.rs index f712fb46e6f..4ec22bafce9 100644 --- a/xtask/src/swift.rs +++ b/xtask/src/swift.rs @@ -169,7 +169,7 @@ fn build_library() -> Result<()> { } fn generate_uniffi(library_path: &Utf8Path, ffi_directory: &Utf8Path) -> Result<()> { - let manifest_path = std::env::current_dir()?.join("Cargo.toml"); + let manifest_path = std::env::current_dir()?.join("Cargo.toml"); println!("manifest path {:?}", manifest_path); // Get metadata using cargo_metadata From fc703a5dc640fd75ec0da95a5b9dc7e8799174d7 Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Thu, 5 Jun 2025 12:31:19 -0400 Subject: [PATCH 6/8] Eliminate some unnecessary .context removals --- bindings/matrix-sdk-ffi/src/client.rs | 49 +++++++++++---------------- 1 file changed, 20 insertions(+), 29 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 55a141785d1..2dabe08871c 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -6,7 +6,7 @@ use std::{ time::Duration, }; -use anyhow::anyhow; +use anyhow::{anyhow, Context}; use futures_util::pin_mut; #[cfg(not(any(target_family = "wasm", feature = "js")))] use matrix_sdk::media::MediaFileHandle as SdkMediaFileHandle; @@ -299,8 +299,7 @@ impl Client { let session_delegate = session_delegate.clone(); Box::new(move |client| { let session_delegate = session_delegate.clone(); - let user_id = - client.user_id().ok_or_else(|| anyhow!("user isn't logged in"))?; + let user_id = client.user_id().context("user isn't logged in")?; Ok(Self::retrieve_session(session_delegate, user_id)?) }) }, @@ -875,23 +874,19 @@ impl Client { } pub fn user_id(&self) -> Result { - let user_id = self.inner.user_id().ok_or_else(|| anyhow!("No User ID found"))?; + let user_id = self.inner.user_id().context("No User ID found")?; Ok(user_id.to_string()) } /// The server name part of the current user ID pub fn user_id_server_name(&self) -> Result { - let user_id = self.inner.user_id().ok_or_else(|| anyhow!("No User ID found"))?; + let user_id = self.inner.user_id().context("No User ID found")?; Ok(user_id.server_name().to_string()) } pub async fn display_name(&self) -> Result { - let display_name = self - .inner - .account() - .get_display_name() - .await? - .ok_or_else(|| anyhow!("No User ID found"))?; + let display_name = + self.inner.account().get_display_name().await?.context("No User ID found")?; Ok(display_name) } @@ -929,7 +924,7 @@ impl Client { } pub fn device_id(&self) -> Result { - let device_id = self.inner.device_id().ok_or_else(|| anyhow!("No Device ID found"))?; + let device_id = self.inner.device_id().context("No Device ID found")?; Ok(device_id.to_string()) } @@ -966,8 +961,7 @@ impl Client { data: Vec, progress_watcher: Option>, ) -> Result { - let mime_type: mime::Mime = - mime_type.parse().map_err(|e| anyhow!("Parsing mime type: {}", e))?; + let mime_type: mime::Mime = mime_type.parse().context("Parsing mime type")?; let request = self.inner.media().upload(&mime_type, data, None); if let Some(progress_watcher) = progress_watcher { @@ -1031,14 +1025,13 @@ impl Client { { return Ok(Arc::new(session_verification_controller.clone())); } - let user_id = - self.inner.user_id().ok_or_else(|| anyhow!("Failed retrieving current user_id"))?; + let user_id = self.inner.user_id().context("Failed retrieving current user_id")?; let user_identity = self .inner .encryption() .get_user_identity(user_id) .await? - .ok_or_else(|| anyhow!("Failed retrieving user identity"))?; + .context("Failed retrieving user identity")?; let session_verification_controller = SessionVerificationController::new( self.inner.encryption(), @@ -1334,14 +1327,13 @@ impl Client { room_id: String, via_servers: Vec, ) -> Result, ClientError> { - let room_id = RoomId::parse(&room_id) - .map_err(|e| anyhow!("room_id is not a valid room id: {}", e))?; + let room_id = RoomId::parse(&room_id).context("room_id is not a valid room id")?; let via_servers = via_servers .into_iter() .map(ServerName::parse) .collect::, _>>() - .map_err(|e| anyhow!("at least one `via` server name is invalid: {}", e))?; + .context("at least one `via` server name is invalid")?; // The `into()` call below doesn't work if I do `(&room_id).into()`, so I let // rustc win that one fight. @@ -1357,8 +1349,8 @@ impl Client { &self, room_alias: String, ) -> Result, ClientError> { - let room_alias = RoomAliasId::parse(&room_alias) - .map_err(|e| anyhow!("room_alias is not a valid room alias: {}", e))?; + let room_alias = + RoomAliasId::parse(&room_alias).context("room_alias is not a valid room alias")?; // The `into()` call below doesn't work if I do `(&room_id).into()`, so I let // rustc win that one fight. @@ -1737,7 +1729,7 @@ impl Client { } fn session_inner(client: matrix_sdk::Client) -> Result { - let auth_api = client.auth_api().ok_or_else(|| anyhow!("Missing authentication API"))?; + let auth_api = client.auth_api().context("Missing authentication API")?; let homeserver_url = client.homeserver().into(); let sliding_sync_version = client.sliding_sync_version(); @@ -2055,7 +2047,7 @@ impl Session { let matrix_sdk::authentication::matrix::MatrixSession { meta: matrix_sdk::SessionMeta { user_id, device_id }, tokens: matrix_sdk::SessionTokens { access_token, refresh_token }, - } = a.session().ok_or_else(|| anyhow!("Missing session"))?; + } = a.session().context("Missing session")?; Ok(Session { access_token, @@ -2072,9 +2064,8 @@ impl Session { let matrix_sdk::authentication::oauth::UserSession { meta: matrix_sdk::SessionMeta { user_id, device_id }, tokens: matrix_sdk::SessionTokens { access_token, refresh_token }, - } = api.user_session().ok_or_else(|| anyhow!("Missing session"))?; - let client_id = - api.client_id().ok_or_else(|| anyhow!("OIDC client ID is missing."))?.clone(); + } = api.user_session().context("Missing session")?; + let client_id = api.client_id().context("OIDC client ID is missing.")?.clone(); let oidc_data = OidcSessionData { client_id }; let oidc_data = serde_json::to_string(&oidc_data).ok(); @@ -2204,7 +2195,7 @@ impl MediaFileHandle { .read() .unwrap() .as_ref() - .ok_or_else(|| anyhow!("MediaFileHandle must not be used after calling persist"))? + .context("MediaFileHandle must not be used after calling persist")? .path() .to_str() .unwrap() @@ -2223,7 +2214,7 @@ impl MediaFileHandle { return Ok( match guard .take() - .ok_or_else(|| anyhow!("MediaFileHandle was already persisted"))? + .context("MediaFileHandle was already persisted")? .persist(path.as_ref()) { Ok(_) => true, From 21bd892696bde8a5d2a4790b4f65fc487f4e56e4 Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Fri, 6 Jun 2025 11:29:46 -0400 Subject: [PATCH 7/8] Update wasm to use native-tls --- bindings/matrix-sdk-ffi/Cargo.toml | 2 +- crates/matrix-sdk/Cargo.toml | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index 2e5c0ba2954..4600f46fcc6 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -110,7 +110,7 @@ features = [ "e2e-encryption", "experimental-widgets", "markdown", - "rustls-tls", + "native-tls", "socks", "indexeddb", "uniffi", diff --git a/crates/matrix-sdk/Cargo.toml b/crates/matrix-sdk/Cargo.toml index c30927e1784..64af82c696b 100644 --- a/crates/matrix-sdk/Cargo.toml +++ b/crates/matrix-sdk/Cargo.toml @@ -41,7 +41,10 @@ sqlite = [ "matrix-sdk-sqlite?/event-cache", ] bundled-sqlite = ["sqlite", "matrix-sdk-sqlite?/bundled"] -indexeddb = ["matrix-sdk-indexeddb/state-store"] +indexeddb = [ + "dep:matrix-sdk-indexeddb", + "matrix-sdk-indexeddb/state-store" +] qrcode = ["e2e-encryption", "matrix-sdk-base/qrcode"] automatic-room-key-forwarding = ["e2e-encryption", "matrix-sdk-base/automatic-room-key-forwarding"] From 3fa7eb203a938941b6558d509ea6f1fcae39eb86 Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Mon, 16 Jun 2025 08:51:46 -0400 Subject: [PATCH 8/8] Remove sdk-base --- Cargo.lock | 1 - bindings/matrix-sdk-ffi/Cargo.toml | 1 - 2 files changed, 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e7a97156bf3..41eb8fd4d7b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3103,7 +3103,6 @@ dependencies = [ "language-tags", "log-panics", "matrix-sdk", - "matrix-sdk-base", "matrix-sdk-common", "matrix-sdk-ffi-macros", "matrix-sdk-ui", diff --git a/bindings/matrix-sdk-ffi/Cargo.toml b/bindings/matrix-sdk-ffi/Cargo.toml index 4600f46fcc6..4755644b540 100644 --- a/bindings/matrix-sdk-ffi/Cargo.toml +++ b/bindings/matrix-sdk-ffi/Cargo.toml @@ -30,7 +30,6 @@ eyeball-im.workspace = true futures-util.workspace = true language-tags = "0.3.2" log-panics = { version = "2", features = ["with-backtrace"] } -matrix-sdk-base.workspace = true matrix-sdk-common.workspace = true matrix-sdk-ffi-macros.workspace = true matrix-sdk-ui = { workspace = true, features = ["uniffi"] }