mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-18 13:40:55 -04:00
Merge branch 'main' into ganfra/kotlin_bindings
This commit is contained in:
107
.github/workflows/bindings_ci.yml
vendored
107
.github/workflows/bindings_ci.yml
vendored
@@ -16,8 +16,73 @@ env:
|
||||
CARGO_TERM_COLOR: always
|
||||
MATRIX_SDK_CRYPTO_NODEJS_PATH: bindings/matrix-sdk-crypto-nodejs
|
||||
MATRIX_SDK_CRYPTO_JS_PATH: bindings/matrix-sdk-crypto-js
|
||||
# keep in sync with uniffi dependency in root Cargo.toml
|
||||
UNIFFI_REV: 6ee61a46f59736f93b912f3cf45481f005c63115
|
||||
|
||||
jobs:
|
||||
xtask-linux:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Check xtask cache
|
||||
uses: actions/cache@v3
|
||||
id: xtask-cache
|
||||
with:
|
||||
path: target/debug/xtask
|
||||
key: xtask-linux-${{ hashFiles('Cargo.toml', 'xtask/**') }}
|
||||
|
||||
- name: Install rust stable toolchain
|
||||
if: steps.xtask-cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Build
|
||||
if: steps.xtask-cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: -p xtask
|
||||
|
||||
test-uniffi-codegen:
|
||||
name: Test UniFFI bindings generation
|
||||
needs: xtask-linux
|
||||
if: github.event_name == 'push' || !github.event.pull_request.draft
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Rust
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
toolchain: nightly
|
||||
profile: minimal
|
||||
override: true
|
||||
|
||||
- name: Load cache
|
||||
uses: Swatinem/rust-cache@v1
|
||||
|
||||
- name: Get xtask
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: target/debug/xtask
|
||||
key: xtask-linux-${{ hashFiles('Cargo.toml', 'xtask/**') }}
|
||||
|
||||
- name: Install Uniffi
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev ${{ env.UNIFFI_REV }}
|
||||
|
||||
- name: Build library & generate bindings
|
||||
run: target/debug/xtask ci bindings
|
||||
|
||||
test-matrix-sdk-crypto-nodejs:
|
||||
name: ${{ matrix.os-name }} [m]-crypto-nodejs, v${{ matrix.node-version }}
|
||||
if: github.event_name == 'push' || !github.event.pull_request.draft
|
||||
@@ -27,7 +92,7 @@ jobs:
|
||||
fail-fast: true
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
node-version: [14.0, 16.0, 18.0]
|
||||
node-version: [14.0, 16.0, 18.0, 19.0]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
os-name: 🐧
|
||||
@@ -133,8 +198,37 @@ jobs:
|
||||
working-directory: ${{ env.MATRIX_SDK_CRYPTO_JS_PATH }}
|
||||
run: npm run doc
|
||||
|
||||
xtask-macos:
|
||||
runs-on: macos-12
|
||||
steps:
|
||||
- name: Checkout repo
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Check xtask cache
|
||||
uses: actions/cache@v3
|
||||
id: xtask-cache
|
||||
with:
|
||||
path: target/debug/xtask
|
||||
key: xtask-macos-${{ hashFiles('Cargo.toml', 'xtask/**') }}
|
||||
|
||||
- name: Install rust stable toolchain
|
||||
if: steps.xtask-cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/toolchain@v1
|
||||
with:
|
||||
profile: minimal
|
||||
toolchain: stable
|
||||
override: true
|
||||
|
||||
- name: Build
|
||||
if: steps.xtask-cache.outputs.cache-hit != 'true'
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: build
|
||||
args: -p xtask
|
||||
|
||||
test-apple:
|
||||
name: matrix-rust-components-swift
|
||||
needs: xtask-macos
|
||||
runs-on: macos-12
|
||||
if: github.event_name == 'push' || !github.event.pull_request.draft
|
||||
|
||||
@@ -152,15 +246,20 @@ jobs:
|
||||
- name: Load cache
|
||||
uses: Swatinem/rust-cache@v1
|
||||
|
||||
- name: Get xtask
|
||||
uses: actions/cache@v3
|
||||
with:
|
||||
path: target/debug/xtask
|
||||
key: xtask-macos-${{ hashFiles('Cargo.toml', 'xtask/**') }}
|
||||
|
||||
- name: Install Uniffi
|
||||
uses: actions-rs/cargo@v1
|
||||
with:
|
||||
command: install
|
||||
# keep in sync with uniffi dependency in root Cargo.toml
|
||||
args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev fdb769b567865d9c5c7c682a18d0c1301a039c85
|
||||
args: uniffi_bindgen --git https://github.com/mozilla/uniffi-rs --rev ${{ env.UNIFFI_REV }}
|
||||
|
||||
- name: Build library & bindings
|
||||
run: cargo xtask swift build-library
|
||||
run: target/debug/xtask swift build-library
|
||||
|
||||
- name: Run XCTests
|
||||
working-directory: bindings/apple
|
||||
|
||||
101
Cargo.lock
generated
101
Cargo.lock
generated
@@ -528,15 +528,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cargo_metadata"
|
||||
version = "0.14.2"
|
||||
version = "0.15.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa"
|
||||
checksum = "406c859255d568f4f742b3146d51851f3bfd49f734a2c289d9107c4395ee0062"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"cargo-platform",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -677,13 +678,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.16"
|
||||
version = "4.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ef582e2c00a63a0c0aa1fb4a4870781c4f5729f51196d3537fa7c1c1992eaa3"
|
||||
checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive 4.0.13",
|
||||
"clap_derive 4.0.18",
|
||||
"clap_lex 0.3.0",
|
||||
"once_cell",
|
||||
"strsim 0.10.0",
|
||||
@@ -705,9 +706,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.0.13"
|
||||
version = "4.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c42f169caba89a7d512b5418b09864543eeb4d497416c917d7137863bd2076ad"
|
||||
checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3"
|
||||
dependencies = [
|
||||
"heck 0.4.0",
|
||||
"proc-macro-error",
|
||||
@@ -1441,7 +1442,7 @@ name = "example-emoji-verification"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.16",
|
||||
"clap 4.0.18",
|
||||
"futures",
|
||||
"matrix-sdk",
|
||||
"tokio",
|
||||
@@ -1499,7 +1500,7 @@ name = "example-timeline"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.16",
|
||||
"clap 4.0.18",
|
||||
"futures",
|
||||
"futures-signals",
|
||||
"matrix-sdk",
|
||||
@@ -1825,6 +1826,19 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "gloo-utils"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40913a05c8297adca04392f707b1e73b12ba7b8eab7244a4961580b1fd34063c"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "goblin"
|
||||
version = "0.5.4"
|
||||
@@ -2283,9 +2297,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.59"
|
||||
version = "0.3.60"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "258451ab10b34f8af53416d1fdab72c22e805f0c92a1136d59470ec0b11138b2"
|
||||
checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47"
|
||||
dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
@@ -2440,7 +2454,7 @@ checksum = "73cbba799671b762df5a175adf59ce145165747bb891505c43d09aefbbf38beb"
|
||||
|
||||
[[package]]
|
||||
name = "matrix-sdk"
|
||||
version = "0.6.0"
|
||||
version = "0.6.2"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"anymap2",
|
||||
@@ -2519,7 +2533,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "matrix-sdk-base"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"async-stream",
|
||||
@@ -2711,6 +2725,7 @@ dependencies = [
|
||||
"dashmap",
|
||||
"derive_builder",
|
||||
"getrandom 0.2.7",
|
||||
"gloo-utils",
|
||||
"indexed_db_futures 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"indexed_db_futures 0.2.3 (git+https://github.com/Hywan/rust-indexed-db?branch=feat-factory-nodejs)",
|
||||
"js-sys",
|
||||
@@ -3861,9 +3876,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-client-api"
|
||||
version = "0.15.1"
|
||||
version = "0.15.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5bcfd3a3853ffdd151fc228441dd9c9e3d835ac85560dface7abda50b3888791"
|
||||
checksum = "d1e72bc731b4dc8b569aa83915f13e419144b67110d858c65bb74aa05e2dc4b7"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"bytes",
|
||||
@@ -3878,9 +3893,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-common"
|
||||
version = "0.10.3"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1e629a01f359234798531a99ba83997abd4c15a65b5bcb8354c4171b59c25be"
|
||||
checksum = "716889595f4edc3cfeb94d9f122e413f73e37d7d80ea1c14196e1004241a3889"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
@@ -3931,9 +3946,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruma-macros"
|
||||
version = "0.10.3"
|
||||
version = "0.10.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7cd8cf8771aaca36042fb7659f4647b05e74a2058d843474dde5e51a56cd85"
|
||||
checksum = "0f82e91eb61cd86d9287303133ee55b54618eccb75a522cc22a42c15f5bda340"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro-crate",
|
||||
@@ -4998,7 +5013,7 @@ checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04"
|
||||
[[package]]
|
||||
name = "uniffi"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bytes",
|
||||
@@ -5014,7 +5029,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"askama",
|
||||
@@ -5036,7 +5051,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "uniffi_build"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"camino",
|
||||
@@ -5046,7 +5061,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "uniffi_macros"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"camino",
|
||||
@@ -5064,7 +5079,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "uniffi_meta"
|
||||
version = "0.21.0"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -5223,21 +5238,19 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.82"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7652e3f6c4706c8d9cd54832c4a4ccb9b5336e2c3bd154d5cccfbf1c1f5f7d"
|
||||
checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-backend"
|
||||
version = "0.2.82"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "662cd44805586bd52971b9586b1df85cdbbd9112e4ef4d8f41559c334dc6ac3f"
|
||||
checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"log",
|
||||
@@ -5250,9 +5263,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.32"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa76fb221a1f8acddf5b54ace85912606980ad661ac7a503b4570ffd3a624dad"
|
||||
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
@@ -5262,9 +5275,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.82"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b260f13d3012071dfb1512849c033b1925038373aea48ced3012c09df952c602"
|
||||
checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"wasm-bindgen-macro-support",
|
||||
@@ -5272,9 +5285,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro-support"
|
||||
version = "0.2.82"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5be8e654bdd9b79216c2929ab90721aa82faf65c48cdf08bdc4e7f51357b80da"
|
||||
checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5285,15 +5298,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-shared"
|
||||
version = "0.2.82"
|
||||
version = "0.2.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6598dd0bd3c7d51095ff6531a5b23e02acdc81804e30d8f07afb77b7215a140a"
|
||||
checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f"
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "513df541345bb9fcc07417775f3d51bbb677daf307d8035c0afafd87dc2e6599"
|
||||
checksum = "09d2fff962180c3fadf677438054b1db62bee4aa32af26a45388af07d1287e1d"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"js-sys",
|
||||
@@ -5305,9 +5318,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-test-macro"
|
||||
version = "0.3.32"
|
||||
version = "0.3.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6150d36a03e90a3cf6c12650be10626a9902d70c5270fd47d7a47e5389a10d56"
|
||||
checksum = "4683da3dfc016f704c9f82cf401520c4f1cb3ee440f7f52b3d6ac29506a49ca7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -5373,7 +5386,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "weedle2"
|
||||
version = "4.0.0"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=fdb769b567865d9c5c7c682a18d0c1301a039c85#fdb769b567865d9c5c7c682a18d0c1301a039c85"
|
||||
source = "git+https://github.com/mozilla/uniffi-rs?rev=6ee61a46f59736f93b912f3cf45481f005c63115#6ee61a46f59736f93b912f3cf45481f005c63115"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
@@ -5536,7 +5549,7 @@ name = "xtask"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"camino",
|
||||
"clap 3.2.22",
|
||||
"clap 4.0.18",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"uniffi_bindgen",
|
||||
|
||||
@@ -18,10 +18,10 @@ resolver = "2"
|
||||
[workspace.dependencies]
|
||||
ruma = { version = "0.7.4", features = ["client-api-c"] }
|
||||
tracing = { version = "0.1.36", default-features = false, features = ["std"] }
|
||||
uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85" }
|
||||
uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85" }
|
||||
uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85" }
|
||||
uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "fdb769b567865d9c5c7c682a18d0c1301a039c85", features = ["builtin-bindgen"] }
|
||||
uniffi = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115" }
|
||||
uniffi_macros = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115" }
|
||||
uniffi_bindgen = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115" }
|
||||
uniffi_build = { git = "https://github.com/mozilla/uniffi-rs", rev = "6ee61a46f59736f93b912f3cf45481f005c63115", features = ["builtin-bindgen"] }
|
||||
vodozemac = "0.3.0"
|
||||
zeroize = "1.3.0"
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
Pod::Spec.new do |s|
|
||||
|
||||
s.name = "MatrixSDKCrypto"
|
||||
s.version = "0.1.2"
|
||||
s.version = "0.1.5"
|
||||
s.summary = "Uniffi based bindings for the Rust SDK crypto crate."
|
||||
s.homepage = "https://github.com/matrix-org/matrix-rust-sdk"
|
||||
s.license = { :type => "Apache License, Version 2.0", :file => "LICENSE" }
|
||||
|
||||
@@ -28,6 +28,7 @@ pub use error::{
|
||||
use js_int::UInt;
|
||||
pub use logger::{set_logger, Logger};
|
||||
pub use machine::{KeyRequestPair, OlmMachine};
|
||||
use matrix_sdk_common::deserialized_responses::VerificationState;
|
||||
use matrix_sdk_crypto::{
|
||||
types::{EventEncryptionAlgorithm as RustEventEncryptionAlgorithm, SigningKey},
|
||||
EncryptionSettings as RustEncryptionSettings, LocalTrust,
|
||||
@@ -458,6 +459,10 @@ pub struct DecryptedEvent {
|
||||
/// key to us. Is empty if the key came directly from the sender of the
|
||||
/// event.
|
||||
pub forwarding_curve25519_chain: Vec<String>,
|
||||
/// The verification state of the device that sent us the event, note this
|
||||
/// is the state of the device at the time of decryption. It may change in
|
||||
/// the future if a device gets verified or deleted.
|
||||
pub verification_state: VerificationState,
|
||||
}
|
||||
|
||||
/// Struct representing the state of our private cross signing keys, it shows
|
||||
|
||||
@@ -629,6 +629,7 @@ impl OlmMachine {
|
||||
.get(&DeviceKeyAlgorithm::Ed25519)
|
||||
.cloned(),
|
||||
forwarding_curve25519_chain: vec![],
|
||||
verification_state: encryption_info.verification_state,
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -82,6 +82,7 @@ dictionary DecryptedEvent {
|
||||
string sender_curve25519_key;
|
||||
string? claimed_ed25519_key;
|
||||
sequence<string> forwarding_curve25519_chain;
|
||||
VerificationState verification_state;
|
||||
};
|
||||
|
||||
dictionary Device {
|
||||
@@ -254,6 +255,12 @@ enum LocalTrust {
|
||||
"Unset",
|
||||
};
|
||||
|
||||
enum VerificationState {
|
||||
"Trusted",
|
||||
"Untrusted",
|
||||
"UnknownDevice",
|
||||
};
|
||||
|
||||
enum EventEncryptionAlgorithm {
|
||||
"OlmV1Curve25519AesSha2",
|
||||
"MegolmV1AesSha2",
|
||||
|
||||
@@ -33,8 +33,8 @@ matrix-sdk-indexeddb = { version = "0.2.0", path = "../../crates/matrix-sdk-inde
|
||||
matrix-sdk-qrcode = { version = "0.4.0", path = "../../crates/matrix-sdk-qrcode", optional = true }
|
||||
ruma = { workspace = true, features = ["js", "rand", "unstable-msc2676", "unstable-msc2677"] }
|
||||
vodozemac = { workspace = true, features = ["js"] }
|
||||
wasm-bindgen = "0.2.80"
|
||||
wasm-bindgen-futures = "0.4.30"
|
||||
wasm-bindgen = "0.2.83"
|
||||
wasm-bindgen-futures = "0.4.33"
|
||||
js-sys = "0.3.49"
|
||||
console_error_panic_hook = "0.1.7"
|
||||
serde_json = "1.0.79"
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
"node": ">= 10"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "cross-env RUSTFLAGS='-C opt-level=z' wasm-pack build --release --target nodejs --scope matrix-org --out-dir ./pkg",
|
||||
"build": "cross-env RUSTFLAGS='-C opt-level=z' WASM_BINDGEN_WEAKREF=1 wasm-pack build --release --target nodejs --scope matrix-org --out-dir ./pkg",
|
||||
"test": "jest --verbose",
|
||||
"doc": "typedoc --tsconfig .",
|
||||
"prepack": "npm run build && npm run test",
|
||||
|
||||
@@ -28,7 +28,17 @@ pub struct OlmMachine {
|
||||
|
||||
#[wasm_bindgen]
|
||||
impl OlmMachine {
|
||||
/// Create a new memory based `OlmMachine`.
|
||||
/// Constructor will always fail. To create a new `OlmMachine`, please use
|
||||
/// the `initialize` method.
|
||||
///
|
||||
/// Why this pattern? `initialize` returns a `Promise`. Returning a
|
||||
// `Promise` from a constructor is not idiomatic in JavaScript.
|
||||
#[wasm_bindgen(constructor)]
|
||||
pub fn new() -> Result<OlmMachine, JsError> {
|
||||
Err(JsError::new("To build an `OlmMachine`, please use the `initialize` method"))
|
||||
}
|
||||
|
||||
/// Create a new `OlmMachine`.
|
||||
///
|
||||
/// The created machine will keep the encryption keys either in a IndexedDB
|
||||
/// based store, or in a memory store and once the objects is dropped,
|
||||
@@ -49,9 +59,7 @@ impl OlmMachine {
|
||||
///
|
||||
/// * `store_passphrase` - The passphrase that should be used to encrypt the
|
||||
/// IndexedDB based
|
||||
#[wasm_bindgen(constructor)]
|
||||
#[allow(clippy::new_ret_no_self)]
|
||||
pub fn new(
|
||||
pub fn initialize(
|
||||
user_id: &identifiers::UserId,
|
||||
device_id: &identifiers::DeviceId,
|
||||
store_name: Option<String>,
|
||||
|
||||
@@ -53,7 +53,7 @@ describe(OlmMachine.name, () => {
|
||||
const room = new RoomId('!baz:matrix.org');
|
||||
|
||||
function machine(new_user, new_device) {
|
||||
return new OlmMachine(new_user || user, new_device || device);
|
||||
return OlmMachine.initialize(new_user || user, new_device || device);
|
||||
}
|
||||
|
||||
test('can read user devices', async () => {
|
||||
@@ -116,7 +116,7 @@ describe('Key Verification', () => {
|
||||
const deviceId2 = new DeviceId('bob_device');
|
||||
|
||||
function machine(new_user, new_device) {
|
||||
return new OlmMachine(new_user || userId1, new_device || deviceId1);
|
||||
return OlmMachine.initialize(new_user || userId1, new_device || deviceId1);
|
||||
}
|
||||
|
||||
describe('SAS', () => {
|
||||
|
||||
@@ -25,7 +25,7 @@ require('fake-indexeddb/auto');
|
||||
|
||||
describe(OlmMachine.name, () => {
|
||||
test('can be instantiated with the async initializer', async () => {
|
||||
expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'))).toBeInstanceOf(OlmMachine);
|
||||
expect(await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'))).toBeInstanceOf(OlmMachine);
|
||||
});
|
||||
|
||||
test('can be instantiated with a store', async () => {
|
||||
@@ -36,7 +36,7 @@ describe(OlmMachine.name, () => {
|
||||
let store_passphrase = 'world';
|
||||
|
||||
// Creating a new Olm machine.
|
||||
expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine);
|
||||
expect(await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine);
|
||||
|
||||
// Oh, there is 2 databases now, prefixed by `store_name`.
|
||||
let databases = await indexedDB.databases();
|
||||
@@ -48,7 +48,7 @@ describe(OlmMachine.name, () => {
|
||||
]);
|
||||
|
||||
// Creating a new Olm machine, with the stored state.
|
||||
expect(await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine);
|
||||
expect(await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase)).toBeInstanceOf(OlmMachine);
|
||||
|
||||
// Same number of databases.
|
||||
expect(await indexedDB.databases()).toHaveLength(2);
|
||||
@@ -62,7 +62,7 @@ describe(OlmMachine.name, () => {
|
||||
let err = null;
|
||||
|
||||
try {
|
||||
await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase);
|
||||
await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase);
|
||||
} catch (error) {
|
||||
err = error;
|
||||
}
|
||||
@@ -77,7 +77,7 @@ describe(OlmMachine.name, () => {
|
||||
let err = null;
|
||||
|
||||
try {
|
||||
await new OlmMachine(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase);
|
||||
await OlmMachine.initialize(new UserId('@foo:bar.org'), new DeviceId('baz'), store_name, store_passphrase);
|
||||
} catch (error) {
|
||||
err = error;
|
||||
}
|
||||
@@ -91,7 +91,7 @@ describe(OlmMachine.name, () => {
|
||||
const room = new RoomId('!baz:matrix.org');
|
||||
|
||||
function machine(new_user, new_device) {
|
||||
return new OlmMachine(new_user || user, new_device || device);
|
||||
return OlmMachine.initialize(new_user || user, new_device || device);
|
||||
}
|
||||
|
||||
test('can read user ID', async () => {
|
||||
|
||||
@@ -68,7 +68,7 @@ describe(Tracing.name, () => {
|
||||
};
|
||||
|
||||
// Do something that emits a `DEBUG` log.
|
||||
await new OlmMachine(new UserId('@alice:example.org'), new DeviceId('foo'));
|
||||
await OlmMachine.initialize(new UserId('@alice:example.org'), new DeviceId('foo'));
|
||||
|
||||
console.debug = originalConsoleDebug;
|
||||
testPostState();
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
const { Agent } = require('https');
|
||||
const { DownloaderHelper } = require('node-downloader-helper');
|
||||
const { version } = require("./package.json");
|
||||
const { platform, arch } = process
|
||||
@@ -22,6 +23,11 @@ function download_lib(libname) {
|
||||
console.info(`Downloading lib ${libname} from ${url}`);
|
||||
const dl = new DownloaderHelper(url, __dirname, {
|
||||
override: true,
|
||||
httpsRequestOptions: {
|
||||
// Disable keepalive to prevent the process hanging open.
|
||||
// https://github.com/matrix-org/matrix-rust-sdk/issues/1160
|
||||
agent: new Agent({ keepAlive: false }),
|
||||
},
|
||||
});
|
||||
|
||||
dl.on('end', () => console.info('Download Completed'));
|
||||
|
||||
@@ -13,7 +13,7 @@ use matrix_sdk::{
|
||||
session::get_login_types,
|
||||
sync::sync_events::v3::Filter,
|
||||
},
|
||||
events::room::MediaSource,
|
||||
events::{room::MediaSource, AnyToDeviceEvent},
|
||||
serde::Raw,
|
||||
TransactionId, UInt,
|
||||
},
|
||||
@@ -49,11 +49,29 @@ pub struct Client {
|
||||
|
||||
impl Client {
|
||||
pub fn new(client: MatrixClient, state: ClientState) -> Self {
|
||||
let session_verification_controller: Arc<
|
||||
matrix_sdk::locks::RwLock<Option<SessionVerificationController>>,
|
||||
> = Default::default();
|
||||
let ctrl = session_verification_controller.clone();
|
||||
|
||||
client.add_event_handler(move |ev: AnyToDeviceEvent| {
|
||||
let ctrl = ctrl.clone();
|
||||
async move {
|
||||
if let Some(session_verification_controller) = &*ctrl.clone().read().await {
|
||||
session_verification_controller.process_to_device_message(ev).await;
|
||||
} else {
|
||||
tracing::warn!(
|
||||
"received to-device message, but verification controller isn't ready"
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Client {
|
||||
client,
|
||||
state: Arc::new(RwLock::new(state)),
|
||||
delegate: Arc::new(RwLock::new(None)),
|
||||
session_verification_controller: Arc::new(matrix_sdk::locks::RwLock::new(None)),
|
||||
session_verification_controller,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -234,7 +252,6 @@ impl Client {
|
||||
{
|
||||
return Ok(Arc::new(session_verification_controller.clone()));
|
||||
}
|
||||
|
||||
let user_id = self.client.user_id().context("Failed retrieving current user_id")?;
|
||||
let user_identity = self
|
||||
.client
|
||||
@@ -263,8 +280,7 @@ impl Client {
|
||||
}
|
||||
|
||||
/// Process a sync error and return loop control accordingly
|
||||
fn process_sync_error(&self, sync_error: Error) -> LoopCtrl {
|
||||
let mut control = LoopCtrl::Continue;
|
||||
pub(crate) fn process_sync_error(&self, sync_error: Error) -> LoopCtrl {
|
||||
if let Some(RumaApiError::ClientApi(error)) = sync_error.as_ruma_api_error() {
|
||||
if let ErrorKind::UnknownToken { soft_logout } = error.kind {
|
||||
self.state.write().unwrap().is_soft_logout = soft_logout;
|
||||
@@ -272,10 +288,12 @@ impl Client {
|
||||
delegate.did_update_restore_token();
|
||||
delegate.did_receive_auth_error(soft_logout);
|
||||
}
|
||||
control = LoopCtrl::Break
|
||||
return LoopCtrl::Break;
|
||||
}
|
||||
}
|
||||
control
|
||||
|
||||
tracing::warn!("Ignoring sync error: {:?}", sync_error);
|
||||
LoopCtrl::Continue
|
||||
}
|
||||
}
|
||||
|
||||
@@ -315,7 +333,6 @@ impl Client {
|
||||
let client = self.client.clone();
|
||||
let state = self.state.clone();
|
||||
let delegate = self.delegate.clone();
|
||||
let session_verification_controller = self.session_verification_controller.clone();
|
||||
let local_self = self.clone();
|
||||
RUNTIME.spawn(async move {
|
||||
let mut filter = FilterDefinition::default();
|
||||
@@ -337,7 +354,7 @@ impl Client {
|
||||
|
||||
client
|
||||
.sync_with_result_callback(sync_settings, |result| async {
|
||||
Ok(if let Ok(sync_response) = result {
|
||||
Ok(if result.is_ok() {
|
||||
if !state.read().unwrap().has_first_synced {
|
||||
state.write().unwrap().has_first_synced = true;
|
||||
}
|
||||
@@ -353,14 +370,6 @@ impl Client {
|
||||
delegate.did_receive_sync_update()
|
||||
}
|
||||
|
||||
if let Some(session_verification_controller) =
|
||||
&*session_verification_controller.read().await
|
||||
{
|
||||
session_verification_controller
|
||||
.process_to_device_messages(sync_response.to_device_events)
|
||||
.await;
|
||||
}
|
||||
|
||||
LoopCtrl::Continue
|
||||
} else {
|
||||
local_self.process_sync_error(result.err().unwrap())
|
||||
|
||||
@@ -106,64 +106,66 @@ impl SessionVerificationController {
|
||||
})
|
||||
}
|
||||
|
||||
pub async fn process_to_device_messages(&self, to_device_events: Vec<Raw<AnyToDeviceEvent>>) {
|
||||
let sas_verification = self.sas_verification.clone();
|
||||
|
||||
for event in to_device_events.into_iter().filter_map(|e| e.deserialize().ok()) {
|
||||
match event {
|
||||
AnyToDeviceEvent::KeyVerificationReady(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
self.start_sas_verification().await;
|
||||
pub async fn process_to_device_message(&self, event: AnyToDeviceEvent) {
|
||||
match event {
|
||||
AnyToDeviceEvent::KeyVerificationReady(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
AnyToDeviceEvent::KeyVerificationCancel(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_cancel()
|
||||
}
|
||||
self.start_sas_verification().await;
|
||||
}
|
||||
AnyToDeviceEvent::KeyVerificationCancel(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
AnyToDeviceEvent::KeyVerificationKey(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(sas_verification) = &*sas_verification.read().unwrap() {
|
||||
if let Some(emojis) = sas_verification.emoji() {
|
||||
if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
let emojis = emojis
|
||||
.iter()
|
||||
.map(|e| {
|
||||
Arc::new(SessionVerificationEmoji {
|
||||
symbol: e.symbol.to_owned(),
|
||||
description: e.description.to_owned(),
|
||||
})
|
||||
if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_cancel()
|
||||
}
|
||||
}
|
||||
AnyToDeviceEvent::KeyVerificationKey(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(sas_verification) = &*self.sas_verification.read().unwrap() {
|
||||
if let Some(emojis) = sas_verification.emoji() {
|
||||
if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
let emojis = emojis
|
||||
.iter()
|
||||
.map(|e| {
|
||||
Arc::new(SessionVerificationEmoji {
|
||||
symbol: e.symbol.to_owned(),
|
||||
description: e.description.to_owned(),
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
delegate.did_receive_verification_data(emojis);
|
||||
}
|
||||
} else if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_fail()
|
||||
delegate.did_receive_verification_data(emojis);
|
||||
}
|
||||
} else if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_fail()
|
||||
}
|
||||
} else if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_fail()
|
||||
}
|
||||
AnyToDeviceEvent::KeyVerificationDone(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_finish()
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
AnyToDeviceEvent::KeyVerificationDone(event) => {
|
||||
if !self.is_transaction_id_valid(event.content.transaction_id.to_string()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Some(delegate) = &*self.delegate.read().unwrap() {
|
||||
delegate.did_finish()
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn process_to_device_messages(&self, to_device_events: Vec<Raw<AnyToDeviceEvent>>) {
|
||||
for event in to_device_events.into_iter().filter_map(|e| e.deserialize().ok()) {
|
||||
self.process_to_device_message(event).await;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ use matrix_sdk::ruma::{
|
||||
assign, IdParseError, OwnedRoomId,
|
||||
};
|
||||
pub use matrix_sdk::{
|
||||
Client as MatrixClient, RoomListEntry as MatrixRoomEntry,
|
||||
Client as MatrixClient, LoopCtrl, RoomListEntry as MatrixRoomEntry,
|
||||
SlidingSyncBuilder as MatrixSlidingSyncBuilder, SlidingSyncMode, SlidingSyncState,
|
||||
};
|
||||
use tokio::task::JoinHandle;
|
||||
@@ -516,6 +516,7 @@ impl SlidingSync {
|
||||
let inner_spawn = spawn.clone();
|
||||
{
|
||||
let mut sync_handle = self.sync_handle.write().unwrap();
|
||||
let client = self.client.clone();
|
||||
|
||||
if let Some(handle) = sync_handle.take() {
|
||||
handle.abort();
|
||||
@@ -528,9 +529,11 @@ impl SlidingSync {
|
||||
let update = match stream.next().await {
|
||||
Some(Ok(u)) => u,
|
||||
Some(Err(e)) => {
|
||||
// FIXME: send this over the FFI
|
||||
tracing::warn!("Sliding Sync failure: {:?}", e);
|
||||
continue;
|
||||
if client.process_sync_error(e) == LoopCtrl::Break {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
None => {
|
||||
tracing::debug!("No update from loop, cancelled");
|
||||
|
||||
@@ -150,6 +150,10 @@ impl TimelineItem {
|
||||
Arc::new(VirtualTimelineItem(vt))
|
||||
})
|
||||
}
|
||||
|
||||
pub fn fmt_debug(&self) -> String {
|
||||
format!("{:#?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct EventTimelineItem(pub(crate) matrix_sdk::room::timeline::EventTimelineItem);
|
||||
@@ -193,6 +197,10 @@ impl EventTimelineItem {
|
||||
pub fn raw(&self) -> Option<String> {
|
||||
self.0.raw().map(|r| r.json().get().to_owned())
|
||||
}
|
||||
|
||||
pub fn fmt_debug(&self) -> String {
|
||||
format!("{:#?}", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, uniffi::Object)]
|
||||
|
||||
@@ -102,7 +102,12 @@ where
|
||||
self.0.poll_ready(cx)
|
||||
}
|
||||
|
||||
fn call(&mut self, req: http::Request<B>) -> Self::Future {
|
||||
fn call(&mut self, mut req: http::Request<B>) -> Self::Future {
|
||||
// When the AppServiceRouter is nested inside another axum Router under
|
||||
// a path that includes path parameters, those should not be received by
|
||||
// the Path extractor used inside the `handlers` module.
|
||||
req.extensions_mut().clear();
|
||||
|
||||
AppServiceRouteFuture(self.0.call(req))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ name = "matrix-sdk-base"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/matrix-org/matrix-rust-sdk"
|
||||
rust-version = "1.62"
|
||||
version = "0.6.0"
|
||||
version = "0.6.1"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
@@ -58,4 +58,4 @@ tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
|
||||
tokio = { version = "1.17.0", default-features = false, features = ["rt-multi-thread", "macros"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.30"
|
||||
wasm-bindgen-test = "0.3.33"
|
||||
|
||||
@@ -27,7 +27,7 @@ serde = "1.0.136"
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
async-lock = "2.5.0"
|
||||
futures-util = { version = "0.3.21", default-features = false, features = ["channel"] }
|
||||
wasm-bindgen-futures = { version = "0.4.30", optional = true }
|
||||
wasm-bindgen-futures = { version = "0.4.33", optional = true }
|
||||
wasm-timer = "0.2.5"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||
@@ -35,4 +35,4 @@ tokio = { version = "1.17.0", default-features = false, features = ["rt", "sync"
|
||||
|
||||
[dev-dependencies]
|
||||
matrix-sdk-test = { path = "../../testing/matrix-sdk-test/", version= "0.6.0"}
|
||||
wasm-bindgen-test = "0.3.30"
|
||||
wasm-bindgen-test = "0.3.33"
|
||||
|
||||
@@ -24,18 +24,19 @@ async-trait = "0.1.53"
|
||||
base64 = "0.13.0"
|
||||
dashmap = { version = "5.2.0", optional = true }
|
||||
derive_builder = "0.11.2"
|
||||
gloo-utils = { version = "0.1", features = ["serde"] }
|
||||
indexed_db_futures = "0.2.3"
|
||||
indexed_db_futures_nodejs = { version = "0.2.3", package = "indexed_db_futures", git = "https://github.com/Hywan/rust-indexed-db", branch = "feat-factory-nodejs", optional = true }
|
||||
js-sys = { version = "0.3.58" }
|
||||
matrix-sdk-base = { version = "0.6.0", path = "../matrix-sdk-base", features = ["js"] }
|
||||
matrix-sdk-crypto = { version = "0.6.0", path = "../matrix-sdk-crypto", features = ["js"], optional = true }
|
||||
matrix-sdk-store-encryption = { version = "0.2.0", path = "../matrix-sdk-store-encryption" }
|
||||
indexed_db_futures = "0.2.3"
|
||||
indexed_db_futures_nodejs = { version = "0.2.3", package = "indexed_db_futures", git = "https://github.com/Hywan/rust-indexed-db", branch = "feat-factory-nodejs", optional = true }
|
||||
ruma = { workspace = true }
|
||||
serde = "1.0.136"
|
||||
serde_json = "1.0.79"
|
||||
thiserror = "1.0.30"
|
||||
tracing = { workspace = true }
|
||||
wasm-bindgen = { version = "0.2.80", features = ["serde-serialize"] }
|
||||
wasm-bindgen = "0.2.83"
|
||||
web-sys = { version = "0.3.57", features = ["IdbKeyRange"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
@@ -48,4 +49,4 @@ matrix-sdk-common = { path = "../matrix-sdk-common", features = ["js"] }
|
||||
matrix-sdk-crypto = { path = "../matrix-sdk-crypto", features = ["js", "testing"] }
|
||||
matrix-sdk-test = { path = "../../testing/matrix-sdk-test" }
|
||||
uuid = "1.0.0"
|
||||
wasm-bindgen-test = "0.3.30"
|
||||
wasm-bindgen-test = "0.3.33"
|
||||
|
||||
@@ -19,6 +19,7 @@ use std::{
|
||||
|
||||
use async_trait::async_trait;
|
||||
use dashmap::DashSet;
|
||||
use gloo_utils::format::JsValueSerdeExt;
|
||||
use matrix_sdk_base::locks::Mutex;
|
||||
use matrix_sdk_crypto::{
|
||||
olm::{
|
||||
|
||||
@@ -23,6 +23,7 @@ use std::{
|
||||
use anyhow::anyhow;
|
||||
use async_trait::async_trait;
|
||||
use derive_builder::Builder;
|
||||
use gloo_utils::format::JsValueSerdeExt;
|
||||
use js_sys::Date as JsDate;
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::MemberEvent,
|
||||
|
||||
@@ -9,7 +9,7 @@ name = "matrix-sdk"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/matrix-org/matrix-rust-sdk"
|
||||
rust-version = "1.62"
|
||||
version = "0.6.0"
|
||||
version = "0.6.2"
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = ["docsrs"]
|
||||
@@ -43,11 +43,10 @@ image-proc = ["dep:image"]
|
||||
image-rayon = ["image-proc", "image?/jpeg_rayon"]
|
||||
|
||||
experimental-room-preview = []
|
||||
experimental-timeline = []
|
||||
experimental-timeline = ["ruma/unstable-msc2676", "ruma/unstable-msc2677"]
|
||||
|
||||
sliding-sync = [
|
||||
"matrix-sdk-base/sliding-sync",
|
||||
"anyhow",
|
||||
"dep:derive_builder",
|
||||
]
|
||||
|
||||
@@ -134,7 +133,7 @@ tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
|
||||
getrandom = { version = "0.2.6", default-features = false, features = ["js"] }
|
||||
wasm-bindgen-test = "0.3.30"
|
||||
wasm-bindgen-test = "0.3.33"
|
||||
|
||||
[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies]
|
||||
ctor = "0.1.23"
|
||||
|
||||
@@ -193,6 +193,11 @@ pub enum Error {
|
||||
#[error(transparent)]
|
||||
ImageError(#[from] ImageError),
|
||||
|
||||
/// An error occurred within sliding-sync
|
||||
#[cfg(feature = "sliding-sync")]
|
||||
#[error(transparent)]
|
||||
SlidingSync(#[from] crate::sliding_sync::Error),
|
||||
|
||||
/// An other error was raised
|
||||
/// this might happen because encryption was enabled on the base-crate
|
||||
/// but not here and that raised.
|
||||
|
||||
@@ -58,8 +58,6 @@ impl TimelineInner {
|
||||
) {
|
||||
let meta = TimelineEventMetadata {
|
||||
sender: own_user_id.to_owned(),
|
||||
origin_server_ts: None,
|
||||
raw_event: None,
|
||||
is_own_event: true,
|
||||
relations: None,
|
||||
// FIXME: Should we supply something here for encrypted rooms?
|
||||
@@ -100,15 +98,15 @@ impl TimelineInner {
|
||||
let is_own_event = sender == own_user_id;
|
||||
|
||||
let meta = TimelineEventMetadata {
|
||||
raw_event: Some(raw),
|
||||
sender,
|
||||
origin_server_ts: Some(event.origin_server_ts()),
|
||||
is_own_event,
|
||||
relations: event.relations().cloned(),
|
||||
encryption_info,
|
||||
};
|
||||
let flow = Flow::Remote {
|
||||
event_id: event.event_id().to_owned(),
|
||||
origin_server_ts: event.origin_server_ts(),
|
||||
raw_event: raw,
|
||||
txn_id: event.transaction_id().map(ToOwned::to_owned),
|
||||
position,
|
||||
};
|
||||
@@ -124,6 +122,8 @@ enum Flow {
|
||||
Remote {
|
||||
event_id: OwnedEventId,
|
||||
txn_id: Option<OwnedTransactionId>,
|
||||
origin_server_ts: MilliSecondsSinceUnixEpoch,
|
||||
raw_event: Raw<AnySyncTimelineEvent>,
|
||||
position: TimelineItemPosition,
|
||||
},
|
||||
}
|
||||
@@ -135,12 +135,24 @@ impl Flow {
|
||||
Self::Local { txn_id } => TimelineKey::TransactionId(txn_id.to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
fn origin_server_ts(&self) -> Option<MilliSecondsSinceUnixEpoch> {
|
||||
match self {
|
||||
Flow::Local { .. } => None,
|
||||
Flow::Remote { origin_server_ts, .. } => Some(*origin_server_ts),
|
||||
}
|
||||
}
|
||||
|
||||
fn raw_event(&self) -> Option<&Raw<AnySyncTimelineEvent>> {
|
||||
match self {
|
||||
Flow::Local { .. } => None,
|
||||
Flow::Remote { raw_event, .. } => Some(raw_event),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct TimelineEventMetadata {
|
||||
raw_event: Option<Raw<AnySyncTimelineEvent>>,
|
||||
sender: OwnedUserId,
|
||||
origin_server_ts: Option<MilliSecondsSinceUnixEpoch>,
|
||||
is_own_event: bool,
|
||||
relations: Option<Relations>,
|
||||
encryption_info: Option<EncryptionInfo>,
|
||||
@@ -382,36 +394,52 @@ impl<'a> TimelineEventHandler<'a> {
|
||||
sender: self.meta.sender.to_owned(),
|
||||
content,
|
||||
reactions,
|
||||
origin_server_ts: self.meta.origin_server_ts,
|
||||
origin_server_ts: self.flow.origin_server_ts(),
|
||||
is_own: self.meta.is_own_event,
|
||||
encryption_info: self.meta.encryption_info.clone(),
|
||||
raw: self.meta.raw_event.clone(),
|
||||
raw: self.flow.raw_event().cloned(),
|
||||
};
|
||||
|
||||
let item = Arc::new(TimelineItem::Event(item));
|
||||
let mut lock = self.timeline.items.lock_mut();
|
||||
match &self.flow {
|
||||
Flow::Local { .. }
|
||||
| Flow::Remote { position: TimelineItemPosition::End, txn_id: None, .. } => {
|
||||
Flow::Local { .. } => {
|
||||
lock.push_cloned(item);
|
||||
}
|
||||
Flow::Remote { position: TimelineItemPosition::Start, txn_id: None, .. } => {
|
||||
lock.insert_cloned(0, item);
|
||||
}
|
||||
Flow::Remote { txn_id: Some(txn_id), event_id, position } => {
|
||||
if let Some((idx, _old_item)) = find_event(&lock, txn_id) {
|
||||
// TODO: Check whether anything is different about the old and new item?
|
||||
lock.set_cloned(idx, item);
|
||||
} else {
|
||||
debug!(
|
||||
%txn_id, %event_id,
|
||||
"Received event with transaction ID, but didn't find matching timeline item"
|
||||
Flow::Remote { txn_id, event_id, position, raw_event, .. } => {
|
||||
if let Some(txn_id) = txn_id {
|
||||
if let Some((idx, _old_item)) = find_event(&lock, txn_id) {
|
||||
// TODO: Check whether anything is different about the
|
||||
// old and new item?
|
||||
lock.set_cloned(idx, item);
|
||||
return;
|
||||
} else {
|
||||
warn!(
|
||||
%txn_id, %event_id,
|
||||
"Received event with transaction ID, but didn't \
|
||||
find matching timeline item"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some((idx, old_item)) = find_event(&lock, event_id) {
|
||||
warn!(
|
||||
?item,
|
||||
?old_item,
|
||||
raw = raw_event.json().get(),
|
||||
"Received event with an ID we already have a timeline item for"
|
||||
);
|
||||
|
||||
match position {
|
||||
TimelineItemPosition::Start => lock.insert_cloned(0, item),
|
||||
TimelineItemPosition::End => lock.push_cloned(item),
|
||||
}
|
||||
// With /messages and /sync sometimes disagreeing on order
|
||||
// of messages, we might want to change the position in some
|
||||
// circumstances, but for now this should be good enough.
|
||||
lock.set_cloned(idx, item);
|
||||
return;
|
||||
}
|
||||
|
||||
match position {
|
||||
TimelineItemPosition::Start => lock.insert_cloned(0, item),
|
||||
TimelineItemPosition::End => lock.push_cloned(item),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,8 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use std::fmt;
|
||||
|
||||
use indexmap::IndexMap;
|
||||
use matrix_sdk_base::deserialized_responses::EncryptionInfo;
|
||||
#[cfg(feature = "experimental-room-preview")]
|
||||
@@ -32,7 +34,7 @@ use ruma::{
|
||||
/// There is always one main event that gives the `EventTimelineItem` its
|
||||
/// identity (see [key](Self::key)) but in many cases, additional events like
|
||||
/// reactions and edits are also part of the item.
|
||||
#[derive(Clone, Debug)]
|
||||
#[derive(Clone)]
|
||||
pub struct EventTimelineItem {
|
||||
pub(super) key: TimelineKey,
|
||||
// If this item is a local echo that has been acknowledged by the server
|
||||
@@ -49,6 +51,22 @@ pub struct EventTimelineItem {
|
||||
pub(super) raw: Option<Raw<AnySyncTimelineEvent>>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for EventTimelineItem {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("EventTimelineItem")
|
||||
.field("key", &self.key)
|
||||
.field("event_id", &self.event_id)
|
||||
.field("sender", &self.sender)
|
||||
.field("content", &self.content)
|
||||
.field("reactions", &self.reactions)
|
||||
.field("origin_server_ts", &self.origin_server_ts)
|
||||
.field("is_own", &self.is_own)
|
||||
.field("encryption_info", &self.encryption_info)
|
||||
// skip raw, too noisy
|
||||
.finish_non_exhaustive()
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! build {
|
||||
(
|
||||
$ty:ident {
|
||||
@@ -234,6 +252,12 @@ impl PartialEq<TimelineKey> for &EventId {
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<TimelineKey> for &OwnedEventId {
|
||||
fn eq(&self, key: &TimelineKey) -> bool {
|
||||
matches!(key, TimelineKey::EventId(event_id) if event_id == *self)
|
||||
}
|
||||
}
|
||||
|
||||
/// Some details of an [`EventTimelineItem`] that may require server requests
|
||||
/// other than just the regular
|
||||
/// [`sync_events`][ruma::api::client::sync::sync_events].
|
||||
|
||||
@@ -29,7 +29,7 @@ use ruma::{
|
||||
events::{reaction::Relation as AnnotationRelation, AnyMessageLikeEventContent},
|
||||
OwnedEventId, OwnedUserId, TransactionId, UInt,
|
||||
};
|
||||
use tracing::{debug, error, instrument};
|
||||
use tracing::{error, instrument, warn};
|
||||
|
||||
use super::{Joined, Room};
|
||||
use crate::{
|
||||
@@ -236,6 +236,6 @@ fn add_event_id(items: &TimelineInner, txn_id: &TransactionId, event_id: OwnedEv
|
||||
}
|
||||
}
|
||||
} else {
|
||||
debug!(%txn_id, "Timeline item not found, can't mark as sent");
|
||||
warn!(%txn_id, "Timeline item not found, can't add event ID");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
|
||||
use std::{fmt::Debug, sync::Arc};
|
||||
|
||||
use anyhow::{bail, Context};
|
||||
use futures_core::stream::Stream;
|
||||
use futures_signals::signal::Mutable;
|
||||
use matrix_sdk_base::deserialized_responses::{SyncResponse, SyncTimelineEvent};
|
||||
@@ -27,10 +26,21 @@ use ruma::{
|
||||
events::RoomEventType,
|
||||
OwnedRoomId, RoomId, UInt,
|
||||
};
|
||||
use thiserror::Error;
|
||||
use url::Url;
|
||||
|
||||
use crate::{Client, Result};
|
||||
|
||||
/// Internal representation of errors in Sliding Sync
|
||||
#[derive(Error, Debug)]
|
||||
#[non_exhaustive]
|
||||
pub enum Error {
|
||||
#[error("Received response for {found} lists, yet we have {expected}.")]
|
||||
BadViewsCount { found: usize, expected: usize },
|
||||
#[error("The sliding sync response could not be handled: {0}")]
|
||||
BadResponse(String),
|
||||
}
|
||||
|
||||
/// The state the [`SlidingSyncView`] is in.
|
||||
///
|
||||
/// The lifetime of a SlidingSync usually starts at a `Preload`, getting a fast
|
||||
@@ -442,13 +452,15 @@ impl SlidingSync {
|
||||
&self,
|
||||
resp: v4::Response,
|
||||
views: &[SlidingSyncView],
|
||||
) -> anyhow::Result<UpdateSummary> {
|
||||
) -> Result<UpdateSummary, crate::Error> {
|
||||
let mut processed = self.client.process_sliding_sync(resp.clone()).await?;
|
||||
tracing::info!("main client processed.");
|
||||
self.pos.replace(Some(resp.pos));
|
||||
let mut updated_views = Vec::new();
|
||||
if resp.lists.len() != views.len() {
|
||||
bail!("Received response for {} lists, yet we have {}", resp.lists.len(), views.len());
|
||||
return Err(
|
||||
Error::BadViewsCount { found: resp.lists.len(), expected: views.len() }.into()
|
||||
);
|
||||
}
|
||||
|
||||
for (view, updates) in std::iter::zip(views, &resp.lists) {
|
||||
@@ -497,23 +509,18 @@ impl SlidingSync {
|
||||
/// Run this stream to receive new updates from the server.
|
||||
pub async fn stream<'a>(
|
||||
&self,
|
||||
) -> anyhow::Result<impl Stream<Item = anyhow::Result<UpdateSummary>> + '_> {
|
||||
) -> Result<impl Stream<Item = Result<UpdateSummary, crate::Error>> + '_, crate::Error> {
|
||||
let views = self.views.lock_ref().to_vec();
|
||||
let extensions = self.extensions.clone();
|
||||
let client = self.client.clone();
|
||||
|
||||
Ok(async_stream::try_stream! {
|
||||
Ok(async_stream::stream! {
|
||||
let mut remaining_views = views.clone();
|
||||
let mut remaining_generators: Vec<SlidingSyncViewRequestGenerator<'_>> = views
|
||||
.iter()
|
||||
.map(SlidingSyncView::request_generator)
|
||||
.collect();
|
||||
loop {
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
if let Err(e) = client.send_outgoing_requests().await {
|
||||
tracing::error!(error = ?e, "Error while sending outgoing E2EE requests");
|
||||
}
|
||||
|
||||
let mut requests = Vec::new();
|
||||
let mut new_remaining_generators = Vec::new();
|
||||
let mut new_remaining_views = Vec::new();
|
||||
@@ -550,14 +557,39 @@ impl SlidingSync {
|
||||
extensions: extensions.lock_mut().take().unwrap_or_default(), // extensions are sticky, we pop them here once
|
||||
});
|
||||
tracing::debug!("requesting");
|
||||
let resp = client
|
||||
.send_with_homeserver(req, None, self.homeserver.as_ref().map(ToString::to_string))
|
||||
.await?;
|
||||
|
||||
let req = client.send_with_homeserver(req, None, self.homeserver.as_ref().map(ToString::to_string));
|
||||
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
let resp_res = {
|
||||
let (e2ee_uploads, resp) = futures_util::join!(client.send_outgoing_requests(), req);
|
||||
if let Err(e) = e2ee_uploads {
|
||||
tracing::error!(error = ?e, "Error while sending outgoing E2EE requests");
|
||||
}
|
||||
resp
|
||||
};
|
||||
#[cfg(not(feature = "e2e-encryption"))]
|
||||
let resp_res = req.await;
|
||||
|
||||
let resp = match resp_res {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
yield Err(e.into());
|
||||
continue
|
||||
}
|
||||
};
|
||||
|
||||
tracing::debug!("received");
|
||||
|
||||
let updates = self.handle_response(resp, &remaining_views).await?;
|
||||
let updates = match self.handle_response(resp, &remaining_views).await {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
yield Err(e.into());
|
||||
continue
|
||||
}
|
||||
};
|
||||
tracing::debug!("handled");
|
||||
yield updates;
|
||||
yield Ok(updates);
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -878,7 +910,7 @@ impl SlidingSyncView {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, ops))]
|
||||
fn room_ops(&self, ops: &Vec<v4::SyncOp>) -> anyhow::Result<()> {
|
||||
fn room_ops(&self, ops: &Vec<v4::SyncOp>) -> Result<(), Error> {
|
||||
let mut rooms_list = self.rooms_list.lock_mut();
|
||||
let _rooms_map = self.rooms.lock_mut();
|
||||
for op in ops {
|
||||
@@ -886,9 +918,16 @@ impl SlidingSyncView {
|
||||
v4::SlidingOp::Sync => {
|
||||
let start: u32 = op
|
||||
.range
|
||||
.context("`range` must be present for Sync and Update operation")?
|
||||
.ok_or_else(|| {
|
||||
Error::BadResponse(
|
||||
"`range` must be present for Sync and Update operation".to_owned(),
|
||||
)
|
||||
})?
|
||||
.0
|
||||
.try_into()?;
|
||||
.try_into()
|
||||
.map_err(|e| {
|
||||
Error::BadResponse(format!("`range` not a valid int: {e:}"))
|
||||
})?;
|
||||
let room_ids = op.room_ids.clone();
|
||||
room_ids
|
||||
.into_iter()
|
||||
@@ -902,21 +941,41 @@ impl SlidingSyncView {
|
||||
v4::SlidingOp::Delete => {
|
||||
let pos: u32 = op
|
||||
.index
|
||||
.context("`index` must be present for DELETE operation")?
|
||||
.try_into()?;
|
||||
.ok_or_else(|| {
|
||||
Error::BadResponse(
|
||||
"`index` must be present for DELETE operation".to_owned(),
|
||||
)
|
||||
})?
|
||||
.try_into()
|
||||
.map_err(|e| {
|
||||
Error::BadResponse(format!(
|
||||
"`index` not a valid int for DELETE: {:}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
rooms_list.set_cloned(pos as usize, RoomListEntry::Empty);
|
||||
}
|
||||
v4::SlidingOp::Insert => {
|
||||
let pos: usize = op
|
||||
.index
|
||||
.context("`index` must be present for INSERT operation")?
|
||||
.try_into()?;
|
||||
.ok_or_else(|| {
|
||||
Error::BadResponse(
|
||||
"`index` must be present for INSERT operation".to_owned(),
|
||||
)
|
||||
})?
|
||||
.try_into()
|
||||
.map_err(|e| {
|
||||
Error::BadResponse(format!(
|
||||
"`index` not a valid int for INSERT: {:}",
|
||||
e
|
||||
))
|
||||
})?;
|
||||
let sliced = rooms_list.as_slice();
|
||||
let room = RoomListEntry::Filled(
|
||||
op.room_id
|
||||
.clone()
|
||||
.context("`room_id` must be present for INSERT operation")?,
|
||||
);
|
||||
let room = RoomListEntry::Filled(op.room_id.clone().ok_or_else(|| {
|
||||
Error::BadResponse(
|
||||
"`room_id` must be present for INSERT operation".to_owned(),
|
||||
)
|
||||
})?);
|
||||
let mut dif = 0usize;
|
||||
loop {
|
||||
// find the next empty slot and drop it
|
||||
@@ -925,7 +984,7 @@ impl SlidingSyncView {
|
||||
let (next_p, overflown) = pos.overflowing_add(dif);
|
||||
let check_after = !overflown && next_p < sliced.len();
|
||||
if !check_prev && !check_after {
|
||||
bail!("We were asked to insert but could not find any direction to shift to");
|
||||
return Err(Error::BadResponse("We were asked to insert but could not find any direction to shift to".to_owned()));
|
||||
}
|
||||
|
||||
if check_prev && sliced[prev_p].empty_or_invalidated() {
|
||||
@@ -945,13 +1004,24 @@ impl SlidingSyncView {
|
||||
v4::SlidingOp::Invalidate => {
|
||||
let max_len = rooms_list.len();
|
||||
let (mut pos, end): (u32, u32) = if let Some(range) = op.range {
|
||||
(range.0.try_into()?, range.1.try_into()?)
|
||||
(
|
||||
range.0.try_into().map_err(|e| {
|
||||
Error::BadResponse(format!("`range.0` not a valid int: {e:}"))
|
||||
})?,
|
||||
range.1.try_into().map_err(|e| {
|
||||
Error::BadResponse(format!("`range.1` not a valid int: {e:}"))
|
||||
})?,
|
||||
)
|
||||
} else {
|
||||
bail!("`range` must be given on `Invalidate` operation")
|
||||
return Err(Error::BadResponse(
|
||||
"`range` must be given on `Invalidate` operation".to_owned(),
|
||||
));
|
||||
};
|
||||
|
||||
if pos > end {
|
||||
bail!("Invalid invalidation, end smaller than start");
|
||||
return Err(Error::BadResponse(
|
||||
"Invalid invalidation, end smaller than start".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
while pos < end {
|
||||
@@ -983,7 +1053,7 @@ impl SlidingSyncView {
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self, ops))]
|
||||
fn handle_response(&self, rooms_count: u32, ops: &Vec<v4::SyncOp>) -> anyhow::Result<bool> {
|
||||
fn handle_response(&self, rooms_count: u32, ops: &Vec<v4::SyncOp>) -> Result<bool, Error> {
|
||||
let mut missing =
|
||||
rooms_count.checked_sub(self.rooms_list.lock_ref().len() as u32).unwrap_or_default();
|
||||
let mut changed = false;
|
||||
|
||||
@@ -13,8 +13,8 @@ test = false
|
||||
|
||||
[dependencies]
|
||||
url = "2.2.2"
|
||||
wasm-bindgen = { version = "0.2.74", features = ["serde-serialize"] }
|
||||
wasm-bindgen-futures = "0.4.24"
|
||||
wasm-bindgen = { version = "0.2.83" }
|
||||
wasm-bindgen-futures = "0.4.33"
|
||||
console_error_panic_hook = "0.1.6"
|
||||
web-sys = { version = "0.3.51", features = ["console"] }
|
||||
|
||||
@@ -25,4 +25,4 @@ default-features = false
|
||||
features = ["js", "native-tls", "e2e-encryption", "indexeddb"]
|
||||
|
||||
[dev-dependencies]
|
||||
wasm-bindgen-test = "0.3.29"
|
||||
wasm-bindgen-test = "0.3.33"
|
||||
|
||||
@@ -22,10 +22,10 @@ serde_json = "1.0.85"
|
||||
structopt = "0.3"
|
||||
tokio = { version = "1", features = ["rt-multi-thread", "sync", "macros"] }
|
||||
tracing-flame = "0.2"
|
||||
tracing-subscriber = "0.3.15"
|
||||
tracing-subscriber = "0.3.15"
|
||||
tui-logger = "0.8.0"
|
||||
tuirealm = "~1.7.1"
|
||||
|
||||
# file-logging specials
|
||||
tracing = { version = "0.1.35", features = ["log"] }
|
||||
log4rs = { version = " 1.1.1", default-features = false, features = ["file_appender"], optional = true }
|
||||
log4rs = { version = "1.1.1", default-features = false, features = ["file_appender"], optional = true }
|
||||
|
||||
@@ -30,4 +30,4 @@ serde_json = "1.0.79"
|
||||
tokio = { version = "1.17.0", default-features = false, features = ["rt", "macros"] }
|
||||
|
||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||
wasm-bindgen-test = "0.3.30"
|
||||
wasm-bindgen-test = "0.3.33"
|
||||
|
||||
@@ -10,8 +10,8 @@ test = false
|
||||
|
||||
[dependencies]
|
||||
camino = "1.0.8"
|
||||
clap = { version = "3.2.4", features = ["derive"] }
|
||||
clap = { version = "4.0.18", features = ["derive"] }
|
||||
serde = { version = "1.0.136", features = ["derive"] }
|
||||
serde_json = "1.0.79"
|
||||
uniffi_bindgen = { workspace = true }
|
||||
uniffi_bindgen = { workspace = true }
|
||||
xshell = "0.1.17"
|
||||
|
||||
@@ -18,31 +18,43 @@ const WASM_TIMEOUT_VALUE: &str = "120";
|
||||
enum CiCommand {
|
||||
/// Check style
|
||||
Style,
|
||||
|
||||
/// Check for typos
|
||||
Typos,
|
||||
|
||||
/// Check clippy lints
|
||||
Clippy,
|
||||
|
||||
/// Check documentation
|
||||
Docs,
|
||||
|
||||
/// Run tests with a specific feature set
|
||||
TestFeatures {
|
||||
#[clap(subcommand)]
|
||||
cmd: Option<FeatureSet>,
|
||||
},
|
||||
|
||||
/// Run tests for the appservice crate
|
||||
TestAppservice,
|
||||
|
||||
/// Run checks for the wasm target
|
||||
Wasm {
|
||||
#[clap(subcommand)]
|
||||
cmd: Option<WasmFeatureSet>,
|
||||
},
|
||||
|
||||
/// Run wasm-pack tests
|
||||
WasmPack {
|
||||
#[clap(subcommand)]
|
||||
cmd: Option<WasmFeatureSet>,
|
||||
},
|
||||
|
||||
/// Run tests for the different crypto crate features
|
||||
TestCrypto,
|
||||
|
||||
/// Check that bindings can be generated
|
||||
Bindings,
|
||||
|
||||
/// Check that the examples compile
|
||||
Examples,
|
||||
}
|
||||
@@ -91,6 +103,7 @@ impl CiArgs {
|
||||
CiCommand::Wasm { cmd } => run_wasm_checks(cmd),
|
||||
CiCommand::WasmPack { cmd } => run_wasm_pack_tests(cmd),
|
||||
CiCommand::TestCrypto => run_crypto_tests(),
|
||||
CiCommand::Bindings => check_bindings(),
|
||||
CiCommand::Examples => check_examples(),
|
||||
},
|
||||
None => {
|
||||
@@ -110,6 +123,34 @@ impl CiArgs {
|
||||
}
|
||||
}
|
||||
|
||||
fn check_bindings() -> Result<()> {
|
||||
cmd!("rustup run stable cargo build -p matrix-sdk-crypto-ffi -p matrix-sdk-ffi").run()?;
|
||||
cmd!(
|
||||
"
|
||||
uniffi-bindgen generate
|
||||
--language kotlin
|
||||
--language swift
|
||||
--lib-file target/debug/libmatrix_sdk_ffi.a
|
||||
--out-dir target/generated-bindings
|
||||
bindings/matrix-sdk-ffi/src/api.udl
|
||||
"
|
||||
)
|
||||
.run()?;
|
||||
cmd!(
|
||||
"
|
||||
uniffi-bindgen generate
|
||||
--language kotlin
|
||||
--language swift
|
||||
--lib-file target/debug/libmatrix_sdk_crypto_ffi.a
|
||||
--out-dir target/generated-bindings
|
||||
bindings/matrix-sdk-crypto-ffi/src/olm.udl
|
||||
"
|
||||
)
|
||||
.run()?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn check_examples() -> Result<()> {
|
||||
cmd!("rustup run stable cargo check -p example-*").run()?;
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user