├── .devcontainer └── devcontainer.json ├── .github ├── dependabot.yml └── workflows │ └── ci.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md └── src ├── command.rs ├── command ├── loggedin.rs └── loggedin │ ├── room.rs │ └── room │ └── user.rs ├── dir.rs ├── main.rs └── matrix.rs /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | // Based on https://github.com/microsoft/vscode-dev-containers/tree/main/containers/rust 3 | "name": "Rust", 4 | "image": "mcr.microsoft.com/vscode/devcontainers/rust", 5 | "runArgs": [ 6 | "--cap-add=SYS_PTRACE", 7 | "--security-opt", 8 | "seccomp=unconfined" 9 | ], 10 | // Configure tool-specific properties. 11 | "customizations": { 12 | // Configure properties specific to VS Code. 13 | "vscode": { 14 | // Set *default* container specific settings.json values on container create. 15 | "settings": { 16 | "lldb.executable": "/usr/bin/lldb", 17 | // VS Code don't watch files under ./target 18 | "files.watcherExclude": { 19 | "**/target/**": true 20 | }, 21 | "rust-analyzer.checkOnSave.command": "clippy" 22 | }, 23 | // Add the IDs of extensions you want installed when the container is created. 24 | "extensions": [ 25 | "vadimcn.vscode-lldb", 26 | "mutantdino.resourcemonitor", 27 | "rust-lang.rust-analyzer", 28 | "tamasfe.even-better-toml", 29 | "serayuzgur.crates" 30 | ] 31 | } 32 | }, 33 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 34 | // "forwardPorts": [], 35 | // Use 'postCreateCommand' to run commands after the container is created. 36 | // "postCreateCommand": "rustc --version", 37 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 38 | "remoteUser": "vscode" 39 | } -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: cargo 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: Continuous integration 2 | 3 | on: 4 | push: 5 | pull_request: 6 | schedule: [cron: "40 1 * * *"] 7 | 8 | jobs: 9 | ci: 10 | name: Rust ${{matrix.rust}} 11 | runs-on: ubuntu-latest 12 | strategy: 13 | matrix: 14 | rust: 15 | - stable 16 | - beta 17 | - nightly 18 | 19 | steps: 20 | - name: Checkout sources 21 | uses: actions/checkout@v2 22 | 23 | - name: Install ${{matrix.rust}} toolchain 24 | uses: actions-rs/toolchain@v1 25 | with: 26 | profile: minimal 27 | toolchain: ${{ matrix.rust }} 28 | override: true 29 | components: rustfmt, clippy 30 | 31 | - name: Run cargo build 32 | uses: actions-rs/cargo@v1 33 | with: 34 | command: build 35 | 36 | - name: Run cargo test 37 | uses: actions-rs/cargo@v1 38 | with: 39 | command: test 40 | 41 | - name: Run cargo fmt 42 | uses: actions-rs/cargo@v1 43 | with: 44 | command: fmt 45 | args: --all -- --check 46 | 47 | - name: Run cargo clippy 48 | uses: actions-rs/cargo@v1 49 | with: 50 | command: clippy 51 | args: -- -D warnings 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "ahash" 7 | version = "0.7.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" 10 | dependencies = [ 11 | "getrandom 0.2.7", 12 | "once_cell", 13 | "version_check", 14 | ] 15 | 16 | [[package]] 17 | name = "anymap2" 18 | version = "0.13.0" 19 | source = "registry+https://github.com/rust-lang/crates.io-index" 20 | checksum = "d301b3b94cb4b2f23d7917810addbbaff90738e0ca2be692bd027e70d7e0330c" 21 | 22 | [[package]] 23 | name = "assign" 24 | version = "1.1.1" 25 | source = "registry+https://github.com/rust-lang/crates.io-index" 26 | checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" 27 | 28 | [[package]] 29 | name = "async-lock" 30 | version = "2.5.0" 31 | source = "registry+https://github.com/rust-lang/crates.io-index" 32 | checksum = "e97a171d191782fba31bb902b14ad94e24a68145032b7eedf871ab0bc0d077b6" 33 | dependencies = [ 34 | "event-listener", 35 | ] 36 | 37 | [[package]] 38 | name = "async-once-cell" 39 | version = "0.3.1" 40 | source = "registry+https://github.com/rust-lang/crates.io-index" 41 | checksum = "72faff1fdc615a0199d7bf71e6f389af54d46a66e9beb5d76c39e48eda93ecce" 42 | 43 | [[package]] 44 | name = "async-stream" 45 | version = "0.3.3" 46 | source = "registry+https://github.com/rust-lang/crates.io-index" 47 | checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" 48 | dependencies = [ 49 | "async-stream-impl", 50 | "futures-core", 51 | ] 52 | 53 | [[package]] 54 | name = "async-stream-impl" 55 | version = "0.3.3" 56 | source = "registry+https://github.com/rust-lang/crates.io-index" 57 | checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" 58 | dependencies = [ 59 | "proc-macro2", 60 | "quote", 61 | "syn", 62 | ] 63 | 64 | [[package]] 65 | name = "async-trait" 66 | version = "0.1.56" 67 | source = "registry+https://github.com/rust-lang/crates.io-index" 68 | checksum = "96cf8829f67d2eab0b2dfa42c5d0ef737e0724e4a82b01b3e292456202b19716" 69 | dependencies = [ 70 | "proc-macro2", 71 | "quote", 72 | "syn", 73 | ] 74 | 75 | [[package]] 76 | name = "atty" 77 | version = "0.2.14" 78 | source = "registry+https://github.com/rust-lang/crates.io-index" 79 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 80 | dependencies = [ 81 | "hermit-abi", 82 | "libc", 83 | "winapi", 84 | ] 85 | 86 | [[package]] 87 | name = "autocfg" 88 | version = "1.1.0" 89 | source = "registry+https://github.com/rust-lang/crates.io-index" 90 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 91 | 92 | [[package]] 93 | name = "backoff" 94 | version = "0.4.0" 95 | source = "registry+https://github.com/rust-lang/crates.io-index" 96 | checksum = "b62ddb9cb1ec0a098ad4bbf9344d0713fa193ae1a80af55febcff2627b6a00c1" 97 | dependencies = [ 98 | "futures-core", 99 | "getrandom 0.2.7", 100 | "instant", 101 | "pin-project-lite", 102 | "rand 0.8.5", 103 | "tokio", 104 | ] 105 | 106 | [[package]] 107 | name = "base64" 108 | version = "0.13.0" 109 | source = "registry+https://github.com/rust-lang/crates.io-index" 110 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" 111 | 112 | [[package]] 113 | name = "bitflags" 114 | version = "1.3.2" 115 | source = "registry+https://github.com/rust-lang/crates.io-index" 116 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 117 | 118 | [[package]] 119 | name = "block-buffer" 120 | version = "0.9.0" 121 | source = "registry+https://github.com/rust-lang/crates.io-index" 122 | checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" 123 | dependencies = [ 124 | "generic-array", 125 | ] 126 | 127 | [[package]] 128 | name = "bumpalo" 129 | version = "3.10.0" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "37ccbd214614c6783386c1af30caf03192f17891059cecc394b4fb119e363de3" 132 | 133 | [[package]] 134 | name = "byteorder" 135 | version = "1.4.3" 136 | source = "registry+https://github.com/rust-lang/crates.io-index" 137 | checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" 138 | 139 | [[package]] 140 | name = "bytes" 141 | version = "1.1.0" 142 | source = "registry+https://github.com/rust-lang/crates.io-index" 143 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" 144 | 145 | [[package]] 146 | name = "cc" 147 | version = "1.0.73" 148 | source = "registry+https://github.com/rust-lang/crates.io-index" 149 | checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11" 150 | 151 | [[package]] 152 | name = "cfg-if" 153 | version = "1.0.0" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 156 | 157 | [[package]] 158 | name = "clap" 159 | version = "3.2.21" 160 | source = "registry+https://github.com/rust-lang/crates.io-index" 161 | checksum = "1ed5341b2301a26ab80be5cbdced622e80ed808483c52e45e3310a877d3b37d7" 162 | dependencies = [ 163 | "atty", 164 | "bitflags", 165 | "clap_derive", 166 | "clap_lex", 167 | "indexmap", 168 | "once_cell", 169 | "strsim", 170 | "termcolor", 171 | "textwrap", 172 | ] 173 | 174 | [[package]] 175 | name = "clap_derive" 176 | version = "3.2.18" 177 | source = "registry+https://github.com/rust-lang/crates.io-index" 178 | checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" 179 | dependencies = [ 180 | "heck", 181 | "proc-macro-error", 182 | "proc-macro2", 183 | "quote", 184 | "syn", 185 | ] 186 | 187 | [[package]] 188 | name = "clap_lex" 189 | version = "0.2.3" 190 | source = "registry+https://github.com/rust-lang/crates.io-index" 191 | checksum = "87eba3c8c7f42ef17f6c659fc7416d0f4758cd3e58861ee63c5fa4a4dde649e4" 192 | dependencies = [ 193 | "os_str_bytes", 194 | ] 195 | 196 | [[package]] 197 | name = "const-oid" 198 | version = "0.6.2" 199 | source = "registry+https://github.com/rust-lang/crates.io-index" 200 | checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" 201 | 202 | [[package]] 203 | name = "cpufeatures" 204 | version = "0.2.2" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "59a6001667ab124aebae2a495118e11d30984c3a653e99d86d58971708cf5e4b" 207 | dependencies = [ 208 | "libc", 209 | ] 210 | 211 | [[package]] 212 | name = "curve25519-dalek" 213 | version = "3.2.0" 214 | source = "registry+https://github.com/rust-lang/crates.io-index" 215 | checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" 216 | dependencies = [ 217 | "byteorder", 218 | "digest", 219 | "rand_core 0.5.1", 220 | "subtle", 221 | "zeroize", 222 | ] 223 | 224 | [[package]] 225 | name = "dashmap" 226 | version = "5.3.4" 227 | source = "registry+https://github.com/rust-lang/crates.io-index" 228 | checksum = "3495912c9c1ccf2e18976439f4443f3fee0fd61f424ff99fde6a66b15ecb448f" 229 | dependencies = [ 230 | "cfg-if", 231 | "hashbrown 0.12.1", 232 | "lock_api", 233 | "parking_lot_core 0.9.3", 234 | ] 235 | 236 | [[package]] 237 | name = "der" 238 | version = "0.4.5" 239 | source = "registry+https://github.com/rust-lang/crates.io-index" 240 | checksum = "79b71cca7d95d7681a4b3b9cdf63c8dbc3730d0584c2c74e31416d64a90493f4" 241 | dependencies = [ 242 | "const-oid", 243 | ] 244 | 245 | [[package]] 246 | name = "digest" 247 | version = "0.9.0" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" 250 | dependencies = [ 251 | "generic-array", 252 | ] 253 | 254 | [[package]] 255 | name = "directories" 256 | version = "4.0.1" 257 | source = "registry+https://github.com/rust-lang/crates.io-index" 258 | checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210" 259 | dependencies = [ 260 | "dirs-sys", 261 | ] 262 | 263 | [[package]] 264 | name = "dirs-sys" 265 | version = "0.3.7" 266 | source = "registry+https://github.com/rust-lang/crates.io-index" 267 | checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" 268 | dependencies = [ 269 | "libc", 270 | "redox_users", 271 | "winapi", 272 | ] 273 | 274 | [[package]] 275 | name = "ed25519" 276 | version = "1.5.2" 277 | source = "registry+https://github.com/rust-lang/crates.io-index" 278 | checksum = "1e9c280362032ea4203659fc489832d0204ef09f247a0506f170dafcac08c369" 279 | dependencies = [ 280 | "signature", 281 | ] 282 | 283 | [[package]] 284 | name = "ed25519-dalek" 285 | version = "1.0.1" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" 288 | dependencies = [ 289 | "curve25519-dalek", 290 | "ed25519", 291 | "rand 0.7.3", 292 | "serde", 293 | "sha2", 294 | "zeroize", 295 | ] 296 | 297 | [[package]] 298 | name = "either" 299 | version = "1.6.1" 300 | source = "registry+https://github.com/rust-lang/crates.io-index" 301 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" 302 | 303 | [[package]] 304 | name = "encoding_rs" 305 | version = "0.8.31" 306 | source = "registry+https://github.com/rust-lang/crates.io-index" 307 | checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" 308 | dependencies = [ 309 | "cfg-if", 310 | ] 311 | 312 | [[package]] 313 | name = "event-listener" 314 | version = "2.5.2" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "77f3309417938f28bf8228fcff79a4a37103981e3e186d2ccd19c74b38f4eb71" 317 | 318 | [[package]] 319 | name = "fnv" 320 | version = "1.0.7" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 323 | 324 | [[package]] 325 | name = "form_urlencoded" 326 | version = "1.1.0" 327 | source = "registry+https://github.com/rust-lang/crates.io-index" 328 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 329 | dependencies = [ 330 | "percent-encoding", 331 | ] 332 | 333 | [[package]] 334 | name = "futures" 335 | version = "0.3.21" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "f73fe65f54d1e12b726f517d3e2135ca3125a437b6d998caf1962961f7172d9e" 338 | dependencies = [ 339 | "futures-channel", 340 | "futures-core", 341 | "futures-executor", 342 | "futures-io", 343 | "futures-sink", 344 | "futures-task", 345 | "futures-util", 346 | ] 347 | 348 | [[package]] 349 | name = "futures-channel" 350 | version = "0.3.21" 351 | source = "registry+https://github.com/rust-lang/crates.io-index" 352 | checksum = "c3083ce4b914124575708913bca19bfe887522d6e2e6d0952943f5eac4a74010" 353 | dependencies = [ 354 | "futures-core", 355 | "futures-sink", 356 | ] 357 | 358 | [[package]] 359 | name = "futures-core" 360 | version = "0.3.21" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "0c09fd04b7e4073ac7156a9539b57a484a8ea920f79c7c675d05d289ab6110d3" 363 | 364 | [[package]] 365 | name = "futures-executor" 366 | version = "0.3.21" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "9420b90cfa29e327d0429f19be13e7ddb68fa1cccb09d65e5706b8c7a749b8a6" 369 | dependencies = [ 370 | "futures-core", 371 | "futures-task", 372 | "futures-util", 373 | ] 374 | 375 | [[package]] 376 | name = "futures-io" 377 | version = "0.3.21" 378 | source = "registry+https://github.com/rust-lang/crates.io-index" 379 | checksum = "fc4045962a5a5e935ee2fdedaa4e08284547402885ab326734432bed5d12966b" 380 | 381 | [[package]] 382 | name = "futures-macro" 383 | version = "0.3.21" 384 | source = "registry+https://github.com/rust-lang/crates.io-index" 385 | checksum = "33c1e13800337f4d4d7a316bf45a567dbcb6ffe087f16424852d97e97a91f512" 386 | dependencies = [ 387 | "proc-macro2", 388 | "quote", 389 | "syn", 390 | ] 391 | 392 | [[package]] 393 | name = "futures-sink" 394 | version = "0.3.21" 395 | source = "registry+https://github.com/rust-lang/crates.io-index" 396 | checksum = "21163e139fa306126e6eedaf49ecdb4588f939600f0b1e770f4205ee4b7fa868" 397 | 398 | [[package]] 399 | name = "futures-task" 400 | version = "0.3.21" 401 | source = "registry+https://github.com/rust-lang/crates.io-index" 402 | checksum = "57c66a976bf5909d801bbef33416c41372779507e7a6b3a5e25e4749c58f776a" 403 | 404 | [[package]] 405 | name = "futures-util" 406 | version = "0.3.21" 407 | source = "registry+https://github.com/rust-lang/crates.io-index" 408 | checksum = "d8b7abd5d659d9b90c8cba917f6ec750a74e2dc23902ef9cd4cc8c8b22e6036a" 409 | dependencies = [ 410 | "futures-channel", 411 | "futures-core", 412 | "futures-io", 413 | "futures-macro", 414 | "futures-sink", 415 | "futures-task", 416 | "memchr", 417 | "pin-project-lite", 418 | "pin-utils", 419 | "slab", 420 | ] 421 | 422 | [[package]] 423 | name = "generic-array" 424 | version = "0.14.5" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "fd48d33ec7f05fbfa152300fdad764757cbded343c1aa1cff2fbaf4134851803" 427 | dependencies = [ 428 | "typenum", 429 | "version_check", 430 | ] 431 | 432 | [[package]] 433 | name = "getrandom" 434 | version = "0.1.16" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" 437 | dependencies = [ 438 | "cfg-if", 439 | "libc", 440 | "wasi 0.9.0+wasi-snapshot-preview1", 441 | ] 442 | 443 | [[package]] 444 | name = "getrandom" 445 | version = "0.2.7" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "4eb1a864a501629691edf6c15a593b7a51eebaa1e8468e9ddc623de7c9b58ec6" 448 | dependencies = [ 449 | "cfg-if", 450 | "js-sys", 451 | "libc", 452 | "wasi 0.11.0+wasi-snapshot-preview1", 453 | "wasm-bindgen", 454 | ] 455 | 456 | [[package]] 457 | name = "h2" 458 | version = "0.3.13" 459 | source = "registry+https://github.com/rust-lang/crates.io-index" 460 | checksum = "37a82c6d637fc9515a4694bbf1cb2457b79d81ce52b3108bdeea58b07dd34a57" 461 | dependencies = [ 462 | "bytes", 463 | "fnv", 464 | "futures-core", 465 | "futures-sink", 466 | "futures-util", 467 | "http", 468 | "indexmap", 469 | "slab", 470 | "tokio", 471 | "tokio-util", 472 | "tracing", 473 | ] 474 | 475 | [[package]] 476 | name = "hashbrown" 477 | version = "0.11.2" 478 | source = "registry+https://github.com/rust-lang/crates.io-index" 479 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" 480 | dependencies = [ 481 | "ahash", 482 | ] 483 | 484 | [[package]] 485 | name = "hashbrown" 486 | version = "0.12.1" 487 | source = "registry+https://github.com/rust-lang/crates.io-index" 488 | checksum = "db0d4cf898abf0081f964436dc980e96670a0f36863e4b83aaacdb65c9d7ccc3" 489 | 490 | [[package]] 491 | name = "heck" 492 | version = "0.4.0" 493 | source = "registry+https://github.com/rust-lang/crates.io-index" 494 | checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" 495 | 496 | [[package]] 497 | name = "hermit-abi" 498 | version = "0.1.19" 499 | source = "registry+https://github.com/rust-lang/crates.io-index" 500 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 501 | dependencies = [ 502 | "libc", 503 | ] 504 | 505 | [[package]] 506 | name = "http" 507 | version = "0.2.8" 508 | source = "registry+https://github.com/rust-lang/crates.io-index" 509 | checksum = "75f43d41e26995c17e71ee126451dd3941010b0514a81a9d11f3b341debc2399" 510 | dependencies = [ 511 | "bytes", 512 | "fnv", 513 | "itoa", 514 | ] 515 | 516 | [[package]] 517 | name = "http-body" 518 | version = "0.4.5" 519 | source = "registry+https://github.com/rust-lang/crates.io-index" 520 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 521 | dependencies = [ 522 | "bytes", 523 | "http", 524 | "pin-project-lite", 525 | ] 526 | 527 | [[package]] 528 | name = "httparse" 529 | version = "1.7.1" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "496ce29bb5a52785b44e0f7ca2847ae0bb839c9bd28f69acac9b99d461c0c04c" 532 | 533 | [[package]] 534 | name = "httpdate" 535 | version = "1.0.2" 536 | source = "registry+https://github.com/rust-lang/crates.io-index" 537 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 538 | 539 | [[package]] 540 | name = "hyper" 541 | version = "0.14.19" 542 | source = "registry+https://github.com/rust-lang/crates.io-index" 543 | checksum = "42dc3c131584288d375f2d07f822b0cb012d8c6fb899a5b9fdb3cb7eb9b6004f" 544 | dependencies = [ 545 | "bytes", 546 | "futures-channel", 547 | "futures-core", 548 | "futures-util", 549 | "h2", 550 | "http", 551 | "http-body", 552 | "httparse", 553 | "httpdate", 554 | "itoa", 555 | "pin-project-lite", 556 | "socket2", 557 | "tokio", 558 | "tower-service", 559 | "tracing", 560 | "want", 561 | ] 562 | 563 | [[package]] 564 | name = "hyper-rustls" 565 | version = "0.23.0" 566 | source = "registry+https://github.com/rust-lang/crates.io-index" 567 | checksum = "d87c48c02e0dc5e3b849a2041db3029fd066650f8f717c07bf8ed78ccb895cac" 568 | dependencies = [ 569 | "http", 570 | "hyper", 571 | "rustls", 572 | "tokio", 573 | "tokio-rustls", 574 | ] 575 | 576 | [[package]] 577 | name = "idna" 578 | version = "0.3.0" 579 | source = "registry+https://github.com/rust-lang/crates.io-index" 580 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 581 | dependencies = [ 582 | "unicode-bidi", 583 | "unicode-normalization", 584 | ] 585 | 586 | [[package]] 587 | name = "indexmap" 588 | version = "1.9.1" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" 591 | dependencies = [ 592 | "autocfg", 593 | "hashbrown 0.12.1", 594 | "serde", 595 | ] 596 | 597 | [[package]] 598 | name = "instant" 599 | version = "0.1.12" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" 602 | dependencies = [ 603 | "cfg-if", 604 | "js-sys", 605 | "wasm-bindgen", 606 | "web-sys", 607 | ] 608 | 609 | [[package]] 610 | name = "ipnet" 611 | version = "2.5.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" 614 | 615 | [[package]] 616 | name = "itertools" 617 | version = "0.10.3" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3" 620 | dependencies = [ 621 | "either", 622 | ] 623 | 624 | [[package]] 625 | name = "itoa" 626 | version = "1.0.2" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d" 629 | 630 | [[package]] 631 | name = "js-sys" 632 | version = "0.3.58" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "c3fac17f7123a73ca62df411b1bf727ccc805daa070338fda671c86dac1bdc27" 635 | dependencies = [ 636 | "wasm-bindgen", 637 | ] 638 | 639 | [[package]] 640 | name = "js_int" 641 | version = "0.2.2" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "d937f95470b270ce8b8950207715d71aa8e153c0d44c6684d59397ed4949160a" 644 | dependencies = [ 645 | "serde", 646 | ] 647 | 648 | [[package]] 649 | name = "js_option" 650 | version = "0.1.1" 651 | source = "registry+https://github.com/rust-lang/crates.io-index" 652 | checksum = "68421373957a1593a767013698dbf206e2b221eefe97a44d98d18672ff38423c" 653 | dependencies = [ 654 | "serde", 655 | ] 656 | 657 | [[package]] 658 | name = "lazy_static" 659 | version = "1.4.0" 660 | source = "registry+https://github.com/rust-lang/crates.io-index" 661 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 662 | 663 | [[package]] 664 | name = "libc" 665 | version = "0.2.126" 666 | source = "registry+https://github.com/rust-lang/crates.io-index" 667 | checksum = "349d5a591cd28b49e1d1037471617a32ddcda5731b99419008085f72d5a53836" 668 | 669 | [[package]] 670 | name = "lock_api" 671 | version = "0.4.7" 672 | source = "registry+https://github.com/rust-lang/crates.io-index" 673 | checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" 674 | dependencies = [ 675 | "autocfg", 676 | "scopeguard", 677 | ] 678 | 679 | [[package]] 680 | name = "log" 681 | version = "0.4.17" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 684 | dependencies = [ 685 | "cfg-if", 686 | ] 687 | 688 | [[package]] 689 | name = "lru" 690 | version = "0.7.7" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "c84e6fe5655adc6ce00787cf7dcaf8dc4f998a0565d23eafc207a8b08ca3349a" 693 | dependencies = [ 694 | "hashbrown 0.11.2", 695 | ] 696 | 697 | [[package]] 698 | name = "maplit" 699 | version = "1.0.2" 700 | source = "registry+https://github.com/rust-lang/crates.io-index" 701 | checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" 702 | 703 | [[package]] 704 | name = "matrix-sdk" 705 | version = "0.5.0" 706 | source = "registry+https://github.com/rust-lang/crates.io-index" 707 | checksum = "6afed7115d3dbf0c91c062b2904c964e2405b2e1f8de5511c5eeae7583b70ebe" 708 | dependencies = [ 709 | "anymap2", 710 | "async-once-cell", 711 | "async-stream", 712 | "async-trait", 713 | "backoff", 714 | "bytes", 715 | "dashmap", 716 | "event-listener", 717 | "futures-core", 718 | "futures-util", 719 | "http", 720 | "matrix-sdk-base", 721 | "matrix-sdk-common", 722 | "mime", 723 | "reqwest", 724 | "ruma", 725 | "serde", 726 | "serde_json", 727 | "thiserror", 728 | "tokio", 729 | "tracing", 730 | "url", 731 | "wasm-timer", 732 | "zeroize", 733 | ] 734 | 735 | [[package]] 736 | name = "matrix-sdk-base" 737 | version = "0.5.1" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "f59a52c744df124832643ecfc03ffb468023e9c3644477f41bf316d500df9504" 740 | dependencies = [ 741 | "async-stream", 742 | "async-trait", 743 | "dashmap", 744 | "futures-channel", 745 | "futures-core", 746 | "futures-util", 747 | "lru", 748 | "matrix-sdk-common", 749 | "ruma", 750 | "serde", 751 | "serde_json", 752 | "thiserror", 753 | "tracing", 754 | "zeroize", 755 | ] 756 | 757 | [[package]] 758 | name = "matrix-sdk-common" 759 | version = "0.5.0" 760 | source = "registry+https://github.com/rust-lang/crates.io-index" 761 | checksum = "52a8af49e5b15c2dee4c0e867cd8065bb999cc63ff2500a0d35331188a9acbae" 762 | dependencies = [ 763 | "async-lock", 764 | "futures-util", 765 | "instant", 766 | "ruma", 767 | "serde", 768 | "tokio", 769 | "wasm-bindgen-futures", 770 | ] 771 | 772 | [[package]] 773 | name = "matrix-send" 774 | version = "0.2.1" 775 | dependencies = [ 776 | "atty", 777 | "clap", 778 | "directories", 779 | "matrix-sdk", 780 | "mime", 781 | "mime_guess", 782 | "serde", 783 | "serde_json", 784 | "thiserror", 785 | "tokio", 786 | "url", 787 | ] 788 | 789 | [[package]] 790 | name = "memchr" 791 | version = "2.5.0" 792 | source = "registry+https://github.com/rust-lang/crates.io-index" 793 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 794 | 795 | [[package]] 796 | name = "mime" 797 | version = "0.3.16" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" 800 | 801 | [[package]] 802 | name = "mime_guess" 803 | version = "2.0.4" 804 | source = "registry+https://github.com/rust-lang/crates.io-index" 805 | checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" 806 | dependencies = [ 807 | "mime", 808 | "unicase", 809 | ] 810 | 811 | [[package]] 812 | name = "mio" 813 | version = "0.8.4" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "57ee1c23c7c63b0c9250c339ffdc69255f110b298b901b9f6c82547b7b87caaf" 816 | dependencies = [ 817 | "libc", 818 | "log", 819 | "wasi 0.11.0+wasi-snapshot-preview1", 820 | "windows-sys", 821 | ] 822 | 823 | [[package]] 824 | name = "num_cpus" 825 | version = "1.13.1" 826 | source = "registry+https://github.com/rust-lang/crates.io-index" 827 | checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1" 828 | dependencies = [ 829 | "hermit-abi", 830 | "libc", 831 | ] 832 | 833 | [[package]] 834 | name = "once_cell" 835 | version = "1.12.0" 836 | source = "registry+https://github.com/rust-lang/crates.io-index" 837 | checksum = "7709cef83f0c1f58f666e746a08b21e0085f7440fa6a29cc194d68aac97a4225" 838 | 839 | [[package]] 840 | name = "opaque-debug" 841 | version = "0.3.0" 842 | source = "registry+https://github.com/rust-lang/crates.io-index" 843 | checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" 844 | 845 | [[package]] 846 | name = "os_str_bytes" 847 | version = "6.1.0" 848 | source = "registry+https://github.com/rust-lang/crates.io-index" 849 | checksum = "21326818e99cfe6ce1e524c2a805c189a99b5ae555a35d19f9a284b427d86afa" 850 | 851 | [[package]] 852 | name = "parking_lot" 853 | version = "0.11.2" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" 856 | dependencies = [ 857 | "instant", 858 | "lock_api", 859 | "parking_lot_core 0.8.5", 860 | ] 861 | 862 | [[package]] 863 | name = "parking_lot_core" 864 | version = "0.8.5" 865 | source = "registry+https://github.com/rust-lang/crates.io-index" 866 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" 867 | dependencies = [ 868 | "cfg-if", 869 | "instant", 870 | "libc", 871 | "redox_syscall", 872 | "smallvec", 873 | "winapi", 874 | ] 875 | 876 | [[package]] 877 | name = "parking_lot_core" 878 | version = "0.9.3" 879 | source = "registry+https://github.com/rust-lang/crates.io-index" 880 | checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" 881 | dependencies = [ 882 | "cfg-if", 883 | "libc", 884 | "redox_syscall", 885 | "smallvec", 886 | "windows-sys", 887 | ] 888 | 889 | [[package]] 890 | name = "percent-encoding" 891 | version = "2.2.0" 892 | source = "registry+https://github.com/rust-lang/crates.io-index" 893 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 894 | 895 | [[package]] 896 | name = "pin-project-lite" 897 | version = "0.2.9" 898 | source = "registry+https://github.com/rust-lang/crates.io-index" 899 | checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116" 900 | 901 | [[package]] 902 | name = "pin-utils" 903 | version = "0.1.0" 904 | source = "registry+https://github.com/rust-lang/crates.io-index" 905 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 906 | 907 | [[package]] 908 | name = "pkcs8" 909 | version = "0.7.6" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" 912 | dependencies = [ 913 | "der", 914 | "spki", 915 | "zeroize", 916 | ] 917 | 918 | [[package]] 919 | name = "ppv-lite86" 920 | version = "0.2.16" 921 | source = "registry+https://github.com/rust-lang/crates.io-index" 922 | checksum = "eb9f9e6e233e5c4a35559a617bf40a4ec447db2e84c20b55a6f83167b7e57872" 923 | 924 | [[package]] 925 | name = "proc-macro-crate" 926 | version = "1.1.3" 927 | source = "registry+https://github.com/rust-lang/crates.io-index" 928 | checksum = "e17d47ce914bf4de440332250b0edd23ce48c005f59fab39d3335866b114f11a" 929 | dependencies = [ 930 | "thiserror", 931 | "toml", 932 | ] 933 | 934 | [[package]] 935 | name = "proc-macro-error" 936 | version = "1.0.4" 937 | source = "registry+https://github.com/rust-lang/crates.io-index" 938 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 939 | dependencies = [ 940 | "proc-macro-error-attr", 941 | "proc-macro2", 942 | "quote", 943 | "syn", 944 | "version_check", 945 | ] 946 | 947 | [[package]] 948 | name = "proc-macro-error-attr" 949 | version = "1.0.4" 950 | source = "registry+https://github.com/rust-lang/crates.io-index" 951 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 952 | dependencies = [ 953 | "proc-macro2", 954 | "quote", 955 | "version_check", 956 | ] 957 | 958 | [[package]] 959 | name = "proc-macro2" 960 | version = "1.0.40" 961 | source = "registry+https://github.com/rust-lang/crates.io-index" 962 | checksum = "dd96a1e8ed2596c337f8eae5f24924ec83f5ad5ab21ea8e455d3566c69fbcaf7" 963 | dependencies = [ 964 | "unicode-ident", 965 | ] 966 | 967 | [[package]] 968 | name = "pulldown-cmark" 969 | version = "0.9.1" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "34f197a544b0c9ab3ae46c359a7ec9cbbb5c7bf97054266fecb7ead794a181d6" 972 | dependencies = [ 973 | "bitflags", 974 | "memchr", 975 | "unicase", 976 | ] 977 | 978 | [[package]] 979 | name = "quote" 980 | version = "1.0.20" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "3bcdf212e9776fbcb2d23ab029360416bb1706b1aea2d1a5ba002727cbcab804" 983 | dependencies = [ 984 | "proc-macro2", 985 | ] 986 | 987 | [[package]] 988 | name = "rand" 989 | version = "0.7.3" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" 992 | dependencies = [ 993 | "getrandom 0.1.16", 994 | "libc", 995 | "rand_chacha 0.2.2", 996 | "rand_core 0.5.1", 997 | "rand_hc", 998 | ] 999 | 1000 | [[package]] 1001 | name = "rand" 1002 | version = "0.8.5" 1003 | source = "registry+https://github.com/rust-lang/crates.io-index" 1004 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1005 | dependencies = [ 1006 | "libc", 1007 | "rand_chacha 0.3.1", 1008 | "rand_core 0.6.3", 1009 | ] 1010 | 1011 | [[package]] 1012 | name = "rand_chacha" 1013 | version = "0.2.2" 1014 | source = "registry+https://github.com/rust-lang/crates.io-index" 1015 | checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" 1016 | dependencies = [ 1017 | "ppv-lite86", 1018 | "rand_core 0.5.1", 1019 | ] 1020 | 1021 | [[package]] 1022 | name = "rand_chacha" 1023 | version = "0.3.1" 1024 | source = "registry+https://github.com/rust-lang/crates.io-index" 1025 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1026 | dependencies = [ 1027 | "ppv-lite86", 1028 | "rand_core 0.6.3", 1029 | ] 1030 | 1031 | [[package]] 1032 | name = "rand_core" 1033 | version = "0.5.1" 1034 | source = "registry+https://github.com/rust-lang/crates.io-index" 1035 | checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" 1036 | dependencies = [ 1037 | "getrandom 0.1.16", 1038 | ] 1039 | 1040 | [[package]] 1041 | name = "rand_core" 1042 | version = "0.6.3" 1043 | source = "registry+https://github.com/rust-lang/crates.io-index" 1044 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" 1045 | dependencies = [ 1046 | "getrandom 0.2.7", 1047 | ] 1048 | 1049 | [[package]] 1050 | name = "rand_hc" 1051 | version = "0.2.0" 1052 | source = "registry+https://github.com/rust-lang/crates.io-index" 1053 | checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" 1054 | dependencies = [ 1055 | "rand_core 0.5.1", 1056 | ] 1057 | 1058 | [[package]] 1059 | name = "redox_syscall" 1060 | version = "0.2.13" 1061 | source = "registry+https://github.com/rust-lang/crates.io-index" 1062 | checksum = "62f25bc4c7e55e0b0b7a1d43fb893f4fa1361d0abe38b9ce4f323c2adfe6ef42" 1063 | dependencies = [ 1064 | "bitflags", 1065 | ] 1066 | 1067 | [[package]] 1068 | name = "redox_users" 1069 | version = "0.4.3" 1070 | source = "registry+https://github.com/rust-lang/crates.io-index" 1071 | checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b" 1072 | dependencies = [ 1073 | "getrandom 0.2.7", 1074 | "redox_syscall", 1075 | "thiserror", 1076 | ] 1077 | 1078 | [[package]] 1079 | name = "reqwest" 1080 | version = "0.11.11" 1081 | source = "registry+https://github.com/rust-lang/crates.io-index" 1082 | checksum = "b75aa69a3f06bbcc66ede33af2af253c6f7a86b1ca0033f60c580a27074fbf92" 1083 | dependencies = [ 1084 | "base64", 1085 | "bytes", 1086 | "encoding_rs", 1087 | "futures-core", 1088 | "futures-util", 1089 | "h2", 1090 | "http", 1091 | "http-body", 1092 | "hyper", 1093 | "hyper-rustls", 1094 | "ipnet", 1095 | "js-sys", 1096 | "lazy_static", 1097 | "log", 1098 | "mime", 1099 | "percent-encoding", 1100 | "pin-project-lite", 1101 | "rustls", 1102 | "rustls-pemfile", 1103 | "serde", 1104 | "serde_json", 1105 | "serde_urlencoded", 1106 | "tokio", 1107 | "tokio-rustls", 1108 | "tower-service", 1109 | "url", 1110 | "wasm-bindgen", 1111 | "wasm-bindgen-futures", 1112 | "web-sys", 1113 | "webpki-roots", 1114 | "winreg", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "ring" 1119 | version = "0.16.20" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1122 | dependencies = [ 1123 | "cc", 1124 | "libc", 1125 | "once_cell", 1126 | "spin", 1127 | "untrusted", 1128 | "web-sys", 1129 | "winapi", 1130 | ] 1131 | 1132 | [[package]] 1133 | name = "ruma" 1134 | version = "0.6.4" 1135 | source = "registry+https://github.com/rust-lang/crates.io-index" 1136 | checksum = "6602cb2ef70629013d1bfade5aeb775d971a5d87f008dd6a8c99566235fa1933" 1137 | dependencies = [ 1138 | "assign", 1139 | "js_int", 1140 | "ruma-client-api", 1141 | "ruma-common", 1142 | "ruma-federation-api", 1143 | "ruma-signatures", 1144 | "ruma-state-res", 1145 | ] 1146 | 1147 | [[package]] 1148 | name = "ruma-client-api" 1149 | version = "0.14.1" 1150 | source = "registry+https://github.com/rust-lang/crates.io-index" 1151 | checksum = "4339827423dbb3b4f86cb191a38621f12daef73cb304ffd4e050c9ee553ecbd6" 1152 | dependencies = [ 1153 | "assign", 1154 | "bytes", 1155 | "http", 1156 | "js_int", 1157 | "maplit", 1158 | "percent-encoding", 1159 | "ruma-common", 1160 | "serde", 1161 | "serde_json", 1162 | ] 1163 | 1164 | [[package]] 1165 | name = "ruma-common" 1166 | version = "0.9.3" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "8ec5360fd23ff56310f9eb571927614feeecceba91fe2d4937f031c236c0e86e" 1169 | dependencies = [ 1170 | "base64", 1171 | "bytes", 1172 | "form_urlencoded", 1173 | "getrandom 0.2.7", 1174 | "http", 1175 | "indexmap", 1176 | "itoa", 1177 | "js-sys", 1178 | "js_int", 1179 | "js_option", 1180 | "percent-encoding", 1181 | "pulldown-cmark", 1182 | "rand 0.8.5", 1183 | "ruma-identifiers-validation", 1184 | "ruma-macros", 1185 | "serde", 1186 | "serde_json", 1187 | "thiserror", 1188 | "tracing", 1189 | "url", 1190 | "uuid", 1191 | "wildmatch", 1192 | ] 1193 | 1194 | [[package]] 1195 | name = "ruma-federation-api" 1196 | version = "0.5.0" 1197 | source = "registry+https://github.com/rust-lang/crates.io-index" 1198 | checksum = "caa53fa447e3ef04889f3f804d49a27045da79e8055f6fd4257c21be6f65edca" 1199 | dependencies = [ 1200 | "js_int", 1201 | "ruma-common", 1202 | "serde", 1203 | "serde_json", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "ruma-identifiers-validation" 1208 | version = "0.8.1" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "74c3b1d01b5ddd8746f25d5971bc1cac5d7f1f455de839a2f817b9e04953a139" 1211 | dependencies = [ 1212 | "thiserror", 1213 | ] 1214 | 1215 | [[package]] 1216 | name = "ruma-macros" 1217 | version = "0.9.3" 1218 | source = "registry+https://github.com/rust-lang/crates.io-index" 1219 | checksum = "ee1a4faf04110071ce7ca438ad0763bdaa5514395593596320c0ca0936519656" 1220 | dependencies = [ 1221 | "proc-macro-crate", 1222 | "proc-macro2", 1223 | "quote", 1224 | "ruma-identifiers-validation", 1225 | "syn", 1226 | ] 1227 | 1228 | [[package]] 1229 | name = "ruma-signatures" 1230 | version = "0.11.0" 1231 | source = "registry+https://github.com/rust-lang/crates.io-index" 1232 | checksum = "8c747652a4f8c5fd83a703f183c73738b2ed8565a740636c045e064ae77f9b51" 1233 | dependencies = [ 1234 | "base64", 1235 | "ed25519-dalek", 1236 | "pkcs8", 1237 | "rand 0.7.3", 1238 | "ruma-common", 1239 | "serde_json", 1240 | "sha2", 1241 | "thiserror", 1242 | "tracing", 1243 | ] 1244 | 1245 | [[package]] 1246 | name = "ruma-state-res" 1247 | version = "0.7.0" 1248 | source = "registry+https://github.com/rust-lang/crates.io-index" 1249 | checksum = "c9b742ca53b37ec3b3cfba1f27bf64be775550aeadf971deb05e4b93cdd27fbe" 1250 | dependencies = [ 1251 | "itertools", 1252 | "js_int", 1253 | "ruma-common", 1254 | "serde", 1255 | "serde_json", 1256 | "thiserror", 1257 | "tracing", 1258 | ] 1259 | 1260 | [[package]] 1261 | name = "rustls" 1262 | version = "0.20.6" 1263 | source = "registry+https://github.com/rust-lang/crates.io-index" 1264 | checksum = "5aab8ee6c7097ed6057f43c187a62418d0c05a4bd5f18b3571db50ee0f9ce033" 1265 | dependencies = [ 1266 | "log", 1267 | "ring", 1268 | "sct", 1269 | "webpki", 1270 | ] 1271 | 1272 | [[package]] 1273 | name = "rustls-pemfile" 1274 | version = "1.0.0" 1275 | source = "registry+https://github.com/rust-lang/crates.io-index" 1276 | checksum = "e7522c9de787ff061458fe9a829dc790a3f5b22dc571694fc5883f448b94d9a9" 1277 | dependencies = [ 1278 | "base64", 1279 | ] 1280 | 1281 | [[package]] 1282 | name = "ryu" 1283 | version = "1.0.10" 1284 | source = "registry+https://github.com/rust-lang/crates.io-index" 1285 | checksum = "f3f6f92acf49d1b98f7a81226834412ada05458b7364277387724a237f062695" 1286 | 1287 | [[package]] 1288 | name = "scopeguard" 1289 | version = "1.1.0" 1290 | source = "registry+https://github.com/rust-lang/crates.io-index" 1291 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1292 | 1293 | [[package]] 1294 | name = "sct" 1295 | version = "0.7.0" 1296 | source = "registry+https://github.com/rust-lang/crates.io-index" 1297 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1298 | dependencies = [ 1299 | "ring", 1300 | "untrusted", 1301 | ] 1302 | 1303 | [[package]] 1304 | name = "serde" 1305 | version = "1.0.145" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "728eb6351430bccb993660dfffc5a72f91ccc1295abaa8ce19b27ebe4f75568b" 1308 | dependencies = [ 1309 | "serde_derive", 1310 | ] 1311 | 1312 | [[package]] 1313 | name = "serde_derive" 1314 | version = "1.0.145" 1315 | source = "registry+https://github.com/rust-lang/crates.io-index" 1316 | checksum = "81fa1584d3d1bcacd84c277a0dfe21f5b0f6accf4a23d04d4c6d61f1af522b4c" 1317 | dependencies = [ 1318 | "proc-macro2", 1319 | "quote", 1320 | "syn", 1321 | ] 1322 | 1323 | [[package]] 1324 | name = "serde_json" 1325 | version = "1.0.87" 1326 | source = "registry+https://github.com/rust-lang/crates.io-index" 1327 | checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" 1328 | dependencies = [ 1329 | "itoa", 1330 | "ryu", 1331 | "serde", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "serde_urlencoded" 1336 | version = "0.7.1" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 1339 | dependencies = [ 1340 | "form_urlencoded", 1341 | "itoa", 1342 | "ryu", 1343 | "serde", 1344 | ] 1345 | 1346 | [[package]] 1347 | name = "sha2" 1348 | version = "0.9.9" 1349 | source = "registry+https://github.com/rust-lang/crates.io-index" 1350 | checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" 1351 | dependencies = [ 1352 | "block-buffer", 1353 | "cfg-if", 1354 | "cpufeatures", 1355 | "digest", 1356 | "opaque-debug", 1357 | ] 1358 | 1359 | [[package]] 1360 | name = "signature" 1361 | version = "1.5.0" 1362 | source = "registry+https://github.com/rust-lang/crates.io-index" 1363 | checksum = "f054c6c1a6e95179d6f23ed974060dcefb2d9388bb7256900badad682c499de4" 1364 | 1365 | [[package]] 1366 | name = "slab" 1367 | version = "0.4.6" 1368 | source = "registry+https://github.com/rust-lang/crates.io-index" 1369 | checksum = "eb703cfe953bccee95685111adeedb76fabe4e97549a58d16f03ea7b9367bb32" 1370 | 1371 | [[package]] 1372 | name = "smallvec" 1373 | version = "1.8.0" 1374 | source = "registry+https://github.com/rust-lang/crates.io-index" 1375 | checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83" 1376 | 1377 | [[package]] 1378 | name = "socket2" 1379 | version = "0.4.4" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | checksum = "66d72b759436ae32898a2af0a14218dbf55efde3feeb170eb623637db85ee1e0" 1382 | dependencies = [ 1383 | "libc", 1384 | "winapi", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "spin" 1389 | version = "0.5.2" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1392 | 1393 | [[package]] 1394 | name = "spki" 1395 | version = "0.4.1" 1396 | source = "registry+https://github.com/rust-lang/crates.io-index" 1397 | checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" 1398 | dependencies = [ 1399 | "der", 1400 | ] 1401 | 1402 | [[package]] 1403 | name = "strsim" 1404 | version = "0.10.0" 1405 | source = "registry+https://github.com/rust-lang/crates.io-index" 1406 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 1407 | 1408 | [[package]] 1409 | name = "subtle" 1410 | version = "2.4.1" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1413 | 1414 | [[package]] 1415 | name = "syn" 1416 | version = "1.0.98" 1417 | source = "registry+https://github.com/rust-lang/crates.io-index" 1418 | checksum = "c50aef8a904de4c23c788f104b7dddc7d6f79c647c7c8ce4cc8f73eb0ca773dd" 1419 | dependencies = [ 1420 | "proc-macro2", 1421 | "quote", 1422 | "unicode-ident", 1423 | ] 1424 | 1425 | [[package]] 1426 | name = "synstructure" 1427 | version = "0.12.6" 1428 | source = "registry+https://github.com/rust-lang/crates.io-index" 1429 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" 1430 | dependencies = [ 1431 | "proc-macro2", 1432 | "quote", 1433 | "syn", 1434 | "unicode-xid", 1435 | ] 1436 | 1437 | [[package]] 1438 | name = "termcolor" 1439 | version = "1.1.3" 1440 | source = "registry+https://github.com/rust-lang/crates.io-index" 1441 | checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755" 1442 | dependencies = [ 1443 | "winapi-util", 1444 | ] 1445 | 1446 | [[package]] 1447 | name = "textwrap" 1448 | version = "0.15.0" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "b1141d4d61095b28419e22cb0bbf02755f5e54e0526f97f1e3d1d160e60885fb" 1451 | 1452 | [[package]] 1453 | name = "thiserror" 1454 | version = "1.0.37" 1455 | source = "registry+https://github.com/rust-lang/crates.io-index" 1456 | checksum = "10deb33631e3c9018b9baf9dcbbc4f737320d2b576bac10f6aefa048fa407e3e" 1457 | dependencies = [ 1458 | "thiserror-impl", 1459 | ] 1460 | 1461 | [[package]] 1462 | name = "thiserror-impl" 1463 | version = "1.0.37" 1464 | source = "registry+https://github.com/rust-lang/crates.io-index" 1465 | checksum = "982d17546b47146b28f7c22e3d08465f6b8903d0ea13c1660d9d84a6e7adcdbb" 1466 | dependencies = [ 1467 | "proc-macro2", 1468 | "quote", 1469 | "syn", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "tinyvec" 1474 | version = "1.6.0" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1477 | dependencies = [ 1478 | "tinyvec_macros", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "tinyvec_macros" 1483 | version = "0.1.0" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1486 | 1487 | [[package]] 1488 | name = "tokio" 1489 | version = "1.21.2" 1490 | source = "registry+https://github.com/rust-lang/crates.io-index" 1491 | checksum = "a9e03c497dc955702ba729190dc4aac6f2a0ce97f913e5b1b5912fc5039d9099" 1492 | dependencies = [ 1493 | "autocfg", 1494 | "bytes", 1495 | "libc", 1496 | "memchr", 1497 | "mio", 1498 | "num_cpus", 1499 | "pin-project-lite", 1500 | "socket2", 1501 | "tokio-macros", 1502 | "winapi", 1503 | ] 1504 | 1505 | [[package]] 1506 | name = "tokio-macros" 1507 | version = "1.8.0" 1508 | source = "registry+https://github.com/rust-lang/crates.io-index" 1509 | checksum = "9724f9a975fb987ef7a3cd9be0350edcbe130698af5b8f7a631e23d42d052484" 1510 | dependencies = [ 1511 | "proc-macro2", 1512 | "quote", 1513 | "syn", 1514 | ] 1515 | 1516 | [[package]] 1517 | name = "tokio-rustls" 1518 | version = "0.23.4" 1519 | source = "registry+https://github.com/rust-lang/crates.io-index" 1520 | checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" 1521 | dependencies = [ 1522 | "rustls", 1523 | "tokio", 1524 | "webpki", 1525 | ] 1526 | 1527 | [[package]] 1528 | name = "tokio-util" 1529 | version = "0.7.3" 1530 | source = "registry+https://github.com/rust-lang/crates.io-index" 1531 | checksum = "cc463cd8deddc3770d20f9852143d50bf6094e640b485cb2e189a2099085ff45" 1532 | dependencies = [ 1533 | "bytes", 1534 | "futures-core", 1535 | "futures-sink", 1536 | "pin-project-lite", 1537 | "tokio", 1538 | "tracing", 1539 | ] 1540 | 1541 | [[package]] 1542 | name = "toml" 1543 | version = "0.5.9" 1544 | source = "registry+https://github.com/rust-lang/crates.io-index" 1545 | checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" 1546 | dependencies = [ 1547 | "serde", 1548 | ] 1549 | 1550 | [[package]] 1551 | name = "tower-service" 1552 | version = "0.3.2" 1553 | source = "registry+https://github.com/rust-lang/crates.io-index" 1554 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1555 | 1556 | [[package]] 1557 | name = "tracing" 1558 | version = "0.1.35" 1559 | source = "registry+https://github.com/rust-lang/crates.io-index" 1560 | checksum = "a400e31aa60b9d44a52a8ee0343b5b18566b03a8321e0d321f695cf56e940160" 1561 | dependencies = [ 1562 | "cfg-if", 1563 | "pin-project-lite", 1564 | "tracing-attributes", 1565 | "tracing-core", 1566 | ] 1567 | 1568 | [[package]] 1569 | name = "tracing-attributes" 1570 | version = "0.1.21" 1571 | source = "registry+https://github.com/rust-lang/crates.io-index" 1572 | checksum = "cc6b8ad3567499f98a1db7a752b07a7c8c7c7c34c332ec00effb2b0027974b7c" 1573 | dependencies = [ 1574 | "proc-macro2", 1575 | "quote", 1576 | "syn", 1577 | ] 1578 | 1579 | [[package]] 1580 | name = "tracing-core" 1581 | version = "0.1.27" 1582 | source = "registry+https://github.com/rust-lang/crates.io-index" 1583 | checksum = "7709595b8878a4965ce5e87ebf880a7d39c9afc6837721b21a5a816a8117d921" 1584 | dependencies = [ 1585 | "once_cell", 1586 | ] 1587 | 1588 | [[package]] 1589 | name = "try-lock" 1590 | version = "0.2.3" 1591 | source = "registry+https://github.com/rust-lang/crates.io-index" 1592 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" 1593 | 1594 | [[package]] 1595 | name = "typenum" 1596 | version = "1.15.0" 1597 | source = "registry+https://github.com/rust-lang/crates.io-index" 1598 | checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" 1599 | 1600 | [[package]] 1601 | name = "unicase" 1602 | version = "2.6.0" 1603 | source = "registry+https://github.com/rust-lang/crates.io-index" 1604 | checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6" 1605 | dependencies = [ 1606 | "version_check", 1607 | ] 1608 | 1609 | [[package]] 1610 | name = "unicode-bidi" 1611 | version = "0.3.8" 1612 | source = "registry+https://github.com/rust-lang/crates.io-index" 1613 | checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" 1614 | 1615 | [[package]] 1616 | name = "unicode-ident" 1617 | version = "1.0.1" 1618 | source = "registry+https://github.com/rust-lang/crates.io-index" 1619 | checksum = "5bd2fe26506023ed7b5e1e315add59d6f584c621d037f9368fea9cfb988f368c" 1620 | 1621 | [[package]] 1622 | name = "unicode-normalization" 1623 | version = "0.1.19" 1624 | source = "registry+https://github.com/rust-lang/crates.io-index" 1625 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" 1626 | dependencies = [ 1627 | "tinyvec", 1628 | ] 1629 | 1630 | [[package]] 1631 | name = "unicode-xid" 1632 | version = "0.2.3" 1633 | source = "registry+https://github.com/rust-lang/crates.io-index" 1634 | checksum = "957e51f3646910546462e67d5f7599b9e4fb8acdd304b087a6494730f9eebf04" 1635 | 1636 | [[package]] 1637 | name = "untrusted" 1638 | version = "0.7.1" 1639 | source = "registry+https://github.com/rust-lang/crates.io-index" 1640 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1641 | 1642 | [[package]] 1643 | name = "url" 1644 | version = "2.3.1" 1645 | source = "registry+https://github.com/rust-lang/crates.io-index" 1646 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1647 | dependencies = [ 1648 | "form_urlencoded", 1649 | "idna", 1650 | "percent-encoding", 1651 | "serde", 1652 | ] 1653 | 1654 | [[package]] 1655 | name = "uuid" 1656 | version = "1.1.2" 1657 | source = "registry+https://github.com/rust-lang/crates.io-index" 1658 | checksum = "dd6469f4314d5f1ffec476e05f17cc9a78bc7a27a6a857842170bdf8d6f98d2f" 1659 | dependencies = [ 1660 | "getrandom 0.2.7", 1661 | ] 1662 | 1663 | [[package]] 1664 | name = "version_check" 1665 | version = "0.9.4" 1666 | source = "registry+https://github.com/rust-lang/crates.io-index" 1667 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1668 | 1669 | [[package]] 1670 | name = "want" 1671 | version = "0.3.0" 1672 | source = "registry+https://github.com/rust-lang/crates.io-index" 1673 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1674 | dependencies = [ 1675 | "log", 1676 | "try-lock", 1677 | ] 1678 | 1679 | [[package]] 1680 | name = "wasi" 1681 | version = "0.9.0+wasi-snapshot-preview1" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" 1684 | 1685 | [[package]] 1686 | name = "wasi" 1687 | version = "0.11.0+wasi-snapshot-preview1" 1688 | source = "registry+https://github.com/rust-lang/crates.io-index" 1689 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1690 | 1691 | [[package]] 1692 | name = "wasm-bindgen" 1693 | version = "0.2.81" 1694 | source = "registry+https://github.com/rust-lang/crates.io-index" 1695 | checksum = "7c53b543413a17a202f4be280a7e5c62a1c69345f5de525ee64f8cfdbc954994" 1696 | dependencies = [ 1697 | "cfg-if", 1698 | "wasm-bindgen-macro", 1699 | ] 1700 | 1701 | [[package]] 1702 | name = "wasm-bindgen-backend" 1703 | version = "0.2.81" 1704 | source = "registry+https://github.com/rust-lang/crates.io-index" 1705 | checksum = "5491a68ab4500fa6b4d726bd67408630c3dbe9c4fe7bda16d5c82a1fd8c7340a" 1706 | dependencies = [ 1707 | "bumpalo", 1708 | "lazy_static", 1709 | "log", 1710 | "proc-macro2", 1711 | "quote", 1712 | "syn", 1713 | "wasm-bindgen-shared", 1714 | ] 1715 | 1716 | [[package]] 1717 | name = "wasm-bindgen-futures" 1718 | version = "0.4.31" 1719 | source = "registry+https://github.com/rust-lang/crates.io-index" 1720 | checksum = "de9a9cec1733468a8c657e57fa2413d2ae2c0129b95e87c5b72b8ace4d13f31f" 1721 | dependencies = [ 1722 | "cfg-if", 1723 | "js-sys", 1724 | "wasm-bindgen", 1725 | "web-sys", 1726 | ] 1727 | 1728 | [[package]] 1729 | name = "wasm-bindgen-macro" 1730 | version = "0.2.81" 1731 | source = "registry+https://github.com/rust-lang/crates.io-index" 1732 | checksum = "c441e177922bc58f1e12c022624b6216378e5febc2f0533e41ba443d505b80aa" 1733 | dependencies = [ 1734 | "quote", 1735 | "wasm-bindgen-macro-support", 1736 | ] 1737 | 1738 | [[package]] 1739 | name = "wasm-bindgen-macro-support" 1740 | version = "0.2.81" 1741 | source = "registry+https://github.com/rust-lang/crates.io-index" 1742 | checksum = "7d94ac45fcf608c1f45ef53e748d35660f168490c10b23704c7779ab8f5c3048" 1743 | dependencies = [ 1744 | "proc-macro2", 1745 | "quote", 1746 | "syn", 1747 | "wasm-bindgen-backend", 1748 | "wasm-bindgen-shared", 1749 | ] 1750 | 1751 | [[package]] 1752 | name = "wasm-bindgen-shared" 1753 | version = "0.2.81" 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" 1755 | checksum = "6a89911bd99e5f3659ec4acf9c4d93b0a90fe4a2a11f15328472058edc5261be" 1756 | 1757 | [[package]] 1758 | name = "wasm-timer" 1759 | version = "0.2.5" 1760 | source = "registry+https://github.com/rust-lang/crates.io-index" 1761 | checksum = "be0ecb0db480561e9a7642b5d3e4187c128914e58aa84330b9493e3eb68c5e7f" 1762 | dependencies = [ 1763 | "futures", 1764 | "js-sys", 1765 | "parking_lot", 1766 | "pin-utils", 1767 | "wasm-bindgen", 1768 | "wasm-bindgen-futures", 1769 | "web-sys", 1770 | ] 1771 | 1772 | [[package]] 1773 | name = "web-sys" 1774 | version = "0.3.58" 1775 | source = "registry+https://github.com/rust-lang/crates.io-index" 1776 | checksum = "2fed94beee57daf8dd7d51f2b15dc2bcde92d7a72304cdf662a4371008b71b90" 1777 | dependencies = [ 1778 | "js-sys", 1779 | "wasm-bindgen", 1780 | ] 1781 | 1782 | [[package]] 1783 | name = "webpki" 1784 | version = "0.22.0" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd" 1787 | dependencies = [ 1788 | "ring", 1789 | "untrusted", 1790 | ] 1791 | 1792 | [[package]] 1793 | name = "webpki-roots" 1794 | version = "0.22.3" 1795 | source = "registry+https://github.com/rust-lang/crates.io-index" 1796 | checksum = "44d8de8415c823c8abd270ad483c6feeac771fad964890779f9a8cb24fbbc1bf" 1797 | dependencies = [ 1798 | "webpki", 1799 | ] 1800 | 1801 | [[package]] 1802 | name = "wildmatch" 1803 | version = "2.1.0" 1804 | source = "registry+https://github.com/rust-lang/crates.io-index" 1805 | checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" 1806 | 1807 | [[package]] 1808 | name = "winapi" 1809 | version = "0.3.9" 1810 | source = "registry+https://github.com/rust-lang/crates.io-index" 1811 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1812 | dependencies = [ 1813 | "winapi-i686-pc-windows-gnu", 1814 | "winapi-x86_64-pc-windows-gnu", 1815 | ] 1816 | 1817 | [[package]] 1818 | name = "winapi-i686-pc-windows-gnu" 1819 | version = "0.4.0" 1820 | source = "registry+https://github.com/rust-lang/crates.io-index" 1821 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 1822 | 1823 | [[package]] 1824 | name = "winapi-util" 1825 | version = "0.1.5" 1826 | source = "registry+https://github.com/rust-lang/crates.io-index" 1827 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 1828 | dependencies = [ 1829 | "winapi", 1830 | ] 1831 | 1832 | [[package]] 1833 | name = "winapi-x86_64-pc-windows-gnu" 1834 | version = "0.4.0" 1835 | source = "registry+https://github.com/rust-lang/crates.io-index" 1836 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 1837 | 1838 | [[package]] 1839 | name = "windows-sys" 1840 | version = "0.36.1" 1841 | source = "registry+https://github.com/rust-lang/crates.io-index" 1842 | checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" 1843 | dependencies = [ 1844 | "windows_aarch64_msvc", 1845 | "windows_i686_gnu", 1846 | "windows_i686_msvc", 1847 | "windows_x86_64_gnu", 1848 | "windows_x86_64_msvc", 1849 | ] 1850 | 1851 | [[package]] 1852 | name = "windows_aarch64_msvc" 1853 | version = "0.36.1" 1854 | source = "registry+https://github.com/rust-lang/crates.io-index" 1855 | checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" 1856 | 1857 | [[package]] 1858 | name = "windows_i686_gnu" 1859 | version = "0.36.1" 1860 | source = "registry+https://github.com/rust-lang/crates.io-index" 1861 | checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" 1862 | 1863 | [[package]] 1864 | name = "windows_i686_msvc" 1865 | version = "0.36.1" 1866 | source = "registry+https://github.com/rust-lang/crates.io-index" 1867 | checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" 1868 | 1869 | [[package]] 1870 | name = "windows_x86_64_gnu" 1871 | version = "0.36.1" 1872 | source = "registry+https://github.com/rust-lang/crates.io-index" 1873 | checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" 1874 | 1875 | [[package]] 1876 | name = "windows_x86_64_msvc" 1877 | version = "0.36.1" 1878 | source = "registry+https://github.com/rust-lang/crates.io-index" 1879 | checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" 1880 | 1881 | [[package]] 1882 | name = "winreg" 1883 | version = "0.10.1" 1884 | source = "registry+https://github.com/rust-lang/crates.io-index" 1885 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d" 1886 | dependencies = [ 1887 | "winapi", 1888 | ] 1889 | 1890 | [[package]] 1891 | name = "zeroize" 1892 | version = "1.5.5" 1893 | source = "registry+https://github.com/rust-lang/crates.io-index" 1894 | checksum = "94693807d016b2f2d2e14420eb3bfcca689311ff775dcf113d74ea624b7cdf07" 1895 | dependencies = [ 1896 | "zeroize_derive", 1897 | ] 1898 | 1899 | [[package]] 1900 | name = "zeroize_derive" 1901 | version = "1.3.2" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "3f8f187641dad4f680d25c4bfc4225b418165984179f26ca76ec4fb6441d3a17" 1904 | dependencies = [ 1905 | "proc-macro2", 1906 | "quote", 1907 | "syn", 1908 | "synstructure", 1909 | ] 1910 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "matrix-send" 3 | version = "0.2.1" 4 | authors = ["Tilo Spannagel "] 5 | edition = "2021" 6 | license = "Apache-2.0" 7 | repository = "https://github.com/tilosp/matrix-send-rs" 8 | homepage = "https://crates.io/crates/matrix-send" 9 | keywords = ["matrix", "chat", "messaging"] 10 | description = "Non-Interactive CLI Matrix Client" 11 | readme = "README.md" 12 | include = [ 13 | "/Cargo.toml", 14 | "/LICENSE-APACHE", 15 | "/LICENSE-MIT", 16 | "/README.md", 17 | "/src/**", 18 | ] 19 | 20 | # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html 21 | 22 | [dependencies] 23 | thiserror = "1.0" 24 | serde = { version = "1.0", features = ["derive"] } 25 | url = { version = "2.3", features = ["serde"] } 26 | serde_json = "1.0" 27 | directories = "4.0" 28 | tokio = { version = "1.21", default-features = false, features = [ 29 | "rt-multi-thread", 30 | "macros", 31 | ] } 32 | clap = { version = "3.2", features = ["derive"] } 33 | atty = "0.2" 34 | matrix-sdk = { version = "0.5", default-features = false, features = [ 35 | "rustls-tls", 36 | "markdown", 37 | ] } 38 | mime = "0.3" 39 | mime_guess = "2.0" 40 | 41 | [profile.release] 42 | strip = "symbols" 43 | lto = true 44 | 45 | [profile.release-tiny] 46 | inherits = "release" 47 | opt-level = "s" 48 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # matrix-send 2 | Non-Interactive CLI Matrix Client 3 | 4 | ## Usage 5 | ``` 6 | matrix-send 7 | 8 | USAGE: 9 | matrix-send 10 | 11 | FLAGS: 12 | -h, --help Prints help information 13 | -V, --version Prints version information 14 | 15 | SUBCOMMANDS: 16 | help Prints this message or the help of the given subcommand(s) 17 | login Login to Matrix Account 18 | logout Logout from Matrix Account 19 | room Room Subcommands 20 | ``` 21 | -------------------------------------------------------------------------------- /src/command.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | 3 | use crate::{dir::Directories, matrix::MatrixClient, Error, Result}; 4 | 5 | use url::Url; 6 | 7 | use clap::Parser; 8 | 9 | mod loggedin; 10 | 11 | #[derive(Debug, Parser)] 12 | pub(crate) enum Command { 13 | #[clap(flatten)] 14 | LoggedInCommands(loggedin::Command), 15 | 16 | /// Login to Matrix Account 17 | Login(LoginCommand), 18 | 19 | /// Logout from Matrix Account 20 | Logout(LogoutCommand), 21 | } 22 | 23 | impl Command { 24 | pub(super) async fn run(self, client: Result, dirs: &Directories) -> Result { 25 | match self { 26 | Self::Login(command) => command.run(client, dirs).await, 27 | Self::Logout(command) => command.run(client, dirs).await, 28 | Self::LoggedInCommands(command) => { 29 | let client = client?; 30 | command.run(client).await 31 | } 32 | } 33 | } 34 | } 35 | 36 | #[derive(Debug, Parser)] 37 | pub(crate) struct LoginCommand { 38 | /// Homeserver Url 39 | homeserver: Url, 40 | 41 | /// Matrix Account Username 42 | username: Option, 43 | 44 | /// Matrix Account Password 45 | password: Option, 46 | } 47 | 48 | impl LoginCommand { 49 | async fn run(self, client: Result, dirs: &Directories) -> Result { 50 | if client.is_ok() { 51 | Error::custom("Already logged in") 52 | } else { 53 | let username = self 54 | .username 55 | .map_or_else(|| Self::user_input("Username:"), Ok)?; 56 | let password = self 57 | .password 58 | .map_or_else(|| Self::user_input("Password:"), Ok)?; 59 | MatrixClient::login(dirs, &self.homeserver, username.trim(), password.trim()).await?; 60 | Ok(()) 61 | } 62 | } 63 | 64 | fn user_input(message: &'static str) -> Result { 65 | println!("{}", message); 66 | let mut line = String::new(); 67 | std::io::stdin().read_line(&mut line)?; 68 | Ok(line) 69 | } 70 | } 71 | 72 | #[derive(Debug, Parser)] 73 | pub(crate) struct LogoutCommand {} 74 | 75 | impl LogoutCommand { 76 | async fn run(self, client: Result, dirs: &Directories) -> Result { 77 | if let Ok(client) = client { 78 | client.logout().await?; 79 | } else { 80 | if dirs.session_file.exists() { 81 | fs::remove_file(&dirs.session_file)?; 82 | } 83 | client?; 84 | } 85 | Ok(()) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /src/command/loggedin.rs: -------------------------------------------------------------------------------- 1 | use crate::{matrix::MatrixClient, Result}; 2 | 3 | use clap::Parser; 4 | 5 | mod room; 6 | 7 | #[derive(Debug, Parser)] 8 | pub(crate) enum Command { 9 | /// Room Subcommands 10 | Room(RoomCommand), 11 | } 12 | 13 | impl Command { 14 | pub(super) async fn run(self, client: MatrixClient) -> Result { 15 | match self { 16 | Self::Room(command) => command.run(client).await, 17 | } 18 | } 19 | } 20 | 21 | #[derive(Debug, Parser)] 22 | pub(crate) struct RoomCommand { 23 | #[clap(subcommand)] 24 | command: room::Command, 25 | } 26 | 27 | impl RoomCommand { 28 | async fn run(self, client: MatrixClient) -> Result { 29 | self.command.run(client).await 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/command/loggedin/room.rs: -------------------------------------------------------------------------------- 1 | use std::borrow::Cow; 2 | use std::fs::{self, File}; 3 | use std::io::{self, Read}; 4 | use std::path::PathBuf; 5 | 6 | use crate::{matrix::MatrixClient, Error, Result}; 7 | 8 | use atty::Stream; 9 | 10 | use clap::{ArgEnum, ArgGroup, Parser}; 11 | 12 | use matrix_sdk::{ 13 | attachment::AttachmentConfig, 14 | room::Room, 15 | ruma::{ 16 | events::room::message::{ 17 | EmoteMessageEventContent, MessageType, NoticeMessageEventContent, 18 | RoomMessageEventContent, TextMessageEventContent, 19 | }, 20 | OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName, 21 | }, 22 | }; 23 | 24 | use mime::Mime; 25 | 26 | mod user; 27 | 28 | #[derive(Debug, Parser)] 29 | pub(crate) enum Command { 30 | /// Join Room 31 | Join(JoinCommand), 32 | 33 | /// Leave Room 34 | Leave(LeaveCommand), 35 | 36 | /// Send Message into Room 37 | Send(SendCommand), 38 | 39 | /// List Rooms 40 | List(ListCommand), 41 | 42 | /// User commands for room 43 | User(UserCommand), 44 | 45 | /// Send file into room 46 | SendFile(SendFileCommand), 47 | } 48 | 49 | impl Command { 50 | pub(super) async fn run(self, client: MatrixClient) -> Result { 51 | match self { 52 | Self::Join(command) => command.run(client).await, 53 | Self::List(command) => command.run(client).await, 54 | Self::Send(command) => command.run(client).await, 55 | Self::Leave(command) => command.run(client).await, 56 | Self::User(command) => command.run(client).await, 57 | Self::SendFile(command) => command.run(client).await, 58 | } 59 | } 60 | } 61 | 62 | #[derive(Debug, Parser)] 63 | pub(crate) struct JoinCommand { 64 | /// Alias or ID of Room 65 | room: OwnedRoomOrAliasId, 66 | 67 | /// Homeservers used to find the Room 68 | servers: Vec, 69 | } 70 | 71 | impl JoinCommand { 72 | async fn run(self, client: MatrixClient) -> Result { 73 | client 74 | .join_room_by_id_or_alias(&self.room, &self.servers) 75 | .await?; 76 | Ok(()) 77 | } 78 | } 79 | 80 | #[derive(Debug, Parser)] 81 | pub(crate) struct LeaveCommand { 82 | /// Room ID 83 | room: OwnedRoomId, 84 | } 85 | 86 | impl LeaveCommand { 87 | async fn run(self, client: MatrixClient) -> Result { 88 | client.joined_room(&self.room)?.leave().await?; 89 | Ok(()) 90 | } 91 | } 92 | 93 | #[derive(Debug, Parser)] 94 | #[clap( 95 | group = ArgGroup::new("msgopt"), 96 | group = ArgGroup::new("format"), 97 | group = ArgGroup::new("type"), 98 | )] 99 | pub(crate) struct SendCommand { 100 | /// Room ID 101 | room: OwnedRoomId, 102 | 103 | /// Message to send 104 | #[clap(group = "msgopt")] 105 | message: Option, 106 | 107 | /// Read Message from file 108 | #[clap(short, long, group = "msgopt")] 109 | file: Option, 110 | 111 | /// Put message in code block 112 | #[clap(name = "language", long = "code", group = "format")] 113 | code: Option>, 114 | 115 | /// Message is Markdown 116 | #[clap(long, group = "format")] 117 | markdown: bool, 118 | 119 | /// Send notice 120 | #[clap(long, group = "type")] 121 | notice: bool, 122 | 123 | /// Send emote 124 | #[clap(long, group = "type")] 125 | emote: bool, 126 | } 127 | 128 | impl SendCommand { 129 | async fn run(self, client: MatrixClient) -> Result { 130 | let msg = if let Some(msg) = self.message { 131 | msg 132 | } else if let Some(file) = self.file { 133 | fs::read_to_string(file)? 134 | } else { 135 | let mut line = String::new(); 136 | if atty::is(Stream::Stdin) { 137 | println!("Message:"); 138 | io::stdin().read_line(&mut line)?; 139 | } else { 140 | io::stdin().read_to_string(&mut line)?; 141 | } 142 | line 143 | }; 144 | let (msg, markdown) = if let Some(language) = self.code { 145 | let mut fmt_msg = String::from("```"); 146 | if let Some(language) = language { 147 | fmt_msg.push_str(&language); 148 | } 149 | fmt_msg.push('\n'); 150 | fmt_msg.push_str(&msg); 151 | if !fmt_msg.ends_with('\n') { 152 | fmt_msg.push('\n'); 153 | } 154 | fmt_msg.push_str("```"); 155 | (fmt_msg, true) 156 | } else { 157 | (msg, self.markdown) 158 | }; 159 | let content = if self.notice { 160 | MessageType::Notice(if markdown { 161 | NoticeMessageEventContent::markdown(msg) 162 | } else { 163 | NoticeMessageEventContent::plain(msg) 164 | }) 165 | } else if self.emote { 166 | MessageType::Emote(if markdown { 167 | EmoteMessageEventContent::markdown(msg) 168 | } else { 169 | EmoteMessageEventContent::plain(msg) 170 | }) 171 | } else { 172 | MessageType::Text(if markdown { 173 | TextMessageEventContent::markdown(msg) 174 | } else { 175 | TextMessageEventContent::plain(msg) 176 | }) 177 | }; 178 | client 179 | .joined_room(&self.room)? 180 | .send(RoomMessageEventContent::new(content), None) 181 | .await?; 182 | Ok(()) 183 | } 184 | } 185 | 186 | #[derive(Debug, Parser)] 187 | pub(crate) struct ListCommand { 188 | /// Kind 189 | #[clap(arg_enum, default_value = "joined")] 190 | kind: Vec, 191 | } 192 | 193 | #[derive(Clone, ArgEnum, Debug)] 194 | enum Kind { 195 | All, 196 | Joined, 197 | Invited, 198 | Left, 199 | } 200 | 201 | impl ListCommand { 202 | async fn run(self, client: MatrixClient) -> Result { 203 | for room in client.rooms().into_iter().filter(|r| { 204 | self.kind.iter().any(|k| { 205 | matches!( 206 | (k, r), 207 | (Kind::All, _) 208 | | (Kind::Joined, Room::Joined(_)) 209 | | (Kind::Left, Room::Left(_)) 210 | | (Kind::Invited, Room::Invited(_)) 211 | ) 212 | }) 213 | }) { 214 | if let Ok(name) = room.display_name().await { 215 | println!("{}\t{}", room.room_id(), name); 216 | } else { 217 | println!("{}", room.room_id()); 218 | } 219 | } 220 | Ok(()) 221 | } 222 | } 223 | 224 | #[derive(Debug, Parser)] 225 | pub(crate) struct UserCommand { 226 | /// Room ID 227 | room: OwnedRoomId, 228 | 229 | #[clap(subcommand)] 230 | command: user::Command, 231 | } 232 | 233 | impl UserCommand { 234 | async fn run(self, client: MatrixClient) -> Result { 235 | self.command.run(client, self.room).await 236 | } 237 | } 238 | 239 | #[derive(Debug, Parser)] 240 | pub(crate) struct SendFileCommand { 241 | /// Room ID 242 | room: OwnedRoomId, 243 | 244 | /// File Path 245 | file: PathBuf, 246 | 247 | /// Override auto detected mime type 248 | #[clap(long)] 249 | mime: Option, 250 | 251 | /// Override fallback text (Defaults to filename) 252 | #[clap(long)] 253 | text: Option, 254 | } 255 | 256 | impl SendFileCommand { 257 | async fn run(self, client: MatrixClient) -> Result { 258 | client 259 | .joined_room(&self.room)? 260 | .send_attachment( 261 | self.text 262 | .as_ref() 263 | .map(Cow::from) 264 | .or_else(|| self.file.file_name().as_ref().map(|o| o.to_string_lossy())) 265 | .ok_or(Error::InvalidFile)? 266 | .as_ref(), 267 | self.mime.as_ref().unwrap_or( 268 | &mime_guess::from_path(&self.file).first_or(mime::APPLICATION_OCTET_STREAM), 269 | ), 270 | &mut File::open(&self.file)?, 271 | AttachmentConfig::new(), 272 | ) 273 | .await?; 274 | Ok(()) 275 | } 276 | } 277 | -------------------------------------------------------------------------------- /src/command/loggedin/room/user.rs: -------------------------------------------------------------------------------- 1 | use crate::{matrix::MatrixClient, Result}; 2 | 3 | use std::cmp::Reverse; 4 | 5 | use clap::Parser; 6 | 7 | use matrix_sdk::ruma::{OwnedRoomId, OwnedUserId}; 8 | 9 | #[derive(Debug, Parser)] 10 | pub(crate) enum Command { 11 | /// Kick a user 12 | Kick(KickCommand), 13 | 14 | /// Ban a user 15 | Ban(BanCommand), 16 | 17 | /// List users 18 | List(ListCommand), 19 | 20 | /// Invite user 21 | Invite(InviteCommand), 22 | } 23 | 24 | impl Command { 25 | pub(super) async fn run(self, client: MatrixClient, room: OwnedRoomId) -> Result { 26 | match self { 27 | Self::Kick(command) => command.run(client, room).await, 28 | Self::Ban(command) => command.run(client, room).await, 29 | Self::List(command) => command.run(client, room).await, 30 | Self::Invite(command) => command.run(client, room).await, 31 | } 32 | } 33 | } 34 | 35 | #[derive(Debug, Parser)] 36 | pub(crate) struct KickCommand { 37 | /// User ID 38 | user: OwnedUserId, 39 | 40 | /// Reason for kick 41 | reason: Option, 42 | } 43 | 44 | impl KickCommand { 45 | async fn run(self, client: MatrixClient, room: OwnedRoomId) -> Result { 46 | client 47 | .joined_room(&room)? 48 | .kick_user(&self.user, self.reason.as_deref()) 49 | .await?; 50 | Ok(()) 51 | } 52 | } 53 | 54 | #[derive(Debug, Parser)] 55 | pub(crate) struct BanCommand { 56 | /// User ID 57 | user: OwnedUserId, 58 | 59 | /// Reason for ban 60 | reason: Option, 61 | } 62 | 63 | impl BanCommand { 64 | async fn run(self, client: MatrixClient, room: OwnedRoomId) -> Result { 65 | client 66 | .joined_room(&room)? 67 | .ban_user(&self.user, self.reason.as_deref()) 68 | .await?; 69 | Ok(()) 70 | } 71 | } 72 | 73 | #[derive(Debug, Parser)] 74 | pub(crate) struct ListCommand {} 75 | 76 | impl ListCommand { 77 | async fn run(self, client: MatrixClient, room: OwnedRoomId) -> Result { 78 | let mut members = client.joined_room(&room)?.joined_members().await?; 79 | 80 | members.sort_by_key(|m| Reverse(m.power_level())); 81 | 82 | for member in members { 83 | if let Some(name) = member.display_name() { 84 | println!("{}\t{}\t{}", member.user_id(), member.power_level(), name); 85 | } else { 86 | println!("{}\t{}", member.user_id(), member.power_level()); 87 | } 88 | } 89 | Ok(()) 90 | } 91 | } 92 | 93 | #[derive(Debug, Parser)] 94 | pub(crate) struct InviteCommand { 95 | /// User ID 96 | user: OwnedUserId, 97 | } 98 | 99 | impl InviteCommand { 100 | async fn run(self, client: MatrixClient, room: OwnedRoomId) -> Result { 101 | client 102 | .joined_room(&room)? 103 | .invite_user_by_id(&self.user) 104 | .await?; 105 | Ok(()) 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/dir.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::path::PathBuf; 3 | 4 | use crate::{Error, Result}; 5 | 6 | use directories::ProjectDirs; 7 | 8 | const SESSION_FILE: &str = "session.json"; 9 | 10 | pub(crate) struct Directories { 11 | pub(crate) session_file: PathBuf, 12 | } 13 | 14 | impl Directories { 15 | pub(crate) fn new() -> Result { 16 | let dirs = 17 | ProjectDirs::from_path(PathBuf::from(crate::APP_NAME)).ok_or(Error::NoNomeDirectory)?; 18 | 19 | fs::create_dir_all(dirs.data_dir())?; 20 | Ok(Directories { 21 | session_file: dirs.data_dir().join(SESSION_FILE), 22 | }) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use crate::dir::Directories; 2 | use crate::matrix::MatrixClient; 3 | 4 | use clap::Parser; 5 | 6 | use thiserror::Error; 7 | 8 | mod command; 9 | mod dir; 10 | mod matrix; 11 | 12 | const APP_NAME: &str = env!("CARGO_PKG_NAME"); 13 | 14 | #[derive(Debug, Parser)] 15 | struct Opt { 16 | #[clap(subcommand)] 17 | command: command::Command, 18 | } 19 | 20 | #[derive(Error, Debug)] 21 | pub(crate) enum Error { 22 | #[error("{0}")] 23 | Custom(&'static str), 24 | 25 | #[error("No valid home directory path")] 26 | NoNomeDirectory, 27 | 28 | #[error("Not logged in")] 29 | NotLoggedIn, 30 | 31 | #[error("Invalid Room")] 32 | InvalidRoom, 33 | 34 | #[error("Invalid File")] 35 | InvalidFile, 36 | 37 | #[error(transparent)] 38 | IO(#[from] std::io::Error), 39 | 40 | #[error(transparent)] 41 | Matrix(#[from] matrix_sdk::Error), 42 | 43 | #[error(transparent)] 44 | Json(#[from] serde_json::Error), 45 | 46 | #[error(transparent)] 47 | Http(#[from] matrix_sdk::HttpError), 48 | } 49 | 50 | impl Error { 51 | pub(crate) fn custom(message: &'static str) -> Result { 52 | Err(Error::Custom(message)) 53 | } 54 | } 55 | 56 | pub(crate) type Result = std::result::Result; 57 | 58 | #[tokio::main] 59 | async fn main() -> Result { 60 | let Opt { command } = Opt::parse(); 61 | 62 | let dirs = Directories::new()?; 63 | 64 | let client = MatrixClient::load(&dirs).await; 65 | 66 | command.run(client, &dirs).await 67 | } 68 | -------------------------------------------------------------------------------- /src/matrix.rs: -------------------------------------------------------------------------------- 1 | use std::fs; 2 | use std::fs::File; 3 | use std::ops::Deref; 4 | use std::path::{Path, PathBuf}; 5 | 6 | use crate::dir::Directories; 7 | use crate::{Error, Result}; 8 | 9 | use matrix_sdk::{ 10 | config::SyncSettings, 11 | room, 12 | ruma::{ 13 | api::client::session::login::v3::Response as LoginResponse, OwnedDeviceId, OwnedUserId, 14 | RoomId, 15 | }, 16 | Client, Session, 17 | }; 18 | use url::Url; 19 | 20 | use serde::{Deserialize, Serialize}; 21 | 22 | #[derive(Serialize, Deserialize)] 23 | struct SessionData { 24 | homeserver: Url, 25 | access_token: String, 26 | device_id: OwnedDeviceId, 27 | user_id: OwnedUserId, 28 | } 29 | 30 | impl SessionData { 31 | fn load(path: &Path) -> Result { 32 | let reader = File::open(path)?; 33 | // matrix-send-rs used to create session.js as world-readable, so just ensuring the correct 34 | // permissions during writing isn't good enough. We also need to fix the existing files. 35 | SessionData::set_permissions(&reader)?; 36 | Ok(serde_json::from_reader(reader)?) 37 | } 38 | 39 | fn save(&self, path: &Path) -> Result { 40 | fs::create_dir_all(path.parent().ok_or(Error::NoNomeDirectory)?)?; 41 | let writer = File::create(path)?; 42 | serde_json::to_writer_pretty(&writer, self)?; 43 | SessionData::set_permissions(&writer)?; 44 | Ok(()) 45 | } 46 | 47 | #[cfg(unix)] 48 | fn set_permissions(file: &File) -> Result { 49 | use std::os::unix::fs::PermissionsExt; 50 | 51 | let perms = file.metadata()?.permissions(); 52 | 53 | // is the file world-readable? if so, reset the permissions to 600 54 | if perms.mode() & 0o4 == 0o4 { 55 | file.set_permissions(fs::Permissions::from_mode(0o600)) 56 | .unwrap(); 57 | } 58 | Ok(()) 59 | } 60 | 61 | #[cfg(not(unix))] 62 | fn set_permissions(file: &File) -> Result { 63 | Ok(()) 64 | } 65 | 66 | fn new(homeserver: Url, response: LoginResponse) -> Self { 67 | let LoginResponse { 68 | access_token, 69 | device_id, 70 | user_id, 71 | .. 72 | } = response; 73 | Self { 74 | homeserver, 75 | access_token, 76 | device_id, 77 | user_id, 78 | } 79 | } 80 | } 81 | 82 | impl From for Session { 83 | fn from(session: SessionData) -> Self { 84 | Self { 85 | access_token: session.access_token, 86 | device_id: session.device_id, 87 | user_id: session.user_id, 88 | } 89 | } 90 | } 91 | 92 | pub(crate) struct MatrixClient { 93 | client: Client, 94 | session_file: PathBuf, 95 | } 96 | 97 | impl Deref for MatrixClient { 98 | type Target = Client; 99 | 100 | fn deref(&self) -> &Self::Target { 101 | &self.client 102 | } 103 | } 104 | 105 | impl MatrixClient { 106 | fn new(client: Client, dirs: &Directories) -> Self { 107 | Self { 108 | client, 109 | session_file: dirs.session_file.clone(), 110 | } 111 | } 112 | 113 | async fn create_client(homserver: Url) -> Result { 114 | Ok(Client::new(homserver).await?) 115 | } 116 | 117 | pub(crate) async fn load(dirs: &Directories) -> Result { 118 | if dirs.session_file.exists() { 119 | let session = SessionData::load(&dirs.session_file)?; 120 | 121 | let client = Self::create_client(session.homeserver.clone()).await?; 122 | client.restore_login(session.into()).await?; 123 | 124 | let client = Self::new(client, dirs); 125 | client.sync_once().await?; 126 | Ok(client) 127 | } else { 128 | Err(Error::NotLoggedIn) 129 | } 130 | } 131 | 132 | pub(crate) async fn login( 133 | dirs: &Directories, 134 | homeserver: &Url, 135 | username: &str, 136 | password: &str, 137 | ) -> Result { 138 | let client = Self::create_client(homeserver.clone()).await?; 139 | SessionData::new( 140 | homeserver.clone(), 141 | client 142 | .login(username, password, None, Some(crate::APP_NAME)) 143 | .await?, 144 | ) 145 | .save(&dirs.session_file)?; 146 | 147 | let client = Self::new(client, dirs); 148 | client.sync_once().await?; 149 | Ok(client) 150 | } 151 | 152 | pub(crate) async fn logout(self) -> Result { 153 | let Self { 154 | client, 155 | session_file, 156 | } = self; 157 | 158 | // TODO: send logout to server 159 | let _ = client; 160 | 161 | fs::remove_file(session_file)?; 162 | Ok(()) 163 | } 164 | 165 | pub(crate) async fn sync_once(&self) -> Result { 166 | self.client.sync_once(SyncSettings::new()).await?; 167 | Ok(()) 168 | } 169 | 170 | /*pub(crate) fn room(&self, room_id: &RoomId) -> Result { 171 | self.get_room(room_id).ok_or(Error::InvalidRoom) 172 | }*/ 173 | 174 | pub(crate) fn joined_room(&self, room_id: &RoomId) -> Result { 175 | self.get_joined_room(room_id).ok_or(Error::InvalidRoom) 176 | } 177 | 178 | /*pub(crate) fn invited_room(&self, room_id: &RoomId) -> Result { 179 | self.get_invited_room(room_id).ok_or(Error::InvalidRoom) 180 | }*/ 181 | 182 | /*pub(crate) fn left_room(&self, room_id: &RoomId) -> Result { 183 | self.get_left_room(room_id).ok_or(Error::InvalidRoom) 184 | }*/ 185 | } 186 | --------------------------------------------------------------------------------