diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..7f56d42 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,4 @@ +root = true + +[*.rs] +indent_style = tab diff --git a/.gitignore b/.gitignore index 211d5d3..2f7896d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,17 +1 @@ -# ---> Rust -# Generated by Cargo -# will have compiled files and executables -/target/ - -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock - -# These are backup files generated by rustfmt -**/*.rs.bk - - - -# Added by cargo - -/target +target/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..25e5f8d --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,4523 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "ab_glyph" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af0ac006645f86f20f6c6fa4dcaef920bf803df819123626f9440e35835e7d80" +dependencies = [ + "ab_glyph_rasterizer", + "owned_ttf_parser", +] + +[[package]] +name = "ab_glyph_rasterizer" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9fe5e32de01730eb1f6b7f5b51c17e03e2325bf40a74f754f04f130043affff" + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "adler32" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" + +[[package]] +name = "aead" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b613b8e1e3cf911a086f53f03bf286f52fd7a7258e4fa606f0ef220d39d8877" +dependencies = [ + "generic-array", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "ctr", + "opaque-debug", +] + +[[package]] +name = "aes-gcm" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df5f85a83a7d8b0442b6aa7b504b8212c1733da07b98aae43d4bc21b2cb3cdf6" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "ahash" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e" + +[[package]] +name = "ahash" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcb51a0695d8f838b1ee009b3fbf66bda078cd64590202a864a8f3e8c4315c47" +dependencies = [ + "getrandom 0.2.3", + "once_cell", + "version_check", +] + +[[package]] +name = "approx" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "072df7202e63b127ab55acfe16ce97013d5b97bf160489336d3f1840fd78e99e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "arrayref" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "arrayvec" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4dc07131ffa69b8072d35f5007352af944213cde02545e2103680baed38fcd" + +[[package]] +name = "ash" +version = "0.33.3+1.2.191" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc4f1d82f164f838ae413296d1131aa6fa79b917d25bebaa7033d25620c09219" +dependencies = [ + "libloading", +] + +[[package]] +name = "assign" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002" + +[[package]] +name = "async-stream" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171374e7e3b2504e0e5236e3b59260560f9fe94bfe9ac39ba5e4e929c5590625" +dependencies = [ + "async-stream-impl", + "futures-core", +] + +[[package]] +name = "async-stream-impl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "648ed8c8d2ce5409ccd57453d9d1b214b342a0d69376a6feda1fd6cae3299308" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "async-trait" +version = "0.1.51" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44318e776df68115a881de9a8fd1b9e53368d7a4a5ce4cc48517da3393233a5e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3410529e8288c463bedb5930f82833bc0c90e5d2fe639a56582a4d09220b281" +dependencies = [ + "autocfg", +] + +[[package]] +name = "autocfg" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" + +[[package]] +name = "backoff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fe17f59a06fe8b87a6fc8bf53bb70b3aba76d7685f432487a68cd5552853625" +dependencies = [ + "futures-core", + "getrandom 0.2.3", + "instant", + "pin-project", + "rand 0.8.4", + "tokio", +] + +[[package]] +name = "base-x" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4521f3e3d031370679b3b140beb36dfe4801b09ac77e30c61941f97df3ef28b" + +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + +[[package]] +name = "bit-set" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e11e16035ea35e4e5997b393eacbf6f63983188f7a2ad25bfb13465f5ad59de" +dependencies = [ + "bit-vec", +] + +[[package]] +name = "bit-vec" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb" + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] +name = "bumpalo" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad807f2fc2bf185eeb98ff3a901bd46dc5ad58163d0fa4577ba0d25674d71708" + +[[package]] +name = "bumpalo" +version = "3.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9df67f7bf9ef8498769f994239c45613ef0c5899415fb58e9add412d2c1a538" + +[[package]] +name = "bytemuck" +version = "1.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72957246c41db82b8ef88a5486143830adeb8227ef9837740bdec67724cf2c5b" +dependencies = [ + "bytemuck_derive", +] + +[[package]] +name = "bytemuck_derive" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e215f8c2f9f79cb53c8335e687ffd07d5bfcb6fe5fc80723762d0be46e7cc54" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "byteorder" +version = "1.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610" + +[[package]] +name = "bytes" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8" + +[[package]] +name = "calloop" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42dcfbd723aa6eff9f024cfd5ad08b11144d79b2d8d37b4a31a006ceab255c77" +dependencies = [ + "log", + "nix 0.22.2", +] + +[[package]] +name = "cc" +version = "1.0.71" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e" + +[[package]] +name = "chacha20" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" +dependencies = [ + "cfg-if 1.0.0", + "cipher", + "cpufeatures", + "zeroize", +] + +[[package]] +name = "chacha20poly1305" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array", +] + +[[package]] +name = "clipboard-win" +version = "4.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e4ea1881992efc993e4dc50a324cdbd03216e41bdc8385720ff47efc9bd2ca8" +dependencies = [ + "error-code", + "str-buf", + "winapi", +] + +[[package]] +name = "clipboard_macos" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145a7f9e9b89453bc0a5e32d166456405d389cea5b578f57f1274b1397588a95" +dependencies = [ + "objc", + "objc-foundation", + "objc_id", +] + +[[package]] +name = "clipboard_wayland" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f6364a9f7a66f2ac1a1a098aa1c7f6b686f2496c6ac5e5c0d773445df912747" +dependencies = [ + "smithay-clipboard", +] + +[[package]] +name = "clipboard_x11" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64240d63f1883d87e5637bfcaf9d77e5c8bd24e30fd440ea2dff5c48c0bf0b7a" +dependencies = [ + "thiserror", + "x11rb", +] + +[[package]] +name = "cmake" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7b858541263efe664aead4a5209a4ae5c5d2811167d4ed4ee0944503f8d2089" +dependencies = [ + "cc", +] + +[[package]] +name = "cocoa" +version = "0.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63902e9223530efb4e26ccd0cf55ec30d592d3b42e21a28defc42a9586e832" +dependencies = [ + "bitflags", + "block", + "cocoa-foundation", + "core-foundation 0.9.2", + "core-graphics 0.22.2", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ade49b65d560ca58c403a479bb396592b155c0185eada742ee323d1d68d6318" +dependencies = [ + "bitflags", + "block", + "core-foundation 0.9.2", + "core-graphics-types", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "codespan-reporting" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" +dependencies = [ + "termcolor", + "unicode-width", +] + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "const-oid" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6f2aa4d0537bcc1c74df8755072bd31c1ef1a3a1b85a68e8404a8c353b7b8b" + +[[package]] +name = "const_fn" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f92cfa0fd5690b3cf8c1ef2cabbd9b7ef22fa53cf5e1f92b05103f6d5d1cf6e7" + +[[package]] +name = "copyless" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2df960f5d869b2dd8532793fde43eb5427cceb126c929747a26823ab0eeb536" + +[[package]] +name = "core-foundation" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57d24c7a13c43e870e37c1556b74555437870a04514f7685f5b354e090567171" +dependencies = [ + "core-foundation-sys 0.7.0", + "libc", +] + +[[package]] +name = "core-foundation" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3" +dependencies = [ + "core-foundation-sys 0.8.3", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3a71ab494c0b5b860bdc8407ae08978052417070c2ced38573a9157ad75b8ac" + +[[package]] +name = "core-foundation-sys" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" + +[[package]] +name = "core-graphics" +version = "0.19.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3889374e6ea6ab25dba90bb5d96202f61108058361f6dc72e8b03e6f8bbe923" +dependencies = [ + "bitflags", + "core-foundation 0.7.0", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "269f35f69b542b80e736a20a89a05215c0ce80c2c03c514abb2e318b78379d86" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a68b68b3446082644c91ac778bf50cd4104bfb002b5a6a7c44cca5a2c70788b" +dependencies = [ + "bitflags", + "core-foundation 0.9.2", + "foreign-types", + "libc", +] + +[[package]] +name = "core-text" +version = "19.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d74ada66e07c1cefa18f8abfba765b486f250de2e4a999e5727fc0dd4b4a25" +dependencies = [ + "core-foundation 0.9.2", + "core-graphics 0.22.2", + "foreign-types", + "libc", +] + +[[package]] +name = "core-video-sys" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34ecad23610ad9757664d644e369246edde1803fcb43ed72876565098a5d3828" +dependencies = [ + "cfg-if 0.1.10", + "core-foundation-sys 0.7.0", + "core-graphics 0.19.2", + "libc", + "objc", +] + +[[package]] +name = "cpufeatures" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "crossbeam-channel" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd" +dependencies = [ + "cfg-if 1.0.0", + "crossbeam-utils", + "lazy_static", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db" +dependencies = [ + "cfg-if 1.0.0", + "lazy_static", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest", + "rand_core 0.5.1", + "subtle", + "zeroize", +] + +[[package]] +name = "d3d12" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2daefd788d1e96e0a9d66dee4b828b883509bc3ea9ce30665f04c3246372690c" +dependencies = [ + "bitflags", + "libloading", + "winapi", +] + +[[package]] +name = "darling" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d706e75d87e35569db781a9b5e2416cff1236a47ed380831f959382ccd5f858" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0c960ae2da4de88a91b2d920c2a7233b400bc33cb28453a2987822d8392519b" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b5a2f4ac4969822c62224815d069952656cadc7084fdca9751e6d959189b72" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "dashmap" +version = "4.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e77a43b28d0668df09411cb0bc9a8c2adc40f9a048afe863e05fd43251e8e39c" +dependencies = [ + "cfg-if 1.0.0", + "num_cpus", +] + +[[package]] +name = "data-url" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d33fe99ccedd6e84bc035f1931bb2e6be79739d6242bd895e7311c886c50dc9c" +dependencies = [ + "matches", +] + +[[package]] +name = "deflate" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73770f8e1fe7d64df17ca66ad28994a0a623ea497fa69486e14984e715c5d174" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "deflate" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f95bf05dffba6e6cce8dfbb30def788154949ccd9aed761b472119c21e01c70" +dependencies = [ + "adler32", +] + +[[package]] +name = "der" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28e98c534e9c8a0483aa01d6f6913bc063de254311bd267c9cf535e9b70e15b2" +dependencies = [ + "const-oid", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "directories" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e69600ff1703123957937708eb27f7a564e48885c537782722ed0ba3189ce1d7" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-next" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" +dependencies = [ + "cfg-if 1.0.0", + "dirs-sys-next", +] + +[[package]] +name = "dirs-sys" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d86534ed367a67548dc68113a0f5db55432fdfbb6e6f9d77704397d95d5780" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys-next" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "discard" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" + +[[package]] +name = "dispatch" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd0c93bb4b0c6d9b77f4435b0ae98c24d17f1c45b2ff844c6151a07256ca923b" + +[[package]] +name = "dlib" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1b7517328c04c2aa68422fc60a41b92208182142ed04a25879c26c8f878794" +dependencies = [ + "libloading", +] + +[[package]] +name = "dodrio" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7593dfc68e57dc1d058ada0f151ba07f4b05183c4da4c4df8ff651a81ef0fab" +dependencies = [ + "bumpalo 2.6.0", + "cfg-if 0.1.10", + "fxhash", + "js-sys", + "longest-increasing-subsequence", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "downcast-rs" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ea835d29036a4087793836fa931b08837ad5e957da9e23886b29586fb9b6650" + +[[package]] +name = "dwrote" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439a1c2ba5611ad3ed731280541d36d2e9c4ac5e7fb818a27b604bdc5a6aa65b" +dependencies = [ + "lazy_static", + "libc", + "winapi", + "wio", +] + +[[package]] +name = "ed25519" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4620d40f6d2601794401d6dd95a5cf69b6c157852539470eeda433a99b3c0efc" +dependencies = [ + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand 0.7.3", + "serde", + "sha2", + "zeroize", +] + +[[package]] +name = "either" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457" + +[[package]] +name = "encoding" +version = "0.2.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b0d943856b990d12d3b55b359144ff341533e516d94098b1d3fc1ac666d36ec" +dependencies = [ + "encoding-index-japanese", + "encoding-index-korean", + "encoding-index-simpchinese", + "encoding-index-singlebyte", + "encoding-index-tradchinese", +] + +[[package]] +name = "encoding-index-japanese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8b2ff42e9a05335dbf8b5c6f7567e5591d0d916ccef4e0b1710d32a0d0c91" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-korean" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dc33fb8e6bcba213fe2f14275f0963fd16f0a02c878e3095ecfdf5bee529d81" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-simpchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d87a7194909b9118fc707194baa434a4e3b0fb6a5a757c73c3adb07aa25031f7" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-singlebyte" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3351d5acffb224af9ca265f435b859c7c01537c0849754d3db3fdf2bfe2ae84a" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding-index-tradchinese" +version = "1.20141219.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0e20d5688ce3cab59eb3ef3a2083a5c77bf496cb798dc6fcdb75f323890c18" +dependencies = [ + "encoding_index_tests", +] + +[[package]] +name = "encoding_index_tests" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569" + +[[package]] +name = "encoding_rs" +version = "0.8.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80df024fbc5ac80f87dfef0d9f5209a252f2a497f7f42944cff24d8253cac065" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "error-code" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5115567ac25674e0043e472be13d14e537f37ea8aa4bdc4aef0c89add1db1ff" +dependencies = [ + "libc", + "str-buf", +] + +[[package]] +name = "euclid" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da96828553a086d7b18dcebfc579bd9628b016f86590d7453c115e490fa74b80" +dependencies = [ + "num-traits", +] + +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + +[[package]] +name = "expat-sys" +version = "2.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "658f19728920138342f68408b7cf7644d90d4784353d8ebc32e7e8663dbe45fa" +dependencies = [ + "cmake", + "pkg-config", +] + +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if 1.0.0", + "crc32fast", + "libc", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "float-cmp" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4" + +[[package]] +name = "float-ord" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bad48618fdb549078c333a7a8528acb57af271d0433bdecd523eb620628364e" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "font-kit" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c9a156ec38864999bc9c4156e5f3b50224d4a5578028a64e5a3875caa9ee28" +dependencies = [ + "bitflags", + "byteorder", + "core-foundation 0.9.2", + "core-graphics 0.22.2", + "core-text", + "dirs-next", + "dwrote", + "float-ord", + "freetype", + "lazy_static", + "libc", + "log", + "pathfinder_geometry", + "pathfinder_simd", + "servo-fontconfig", + "walkdir", + "winapi", +] + +[[package]] +name = "fontdb" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d66551cc28351f0bc6a73da86459ee7765caaad03ce284f2dc36472dbf539cd" +dependencies = [ + "log", + "memmap2 0.3.1", + "ttf-parser", +] + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191" +dependencies = [ + "matches", + "percent-encoding", +] + +[[package]] +name = "freetype" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee38378a9e3db1cc693b4f88d166ae375338a0ff75cb8263e1c601d51f35dc6" +dependencies = [ + "freetype-sys", + "libc", +] + +[[package]] +name = "freetype-sys" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a37d4011c0cc628dfa766fcc195454f4b068d7afdc2adfd28861191d866e731a" +dependencies = [ + "cmake", + "libc", + "pkg-config", +] + +[[package]] +name = "fs2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9564fc758e15025b46aa6643b1b77d047d1a56a1aea6e01002ac0c7026876213" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "futures" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a12aa0eb539080d55c3f2d45a67c3b58b6b0773c1a3ca2dfec66d58c97fd66ca" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5da6ba8c3bb3c165d3c7319fc1cc8304facf1fb8db99c5de877183c08a273888" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88d1c26957f23603395cd326b0ffe64124b818f4449552f960d815cfba83a53d" + +[[package]] +name = "futures-executor" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45025be030969d763025784f7f355043dc6bc74093e4ecc5000ca4dc50d8745c" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", + "num_cpus", +] + +[[package]] +name = "futures-io" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "522de2a0fe3e380f1bc577ba0474108faf3f6b18321dbf60b3b9c39a75073377" + +[[package]] +name = "futures-locks" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50c4e684ddb2d8a4db5ca8a02b35156da129674ba4412b6f528698d58c594954" +dependencies = [ + "futures", +] + +[[package]] +name = "futures-macro" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "18e4a4b95cea4b4ccbcf1c5675ca7c4ee4e9e75eb79944d07defde18068f79bb" +dependencies = [ + "autocfg", + "proc-macro-hack", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36ea153c13024fe480590b3e3d4cad89a0cfacecc24577b68f86c6ced9c2bc11" + +[[package]] +name = "futures-task" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d3d00f4eddb73e498a54394f228cd55853bdf059259e8e7bc6e69d408892e99" + +[[package]] +name = "futures-timer" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e64b03909df88034c26dc1547e8970b91f98bdb65165d6a4e9110d94263dbb2c" +dependencies = [ + "gloo-timers", + "send_wrapper", +] + +[[package]] +name = "futures-util" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36568465210a3a6ee45e1f165136d68671471a501e632e9a98d96872222b5481" +dependencies = [ + "autocfg", + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "proc-macro-hack", + "proc-macro-nested", + "slab", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "generic-array" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "gethostname" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e692e296bfac1d2533ef168d0b60ff5897b8b70a4009276834014dd8924cc028" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if 1.0.0", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "libc", + "wasi 0.10.2+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1583cc1656d7839fd3732b80cf4f38850336cdb9b8ded1cd399ca62958de3c99" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gif" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3a7187e78088aead22ceedeee99779455b23fc231fe13ec443f99bb71694e5b" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "glam" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "579160312273c954cc51bd440f059dde741029ac8daf8c84fece76cb77f62c15" +dependencies = [ + "version_check", +] + +[[package]] +name = "gloo-timers" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47204a46aaff920a1ea58b11d03dec6f704287d27561724a4631e450654a891f" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glow" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f04649123493bc2483cbef4daddb45d40bbdae5adb221a63a23efdb0cc99520" +dependencies = [ + "js-sys", + "slotmap", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "glyph_brush" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e3f00b8574a76fb6c50890c48da03946ca50e4372a2778737922666a2238221" +dependencies = [ + "glyph_brush_draw_cache", + "glyph_brush_layout", + "log", + "ordered-float", + "rustc-hash", + "twox-hash", +] + +[[package]] +name = "glyph_brush_draw_cache" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac2c82074cafb68b9e459c50c655f7eedcb92d6ee7166813802934bc6fc29fa3" +dependencies = [ + "ab_glyph", + "crossbeam-channel", + "crossbeam-deque", + "linked-hash-map", + "rayon", + "rustc-hash", +] + +[[package]] +name = "glyph_brush_layout" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc32c2334f00ca5ac3695c5009ae35da21da8c62d255b5b96d56e2597a637a38" +dependencies = [ + "ab_glyph", + "approx", + "xi-unicode", +] + +[[package]] +name = "gpu-alloc" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e64cbb8d36508d3e19da95e56e196a84f674fc190881f2cc010000798838aa6" +dependencies = [ + "bitflags", + "gpu-alloc-types", +] + +[[package]] +name = "gpu-alloc-types" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54804d0d6bc9d7f26db4eaec1ad10def69b599315f487d32c334a80d1efe67a5" +dependencies = [ + "bitflags", +] + +[[package]] +name = "gpu-descriptor" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7a237f0419ab10d17006d55c62ac4f689a6bf52c75d3f38b8361d249e8d4b0b" +dependencies = [ + "bitflags", + "gpu-descriptor-types", + "hashbrown 0.9.1", +] + +[[package]] +name = "gpu-descriptor-types" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "363e3677e55ad168fef68cf9de3a4a310b53124c5e784c53a1d70e92d23f2126" +dependencies = [ + "bitflags", +] + +[[package]] +name = "guillotiere" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62d5865c036cb1393e23c50693df631d3f5d7bcca4c04fe4cc0fd592e74a782" +dependencies = [ + "euclid", + "svg_fmt", +] + +[[package]] +name = "h2" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c06815895acec637cd6ed6e9662c935b866d20a106f8361892893a7d9234964" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04" +dependencies = [ + "ahash 0.4.7", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.6", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hexf-parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfa686283ad6dd069f105e5ab091b04c62850d3e4cf5d67debad1933f55023df" + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac", + "digest", +] + +[[package]] +name = "http" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "399c583b2979440c60be0821a6199eca73bc3c8dcd9d070d75ac726e2c6186e5" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503" + +[[package]] +name = "httpdate" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6456b8a6c8f33fee7d958fcd1b60d55b11940a79e63ae87013e6d22e26034440" + +[[package]] +name = "hyper" +version = "0.14.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15d1cfb9e4f68655fa04c01f59edb405b6074a0f7118ea881e5026e4a1cd8593" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f9f7a97316d44c0af9b0301e65010573a853a9fc97046d7331d7f6bc0fd5a64" +dependencies = [ + "futures-util", + "hyper", + "log", + "rustls", + "tokio", + "tokio-rustls", + "webpki", +] + +[[package]] +name = "iced" +version = "0.3.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "iced_core", + "iced_futures", + "iced_web", + "iced_wgpu", + "iced_winit", + "thiserror", +] + +[[package]] +name = "iced_core" +version = "0.4.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "bitflags", +] + +[[package]] +name = "iced_futures" +version = "0.3.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "futures", + "log", + "tokio", + "wasm-bindgen-futures", +] + +[[package]] +name = "iced_graphics" +version = "0.2.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "bytemuck", + "font-kit", + "glam", + "iced_native", + "iced_style", + "raw-window-handle", + "thiserror", +] + +[[package]] +name = "iced_native" +version = "0.4.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "iced_core", + "iced_futures", + "num-traits", + "twox-hash", + "unicode-segmentation", +] + +[[package]] +name = "iced_style" +version = "0.3.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "iced_core", +] + +[[package]] +name = "iced_web" +version = "0.4.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "base64", + "dodrio", + "iced_core", + "iced_futures", + "iced_style", + "num-traits", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "iced_wgpu" +version = "0.4.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "bitflags", + "bytemuck", + "futures", + "glyph_brush", + "guillotiere", + "iced_graphics", + "iced_native", + "image", + "kamadak-exif", + "log", + "raw-window-handle", + "resvg", + "tiny-skia", + "usvg", + "wgpu", + "wgpu_glyph", +] + +[[package]] +name = "iced_winit" +version = "0.3.0" +source = "git+https://github.com/hecrj/iced?rev=378a135#378a13555d47c77dd1c43742ec2b2a7ae5190286" +dependencies = [ + "iced_futures", + "iced_graphics", + "iced_native", + "log", + "thiserror", + "winapi", + "window_clipboard", + "winit", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "image" +version = "0.23.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24ffcb7e7244a9bf19d35bf2883b9c080c4ced3c07a9895572178cdb8f13f6a1" +dependencies = [ + "bytemuck", + "byteorder", + "color_quant", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png 0.16.8", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown 0.11.2", + "serde", +] + +[[package]] +name = "indoc" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a75aeaaef0ce18b58056d306c27b07436fbb34b8816c53094b76dd81803136" +dependencies = [ + "unindent", +] + +[[package]] +name = "inplace_it" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90953f308a79fe6d62a4643e51f848fbfddcd05975a38e69fdf4ab86a7baf7ca" + +[[package]] +name = "instant" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "716d3d89f35ac6a34fd0eed635395f4c3b76fa889338a4632e5231a8684216bd" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "time", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ipnet" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9" + +[[package]] +name = "itertools" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69ddb889f9d0d08a67338271fa9b62996bc788c7796a5c18cf057420aaed5eaf" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4" + +[[package]] +name = "jni-sys" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" + +[[package]] +name = "jpeg-decoder" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229d53d58899083193af11e15917b5640cd40b29ff475a1fe4ef725deb02d0f2" +dependencies = [ + "rayon", +] + +[[package]] +name = "js-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "js_int" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "defaba9bcd19568a4b4b3736b23e368e5b75e3ea126fd4cb3e4ad2ea5af274fd" +dependencies = [ + "serde", +] + +[[package]] +name = "kamadak-exif" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70494964492bf8e491eb3951c5d70c9627eb7100ede6cc56d748b9a3f302cfb6" +dependencies = [ + "mutate_once", +] + +[[package]] +name = "khronos-egl" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2352bd1d0bceb871cb9d40f24360c8133c11d7486b68b5381c1dd1a32015e3" +dependencies = [ + "libc", + "libloading", +] + +[[package]] +name = "kurbo" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb348d766edbac91ba1eb83020d96f4f8867924d194393083c15a51f185e6a82" +dependencies = [ + "arrayvec 0.5.2", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.103" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd8f7255a17a627354f321ef0055d63b898c6fb27eff628af4d1b66b7331edf6" + +[[package]] +name = "libloading" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cf036d15402bea3c5d4de17b3fce76b3e4a56ebc1f577be0e7a72f7c607cf0" +dependencies = [ + "cfg-if 1.0.0", + "winapi", +] + +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + +[[package]] +name = "lock_api" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710" +dependencies = [ + "cfg-if 1.0.0", +] + +[[package]] +name = "longest-increasing-subsequence" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bd0dd2cd90571056fdb71f6275fada10131182f84899f4b2a916e565d81d86" + +[[package]] +name = "lru" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ea2d928b485416e8908cff2d97d621db22b27f7b3b6729e438bcf42c671ba91" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + +[[package]] +name = "maplit" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" + +[[package]] +name = "matches" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" + +[[package]] +name = "matrix-sdk" +version = "0.4.1" +source = "git+https://github.com/matrix-org/matrix-rust-sdk?rev=9e1024f#9e1024f4b5907f492a8599937769a139894561f9" +dependencies = [ + "async-stream", + "backoff", + "bytes", + "dashmap", + "event-listener", + "futures", + "futures-timer", + "http", + "matrix-sdk-base", + "matrix-sdk-common", + "mime", + "reqwest", + "ruma", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-futures", + "url", + "zeroize", +] + +[[package]] +name = "matrix-sdk-base" +version = "0.4.1" +source = "git+https://github.com/matrix-org/matrix-rust-sdk?rev=9e1024f#9e1024f4b5907f492a8599937769a139894561f9" +dependencies = [ + "chacha20poly1305", + "dashmap", + "futures", + "hmac", + "lru", + "matrix-sdk-common", + "matrix-sdk-crypto", + "pbkdf2", + "rand 0.8.4", + "ruma", + "serde", + "serde_json", + "sha2", + "sled", + "thiserror", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "matrix-sdk-common" +version = "0.4.1" +source = "git+https://github.com/matrix-org/matrix-rust-sdk?rev=9e1024f#9e1024f4b5907f492a8599937769a139894561f9" +dependencies = [ + "async-trait", + "futures", + "futures-locks", + "instant", + "ruma", + "serde", + "tokio", + "uuid", + "wasm-bindgen-futures", +] + +[[package]] +name = "matrix-sdk-crypto" +version = "0.4.1" +source = "git+https://github.com/matrix-org/matrix-rust-sdk?rev=9e1024f#9e1024f4b5907f492a8599937769a139894561f9" +dependencies = [ + "aes", + "aes-gcm", + "atomic", + "base64", + "byteorder", + "dashmap", + "futures", + "getrandom 0.2.3", + "hmac", + "matrix-sdk-common", + "olm-rs", + "pbkdf2", + "ruma", + "serde", + "serde_json", + "sha2", + "sled", + "thiserror", + "tracing", + "zeroize", +] + +[[package]] +name = "memchr" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a" + +[[package]] +name = "memmap2" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723e3ebdcdc5c023db1df315364573789f8857c11b631a2fdfad7c00f5c046b4" +dependencies = [ + "libc", +] + +[[package]] +name = "memmap2" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b6c2ebff6180198788f5db08d7ce3bc1d0b617176678831a7510825973e357" +dependencies = [ + "libc", +] + +[[package]] +name = "memoffset" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59accc507f1338036a0477ef61afdae33cde60840f4dfe481319ce3ad116ddf9" +dependencies = [ + "autocfg", +] + +[[package]] +name = "metal" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0514f491f4cc03632ab399ee01e2c1c1b12d3e1cf2d667c1ff5f87d6dcd2084" +dependencies = [ + "bitflags", + "block", + "core-graphics-types", + "foreign-types", + "log", + "objc", +] + +[[package]] +name = "mime" +version = "0.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d" + +[[package]] +name = "minimal-lexical" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c64630dcdd71f1a64c435f54885086a0de5d6a12d104d69b165fb7d5286d677" + +[[package]] +name = "miniz_oxide" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791daaae1ed6889560f8c4359194f56648355540573244a5448a83ba1ecc7435" +dependencies = [ + "adler32", +] + +[[package]] +name = "miniz_oxide" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b" +dependencies = [ + "adler", + "autocfg", +] + +[[package]] +name = "mio" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c2bdb6314ec10835cd3293dd268473a835c02b7b352e788be788b3c6ca6bb16" +dependencies = [ + "libc", + "log", + "miow", + "ntapi", + "winapi", +] + +[[package]] +name = "miow" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21" +dependencies = [ + "winapi", +] + +[[package]] +name = "mutate_once" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" + +[[package]] +name = "naga" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eda66d09f712e1f0a6ab436137da4fac312f78301f6d4ac7cb8bfe96e988734f" +dependencies = [ + "bit-set", + "bitflags", + "codespan-reporting", + "fxhash", + "hexf-parse", + "indexmap", + "log", + "num-traits", + "spirv", + "thiserror", +] + +[[package]] +name = "ndk" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8794322172319b972f528bf90c6b467be0079f1fa82780ffb431088e741a73ab" +dependencies = [ + "jni-sys", + "ndk-sys", + "num_enum", + "thiserror", +] + +[[package]] +name = "ndk-glue" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5caf0c24d51ac1c905c27d4eda4fa0635bbe0de596b8f79235e0b17a4d29385" +dependencies = [ + "lazy_static", + "libc", + "log", + "ndk", + "ndk-macro", + "ndk-sys", +] + +[[package]] +name = "ndk-macro" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05d1c6307dc424d0f65b9b06e94f88248e6305726b14729fd67a5e47b2dc481d" +dependencies = [ + "darling", + "proc-macro-crate 0.1.5", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ndk-sys" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c44922cb3dbb1c70b5e5f443d63b64363a898564d739ba5198e3a9138442868d" + +[[package]] +name = "nix" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5e06129fb611568ef4e868c14b326274959aa70ff7776e9d55323531c374945" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + +[[package]] +name = "nix" +version = "0.22.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3bb9a13fa32bc5aeb64150cd3f32d6cf4c748f8f8a417cce5d2eb976a8370ba" +dependencies = [ + "bitflags", + "cc", + "cfg-if 1.0.0", + "libc", + "memoffset", +] + +[[package]] +name = "nom" +version = "7.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffd9d26838a953b4af82cbeb9f1592c6798916983959be223a7124e992742c1" +dependencies = [ + "memchr", + "minimal-lexical", + "version_check", +] + +[[package]] +name = "ntapi" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44" +dependencies = [ + "winapi", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2021c8337a54d21aca0d59a92577a029af9431cb59b909b03252b9c164fad59" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "12ac428b1cb17fce6f731001d307d351ec70a6d202fc2e60f7d4c5e42d8f4f07" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9bd055fb730c4f8f4f57d45d35cd6b3f0980535b056dc7ff119cee6a66ed6f" +dependencies = [ + "derivative", + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "486ea01961c4a818096de679a8b740b26d9033146ac5291b1c98557658f8cdd9" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", + "objc_exception", +] + +[[package]] +name = "objc-foundation" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9" +dependencies = [ + "block", + "objc", + "objc_id", +] + +[[package]] +name = "objc_exception" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ad970fb455818ad6cba4c122ad012fae53ae8b4795f86378bce65e4f6bab2ca4" +dependencies = [ + "cc", +] + +[[package]] +name = "objc_id" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b" +dependencies = [ + "objc", +] + +[[package]] +name = "olm-rs" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a5773f317476f5687fc8200fc0120d97b075c30c133a5b15ca558252743720" +dependencies = [ + "getrandom 0.2.3", + "olm-sys", + "serde", + "serde_json", + "zeroize", +] + +[[package]] +name = "olm-sys" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9074a928e1840d69d43d246b78e0ad580aae240e5add5a09add02e9dc3a4f621" +dependencies = [ + "cmake", +] + +[[package]] +name = "once_cell" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "ordered-float" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97c9d06878b3a851e8026ef94bf7fef9ba93062cd412601da4d9cf369b1cc62d" +dependencies = [ + "num-traits", +] + +[[package]] +name = "owned_ttf_parser" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60ac8dda2e5cc09bf6480e3b3feff9783db251710c922ae9369a429c51efdeb0" +dependencies = [ + "ttf-parser", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216" +dependencies = [ + "cfg-if 1.0.0", + "instant", + "libc", + "redox_syscall", + "smallvec", + "winapi", +] + +[[package]] +name = "paste" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" + +[[package]] +name = "pathfinder_geometry" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b7e7b4ea703700ce73ebf128e1450eb69c3a8329199ffbfb9b2a0418e5ad3" +dependencies = [ + "log", + "pathfinder_simd", +] + +[[package]] +name = "pathfinder_simd" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39fe46acc5503595e5949c17b818714d26fdf9b4920eacf3b2947f0199f4a6ff" +dependencies = [ + "rustc_version 0.3.3", +] + +[[package]] +name = "pbkdf2" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" +dependencies = [ + "crypto-mac", +] + +[[package]] +name = "percent-encoding" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e" + +[[package]] +name = "pest" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53" +dependencies = [ + "ucd-trie", +] + +[[package]] +name = "pico-args" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468" + +[[package]] +name = "pin-project" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "576bc800220cc65dac09e99e97b08b358cfab6e17078de8dc5fee223bd2d0c08" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e8fe8163d14ce7f0cdac2e040116f22eac817edabff0be91e8aff7e9accf389" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee3ef9b64d26bad0536099c816c6734379e45bbd5f14798def6809e5cc350447" +dependencies = [ + "der", + "spki", + "zeroize", +] + +[[package]] +name = "pkg-config" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb" + +[[package]] +name = "png" +version = "0.16.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3287920cb847dee3de33d301c463fba14dda99db24214ddf93f83d3021f4c6" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.8.6", + "miniz_oxide 0.3.7", +] + +[[package]] +name = "png" +version = "0.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c845088517daa61e8a57eee40309347cea13f273694d1385c553e7a57127763b" +dependencies = [ + "bitflags", + "crc32fast", + "deflate 0.9.1", + "encoding", + "miniz_oxide 0.4.4", +] + +[[package]] +name = "poly1305" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" +dependencies = [ + "cfg-if 1.0.0", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "ppv-lite86" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3ca011bd0129ff4ae15cd04c4eef202cadf6c51c21e47aba319b4e0501db741" + +[[package]] +name = "proc-macro-crate" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6ea3c4595b96363c13943497db34af4460fb474a95c43f4446ad341b8c9785" +dependencies = [ + "toml", +] + +[[package]] +name = "proc-macro-crate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebace6889caf889b4d3f76becee12e90353f2b8c7d875534a71e5742f8f6f83" +dependencies = [ + "thiserror", + "toml", +] + +[[package]] +name = "proc-macro-hack" +version = "0.5.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbf0c48bc1d91375ae5c3cd81e3722dff1abcf81a30960240640d223f59fe0e5" + +[[package]] +name = "proc-macro-nested" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc881b2c22681370c6a780e47af9840ef841837bc98118431d4e1868bd0c1086" + +[[package]] +name = "proc-macro2" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edc3358ebc67bc8b7fa0c007f945b0b18226f78437d61bec735a9eb96b61ee70" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "profiling" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87dfd5592a8eed7e74f56ad7b125f8234763b805c30f0c7c95c486920026a6ec" + +[[package]] +name = "quote" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc 0.2.0", +] + +[[package]] +name = "rand" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.3", + "rand_hc 0.3.1", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.3", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7" +dependencies = [ + "getrandom 0.2.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rand_hc" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7" +dependencies = [ + "rand_core 0.6.3", +] + +[[package]] +name = "range-alloc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e935c45e09cc6dcf00d2f0b2d630a58f4095320223d47fc68918722f0538b6" + +[[package]] +name = "raw-window-handle" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a441a7a6c80ad6473bd4b74ec1c9a4c951794285bf941c2126f607c72e48211" +dependencies = [ + "libc", +] + +[[package]] +name = "rayon" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90" +dependencies = [ + "autocfg", + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e" +dependencies = [ + "crossbeam-channel", + "crossbeam-deque", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "rctree" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ae028b272a6e99d9f8260ceefa3caa09300a8d6c8d2b2001316474bc52122e9" + +[[package]] +name = "redox_syscall" +version = "0.2.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff" +dependencies = [ + "bitflags", +] + +[[package]] +name = "redox_users" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "528532f3d801c87aec9def2add9ca802fe569e44a544afe633765267840abe64" +dependencies = [ + "getrandom 0.2.3", + "redox_syscall", +] + +[[package]] +name = "renderdoc-sys" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1382d1f0a252c4bf97dc20d979a2fdd05b024acd7c2ed0f7595d7817666a157" + +[[package]] +name = "reqwest" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51c732d463dd300362ffb44b7b125f299c23d2990411a4253824630ebc7467fb" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "hyper-rustls", + "ipnet", + "js-sys", + "lazy_static", + "log", + "mime", + "percent-encoding", + "pin-project-lite", + "rustls", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tokio-rustls", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "webpki-roots", + "winreg", +] + +[[package]] +name = "resvg" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "608c6e8aa6fb2c13bc06e4184d7c7b2cc1b7c138f88a539da8be55c3c033d7f4" +dependencies = [ + "jpeg-decoder", + "log", + "pico-args", + "png 0.17.2", + "rgb", + "svgfilters", + "tiny-skia", + "usvg", +] + +[[package]] +name = "retrix" +version = "0.1.0" +dependencies = [ + "directories", + "iced", + "matrix-sdk", + "serde", + "serde_json", + "url", +] + +[[package]] +name = "rgb" +version = "0.8.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fddb3b23626145d1776addfc307e1a1851f60ef6ca64f376bcb889697144cf0" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin", + "untrusted", + "web-sys", + "winapi", +] + +[[package]] +name = "roxmltree" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "921904a62e410e37e215c40381b7117f830d9d89ba60ab5236170541dd25646b" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "ruma" +version = "0.4.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "assign", + "js_int", + "ruma-api", + "ruma-client-api", + "ruma-common", + "ruma-events", + "ruma-federation-api", + "ruma-identifiers", + "ruma-serde", + "ruma-signatures", + "ruma-state-res", +] + +[[package]] +name = "ruma-api" +version = "0.18.5" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "bytes", + "http", + "percent-encoding", + "ruma-api-macros", + "ruma-identifiers", + "ruma-serde", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ruma-api-macros" +version = "0.18.5" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ruma-client-api" +version = "0.12.3" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "assign", + "bytes", + "http", + "js_int", + "maplit", + "percent-encoding", + "ruma-api", + "ruma-common", + "ruma-events", + "ruma-identifiers", + "ruma-serde", + "serde", + "serde_json", +] + +[[package]] +name = "ruma-common" +version = "0.6.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "indexmap", + "js_int", + "ruma-identifiers", + "ruma-serde", + "serde", + "serde_json", + "tracing", + "wildmatch", +] + +[[package]] +name = "ruma-events" +version = "0.24.6" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "indoc", + "js_int", + "ruma-common", + "ruma-events-macros", + "ruma-identifiers", + "ruma-serde", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "ruma-events-macros" +version = "0.24.6" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ruma-federation-api" +version = "0.3.1" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "js_int", + "ruma-api", + "ruma-common", + "ruma-events", + "ruma-identifiers", + "ruma-serde", + "serde", + "serde_json", +] + +[[package]] +name = "ruma-identifiers" +version = "0.20.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "paste", + "percent-encoding", + "ruma-identifiers-macros", + "ruma-identifiers-validation", + "ruma-serde", + "ruma-serde-macros", + "serde", +] + +[[package]] +name = "ruma-identifiers-macros" +version = "0.20.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "quote", + "ruma-identifiers-validation", + "syn", +] + +[[package]] +name = "ruma-identifiers-validation" +version = "0.5.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "thiserror", +] + +[[package]] +name = "ruma-serde" +version = "0.5.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "bytes", + "form_urlencoded", + "itoa", + "js_int", + "ruma-serde-macros", + "serde", + "serde_json", +] + +[[package]] +name = "ruma-serde-macros" +version = "0.5.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "proc-macro-crate 1.1.0", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ruma-signatures" +version = "0.9.0" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "base64", + "ed25519-dalek", + "pkcs8", + "rand 0.7.3", + "ruma-identifiers", + "ruma-serde", + "serde_json", + "sha2", + "thiserror", + "tracing", +] + +[[package]] +name = "ruma-state-res" +version = "0.4.1" +source = "git+https://github.com/ruma/ruma?rev=0101e110f#0101e110f8b56e5f0b0bcaac5a31a9cdbf299b8e" +dependencies = [ + "itertools", + "js_int", + "ruma-common", + "ruma-events", + "ruma-identifiers", + "ruma-serde", + "serde", + "serde_json", + "thiserror", + "tracing", +] + +[[package]] +name = "rustc-hash" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" + +[[package]] +name = "rustc_version" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a" +dependencies = [ + "semver 0.9.0", +] + +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64", + "log", + "ring", + "sct", + "webpki", +] + +[[package]] +name = "rustybuzz" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44561062e583c4873162861261f16fd1d85fe927c4904d71329a4fe43dc355ef" +dependencies = [ + "bitflags", + "bytemuck", + "smallvec", + "ttf-parser", + "unicode-bidi-mirroring", + "unicode-ccc", + "unicode-general-category", + "unicode-script", +] + +[[package]] +name = "ryu" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" + +[[package]] +name = "safe_arch" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1ff3d6d9696af502cc3110dacce942840fb06ff4514cad92236ecc455f2ce05" +dependencies = [ + "bytemuck", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "scoped-tls" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea6a9290e3c9cf0f18145ef7ffa62d68ee0bf5fcd651017e586dc7fd5da448c2" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "semver" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403" +dependencies = [ + "semver-parser 0.7.0", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser 0.10.2", +] + +[[package]] +name = "semver-parser" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "send_wrapper" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f638d531eccd6e23b980caf34876660d38e265409d8e99b397ab71eb3612fad0" + +[[package]] +name = "serde" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f12d06de37cf59146fbdecab66aa99f9fe4f78722e3607577a5375d66bd0c913" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.130" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7bc1a1ab1961464eae040d96713baa5a724a8152c1222492465b54322ec508b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.68" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f690853975602e1bfe1ccbf50504d67174e3bcf340f23b5ea9992e0587a52d8" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "servo-fontconfig" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e3e22fe5fd73d04ebf0daa049d3efe3eae55369ce38ab16d07ddd9ac5c217c" +dependencies = [ + "libc", + "servo-fontconfig-sys", +] + +[[package]] +name = "servo-fontconfig-sys" +version = "5.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e36b879db9892dfa40f95da1c38a835d41634b825fbd8c4c418093d53c24b388" +dependencies = [ + "expat-sys", + "freetype-sys", + "pkg-config", +] + +[[package]] +name = "sha1" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2579985fda508104f7587689507983eadd6a6e84dd35d6d115361f530916fa0d" + +[[package]] +name = "sha2" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b69f9a4c9740d74c5baa3fd2e547f9525fa8088a8a958e0ca2409a514e33f5fa" +dependencies = [ + "block-buffer", + "cfg-if 1.0.0", + "cpufeatures", + "digest", + "opaque-debug", +] + +[[package]] +name = "signature" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19772be3c4dd2ceaacf03cb41d5885f2a02c4d8804884918e3a258480803335" + +[[package]] +name = "simplecss" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a11be7c62927d9427e9f40f3444d5499d868648e2edbc4e2116de69e7ec0e89d" +dependencies = [ + "log", +] + +[[package]] +name = "siphasher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "533494a8f9b724d33625ab53c6c4800f7cc445895924a8ef649222dcb76e938b" + +[[package]] +name = "slab" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5" + +[[package]] +name = "sled" +version = "0.34.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f96b4737c2ce5987354855aed3797279def4ebf734436c6aa4552cf8e169935" +dependencies = [ + "crc32fast", + "crossbeam-epoch", + "crossbeam-utils", + "fs2", + "fxhash", + "libc", + "log", + "parking_lot", +] + +[[package]] +name = "slotmap" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e08e261d0e8f5c43123b7adf3e4ca1690d655377ac93a03b2c9d3e98de1342" +dependencies = [ + "version_check", +] + +[[package]] +name = "smallvec" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309" + +[[package]] +name = "smithay-client-toolkit" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec783683499a2cfc85b6df3d04f83b1907b5cbd98a1aed44667dbdf1eac4e64c" +dependencies = [ + "bitflags", + "dlib", + "lazy_static", + "log", + "memmap2 0.2.3", + "nix 0.20.2", + "wayland-client 0.28.6", + "wayland-cursor 0.28.6", + "wayland-protocols 0.28.6", +] + +[[package]] +name = "smithay-client-toolkit" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f41633cd89f7d598d5d933fe36ce614fe9eb54d8b5bc2340556d8b0b7f2c144" +dependencies = [ + "bitflags", + "calloop", + "dlib", + "lazy_static", + "log", + "memmap2 0.3.1", + "nix 0.22.2", + "pkg-config", + "wayland-client 0.29.0", + "wayland-cursor 0.29.0", + "wayland-protocols 0.29.0", +] + +[[package]] +name = "smithay-clipboard" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "986c5b4a7bd4f50d4c51f81f844745535cb488360f9cf63293780b109b9295f3" +dependencies = [ + "smithay-client-toolkit 0.14.0", + "wayland-client 0.28.6", +] + +[[package]] +name = "socket2" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spirv" +version = "0.2.0+1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "246bfa38fe3db3f1dfc8ca5a2cdeb7348c78be2112740cc0ec8ef18b6d94f830" +dependencies = [ + "bitflags", + "num-traits", +] + +[[package]] +name = "spki" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c01a0c15da1b0b0e1494112e7af814a678fec9bd157881b49beac661e9b6f32" +dependencies = [ + "der", +] + +[[package]] +name = "standback" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e113fb6f3de07a243d434a56ec6f186dfd51cb08448239fe7bcae73f87ff28ff" +dependencies = [ + "version_check", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stdweb" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d022496b16281348b52d0e30ae99e01a73d737b2f45d38fed4edf79f9325a1d5" +dependencies = [ + "discard", + "rustc_version 0.2.3", + "stdweb-derive", + "stdweb-internal-macros", + "stdweb-internal-runtime", + "wasm-bindgen", +] + +[[package]] +name = "stdweb-derive" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c87a60a40fccc84bef0652345bbbbbe20a605bf5d0ce81719fc476f5c03b50ef" +dependencies = [ + "proc-macro2", + "quote", + "serde", + "serde_derive", + "syn", +] + +[[package]] +name = "stdweb-internal-macros" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58fa5ff6ad0d98d1ffa8cb115892b6e69d67799f6763e162a1c9db421dc22e11" +dependencies = [ + "base-x", + "proc-macro2", + "quote", + "serde", + "serde_derive", + "serde_json", + "sha1", + "syn", +] + +[[package]] +name = "stdweb-internal-runtime" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" + +[[package]] +name = "str-buf" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d44a3643b4ff9caf57abcee9c2c621d6c03d9135e0d8b589bd9afb5992cb176a" + +[[package]] +name = "strsim" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6446ced80d6c486436db5c078dde11a9f73d42b57fb273121e160b84f63d894c" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "svg_fmt" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fb1df15f412ee2e9dfc1c504260fa695c1c3f10fe9f4a6ee2d2184d7d6450e2" + +[[package]] +name = "svgfilters" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "639abcebc15fdc2df179f37d6f5463d660c1c79cd552c12343a4600827a04bce" +dependencies = [ + "float-cmp", + "rgb", +] + +[[package]] +name = "svgtypes" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dabb3eb59a457c56d5282ab4545609e2cc382b41f6af239bb8d59a7267ef94b3" +dependencies = [ + "siphasher", +] + +[[package]] +name = "syn" +version = "1.0.80" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d010a1623fbd906d51d650a9916aaefc05ffa0e4053ff7fe601167f3e715d194" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "synstructure" +version = "0.12.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "time" +version = "0.2.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4752a97f8eebd6854ff91f1c1824cd6160626ac4bd44287f7f4ea2035a02a242" +dependencies = [ + "const_fn", + "libc", + "standback", + "stdweb", + "time-macros", + "version_check", + "winapi", +] + +[[package]] +name = "time-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "957e9c6e26f12cb6d0dd7fc776bb67a706312e7299aed74c8dd5b17ebb27e2f1" +dependencies = [ + "proc-macro-hack", + "time-macros-impl", +] + +[[package]] +name = "time-macros-impl" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd3c141a1b43194f3f56a1411225df8646c55781d5f26db825b3d98507eb482f" +dependencies = [ + "proc-macro-hack", + "proc-macro2", + "quote", + "standback", + "syn", +] + +[[package]] +name = "tiny-skia" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657db71220a7b20cc51aa6a8a0e14961cff9decb3d99b5415fbd34ca0a21cdc" +dependencies = [ + "arrayref", + "arrayvec 0.5.2", + "bytemuck", + "cfg-if 1.0.0", + "png 0.17.2", + "safe_arch", +] + +[[package]] +name = "tinyvec" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f83b2a3d4d9091d0abd7eba4dc2710b1718583bd4d8992e2190720ea38f391f7" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + +[[package]] +name = "tokio" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2c2416fdedca8443ae44b4527de1ea633af61d8f7169ffa6e72c5b53d24efcc" +dependencies = [ + "autocfg", + "bytes", + "libc", + "memchr", + "mio", + "num_cpus", + "pin-project-lite", + "winapi", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls", + "tokio", + "webpki", +] + +[[package]] +name = "tokio-util" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08d3725d3efa29485e87311c5b699de63cde14b00ed4d256b8318aa30ca452cd" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "log", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "toml" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa" +dependencies = [ + "serde", +] + +[[package]] +name = "tower-service" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6" + +[[package]] +name = "tracing" +version = "0.1.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105" +dependencies = [ + "cfg-if 1.0.0", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f480b8f81512e825f337ad51e94c1eb5d3bbdf2b363dcd01e2b19a9ffe3f8e" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "tracing-futures" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97d095ae15e245a057c8e8451bab9b3ee1e1f68e9ba2b4fbc18d0ac5237835f2" +dependencies = [ + "pin-project", + "tracing", +] + +[[package]] +name = "try-lock" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" + +[[package]] +name = "ttf-parser" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6" + +[[package]] +name = "twox-hash" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f559b464de2e2bdabcac6a210d12e9b5a5973c251e102c44c585c71d51bd78e" +dependencies = [ + "cfg-if 1.0.0", + "rand 0.8.4", + "static_assertions", +] + +[[package]] +name = "typenum" +version = "1.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" + +[[package]] +name = "ucd-trie" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c" + +[[package]] +name = "unicode-bidi" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f" + +[[package]] +name = "unicode-bidi-mirroring" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56d12260fb92d52f9008be7e4bca09f584780eb2266dc8fecc6a192bec561694" + +[[package]] +name = "unicode-ccc" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2520efa644f8268dce4dcd3050eaa7fc044fca03961e9998ac7e2e92b77cf1" + +[[package]] +name = "unicode-general-category" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07547e3ee45e28326cc23faac56d44f58f16ab23e413db526debce3b0bfd2742" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-script" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58dd944fd05f2f0b5c674917aea8a4df6af84f2d8de3fe8d988b95d28fb8fb09" + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-vo" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94" + +[[package]] +name = "unicode-width" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "unindent" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f14ee04d9415b52b3aeab06258a3f07093182b88ba0f9b8d203f211a7a7d41c7" + +[[package]] +name = "universal-hash" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", + "serde", +] + +[[package]] +name = "usvg" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4058e0bd091a56f905e6963e40776ce6880b271275f0b493bff951433e303071" +dependencies = [ + "base64", + "data-url", + "flate2", + "float-cmp", + "fontdb", + "kurbo", + "log", + "pico-args", + "rctree", + "roxmltree", + "rustybuzz", + "simplecss", + "siphasher", + "svgtypes", + "ttf-parser", + "unicode-bidi", + "unicode-script", + "unicode-vo", + "xmlwriter", +] + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" +dependencies = [ + "getrandom 0.2.3", + "serde", +] + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + +[[package]] +name = "walkdir" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56" +dependencies = [ + "same-file", + "winapi", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" +dependencies = [ + "log", + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.10.2+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" + +[[package]] +name = "wasm-bindgen" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce" +dependencies = [ + "cfg-if 1.0.0", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b" +dependencies = [ + "bumpalo 3.7.1", + "lazy_static", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39" +dependencies = [ + "cfg-if 1.0.0", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc" + +[[package]] +name = "wayland-client" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ab332350e502f159382201394a78e3cc12d0f04db863429260164ea40e0355" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix 0.20.2", + "scoped-tls", + "wayland-commons 0.28.6", + "wayland-scanner 0.28.6", + "wayland-sys 0.28.6", +] + +[[package]] +name = "wayland-client" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6deeba72b1fd9e9fc6641603bd5f72fa465857e3577b9a823fc316ffd45e69b4" +dependencies = [ + "bitflags", + "downcast-rs", + "libc", + "nix 0.22.2", + "scoped-tls", + "wayland-commons 0.29.0", + "wayland-scanner 0.29.0", + "wayland-sys 0.29.0", +] + +[[package]] +name = "wayland-commons" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21817947c7011bbd0a27e11b17b337bfd022e8544b071a2641232047966fbda" +dependencies = [ + "nix 0.20.2", + "once_cell", + "smallvec", + "wayland-sys 0.28.6", +] + +[[package]] +name = "wayland-commons" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6377fc0efc620da05cb78c5dc846420940e7b2c471aa2faf59c58e063c2b7" +dependencies = [ + "nix 0.22.2", + "once_cell", + "smallvec", + "wayland-sys 0.29.0", +] + +[[package]] +name = "wayland-cursor" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be610084edd1586d45e7bdd275fe345c7c1873598caa464c4fb835dee70fa65a" +dependencies = [ + "nix 0.20.2", + "wayland-client 0.28.6", + "xcursor", +] + +[[package]] +name = "wayland-cursor" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf9197a26e00b5e282b57ea9b620e4305ea5682f55f0b1ad862e388abf2d2bb5" +dependencies = [ + "nix 0.22.2", + "wayland-client 0.29.0", + "xcursor", +] + +[[package]] +name = "wayland-protocols" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "286620ea4d803bacf61fa087a4242ee316693099ee5a140796aaba02b29f861f" +dependencies = [ + "bitflags", + "wayland-client 0.28.6", + "wayland-commons 0.28.6", + "wayland-scanner 0.28.6", +] + +[[package]] +name = "wayland-protocols" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "503643f261c0f18124a4666b8c1e66258cf68b51f675d6e64469fbc72ddf0cd6" +dependencies = [ + "bitflags", + "wayland-client 0.29.0", + "wayland-commons 0.29.0", + "wayland-scanner 0.29.0", +] + +[[package]] +name = "wayland-scanner" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce923eb2deb61de332d1f356ec7b6bf37094dc5573952e1c8936db03b54c03f1" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-scanner" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d3d043a8926b2836749018bfb393e2328cac86bd414b9c3d3f8c523d0dee2dd" +dependencies = [ + "proc-macro2", + "quote", + "xml-rs", +] + +[[package]] +name = "wayland-sys" +version = "0.28.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d841fca9aed7febf9bed2e9796c49bf58d4152ceda8ac949ebe00868d8f0feb8" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "wayland-sys" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fef2a7d20f93be1379a2dfd9457c291e840b942fa38fe0b95ad6b0425a22d43a" +dependencies = [ + "dlib", + "lazy_static", + "pkg-config", +] + +[[package]] +name = "web-sys" +version = "0.3.55" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring", + "untrusted", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki", +] + +[[package]] +name = "weezl" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8b77fdfd5a253be4ab714e4ffa3c49caf146b4de743e97510c0656cf90f1e8e" + +[[package]] +name = "wgpu" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1577ecc4f6992b9e965878ac594efb24eed2bdf089c11f45b3d1c5f216e2e30" +dependencies = [ + "arrayvec 0.7.1", + "js-sys", + "log", + "parking_lot", + "raw-window-handle", + "smallvec", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "wgpu-core", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-core" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45af76ba5545b61a6904f26cdcf4287329144ae9e12f0c23ec4c9be982d675a6" +dependencies = [ + "arrayvec 0.7.1", + "bitflags", + "cfg_aliases", + "copyless", + "fxhash", + "log", + "naga", + "parking_lot", + "profiling", + "raw-window-handle", + "smallvec", + "thiserror", + "wgpu-hal", + "wgpu-types", +] + +[[package]] +name = "wgpu-hal" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11095a81f4406b1e594dab7dc35d6508409d364e62458f2e5b07b3edc7aca517" +dependencies = [ + "arrayvec 0.7.1", + "ash", + "bit-set", + "bitflags", + "block", + "core-graphics-types", + "d3d12", + "foreign-types", + "fxhash", + "glow", + "gpu-alloc", + "gpu-descriptor", + "inplace_it", + "js-sys", + "khronos-egl", + "libloading", + "log", + "metal", + "naga", + "objc", + "parking_lot", + "profiling", + "range-alloc", + "raw-window-handle", + "renderdoc-sys", + "thiserror", + "wasm-bindgen", + "web-sys", + "wgpu-types", + "winapi", +] + +[[package]] +name = "wgpu-types" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e15e44ba88ec415466e18e91881319e7c9e96cb905dc623305168aea65b85ccc" +dependencies = [ + "bitflags", +] + +[[package]] +name = "wgpu_glyph" +version = "0.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c78d49f4d168b245882ce000ee94fc67e744b33760c0119b0dbf8cb3caf20de5" +dependencies = [ + "bytemuck", + "glyph_brush", + "log", + "wgpu", +] + +[[package]] +name = "wildmatch" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6c48bd20df7e4ced539c12f570f937c6b4884928a87fee70a479d72f031d4e0" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-wsapoll" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c17110f57155602a80dca10be03852116403c9ff3cd25b079d666f2aa3df6e" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "window_clipboard" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33a4518b538a45ad39d138a8c3bea8f6b4452174aeb38143d1dd643a3a838ccc" +dependencies = [ + "clipboard-win", + "clipboard_macos", + "clipboard_wayland", + "clipboard_x11", + "raw-window-handle", +] + +[[package]] +name = "winit" +version = "0.25.0" +source = "git+https://github.com/iced-rs/winit?rev=1e6623c4d06d110e5408dcbdf1edebd07e6a200e#1e6623c4d06d110e5408dcbdf1edebd07e6a200e" +dependencies = [ + "bitflags", + "block", + "cocoa", + "core-foundation 0.9.2", + "core-graphics 0.22.2", + "core-video-sys", + "dispatch", + "instant", + "lazy_static", + "libc", + "log", + "mio", + "ndk", + "ndk-glue", + "ndk-sys", + "objc", + "parking_lot", + "percent-encoding", + "raw-window-handle", + "smithay-client-toolkit 0.15.1", + "wasm-bindgen", + "wayland-client 0.29.0", + "wayland-protocols 0.29.0", + "web-sys", + "winapi", + "x11-dl", +] + +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi", +] + +[[package]] +name = "wio" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d129932f4644ac2396cb456385cbf9e63b5b30c6e8dc4820bdca4eb082037a5" +dependencies = [ + "winapi", +] + +[[package]] +name = "x11-dl" +version = "2.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea26926b4ce81a6f5d9d0f3a0bc401e5a37c6ae14a1bfaa8ff6099ca80038c59" +dependencies = [ + "lazy_static", + "libc", + "pkg-config", +] + +[[package]] +name = "x11rb" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ffb080b3f2f616242a4eb8e7d325035312127901025b0052bc3154a282d0f19" +dependencies = [ + "gethostname", + "nix 0.20.2", + "winapi", + "winapi-wsapoll", +] + +[[package]] +name = "xcursor" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "463705a63313cd4301184381c5e8042f0a7e9b4bb63653f216311d4ae74690b7" +dependencies = [ + "nom", +] + +[[package]] +name = "xi-unicode" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a67300977d3dc3f8034dae89778f502b6ba20b269527b3223ba59c0cf393bb8a" + +[[package]] +name = "xml-rs" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3" + +[[package]] +name = "xmlparser" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "114ba2b24d2167ef6d67d7d04c8cc86522b87f490025f39f0303b7db5bf5e3d8" + +[[package]] +name = "xmlwriter" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec7a2a501ed189703dba8b08142f057e887dfc4b2cc4db2d343ac6376ba3e0b9" + +[[package]] +name = "zeroize" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf68b08513768deaa790264a7fac27a58cbf2705cfcdc9448362229217d7e970" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bdff2024a851a322b08f179173ae2ba620445aef1e838f0c196820eade4ae0c7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] diff --git a/Cargo.toml b/Cargo.toml index 4947e18..d57d69c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,32 +1,25 @@ [package] name = "retrix" -version = "0.1.0" authors = ["Amanda Graven "] +version = "0.1.0" edition = "2018" +resolver = "2" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = "1.0" -async-stream = "0.3" -async-trait = "0.1" -dirs-next = "2.0" -futures = "0.3" -iced = { git = "https://github.com/hecrj/iced", rev = "90fee3a", features = ["debug", "image", "tokio"] } -iced_futures = { git = "https://github.com/hecrj/iced", rev = "90fee3a" } -#iced = { git = "https://github.com/hecrj/iced", rev = "90fee3a", features = ["debug", "image", "tokio", "glow"] } -#iced_glow = { git = "https://github.com/hecrj/iced", rev = "90fee3a", features = ["image"] } +directories = "3.0" serde = { version = "1.0", features = ["derive"] } -time = "0.2" -tokio = { version = "1.1", features = ["sync"] } -toml = "0.5" -tracing-subscriber = { version = "0.2", features = ["parking_lot"] } +serde_json = "1.0" +url = { version = "2.2", features = ["serde"] } + +[dependencies.iced] +git = "https://github.com/hecrj/iced" +rev = "378a135" +features = ["image", "svg", "debug", "tokio"] [dependencies.matrix-sdk] git = "https://github.com/matrix-org/matrix-rust-sdk" -rev = "ff68360" -default_features = false -features = ["encryption", "rustls-tls", "unstable-synapse-quirks", "sled_cryptostore"] - -[profile.release] -lto = "thin" +rev = "9e1024f" +default-features = false +features = ["encryption", "sled_state_store", "sled_cryptostore", "rustls-tls", "require_auth_for_profile_requests"] diff --git a/LICENSE b/LICENSE deleted file mode 100644 index e142a52..0000000 --- a/LICENSE +++ /dev/null @@ -1,625 +0,0 @@ -GNU GENERAL PUBLIC LICENSE - -Version 3, 29 June 2007 - -Copyright © 2007 Free Software Foundation, Inc. - -Everyone is permitted to copy and distribute verbatim copies of this license -document, but changing it is not allowed. - -Preamble - -The GNU General Public License is a free, copyleft license for software and -other kinds of works. - -The licenses for most software and other practical works are designed to take -away your freedom to share and change the works. By contrast, the GNU General -Public License is intended to guarantee your freedom to share and change all -versions of a program--to make sure it remains free software for all its users. -We, the Free Software Foundation, use the GNU General Public License for most -of our software; it applies also to any other work released this way by its -authors. You can apply it to your programs, too. - -When we speak of free software, we are referring to freedom, not price. Our -General Public Licenses are designed to make sure that you have the freedom -to distribute copies of free software (and charge for them if you wish), that -you receive source code or can get it if you want it, that you can change -the software or use pieces of it in new free programs, and that you know you -can do these things. - -To protect your rights, we need to prevent others from denying you these rights -or asking you to surrender the rights. Therefore, you have certain responsibilities -if you distribute copies of the software, or if you modify it: responsibilities -to respect the freedom of others. - -For example, if you distribute copies of such a program, whether gratis or -for a fee, you must pass on to the recipients the same freedoms that you received. -You must make sure that they, too, receive or can get the source code. And -you must show them these terms so they know their rights. - -Developers that use the GNU GPL protect your rights with two steps: (1) assert -copyright on the software, and (2) offer you this License giving you legal -permission to copy, distribute and/or modify it. - -For the developers' and authors' protection, the GPL clearly explains that -there is no warranty for this free software. For both users' and authors' -sake, the GPL requires that modified versions be marked as changed, so that -their problems will not be attributed erroneously to authors of previous versions. - -Some devices are designed to deny users access to install or run modified -versions of the software inside them, although the manufacturer can do so. -This is fundamentally incompatible with the aim of protecting users' freedom -to change the software. The systematic pattern of such abuse occurs in the -area of products for individuals to use, which is precisely where it is most -unacceptable. Therefore, we have designed this version of the GPL to prohibit -the practice for those products. If such problems arise substantially in other -domains, we stand ready to extend this provision to those domains in future -versions of the GPL, as needed to protect the freedom of users. - -Finally, every program is threatened constantly by software patents. States -should not allow patents to restrict development and use of software on general-purpose -computers, but in those that do, we wish to avoid the special danger that -patents applied to a free program could make it effectively proprietary. To -prevent this, the GPL assures that patents cannot be used to render the program -non-free. - -The precise terms and conditions for copying, distribution and modification -follow. - -TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - -"Copyright" also means copyright-like laws that apply to other kinds of works, -such as semiconductor masks. - -"The Program" refers to any copyrightable work licensed under this License. -Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals -or organizations. - -To "modify" a work means to copy from or adapt all or part of the work in -a fashion requiring copyright permission, other than the making of an exact -copy. The resulting work is called a "modified version" of the earlier work -or a work "based on" the earlier work. - -A "covered work" means either the unmodified Program or a work based on the -Program. - -To "propagate" a work means to do anything with it that, without permission, -would make you directly or secondarily liable for infringement under applicable -copyright law, except executing it on a computer or modifying a private copy. -Propagation includes copying, distribution (with or without modification), -making available to the public, and in some countries other activities as -well. - -To "convey" a work means any kind of propagation that enables other parties -to make or receive copies. Mere interaction with a user through a computer -network, with no transfer of a copy, is not conveying. - -An interactive user interface displays "Appropriate Legal Notices" to the -extent that it includes a convenient and prominently visible feature that -(1) displays an appropriate copyright notice, and (2) tells the user that -there is no warranty for the work (except to the extent that warranties are -provided), that licensees may convey the work under this License, and how -to view a copy of this License. If the interface presents a list of user commands -or options, such as a menu, a prominent item in the list meets this criterion. - - 1. Source Code. - -The "source code" for a work means the preferred form of the work for making -modifications to it. "Object code" means any non-source form of a work. - -A "Standard Interface" means an interface that either is an official standard -defined by a recognized standards body, or, in the case of interfaces specified -for a particular programming language, one that is widely used among developers -working in that language. - -The "System Libraries" of an executable work include anything, other than -the work as a whole, that (a) is included in the normal form of packaging -a Major Component, but which is not part of that Major Component, and (b) -serves only to enable use of the work with that Major Component, or to implement -a Standard Interface for which an implementation is available to the public -in source code form. A "Major Component", in this context, means a major essential -component (kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to produce -the work, or an object code interpreter used to run it. - -The "Corresponding Source" for a work in object code form means all the source -code needed to generate, install, and (for an executable work) run the object -code and to modify the work, including scripts to control those activities. -However, it does not include the work's System Libraries, or general-purpose -tools or generally available free programs which are used unmodified in performing -those activities but which are not part of the work. For example, Corresponding -Source includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically linked -subprograms that the work is specifically designed to require, such as by -intimate data communication or control flow between those subprograms and -other parts of the work. - -The Corresponding Source need not include anything that users can regenerate -automatically from other parts of the Corresponding Source. - - The Corresponding Source for a work in source code form is that same work. - - 2. Basic Permissions. - -All rights granted under this License are granted for the term of copyright -on the Program, and are irrevocable provided the stated conditions are met. -This License explicitly affirms your unlimited permission to run the unmodified -Program. The output from running a covered work is covered by this License -only if the output, given its content, constitutes a covered work. This License -acknowledges your rights of fair use or other equivalent, as provided by copyright -law. - -You may make, run and propagate covered works that you do not convey, without -conditions so long as your license otherwise remains in force. You may convey -covered works to others for the sole purpose of having them make modifications -exclusively for you, or provide you with facilities for running those works, -provided that you comply with the terms of this License in conveying all material -for which you do not control copyright. Those thus making or running the covered -works for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of your copyrighted -material outside their relationship with you. - -Conveying under any other circumstances is permitted solely under the conditions -stated below. Sublicensing is not allowed; section 10 makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - -No covered work shall be deemed part of an effective technological measure -under any applicable law fulfilling obligations under article 11 of the WIPO -copyright treaty adopted on 20 December 1996, or similar laws prohibiting -or restricting circumvention of such measures. - -When you convey a covered work, you waive any legal power to forbid circumvention -of technological measures to the extent such circumvention is effected by -exercising rights under this License with respect to the covered work, and -you disclaim any intention to limit operation or modification of the work -as a means of enforcing, against the work's users, your or third parties' -legal rights to forbid circumvention of technological measures. - - 4. Conveying Verbatim Copies. - -You may convey verbatim copies of the Program's source code as you receive -it, in any medium, provided that you conspicuously and appropriately publish -on each copy an appropriate copyright notice; keep intact all notices stating -that this License and any non-permissive terms added in accord with section -7 apply to the code; keep intact all notices of the absence of any warranty; -and give all recipients a copy of this License along with the Program. - -You may charge any price or no price for each copy that you convey, and you -may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - -You may convey a work based on the Program, or the modifications to produce -it from the Program, in the form of source code under the terms of section -4, provided that you also meet all of these conditions: - -a) The work must carry prominent notices stating that you modified it, and -giving a relevant date. - -b) The work must carry prominent notices stating that it is released under -this License and any conditions added under section 7. This requirement modifies -the requirement in section 4 to "keep intact all notices". - -c) You must license the entire work, as a whole, under this License to anyone -who comes into possession of a copy. This License will therefore apply, along -with any applicable section 7 additional terms, to the whole of the work, -and all its parts, regardless of how they are packaged. This License gives -no permission to license the work in any other way, but it does not invalidate -such permission if you have separately received it. - -d) If the work has interactive user interfaces, each must display Appropriate -Legal Notices; however, if the Program has interactive interfaces that do -not display Appropriate Legal Notices, your work need not make them do so. - -A compilation of a covered work with other separate and independent works, -which are not by their nature extensions of the covered work, and which are -not combined with it such as to form a larger program, in or on a volume of -a storage or distribution medium, is called an "aggregate" if the compilation -and its resulting copyright are not used to limit the access or legal rights -of the compilation's users beyond what the individual works permit. Inclusion -of a covered work in an aggregate does not cause this License to apply to -the other parts of the aggregate. - - 6. Conveying Non-Source Forms. - -You may convey a covered work in object code form under the terms of sections -4 and 5, provided that you also convey the machine-readable Corresponding -Source under the terms of this License, in one of these ways: - -a) Convey the object code in, or embodied in, a physical product (including -a physical distribution medium), accompanied by the Corresponding Source fixed -on a durable physical medium customarily used for software interchange. - -b) Convey the object code in, or embodied in, a physical product (including -a physical distribution medium), accompanied by a written offer, valid for -at least three years and valid for as long as you offer spare parts or customer -support for that product model, to give anyone who possesses the object code -either (1) a copy of the Corresponding Source for all the software in the -product that is covered by this License, on a durable physical medium customarily -used for software interchange, for a price no more than your reasonable cost -of physically performing this conveying of source, or (2) access to copy the -Corresponding Source from a network server at no charge. - -c) Convey individual copies of the object code with a copy of the written -offer to provide the Corresponding Source. This alternative is allowed only -occasionally and noncommercially, and only if you received the object code -with such an offer, in accord with subsection 6b. - -d) Convey the object code by offering access from a designated place (gratis -or for a charge), and offer equivalent access to the Corresponding Source -in the same way through the same place at no further charge. You need not -require recipients to copy the Corresponding Source along with the object -code. If the place to copy the object code is a network server, the Corresponding -Source may be on a different server (operated by you or a third party) that -supports equivalent copying facilities, provided you maintain clear directions -next to the object code saying where to find the Corresponding Source. Regardless -of what server hosts the Corresponding Source, you remain obligated to ensure -that it is available for as long as needed to satisfy these requirements. - -e) Convey the object code using peer-to-peer transmission, provided you inform -other peers where the object code and Corresponding Source of the work are -being offered to the general public at no charge under subsection 6d. - -A separable portion of the object code, whose source code is excluded from -the Corresponding Source as a System Library, need not be included in conveying -the object code work. - -A "User Product" is either (1) a "consumer product", which means any tangible -personal property which is normally used for personal, family, or household -purposes, or (2) anything designed or sold for incorporation into a dwelling. -In determining whether a product is a consumer product, doubtful cases shall -be resolved in favor of coverage. For a particular product received by a particular -user, "normally used" refers to a typical or common use of that class of product, -regardless of the status of the particular user or of the way in which the -particular user actually uses, or expects or is expected to use, the product. -A product is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent the -only significant mode of use of the product. - -"Installation Information" for a User Product means any methods, procedures, -authorization keys, or other information required to install and execute modified -versions of a covered work in that User Product from a modified version of -its Corresponding Source. The information must suffice to ensure that the -continued functioning of the modified object code is in no case prevented -or interfered with solely because modification has been made. - -If you convey an object code work under this section in, or with, or specifically -for use in, a User Product, and the conveying occurs as part of a transaction -in which the right of possession and use of the User Product is transferred -to the recipient in perpetuity or for a fixed term (regardless of how the -transaction is characterized), the Corresponding Source conveyed under this -section must be accompanied by the Installation Information. But this requirement -does not apply if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has been installed -in ROM). - -The requirement to provide Installation Information does not include a requirement -to continue to provide support service, warranty, or updates for a work that -has been modified or installed by the recipient, or for the User Product in -which it has been modified or installed. Access to a network may be denied -when the modification itself materially and adversely affects the operation -of the network or violates the rules and protocols for communication across -the network. - -Corresponding Source conveyed, and Installation Information provided, in accord -with this section must be in a format that is publicly documented (and with -an implementation available to the public in source code form), and must require -no special password or key for unpacking, reading or copying. - - 7. Additional Terms. - -"Additional permissions" are terms that supplement the terms of this License -by making exceptions from one or more of its conditions. Additional permissions -that are applicable to the entire Program shall be treated as though they -were included in this License, to the extent that they are valid under applicable -law. If additional permissions apply only to part of the Program, that part -may be used separately under those permissions, but the entire Program remains -governed by this License without regard to the additional permissions. - -When you convey a copy of a covered work, you may at your option remove any -additional permissions from that copy, or from any part of it. (Additional -permissions may be written to require their own removal in certain cases when -you modify the work.) You may place additional permissions on material, added -by you to a covered work, for which you have or can give appropriate copyright -permission. - -Notwithstanding any other provision of this License, for material you add -to a covered work, you may (if authorized by the copyright holders of that -material) supplement the terms of this License with terms: - -a) Disclaiming warranty or limiting liability differently from the terms of -sections 15 and 16 of this License; or - -b) Requiring preservation of specified reasonable legal notices or author -attributions in that material or in the Appropriate Legal Notices displayed -by works containing it; or - -c) Prohibiting misrepresentation of the origin of that material, or requiring -that modified versions of such material be marked in reasonable ways as different -from the original version; or - -d) Limiting the use for publicity purposes of names of licensors or authors -of the material; or - -e) Declining to grant rights under trademark law for use of some trade names, -trademarks, or service marks; or - -f) Requiring indemnification of licensors and authors of that material by -anyone who conveys the material (or modified versions of it) with contractual -assumptions of liability to the recipient, for any liability that these contractual -assumptions directly impose on those licensors and authors. - -All other non-permissive additional terms are considered "further restrictions" -within the meaning of section 10. If the Program as you received it, or any -part of it, contains a notice stating that it is governed by this License -along with a term that is a further restriction, you may remove that term. -If a license document contains a further restriction but permits relicensing -or conveying under this License, you may add to a covered work material governed -by the terms of that license document, provided that the further restriction -does not survive such relicensing or conveying. - -If you add terms to a covered work in accord with this section, you must place, -in the relevant source files, a statement of the additional terms that apply -to those files, or a notice indicating where to find the applicable terms. - -Additional terms, permissive or non-permissive, may be stated in the form -of a separately written license, or stated as exceptions; the above requirements -apply either way. - - 8. Termination. - -You may not propagate or modify a covered work except as expressly provided -under this License. Any attempt otherwise to propagate or modify it is void, -and will automatically terminate your rights under this License (including -any patent licenses granted under the third paragraph of section 11). - -However, if you cease all violation of this License, then your license from -a particular copyright holder is reinstated (a) provisionally, unless and -until the copyright holder explicitly and finally terminates your license, -and (b) permanently, if the copyright holder fails to notify you of the violation -by some reasonable means prior to 60 days after the cessation. - -Moreover, your license from a particular copyright holder is reinstated permanently -if the copyright holder notifies you of the violation by some reasonable means, -this is the first time you have received notice of violation of this License -(for any work) from that copyright holder, and you cure the violation prior -to 30 days after your receipt of the notice. - -Termination of your rights under this section does not terminate the licenses -of parties who have received copies or rights from you under this License. -If your rights have been terminated and not permanently reinstated, you do -not qualify to receive new licenses for the same material under section 10. - - 9. Acceptance Not Required for Having Copies. - -You are not required to accept this License in order to receive or run a copy -of the Program. Ancillary propagation of a covered work occurring solely as -a consequence of using peer-to-peer transmission to receive a copy likewise -does not require acceptance. However, nothing other than this License grants -you permission to propagate or modify any covered work. These actions infringe -copyright if you do not accept this License. Therefore, by modifying or propagating -a covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - -Each time you convey a covered work, the recipient automatically receives -a license from the original licensors, to run, modify and propagate that work, -subject to this License. You are not responsible for enforcing compliance -by third parties with this License. - -An "entity transaction" is a transaction transferring control of an organization, -or substantially all assets of one, or subdividing an organization, or merging -organizations. If propagation of a covered work results from an entity transaction, -each party to that transaction who receives a copy of the work also receives -whatever licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the Corresponding -Source of the work from the predecessor in interest, if the predecessor has -it or can get it with reasonable efforts. - -You may not impose any further restrictions on the exercise of the rights -granted or affirmed under this License. For example, you may not impose a -license fee, royalty, or other charge for exercise of rights granted under -this License, and you may not initiate litigation (including a cross-claim -or counterclaim in a lawsuit) alleging that any patent claim is infringed -by making, using, selling, offering for sale, or importing the Program or -any portion of it. - - 11. Patents. - -A "contributor" is a copyright holder who authorizes use under this License -of the Program or a work on which the Program is based. The work thus licensed -is called the contributor's "contributor version". - -A contributor's "essential patent claims" are all patent claims owned or controlled -by the contributor, whether already acquired or hereafter acquired, that would -be infringed by some manner, permitted by this License, of making, using, -or selling its contributor version, but do not include claims that would be -infringed only as a consequence of further modification of the contributor -version. For purposes of this definition, "control" includes the right to -grant patent sublicenses in a manner consistent with the requirements of this -License. - -Each contributor grants you a non-exclusive, worldwide, royalty-free patent -license under the contributor's essential patent claims, to make, use, sell, -offer for sale, import and otherwise run, modify and propagate the contents -of its contributor version. - -In the following three paragraphs, a "patent license" is any express agreement -or commitment, however denominated, not to enforce a patent (such as an express -permission to practice a patent or covenant not to sue for patent infringement). -To "grant" such a patent license to a party means to make such an agreement -or commitment not to enforce a patent against the party. - -If you convey a covered work, knowingly relying on a patent license, and the -Corresponding Source of the work is not available for anyone to copy, free -of charge and under the terms of this License, through a publicly available -network server or other readily accessible means, then you must either (1) -cause the Corresponding Source to be so available, or (2) arrange to deprive -yourself of the benefit of the patent license for this particular work, or -(3) arrange, in a manner consistent with the requirements of this License, -to extend the patent license to downstream recipients. "Knowingly relying" -means you have actual knowledge that, but for the patent license, your conveying -the covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that country -that you have reason to believe are valid. - -If, pursuant to or in connection with a single transaction or arrangement, -you convey, or propagate by procuring conveyance of, a covered work, and grant -a patent license to some of the parties receiving the covered work authorizing -them to use, propagate, modify or convey a specific copy of the covered work, -then the patent license you grant is automatically extended to all recipients -of the covered work and works based on it. - -A patent license is "discriminatory" if it does not include within the scope -of its coverage, prohibits the exercise of, or is conditioned on the non-exercise -of one or more of the rights that are specifically granted under this License. -You may not convey a covered work if you are a party to an arrangement with -a third party that is in the business of distributing software, under which -you make payment to the third party based on the extent of your activity of -conveying the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory patent -license (a) in connection with copies of the covered work conveyed by you -(or copies made from those copies), or (b) primarily for and in connection -with specific products or compilations that contain the covered work, unless -you entered into that arrangement, or that patent license was granted, prior -to 28 March 2007. - -Nothing in this License shall be construed as excluding or limiting any implied -license or other defenses to infringement that may otherwise be available -to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - -If conditions are imposed on you (whether by court order, agreement or otherwise) -that contradict the conditions of this License, they do not excuse you from -the conditions of this License. If you cannot convey a covered work so as -to satisfy simultaneously your obligations under this License and any other -pertinent obligations, then as a consequence you may not convey it at all. -For example, if you agree to terms that obligate you to collect a royalty -for further conveying from those to whom you convey the Program, the only -way you could satisfy both those terms and this License would be to refrain -entirely from conveying the Program. - - 13. Use with the GNU Affero General Public License. - -Notwithstanding any other provision of this License, you have permission to -link or combine any covered work with a work licensed under version 3 of the -GNU Affero General Public License into a single combined work, and to convey -the resulting work. The terms of this License will continue to apply to the -part which is the covered work, but the special requirements of the GNU Affero -General Public License, section 13, concerning interaction through a network -will apply to the combination as such. - - 14. Revised Versions of this License. - -The Free Software Foundation may publish revised and/or new versions of the -GNU General Public License from time to time. Such new versions will be similar -in spirit to the present version, but may differ in detail to address new -problems or concerns. - -Each version is given a distinguishing version number. If the Program specifies -that a certain numbered version of the GNU General Public License "or any -later version" applies to it, you have the option of following the terms and -conditions either of that numbered version or of any later version published -by the Free Software Foundation. If the Program does not specify a version -number of the GNU General Public License, you may choose any version ever -published by the Free Software Foundation. - -If the Program specifies that a proxy can decide which future versions of -the GNU General Public License can be used, that proxy's public statement -of acceptance of a version permanently authorizes you to choose that version -for the Program. - -Later license versions may give you additional or different permissions. However, -no additional obligations are imposed on any author or copyright holder as -a result of your choosing to follow a later version. - - 15. Disclaimer of Warranty. - -THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE -LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER -EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM -PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR -CORRECTION. - - 16. Limitation of Liability. - -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL -ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM -AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, -INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO -USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED -INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE -PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER -PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - -If the disclaimer of warranty and limitation of liability provided above cannot -be given local legal effect according to their terms, reviewing courts shall -apply local law that most closely approximates an absolute waiver of all civil -liability in connection with the Program, unless a warranty or assumption -of liability accompanies a copy of the Program in return for a fee. END OF -TERMS AND CONDITIONS - -How to Apply These Terms to Your New Programs - -If you develop a new program, and you want it to be of the greatest possible -use to the public, the best way to achieve this is to make it free software -which everyone can redistribute and change under these terms. - -To do so, attach the following notices to the program. It is safest to attach -them to the start of each source file to most effectively state the exclusion -of warranty; and each file should have at least the "copyright" line and a -pointer to where the full notice is found. - - - -Copyright (C) - -This program is free software: you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation, either version 3 of the License, or (at your option) any later -version. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - -If the program does terminal interaction, make it output a short notice like -this when it starts in an interactive mode: - - Copyright (C) - -This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - -This is free software, and you are welcome to redistribute it under certain -conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands might -be different; for a GUI interface, you would use an "about box". - -You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. For -more information on this, and how to apply and follow the GNU GPL, see . - -The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General Public -License instead of this License. But first, please read . diff --git a/README.md b/README.md deleted file mode 100644 index b6e6737..0000000 --- a/README.md +++ /dev/null @@ -1,47 +0,0 @@ -# retrix - -Retrix is a lightweight matrix client built with [iced] and [matrix-rust-sdk]. - -The project is currently in early stages, and is decidedly not feature complete. Also note that both iced and matrix-sdk are somewhat unstable and under very rapid development, which means that there might be functionality that's broken or can't be implemented that I don't have direct influence over. - -## Features -- [x] Rooms - - [x] List rooms - - [ ] Join rooms - - [ ] Explore public room list - - [ ] Create room -- [ ] Communities -- [x] Messages - - [x] Plain text - - [ ] Formatted text (waiting on iced, markdown will be shown raw) - - [ ] Stickers - - [x] Images (in unencrypted rooms) - - [ ] Audio - - [ ] Video - - [ ] Location -- [x] E2E Encryption - - [x] Import key export - - [x] Receiving verification start - - [ ] Receiving verification request (waiting on matrix-sdk) -- [ ] Account settings - - [ ] Device management - - [ ] Change password -- [x] Profile settings - - [x] Display name - - [ ] Avatar - -### Things I (currently) don't intend to implement -- VoIP Calls - -## Building -Retrix can be compiled with -```bash -cargo build --release -``` -Be warned that retrix is very heavy to build due to the dependencies it uses. On the less powerful of my laptops, it takes on average 6 minutes to build in release mode. - -## Installing -You can put the compiled binary wherever binaries go. Retrix keeps its configuration and caching data in `~/.config/retrix` on linux systems, and in `%APPDATA%\retrix` on windows systems. It will automatically create the needed folder if it does not exist. - -[iced]: https://github.com/hecrj/iced -[matrix-rust-sdk]: https://github.com/matrix-org/matrix-rust-sdk diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..9d9f79c --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1,7 @@ +edition = "2018" +hard_tabs=true +max_width = 100 +wrap_comments = true +imports_granularity = "Crate" +use_small_heuristics = "Max" +group_imports = "StdExternalCrate" diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..ca1c57d --- /dev/null +++ b/src/config.rs @@ -0,0 +1,145 @@ +//! Configuration + +use std::{fmt::Display, fs::File, io::ErrorKind as IoErrorKind}; + +use serde::{Deserialize, Serialize}; + +/// Result alias for this module +pub type Result = std::result::Result; + +/// Data for a valid login, including access token and homeserver address +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Session { + /// Access token, mxid and device id of the session + pub session: matrix_sdk::Session, + /// The address of the homeserver + pub homeserver: String, +} + +impl Session { + /// Read session data from disk. + pub fn from_file() -> Result> { + let dirs = dirs()?; + let file = File::open(dirs.data_dir().join("session.json")); + let file = match file { + Ok(file) => file, + Err(e) => { + return match e.kind() { + IoErrorKind::NotFound => Ok(None), + _ => Err(e.into()), + } + } + }; + let session = serde_json::from_reader(file)?; + Ok(session) + } + + /// Writes the session data to disk. + pub fn write(&self) -> Result<()> { + let dirs = dirs()?; + std::fs::create_dir_all(dirs.data_dir())?; + let file = File::create(dirs.data_dir().join("session.json"))?; + serde_json::to_writer_pretty(file, self)?; + Ok(()) + } +} + +/// Configuration for the application +#[derive(Serialize, Deserialize, Clone, Debug)] +pub struct Config { + /// The global zoom level. + pub zoom: f64, +} + +impl Config { + /// Creates a new `Config` with default settings + pub fn new() -> Config { + Config { zoom: 1.0 } + } +} + +impl Default for Config { + fn default() -> Self { + Self::new() + } +} + +impl Config { + /// Reads the configuration from disk, or creates a new file with default settings if none + /// exists + pub fn from_file() -> Result { + let dirs = dirs()?; + let file = File::open(dirs.config_dir().join("retrix.json")); + // Create the file if it doesn't exist + let file = match file { + Ok(file) => file, + Err(e) => match e.kind() { + IoErrorKind::NotFound => { + let config = Config::default(); + config.write()?; + return Ok(config); + } + _ => return Err(e.into()), + }, + }; + let config: Config = serde_json::from_reader(file)?; + Ok(config) + } + + /// Writes the configuration to disk + pub fn write(&self) -> Result<()> { + let dirs = dirs()?; + std::fs::create_dir_all(dirs.config_dir())?; + let file = File::create(dirs.config_dir().join("retrix.json"))?; + serde_json::to_writer_pretty(file, self)?; + Ok(()) + } +} + +/// Generates structure holding paths for config dirs etc. +pub fn dirs() -> Result { + dirs::ProjectDirs::from("net.amandag", "", "retrix").ok_or(Error::HomeDir) +} + +/// Errors which can happen when handling config files +#[derive(Debug)] +pub enum Error { + /// An error happened opening or creating a file + Io(std::io::Error), + /// (De)serializing a file failed + Parsing(serde_json::Error), + /// The home directory couldn't be found + HomeDir, +} + +impl Display for Error { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + Error::Io(e) => write!(f, "Error opening file: {}", e), + Error::Parsing(e) => write!(f, "Error in config file: {}", e), + Error::HomeDir => write!(f, "Couldn't find home directory"), + } + } +} + +impl std::error::Error for Error { + fn source(&self) -> Option<&(dyn std::error::Error + 'static)> { + match *self { + Error::Io(ref e) => Some(e), + Error::Parsing(ref e) => Some(e), + Error::HomeDir => None, + } + } +} + +impl From for Error { + fn from(e: std::io::Error) -> Self { + Error::Io(e) + } +} + +impl From for Error { + fn from(e: serde_json::Error) -> Self { + Error::Parsing(e) + } +} diff --git a/src/main.rs b/src/main.rs index cb11a71..e8ff28c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,25 +1,30 @@ -extern crate dirs_next as dirs; +//! Retrix is a matrix client +#![warn( + missing_docs, + missing_debug_implementations, + trivial_casts, + trivial_numeric_casts, + unused_extern_crates, + unused_allocation +)] -#[cfg(unix)] -use std::{fs::Permissions, os::unix::fs::PermissionsExt}; +use config::Config; +use iced::{Application, Settings}; +use ui::Flags; -use iced::Application; +use crate::{config::Session, ui::Retrix}; +extern crate directories as dirs; + +pub mod config; pub mod matrix; +pub mod style; pub mod ui; -fn main() -> Result<(), Box> { - tracing_subscriber::fmt::init(); - - let config_dir = dirs::config_dir().unwrap().join("retrix"); - // Make sure config dir exists and is not accessible by other users. - if !config_dir.is_dir() { - std::fs::create_dir(&config_dir)?; - #[cfg(unix)] - std::fs::set_permissions(&config_dir, Permissions::from_mode(0o700))?; - } - - ui::Retrix::run(iced::Settings::default())?; - - Ok(()) +fn main() { + let session = Session::from_file().unwrap(); + let config = Config::from_file().unwrap(); + let settings = + Settings { text_multithreading: true, ..Settings::with_flags(Flags { config, session }) }; + Retrix::run(settings).unwrap(); } diff --git a/src/matrix.rs b/src/matrix.rs index eddcf4d..efb5ddf 100644 --- a/src/matrix.rs +++ b/src/matrix.rs @@ -1,331 +1,90 @@ -use std::{ - convert::TryFrom, - sync::Arc, - time::{Duration, SystemTime}, -}; +use std::path::{Path, PathBuf}; -use async_stream::stream; use matrix_sdk::{ - api::r0::{account::register::Request as RegistrationRequest, uiaa::AuthData}, - events::{ - room::message::{MessageEvent, MessageEventContent, MessageType}, - AnyMessageEvent, AnyRoomEvent, AnySyncRoomEvent, AnyToDeviceEvent, - }, - identifiers::{DeviceId, EventId, RoomId, ServerName, UserId}, - reqwest::Url, - Client, ClientConfig, LoopCtrl, SyncSettings, + config::ClientConfig, + reqwest::Url, + ruma::{DeviceIdBox, UserId}, + Client, }; use serde::{Deserialize, Serialize}; -pub type Error = anyhow::Error; - -// Needed to be able to serialize `Session`s. Should be done with serde remote. -#[derive(Debug, Clone, Deserialize, Serialize)] +#[derive(Debug, Clone, Serialize, Deserialize)] pub struct Session { - access_token: String, - pub user_id: UserId, - pub device_id: Box, - pub homeserver: String, + /// The homeserver URL + pub homeserver: Url, + /// Access token for authentication + pub access_token: String, + /// The user's mxid. + pub user_id: UserId, + /// The user's device ID. + pub device_id: DeviceIdBox, } -impl From for matrix_sdk::Session { - fn from(s: Session) -> Self { - Self { - access_token: s.access_token, - user_id: s.user_id, - device_id: s.device_id, - } - } +/// Create a matrix client and log it in to the server at the given URL with the +/// given credentials. +pub async fn login(url: &str, user: &str, password: &str) -> Result { + let url: Url = + if !url.contains("://") { format!("https://{}", url).parse() } else { url.parse() }?; + let client = Client::new_with_config(url.clone(), config()?)?; + let response = client.login(user, password, None, None).await?; + let session = Session { + homeserver: url, + access_token: response.access_token, + user_id: response.user_id, + device_id: response.device_id, + }; + Ok(client) } -pub async fn signup( - username: &str, - password: &str, - server: &str, - device_name: Option<&str>, -) -> Result<(Client, Session), Error> { - let url = Url::parse(server)?; - let client = client(url)?; - - let mut request = RegistrationRequest::new(); - request.username = Some(username); - request.password = Some(password); - request.initial_device_display_name = Some(device_name.unwrap_or("retrix")); - request.inhibit_login = false; - - // Get UIAA session key - let uiaa = match client.register(request.clone()).await { - Err(e) => match e.uiaa_response().cloned() { - Some(uiaa) => uiaa, - None => return Err(anyhow::anyhow!("Missing UIAA response")), - }, - Ok(_) => { - return Err(anyhow::anyhow!("Missing UIAA response")); - } - }; - // Get the first step in the authentication flow (we're ignoring the rest) - let stages = uiaa.flows.get(0); - let kind = stages.and_then(|flow| flow.stages.get(0)).cloned(); - - // Set authentication data, fallback to password type - request.auth = Some(AuthData::DirectRequest { - kind: kind.as_deref().unwrap_or("m.login.password"), - session: uiaa.session.as_deref(), - auth_parameters: Default::default(), - }); - - let response = client.register(request).await?; - client.sync_once(SyncSettings::new()).await?; - - let session = Session { - access_token: response.access_token.unwrap(), - user_id: response.user_id, - device_id: response.device_id.unwrap(), - homeserver: server.to_owned(), - }; - - Ok((client, session)) +/// Errors that can happen when logging in +#[derive(Debug)] +pub enum LoginError { + /// Invalid URL + Url(url::ParseError), + /// Matrix SDK error + Sdk(matrix_sdk::Error), + /// I/O error + Io(std::io::Error), } -/// Login with credentials, creating a new authentication session -pub async fn login( - username: &str, - password: &str, - server: &str, - device_name: Option<&str>, -) -> Result<(Client, Session), Error> { - let url = Url::parse(server)?; - let client = client(url)?; - - let response = client - .login( - username, - password, - None, - Some(device_name.unwrap_or("retrix")), - ) - .await?; - let session = Session { - access_token: response.access_token, - user_id: response.user_id, - device_id: response.device_id, - homeserver: server.to_owned(), - }; - write_session(&session)?; - client.sync_once(SyncSettings::new()).await?; - - Ok((client, session)) +impl std::fmt::Display for LoginError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + LoginError::Url(_) => write!(f, "Invalid homeserver address"), + LoginError::Sdk(e) => write!(f, "{}", e), + LoginError::Io(e) => write!(f, "Filesystem error: {}", e), + } + } } -pub async fn restore_login(session: Session) -> Result<(Client, Session), Error> { - let url = Url::parse(&session.homeserver)?; - let client = client(url)?; +impl std::error::Error for LoginError {} - client.restore_login(session.clone().into()).await?; - client.sync_once(SyncSettings::new()).await?; - - Ok((client, session)) +impl From for LoginError { + fn from(e: url::ParseError) -> Self { + LoginError::Url(e) + } } -/// Create a matrix client handler with the desired configuration -fn client(url: Url) -> Result { - let config = ClientConfig::new().store_path(&dirs::config_dir().unwrap().join("retrix")); - Client::new_with_config(url, config) +impl From for LoginError { + fn from(e: matrix_sdk::Error) -> Self { + LoginError::Sdk(e) + } } -/// File path to store session data in -fn session_path() -> std::path::PathBuf { - dirs::config_dir() - .unwrap() - .join("retrix") - .join("session.toml") +impl From for LoginError { + fn from(e: std::io::Error) -> Self { + LoginError::Io(e) + } } -/// Read session data from config file -pub fn get_session() -> Result, Error> { - let path = session_path(); - if !path.is_file() { - return Ok(None); - } - let session: Session = toml::from_slice(&std::fs::read(path)?)?; - Ok(Some(session)) +/// Configuration for `Clients`. +fn config() -> Result { + Ok(ClientConfig::new().store_path(&path()?)) } -/// Save session data to config file -fn write_session(session: &Session) -> Result<(), Error> { - let serialized = toml::to_string(&session)?; - std::fs::write(session_path(), serialized)?; - - Ok(()) -} - -/// Break down an mxc url to its authority and path -pub fn parse_mxc(url: &str) -> Result<(Box, String), Error> { - let url = Url::parse(&url)?; - anyhow::ensure!(url.scheme() == "mxc", "Not an mxc url"); - let host = url.host_str().ok_or_else(|| anyhow::anyhow!("url"))?; - let server_name: Box = <&ServerName>::try_from(host)?.into(); - let path = url.path_segments().and_then(|mut p| p.next()); - match path { - Some(path) => Ok((server_name, path.to_owned())), - _ => Err(anyhow::anyhow!("Invalid mxc url")), - } -} - -/// Makes an iced subscription for listening for matrix events. -pub struct MatrixSync { - client: matrix_sdk::Client, - join: Option>, - //id: String, -} - -impl MatrixSync { - pub fn subscription(client: matrix_sdk::Client) -> iced::Subscription { - iced::Subscription::from_recipe(MatrixSync { client, join: None }) - } -} - -/// A matrix event that should be passed to the iced subscription -#[derive(Clone, Debug)] -pub enum Event { - /// An event for an invited room - Invited(AnyRoomEvent, Arc), - /// An event for a joined room - Joined(AnyRoomEvent, Arc), - /// An event for a left room - Left(AnyRoomEvent, Arc), - /// A to-device event - ToDevice(AnyToDeviceEvent), - /// Synchronization token - Token(String), -} - -impl iced_futures::subscription::Recipe for MatrixSync -where - H: std::hash::Hasher, -{ - type Output = Event; - - fn hash(&self, state: &mut H) { - use std::hash::Hash; - - std::any::TypeId::of::().hash(state); - //self.id.hash(state); - } - - fn stream( - mut self: Box, - _input: iced_futures::BoxStream, - ) -> iced_futures::BoxStream { - let (sender, mut receiver) = tokio::sync::mpsc::unbounded_channel(); - let client = self.client.clone(); - let join = tokio::task::spawn(async move { - client - .sync_with_callback( - SyncSettings::new() - .token(client.sync_token().await.unwrap()) - .timeout(Duration::from_secs(30)), - |response| async { - for (id, room) in response.rooms.join { - let joined = Arc::new(client.get_joined_room(&id).unwrap()); - for event in room.state.events { - let id = id.clone(); - let event = AnyRoomEvent::State(event.into_full_event(id)); - sender.send(Event::Joined(event, Arc::clone(&joined))).ok(); - } - for event in room.timeline.events { - let event = event.into_full_event(id.clone()); - sender.send(Event::Joined(event, Arc::clone(&joined))).ok(); - } - } - for event in response.to_device.events { - sender.send(Event::ToDevice(event)).ok(); - } - LoopCtrl::Continue - }, - ) - .await; - }); - self.join = Some(join); - let stream = stream! { - while let Some(item) = receiver.recv().await { - yield item; - } - }; - Box::pin(stream) - } -} - -pub trait AnyRoomEventExt { - /// Gets the event id of the underlying event - fn event_id(&self) -> &EventId; - /// Gets the ´origin_server_ts` member of the underlying event - fn origin_server_ts(&self) -> SystemTime; - /// Gets the mxc url in a message event if there is noe - fn image_url(&self) -> Option; -} - -impl AnyRoomEventExt for AnyRoomEvent { - fn event_id(&self) -> &EventId { - match self { - AnyRoomEvent::Message(e) => e.event_id(), - AnyRoomEvent::State(e) => e.event_id(), - AnyRoomEvent::RedactedMessage(e) => e.event_id(), - AnyRoomEvent::RedactedState(e) => e.event_id(), - } - } - fn origin_server_ts(&self) -> SystemTime { - match self { - AnyRoomEvent::Message(e) => e.origin_server_ts(), - AnyRoomEvent::State(e) => e.origin_server_ts(), - AnyRoomEvent::RedactedMessage(e) => e.origin_server_ts(), - AnyRoomEvent::RedactedState(e) => e.origin_server_ts(), - } - .to_owned() - } - fn image_url(&self) -> Option { - match self { - AnyRoomEvent::Message(message) => message.image_url(), - _ => None, - } - } -} - -pub trait AnyMessageEventExt { - fn image_url(&self) -> Option; -} - -impl AnyMessageEventExt for AnyMessageEvent { - fn image_url(&self) -> Option { - match self { - AnyMessageEvent::RoomMessage(MessageEvent { - content: - MessageEventContent { - msgtype: MessageType::Image(ref image), - .. - }, - .. - }) => image.url.clone(), - _ => None, - } - } -} - -pub trait AnySyncRoomEventExt { - fn into_full_event(self, room_id: RoomId) -> AnyRoomEvent; -} - -impl AnySyncRoomEventExt for AnySyncRoomEvent { - fn into_full_event(self, id: RoomId) -> AnyRoomEvent { - match self { - AnySyncRoomEvent::Message(e) => AnyRoomEvent::Message(e.into_full_event(id)), - AnySyncRoomEvent::State(e) => AnyRoomEvent::State(e.into_full_event(id)), - AnySyncRoomEvent::RedactedMessage(e) => { - AnyRoomEvent::RedactedMessage(e.into_full_event(id)) - } - AnySyncRoomEvent::RedactedState(e) => { - AnyRoomEvent::RedactedState(e.into_full_event(id)) - } - } - } +/// The path the the sdk store should be put in. +fn path() -> Result { + let path = Path::new(&std::env::var_os("HOME").unwrap()).join(".config").join("retrix"); + std::fs::create_dir_all(&path)?; + Ok(path) } diff --git a/src/style.rs b/src/style.rs new file mode 100644 index 0000000..94218db --- /dev/null +++ b/src/style.rs @@ -0,0 +1,24 @@ +//! Style definitions for various elements + +/// Style definitions for [`iced::Container`] +pub mod container { + use iced::{ + container::{Style, StyleSheet}, + Color, + }; + + #[derive(Debug)] + /// Style for a container displaying an error message + pub struct Error; + + impl StyleSheet for Error { + fn style(&self) -> Style { + iced::container::Style { + background: Color::from_rgb(1.0, 0.0, 0.0).into(), + text_color: Some(Color::from_rgb(1.0, 1.0, 1.0)), + border_radius: 2.0, + ..Default::default() + } + } + } +} diff --git a/src/ui.rs b/src/ui.rs index 04d2280..967510e 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,1299 +1,84 @@ -use std::{ - collections::{BTreeMap, HashSet}, - time::SystemTime, -}; +//! The graphical iced-based interface -use futures::executor::block_on; -use iced::{ - Align, Application, Button, Column, Command, Container, Element, Image, Length, Row, Rule, - Scrollable, Subscription, Text, TextInput, -}; -use matrix_sdk::{ - api::r0::{ - media::get_content::Request as ImageRequest, - message::get_message_events::{Request as MessageRequest, Response as MessageResponse}, - }, - events::{ - key::verification::cancel::CancelCode as VerificationCancelCode, - room::{ - member::MembershipState, - message::{MessageEventContent, MessageType, Relation}, - }, - AnyMessageEvent, AnyMessageEventContent, AnyRoomEvent, AnyStateEvent, AnyToDeviceEvent, - }, - identifiers::{EventId, RoomAliasId, RoomId, UserId}, -}; +use iced::Command; -use crate::matrix::{self, AnyMessageEventExt, AnyRoomEventExt}; +use crate::config; -pub mod prompt; -pub mod settings; -pub mod theme; +pub mod login; +pub mod session; -use prompt::{PromptAction, PromptView}; -use settings::SettingsView; - -const THUMBNAIL_SIZE: u32 = 48; - -/// What order to sort rooms in in the room list. -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum RoomSorting { - Recent, - Alphabetic, +/// Data for the running application +#[derive(Debug)] +pub struct Retrix { + /// The currently active view + pub view: View, + /// Configuration + pub config: config::Config, } -/// Data for en entry in the room list -#[derive(Clone, Debug, Default)] -pub struct RoomEntry { - /// Cached calculated name - pub name: String, - /// Room topic - pub topic: String, - /// Canonical alias - pub alias: Option, - /// Defined display name - pub display_name: Option, - /// mxc url for the rooms avatar - pub avatar: Option, - /// Person we're in a direct message with - pub direct: Option, - /// Cache of messages - pub messages: MessageBuffer, -} - -impl RoomEntry { - pub async fn from_sdk(room: &matrix_sdk::room::Joined) -> Self { - Self { - direct: room.direct_target(), - name: room.display_name().await.unwrap(), - topic: room.topic().unwrap_or_default(), - alias: room.canonical_alias(), - avatar: room.avatar_url(), - ..Default::default() - } - } -} - -// Alternate storage strategies: HashMap+Vec, -// HashSet+BTreemap -/// Message history/event cache for a given room. -#[derive(Clone, Debug)] -pub struct MessageBuffer { - /// The messages we have stored - messages: Vec, - /// Set of event id's we have - known_ids: HashSet, - /// Token for the start of the messages we have - start: Option, - /// Token for the end of the messages we have - end: Option, - /// Most recent activity in the room - updated: std::time::SystemTime, - /// Whether we're awaiting for backfill to be received - loading: bool, -} - -impl MessageBuffer { - /// Sorts the messages by send time - fn sort(&mut self) { - self.messages - .sort_unstable_by_key(|msg| msg.origin_server_ts()) - } - - /// Gets the send time of the most recently sent message - fn update_time(&mut self) { - self.updated = match self.messages.last() { - Some(message) => message.origin_server_ts(), - None => SystemTime::UNIX_EPOCH, - }; - } - - fn remove(&mut self, id: &EventId) { - self.messages.retain(|e| e.event_id() != id); - self.known_ids.remove(&id); - } - - /// Add a message to the buffer. - pub fn push(&mut self, event: AnyRoomEvent) { - self.known_ids.insert(event.event_id().clone()); - if let AnyRoomEvent::Message(AnyMessageEvent::RoomMessage( - matrix_sdk::events::MessageEvent { - content: - MessageEventContent { - relates_to: Some(Relation::Replacement(ref replacement)), - .. - }, - .. - }, - )) = event - { - self.remove(&replacement.event_id); - } - if let AnyRoomEvent::Message(AnyMessageEvent::RoomRedaction(ref redaction)) = event { - self.remove(&redaction.redacts); - } - self.messages.push(event); - self.sort(); - self.update_time(); - } - - /// Adds several messages to the buffer - pub fn append(&mut self, mut events: Vec) { - events.retain(|e| !self.known_ids.contains(e.event_id())); - for event in events.iter() { - // Handle replacement - if let AnyRoomEvent::Message(AnyMessageEvent::RoomMessage( - matrix_sdk::events::MessageEvent { - content: - MessageEventContent { - relates_to: Some(Relation::Replacement(replacement)), - .. - }, - .. - }, - )) = event - { - self.remove(&replacement.event_id); - } - if let AnyRoomEvent::Message(AnyMessageEvent::RoomRedaction(redaction)) = event { - self.remove(&redaction.redacts); - } - self.known_ids.insert(event.event_id().clone()); - } - self.messages.append(&mut events); - self.sort(); - self.update_time(); - } - - /// Whather the message buffer has the room creation event - pub fn has_beginning(&self) -> bool { - self.messages - .iter() - .any(|e| matches!(e, AnyRoomEvent::State(AnyStateEvent::RoomCreate(_)))) - } -} - -impl Default for MessageBuffer { - fn default() -> Self { - Self { - messages: Default::default(), - known_ids: Default::default(), - start: None, - end: None, - updated: SystemTime::UNIX_EPOCH, - loading: false, - } - } -} - -/// Main view after successful login -#[derive(Debug, Clone)] -pub struct MainView { - /// Settings view, if open - settings_view: Option, - /// The matrix-sdk client - client: matrix_sdk::Client, - /// Sync token to use for backfill calls - sync_token: String, - session: matrix::Session, - /// Draft of message to send - draft: String, - /// Potential error message - error: Option<(String, iced::button::State)>, - /// Selected room - selected: Option, - /// Potential verification flow - sas: Option, - /// Whether to sort rooms alphabetically or by activity - sorting: RoomSorting, - /// Room state - rooms: BTreeMap, - /// A map of mxc urls to image data - images: BTreeMap, - /// A map of mxc urls to image thumbnails - thumbnails: BTreeMap, - - /// Room list entries for direct conversations - dm_buttons: Vec, - /// Room list entries for group conversations - group_buttons: Vec, - /// Room list scrollbar state - room_scroll: iced::scrollable::State, - /// Message view scrollbar state - message_scroll: iced::scrollable::State, - /// Backfill fetch button state - backfill_button: iced::button::State, - /// Button to go the room a tombstone points to - tombstone_button: iced::button::State, - /// Message draft text input - message_input: iced::text_input::State, - /// Button to send drafted message - send_button: iced::button::State, - /// Button to open settings menu - settings_button: iced::button::State, - /// Button for accepting/continuing verification - sas_accept_button: iced::button::State, - /// Button for cancelling verification - sas_deny_button: iced::button::State, -} - -impl MainView { - pub fn new(client: matrix_sdk::Client, session: matrix::Session) -> Self { - Self { - client, - session, - sync_token: String::new(), - settings_view: None, - settings_button: Default::default(), - error: None, - sas: None, - rooms: Default::default(), - selected: None, - images: Default::default(), - thumbnails: Default::default(), - room_scroll: Default::default(), - message_scroll: Default::default(), - backfill_button: Default::default(), - tombstone_button: Default::default(), - message_input: Default::default(), - dm_buttons: Vec::new(), - group_buttons: Vec::new(), - draft: String::new(), - send_button: Default::default(), - sorting: RoomSorting::Alphabetic, - sas_accept_button: Default::default(), - sas_deny_button: Default::default(), - } - } - - pub fn room<'a>(&'a self, id: &RoomId) -> Result<&'a RoomEntry, Command> { - match self.rooms.get(&id) { - Some(room) => Ok(room), - None => { - let id = id.clone(); - let client = self.client.clone(); - let cmd = async move { - let room = client.get_joined_room(&id).unwrap(); - let entry = RoomEntry::from_sdk(&room).await; - Message::ResetRoom(id, entry) - } - .into(); - Err(cmd) - } - } - } - - pub fn view(&mut self) -> Element { - // If settings view is open, display that instead - if let Some(ref mut settings) = self.settings_view { - return settings.view(self.sorting); - } - let mut root_row = Row::new().width(Length::Fill).height(Length::Fill); - - let mut room_scroll = Scrollable::new(&mut self.room_scroll) - .width(300.into()) - .height(Length::Fill) - .scrollbar_width(5); - - let client = &self.client; - let rooms = &self.rooms; - // Group by DM and group conversation - #[allow(clippy::type_complexity)] - let (mut dm_rooms, mut group_rooms): ( - Vec<(&RoomId, &RoomEntry)>, - Vec<(&RoomId, &RoomEntry)>, - ) = rooms - .iter() - // Hide if have joined the room the tombstone points to - .filter(|(id, _)| { - !client - .get_joined_room(id) - .and_then(|j| j.tombstone()) - .map(|t| rooms.contains_key(&t.replacement_room)) - .unwrap_or(false) - }) - .partition(|(_, room)| room.direct.is_some()); - // Sort - for list in [&mut dm_rooms, &mut group_rooms].iter_mut() { - match self.sorting { - RoomSorting::Alphabetic => { - list.sort_unstable_by_key(|(_, room)| room.name.to_uppercase()) - } - RoomSorting::Recent => list.sort_unstable_by(|(_, a), (_, b)| { - a.messages.updated.cmp(&b.messages.updated).reverse() - }), - }; - } - // Make sure button handler list has appropriate length - self.dm_buttons - .resize_with(dm_rooms.len(), Default::default); - self.group_buttons - .resize_with(group_rooms.len(), Default::default); - // Create buttons - let thumbnails = &self.thumbnails; - let images = &self.images; - let dm_buttons: Vec> = self - .dm_buttons - .iter_mut() - .enumerate() - .map(|(idx, button)| { - // TODO: highlight selected - let (id, room) = unsafe { dm_rooms.get_unchecked(idx) }; - let name = if room.name.is_empty() { - "Empty room" - } else { - &room.name - }; - let mut row = Row::new().align_items(Align::Center); - if let Some(ref url) = room.avatar { - if let Some(handle) = thumbnails.get(url) { - row = row.push( - Image::new(handle.clone()) - .width(20.into()) - .height(20.into()), - ); - } - } - Button::new(button, row.push(Text::new(name))) - .width(300.into()) - .on_press(Message::SelectRoom(id.to_owned().to_owned())) - }) - .collect(); - let room_buttons: Vec> = self - .group_buttons - .iter_mut() - .enumerate() - .map(|(idx, button)| { - let (id, room) = unsafe { group_rooms.get_unchecked(idx) }; - let name = if room.name.is_empty() { - "Missing name" - } else { - &room.name - }; - let mut row = Row::new().align_items(Align::Center); - if let Some(ref url) = room.avatar { - if let Some(handle) = images.get(url) { - row = row.push( - Image::new(handle.clone()) - .width(20.into()) - .height(20.into()), - ); - } - } - Button::new(button, row.push(Text::new(name))) - .width(300.into()) - .on_press(Message::SelectRoom(id.to_owned().to_owned())) - }) - .collect(); - // Add buttons to container - room_scroll = room_scroll.push(Text::new("Direct messages")); - for button in dm_buttons.into_iter() { - room_scroll = room_scroll.push(button); - } - room_scroll = room_scroll.push(Text::new("Rooms")); - for button in room_buttons.into_iter() { - room_scroll = room_scroll.push(button); - } - - let room_col = Column::new() - .push( - Button::new(&mut self.settings_button, Text::new("Settings")) - .on_press(Message::OpenSettings), - ) - .push(room_scroll); - root_row = root_row.push(room_col); - - let mut message_col = Column::new().spacing(5).padding(5); - let selected_room = match self.selected { - Some(ref selected) => match ( - self.rooms.get(selected), - self.client.get_joined_room(selected), - ) { - (Some(room), Some(joined)) => Some((room, joined)), - _ => None, - }, - None => None, - }; - if let Some((room, joined)) = selected_room { - // Include user id or canonical alias in title when appropriate - let title = if let Some(ref direct) = room.direct { - format!("{} ({})", &room.name, direct) - } else if let Some(ref alias) = room.alias { - format!("{} ({})", &room.name, alias) - } else { - room.name.clone() - }; - - let mut title_row = Row::new().align_items(Align::Center); - if let Some(handle) = room.avatar.as_deref().and_then(|a| images.get(a)) { - title_row = title_row.push( - Image::new(handle.to_owned()) - .width(24.into()) - .height(24.into()), - ); - } - message_col = message_col - .push(title_row.push(Text::new(title).size(25))) - .push(Rule::horizontal(2)); - let mut scroll = Scrollable::new(&mut self.message_scroll) - .scrollbar_width(2) - .spacing(4) - .height(Length::Fill); - // Backfill button or loading message - let backfill: Element<_> = if room.messages.loading { - Text::new("Loading...").into() - } else if room.messages.has_beginning() { - let creation = joined.create_content().unwrap(); - let mut col = - Column::new().push(Text::new("This is the beginning of room history")); - if let Some(prevous) = creation.predecessor { - col = col.push( - Button::new(&mut self.backfill_button, Text::new("Go to older version")) - .on_press(Message::SelectRoom(prevous.room_id)), - ); - } - col.into() - } else { - Button::new(&mut self.backfill_button, Text::new("Load more messages")) - .on_press(Message::BackFill(self.selected.clone().unwrap())) - .into() - }; - scroll = scroll.push(Container::new(backfill).width(Length::Fill).center_x()); - // mxid of most recent sender - let mut last_sender: Option = None; - // Rendered display name of most recent sender - let mut sender = String::from("Unknown sender"); - // Messages - for event in room.messages.messages.iter() { - #[allow(clippy::single_match)] - match event { - AnyRoomEvent::Message(AnyMessageEvent::RoomMessage(message)) => { - // Display sender if message is from new sender - if last_sender.as_ref() != Some(&message.sender) { - last_sender = Some(message.sender.clone()); - sender = match block_on(async { - joined.get_member(&message.sender).await - }) { - Ok(Some(member)) => member.name().to_owned(), - _ => message.sender.to_string(), - }; - scroll = scroll - .push(iced::Space::with_height(4.into())) - .push(Text::new(&sender).color([0.0, 0.0, 1.0])); - } - let content: Element<_> = match &message.content.msgtype { - MessageType::Audio(audio) => { - Text::new(format!("Audio message: {}", audio.body)) - .color([0.2, 0.2, 0.2]) - .width(Length::Fill) - .into() - } - MessageType::Emote(emote) => { - Text::new(format!("* {} {}", sender, emote.body)) - .width(Length::Fill) - .into() - } - MessageType::File(file) => Text::new(format!("File '{}'", file.body)) - .color([0.2, 0.2, 0.2]) - .width(Length::Fill) - .into(), - MessageType::Image(image) => { - if let Some(ref url) = image.url { - match self.images.get(url) { - Some(handle) => Container::new( - Image::new(handle.to_owned()) - .width(800.into()) - .height(1200.into()), - ) - .width(Length::Fill) - .into(), - None => { - Text::new("Image not loaded").width(Length::Fill).into() - } - } - } else { - Text::new("Encrypted images not supported yet") - .width(Length::Fill) - .into() - } - } - MessageType::Notice(notice) => { - Text::new(¬ice.body).width(Length::Fill).into() - } - MessageType::ServerNotice(notice) => { - Text::new(¬ice.body).width(Length::Fill).into() - } - MessageType::Text(text) => { - Text::new(&text.body).width(Length::Fill).into() - } - MessageType::Video(video) => { - Text::new(format!("Video: {}", video.body)) - .color([0.2, 0.2, 0.2]) - .into() - } - _ => Text::new("Unknown message type").into(), - }; - let row = Row::new() - .spacing(5) - .push(content) - .push(Text::new(format_systime(message.origin_server_ts))); - scroll = scroll.push(row); - } - AnyRoomEvent::Message(AnyMessageEvent::RoomEncrypted(_encrypted)) => { - scroll = scroll.push(Text::new("Encrypted event").color([0.3, 0.3, 0.3])); - } - AnyRoomEvent::RedactedMessage(_) => { - scroll = scroll.push(Text::new("Deleted message").color([0.3, 0.3, 0.3])); - } - _ => (), - } - } - // Tombstone - if let Some(tombstone) = joined.tombstone() { - let text = Text::new(format!( - "This room has been upgraded to a new version: {}", - tombstone.body - )); - let button = - Button::new(&mut self.tombstone_button, Text::new("Go to upgraded room")) - .on_press(Message::SelectRoom(tombstone.replacement_room)); - scroll = scroll.push( - Container::new( - Column::new() - .push(text) - .push(button) - .align_items(Align::Center), - ) - .center_x() - .width(Length::Fill), - ); - } - message_col = message_col.push(scroll); - } else { - message_col = message_col.push( - Container::new(Text::new("Select a room to start chatting")) - .center_x() - .center_y() - .width(Length::Fill) - .height(Length::Fill), - ); - } - // Verification info - if let Some(ref sas) = self.sas { - let device = sas.other_device(); - let sas_row = match sas.emoji() { - _ if sas.is_done() => Row::new() - .push(Text::new("Verification complete").width(Length::Fill)) - .push( - Button::new(&mut self.sas_accept_button, Text::new("Close")) - .on_press(Message::VerificationClose), - ), - Some(emojis) => { - let mut row = Row::new().push(Text::new("Verify emojis match:")); - for (emoji, name) in emojis.iter() { - row = row - .push( - Column::new() - .align_items(iced::Align::Center) - .push(Text::new(*emoji).size(32)) - .push(Text::new(*name)), - ) - .spacing(5); - } - row.push(iced::Space::with_width(Length::Fill)) - .push( - Button::new(&mut self.sas_accept_button, Text::new("Confirm")) - .on_press(Message::VerificationConfirm), - ) - .push( - Button::new(&mut self.sas_deny_button, Text::new("Deny")) - .on_press(Message::VerificationCancel), - ) - } - None => Row::new() - .push( - Text::new(format!( - "Incoming verification request from {}", - match device.display_name() { - Some(name) => name, - None => device.device_id().as_str(), - } - )) - .width(Length::Fill), - ) - .push( - Button::new(&mut self.sas_accept_button, Text::new("Accept")) - .on_press(Message::VerificationAccept), - ) - .push( - Button::new(&mut self.sas_deny_button, Text::new("Cancel")) - .on_press(Message::VerificationCancel), - ), - }; - message_col = message_col.push(sas_row); - } - // Potential error message - if let Some((ref error, ref mut button)) = self.error { - message_col = message_col.push( - Row::new() - .push(Text::new(error).width(Length::Fill).color([1.0, 0.0, 0.0])) - .push(Button::new(button, Text::new("Close")).on_press(Message::ClearError)), - ); - } - // Compose box - message_col = message_col.push( - Row::new() - .push( - TextInput::new( - &mut self.message_input, - "Write a message...", - &self.draft, - Message::SetMessage, - ) - .width(Length::Fill) - .padding(5) - .on_submit(Message::SendMessage), - ) - .push( - Button::new(&mut self.send_button, Text::new("Send")) - .on_press(Message::SendMessage), - ), - ); - root_row = root_row.push(message_col); - - root_row.into() - } - - fn update(&mut self, message: Message) -> Command { - let view = self; - match message { - Message::ErrorMessage(e) => view.error = Some((e, Default::default())), - Message::ClearError => view.error = None, - Message::SetSort(s) => view.sorting = s, - Message::ResetRoom(id, room) => { - view.rooms.insert(id.clone(), room); - return async move { Message::BackFill(id) }.into(); - } - Message::SelectRoom(r) => { - view.selected = Some(r.clone()); - if view.rooms.get(&r).unwrap().messages.messages.is_empty() { - return async move { Message::BackFill(r) }.into(); - } - } - Message::Sync(event) => match event { - matrix::Event::Joined(event, joined) => match event { - AnyRoomEvent::Message(event) => { - let room = view.rooms.entry(event.room_id().clone()).or_default(); - room.messages.push(AnyRoomEvent::Message(event.clone())); - let mut commands = Vec::new(); - // Add fetch image command if the message has an image - let img_cmd = match event.image_url() { - Some(url) => async { Message::FetchImage(url) }.into(), - None => Command::none(), - }; - commands.push(img_cmd); - // Set read marker if message is in selected room - /*if view.selected.as_ref() == Some(event.room_id()) { - let client = view.client.clone(); - let marker_cmd = async move { - let result = client - .read_marker( - event.room_id(), - event.event_id(), - Some(event.event_id()), - ) - .await - .err(); - match result { - Some(err) => Message::ErrorMessage(err.to_string()), - // TODO: Make this an actual no-op - None => Message::Login, - } - } - .into(); - commands.push(marker_cmd); - }*/ - - return Command::batch(commands); - } - AnyRoomEvent::State(event) => match event { - AnyStateEvent::RoomCanonicalAlias(ref alias) => { - let room = view.rooms.entry(alias.room_id.clone()).or_default(); - room.alias = alias.content.alias.clone(); - room.messages.push(AnyRoomEvent::State(event)); - } - AnyStateEvent::RoomName(ref name) => { - let id = name.room_id.clone(); - let room = view.rooms.entry(id.clone()).or_default(); - room.display_name = name.content.name().map(String::from); - room.messages.push(AnyRoomEvent::State(event)); - let client = view.client.clone(); - return async move { - let joined = client.get_joined_room(&id).unwrap(); - match joined.display_name().await { - Ok(name) => Message::RoomName(id, name), - Err(e) => Message::ErrorMessage(e.to_string()), - } - } - .into(); - } - AnyStateEvent::RoomTopic(ref topic) => { - let room = view.rooms.entry(topic.room_id.clone()).or_default(); - room.topic = topic.content.topic.clone(); - room.messages.push(AnyRoomEvent::State(event)); - } - AnyStateEvent::RoomAvatar(ref avatar) => { - let room = view.rooms.entry(avatar.room_id.clone()).or_default(); - room.messages.push(AnyRoomEvent::State(event)); - if let Some(url) = room.avatar.clone() { - room.avatar = Some(url.clone()); - //return async { Message::FetchThumb(url) }.into(); - return Command::none(); - } - } - AnyStateEvent::RoomCreate(ref create) => { - // Add room to the entry list - let joined = view.client.get_joined_room(&create.room_id).unwrap(); - let id = create.room_id.clone(); - return async move { - let mut entry = RoomEntry::from_sdk(&joined).await; - entry.messages.push(AnyRoomEvent::State(event)); - Message::ResetRoom(id, entry) - } - .into(); - } - AnyStateEvent::RoomMember(ref member) => { - let room = view.rooms.entry(member.room_id.clone()).or_default(); - let client = view.client.clone(); - // If we left a room, remove it from the RoomEntry list - if member.state_key == view.session.user_id { - match member.content.membership { - MembershipState::Join => { - let id = member.room_id.clone(); - return async move { - let joined = client.get_joined_room(&id).unwrap(); - let entry = RoomEntry::from_sdk(&joined).await; - - Message::ResetRoom(id, entry) - } - .into(); - } - MembershipState::Leave => { - // Deselect room if we're leaving selected room - if view.selected.as_ref() == Some(&member.room_id) { - view.selected = None; - } - view.rooms.remove(&member.room_id); - return Command::none(); - } - _ => (), - } - } - room.messages.push(AnyRoomEvent::State(event)); - } - ref any => { - // Ensure room exists - let room = view.rooms.entry(any.room_id().clone()).or_default(); - room.messages.push(AnyRoomEvent::State(event)); - } - }, - AnyRoomEvent::RedactedMessage(redacted) => { - let room = view.rooms.entry(redacted.room_id().clone()).or_default(); - room.messages.push(AnyRoomEvent::RedactedMessage(redacted)); - } - AnyRoomEvent::RedactedState(redacted) => { - let room = view.rooms.entry(redacted.room_id().clone()).or_default(); - room.messages.push(AnyRoomEvent::RedactedState(redacted)); - } - }, - matrix::Event::ToDevice(event) => match event { - AnyToDeviceEvent::KeyVerificationStart(start) => { - let client = view.client.clone(); - return Command::perform( - async move { client.get_verification(&start.content.transaction_id).await }, - Message::SetVerification, - ); - } - AnyToDeviceEvent::KeyVerificationCancel(cancel) => { - return async { Message::VerificationCancelled(cancel.content.code) } - .into(); - } - _ => (), - }, - matrix::Event::Token(token) => { - view.sync_token = token; - } - _ => (), - }, - Message::BackFill(id) => { - let entry = view.rooms.entry(id.clone()).or_default(); - entry.messages.loading = true; - let client = view.client.clone(); - let room = client.get_joined_room(&id).unwrap(); - let token = match entry.messages.end.clone() { - Some(end) => end, - None => room - .last_prev_batch() - .unwrap_or_else(|| view.sync_token.clone()), - }; - return async move { - let mut request = MessageRequest::backward(&id, &token); - request.limit = matrix_sdk::uint!(30); - match room.messages(request).await { - Ok(response) => Message::BackFilled(id, response), - Err(e) => Message::ErrorMessage(e.to_string()), - } - } - .into(); - } - Message::BackFilled(id, response) => { - let room = view.rooms.get_mut(&id).unwrap(); - room.messages.loading = false; - let events: Vec = response - .chunk - .into_iter() - .filter_map(|e| e.deserialize().ok()) - .chain( - response - .state - .into_iter() - .filter_map(|e| e.deserialize().ok().map(AnyRoomEvent::State)), - ) - .collect(); - - if let Some(start) = response.start { - room.messages.start = Some(start); - } - if let Some(end) = response.end { - room.messages.end = Some(end); - } - let commands: Vec> = events - .iter() - .filter_map(|e| e.image_url()) - .map(|url| async { Message::FetchImage(url) }.into()) - .collect(); - room.messages.append(events); - return Command::batch(commands); - } - - Message::FetchImage(url) => { - let (server, path) = match matrix::parse_mxc(&url) { - Ok((server, path)) => (server, path), - Err(e) => return async move { Message::ErrorMessage(e.to_string()) }.into(), - }; - let client = view.client.clone(); - return async move { - let request = ImageRequest::new(&path, &*server); - let response = client.send(request, None).await; - match response { - Ok(response) => Message::FetchedImage( - url, - iced::image::Handle::from_memory(response.file), - ), - Err(e) => Message::ErrorMessage(e.to_string()), - } - } - .into(); - } - Message::FetchedImage(url, handle) => { - view.images.insert(url, handle); - } - Message::FetchedThumbnail(url, handle) => { - view.thumbnails.insert(url, handle); - } - Message::RoomName(id, name) => { - if let Some(room) = view.rooms.get_mut(&id) { - room.name = name; - } - } - Message::SetVerification(v) => view.sas = v, - Message::VerificationAccept => { - let sas = match &view.sas { - Some(sas) => sas.clone(), - None => return Command::none(), - }; - return Command::perform( - async move { sas.accept().await }, - |result| match result { - Ok(()) => Message::VerificationAccepted, - Err(e) => Message::ErrorMessage(e.to_string()), - }, - ); - } - Message::VerificationConfirm => { - let sas = match &view.sas { - Some(sas) => sas.clone(), - None => return Command::none(), - }; - return Command::perform( - async move { sas.confirm().await }, - |result| match result { - Ok(()) => Message::VerificationConfirmed, - Err(e) => Message::ErrorMessage(e.to_string()), - }, - ); - } - Message::VerificationCancel => { - let sas = match &view.sas { - Some(sas) => sas.clone(), - None => return Command::none(), - }; - return Command::perform( - async move { sas.cancel().await }, - |result| match result { - Ok(()) => Message::VerificationCancelled(VerificationCancelCode::User), - Err(e) => Message::ErrorMessage(e.to_string()), - }, - ); - } - Message::VerificationCancelled(code) => { - view.sas = None; - return async move { Message::ErrorMessage(code.as_str().to_owned()) }.into(); - } - Message::VerificationClose => view.sas = None, - Message::SetMessage(m) => view.draft = m, - Message::SendMessage => { - let selected = match view.selected.clone() { - Some(selected) => selected, - None => return Command::none(), - }; - let draft = view.draft.clone(); - let client = view.client.clone(); - return Command::perform( - async move { - client - .room_send( - &selected, - AnyMessageEventContent::RoomMessage( - MessageEventContent::text_plain(draft), - ), - None, - ) - .await - }, - |result| match result { - Ok(_) => Message::SetMessage(String::new()), - Err(e) => Message::ErrorMessage(e.to_string()), - }, - ); - } - Message::OpenSettings => { - view.settings_view = Some(SettingsView::new()); - let client = view.client.clone(); - return Command::perform( - async move { - client - .display_name() - .await - .unwrap_or_default() - .unwrap_or_default() - }, - Message::SetDisplayNameInput, - ); - } - Message::SetDisplayNameInput(name) => { - if let Some(ref mut settings) = view.settings_view { - settings.display_name = name; - } - } - Message::SaveDisplayName => { - if let Some(ref mut settings) = view.settings_view { - let client = view.client.clone(); - let name = settings.display_name.clone(); - settings.saving_name = true; - return Command::perform( - async move { client.set_display_name(Some(&name)).await }, - |result| match result { - Ok(()) => Message::DisplayNameSaved, - // TODO: set saving to false and report error - Err(_) => Message::DisplayNameSaved, - }, - ); - } - } - Message::DisplayNameSaved => { - if let Some(ref mut settings) = view.settings_view { - settings.saving_name = false; - } - } - Message::SetKeyPath(p) => { - if let Some(ref mut settings) = view.settings_view { - settings.key_path = p; - } - } - Message::SetKeyPassword(p) => { - if let Some(ref mut settings) = view.settings_view { - settings.key_password = p; - } - } - Message::ImportKeys => { - if let Some(ref settings) = view.settings_view { - let path = std::path::PathBuf::from(&settings.key_path); - let password = settings.key_password.clone(); - let client = view.client.clone(); - return Command::perform( - async move { client.import_keys(path, &password).await }, - |result| match result { - Ok(_) => Message::SetKeyPassword(String::new()), - // TODO: Actual error reporting here - Err(e) => Message::SetKeyPath(e.to_string()), - }, - ); - } - } - Message::CloseSettings => view.settings_view = None, - _ => (), - }; - Command::none() - } -} - -#[allow(clippy::large_enum_variant)] -#[derive(Debug, Clone)] -pub enum Retrix { - Prompt(PromptView), - AwaitLogin, - LoggedIn(MainView), +/// Available application views. +#[derive(Debug)] +pub enum View { + /// The login prompt + Login(login::Login), + /// The main view + Main(session::View), } +/// A message notifying application state should change #[derive(Debug, Clone)] pub enum Message { - /// Do nothing - Noop, - // Login form messages - SetUser(String), - SetPassword(String), - SetServer(String), - SetDeviceName(String), - SetAction(PromptAction), - Login, - Signup, - // Auth result messages - LoggedIn(matrix_sdk::Client, matrix::Session), - LoginFailed(String), - - // Main state messages - /// Reset state for room - ResetRoom(RoomId, RoomEntry), - RoomName(RoomId, String), - /// Get backfill for given room - BackFill(RoomId), - /// Received backfill - BackFilled(RoomId, MessageResponse), - /// Fetched a thumbnail - FetchedThumbnail(String, iced::image::Handle), - /// Fetch an image pointed to by an mxc url - FetchImage(String), - /// Fetched an image - FetchedImage(String, iced::image::Handle), - /// View messages from this room - SelectRoom(RoomId), - /// Set error message - ErrorMessage(String), - /// Close error message - ClearError, - /// Set how the room list is sorted - SetSort(RoomSorting), - /// Set verification flow - SetVerification(Option), - /// Accept verification flow - VerificationAccept, - /// Accept sent - VerificationAccepted, - /// Confirm keys match - VerificationConfirm, - /// Confirmation sent - VerificationConfirmed, - /// Cancel verification flow - VerificationCancel, - /// Verification flow cancelled - VerificationCancelled(VerificationCancelCode), - /// Close verification bar - VerificationClose, - /// Matrix event received - Sync(matrix::Event), - /// Update the sync token to use - SyncToken(String), - /// Set contents of message compose box - SetMessage(String), - /// Send the contents of the compose box to the selected room - SendMessage, - - // Settings messages - /// Open settings menu - OpenSettings, - /// Close settings menu - CloseSettings, - /// Set display name input field - SetDisplayNameInput(String), - /// Save new display name - SaveDisplayName, - /// New display name saved successfully - DisplayNameSaved, - /// Set key import path - SetKeyPath(String), - /// Set password key backup is encrypted with - SetKeyPassword(String), - /// Import encryption keys - ImportKeys, + /// Do nothing. A workaround for async stuff + Noop, + /// A message for the login view + Login(login::Message), } -impl Application for Retrix { - type Message = Message; - type Executor = iced::executor::Default; - type Flags = (); - - fn new(_flags: ()) -> (Self, Command) { - // Skip login prompt if we have a session saved - match matrix::get_session().ok().flatten() { - Some(session) => { - let command = Command::perform( - async move { matrix::restore_login(session).await }, - |result| match result { - Ok((s, c)) => Message::LoggedIn(s, c), - Err(e) => Message::LoginFailed(e.to_string()), - }, - ); - (Retrix::AwaitLogin, command) - } - None => (Retrix::Prompt(PromptView::new()), Command::none()), - } - } - - fn title(&self) -> String { - String::from("Retrix matrix client") - } - - fn subscription(&self) -> Subscription { - match self { - Retrix::LoggedIn(view) => { - matrix::MatrixSync::subscription(view.client.clone()).map(Message::Sync) - } - _ => Subscription::none(), - } - } - - fn update( - &mut self, - message: Self::Message, - _clipboard: &mut iced::Clipboard, - ) -> Command { - match self { - Retrix::Prompt(prompt) => match message { - Message::SetUser(u) => prompt.user = u, - Message::SetPassword(p) => prompt.password = p, - Message::SetServer(s) => prompt.server = s, - Message::SetDeviceName(n) => prompt.device_name = n, - Message::SetAction(a) => prompt.action = a, - Message::Login => { - let user = prompt.user.clone(); - let password = prompt.password.clone(); - let server = prompt.server.clone(); - let device = prompt.device_name.clone(); - let device = match device.is_empty() { - false => Some(device), - true => None, - }; - *self = Retrix::AwaitLogin; - return Command::perform( - async move { matrix::login(&user, &password, &server, device.as_deref()).await }, - |result| match result { - Ok((c, r)) => Message::LoggedIn(c, r), - Err(e) => Message::LoginFailed(e.to_string()), - }, - ); - } - Message::Signup => { - let user = prompt.user.clone(); - let password = prompt.password.clone(); - let server = prompt.server.clone(); - let device = prompt.device_name.clone(); - let device = match device.is_empty() { - false => Some(device), - true => None, - }; - *self = Retrix::AwaitLogin; - return Command::perform( - async move { - matrix::signup(&user, &password, &server, device.as_deref()).await - }, - |result| match result { - Ok((client, response)) => Message::LoggedIn(client, response), - Err(e) => Message::LoginFailed(e.to_string()), - }, - ); - } - _ => (), - }, - Retrix::AwaitLogin => match message { - Message::LoginFailed(e) => { - let view = PromptView { - error: Some(e), - ..PromptView::default() - }; - *self = Retrix::Prompt(view); - } - Message::LoggedIn(client, session) => { - *self = Retrix::LoggedIn(MainView::new(client.clone(), session)); - let mut commands: Vec> = Vec::new(); - for room in client.joined_rooms().into_iter() { - let room = std::sync::Arc::new(room); - let r = room.clone(); - let command: Command<_> = async move { - let entry = RoomEntry::from_sdk(&r).await; - Message::ResetRoom(r.room_id().to_owned(), entry) - } - .into(); - commands.push(command); - // Fetch room avatar thumbnail if available - commands.push( - async move { - match room - .avatar(Some(THUMBNAIL_SIZE), Some(THUMBNAIL_SIZE)) - .await - { - Ok(Some(avatar)) => Message::FetchedThumbnail( - room.avatar_url().unwrap(), - iced::image::Handle::from_memory(avatar), - ), - Ok(None) => Message::Noop, - Err(e) => Message::ErrorMessage(e.to_string()), - } - } - .into(), - ) - } - return Command::batch(commands); - } - _ => (), - }, - Retrix::LoggedIn(view) => return view.update(message), - }; - Command::none() - } - - fn view(&mut self) -> Element { - match self { - Retrix::Prompt(prompt) => prompt.view(), - Retrix::AwaitLogin => Container::new(Text::new("Logging in...")) - .center_x() - .center_y() - .width(Length::Fill) - .height(Length::Fill) - .into(), - Retrix::LoggedIn(view) => view.view(), - } - } +/// Data for application startup +#[derive(Debug)] +pub struct Flags { + /// The application configuration + pub config: config::Config, + /// The session data if we've logged in + pub session: Option, } -fn format_systime(time: std::time::SystemTime) -> String { - let offset = time::UtcOffset::try_current_local_offset().unwrap_or(time::UtcOffset::UTC); - let time = time::OffsetDateTime::from(time).to_offset(offset); - let today = time::OffsetDateTime::now_utc().to_offset(offset).date(); - // Display - if time.date() == today { - time.format("%T") - } else { - time.format("%F %T") - } +impl iced::Application for Retrix { + type Executor = iced::executor::Default; + type Message = Message; + type Flags = Flags; + + fn new(flags: Self::Flags) -> (Self, Command) { + let state = Retrix { view: View::Login(login::Login::default()), config: flags.config }; + (state, Command::none()) + } + + fn title(&self) -> String { + String::from("Retrix") + } + + fn update(&mut self, message: Self::Message) -> Command { + match (&mut self.view, message) { + (_, Message::Login(login::Message::LoggedIn(client))) => { + self.view = View::Main(session::View::with_client(client)); + Command::none() + } + (View::Login(ref mut view), Message::Login(message)) => view.update(message), + _ => { + eprint!("WARN: Received a message for an inactive view"); + Command::none() + } + } + } + + fn view(&mut self) -> iced::Element<'_, Self::Message> { + match self.view { + View::Login(ref mut login) => login.view(), + View::Main(ref mut view) => view.view(), + } + } + + fn scale_factor(&self) -> f64 { + self.config.zoom + } } diff --git a/src/ui/login.rs b/src/ui/login.rs new file mode 100644 index 0000000..1fbcb35 --- /dev/null +++ b/src/ui/login.rs @@ -0,0 +1,170 @@ +//! The login prompt + +use iced::{ + widget::{button::State as ButtonState, text_input::State as InputState}, + Button, Column, Command, Container, Element, Length, Space, Text, TextInput, Toggler, +}; + +use self::Message::*; +use crate::{matrix, style}; + +/// Data for the login prompt +#[derive(Debug, Default)] +pub struct Login { + /// The username + user: String, + /// The password + password: String, + /// Whether the password should be visible. + show_password: bool, + /// The homeserver URL. + homeserver: String, + /// Whether we're waiting for a response to a login attempt + waiting: bool, + /// The text of an error message + error: Option, + + /// Widget state + state: State, +} + +/// Login prompt widget state +#[derive(Debug, Default)] +pub struct State { + /// State for the login input + user: InputState, + /// State from the password input + password: InputState, + /// State for the homeserver input + homeserver: InputState, + /// State for the login button + login: ButtonState, +} + +/// Notification to change the state for the login view. +#[derive(Debug, Clone)] +pub enum Message { + /// The login input changed. + InputUser(String), + /// The password input changed. + InputPassword(String), + /// The homerserver input changed. + InputHomeserver(String), + /// The "show password" toggle has been switched. + TogglePassword(bool), + /// Triggers login. + Login, + /// A login attempt failed. + LoginFailed(String), + /// Login completed. + LoggedIn(matrix_sdk::Client), + /// Hide the error message. + ResetError, +} + +impl Login { + /// Update state + pub fn update(&mut self, message: Message) -> Command { + match message { + InputUser(input) => self.user = input, + InputPassword(input) => self.password = input, + InputHomeserver(input) => self.homeserver = input, + TogglePassword(toggle) => self.show_password = toggle, + Login => { + self.waiting = true; + let homeserver = self.homeserver.clone(); + let user = self.user.clone(); + let password = self.password.clone(); + let command = async move { + let client = match matrix::login(&homeserver, &user, &password).await { + Ok(client) => client, + Err(e) => return LoginFailed(e.to_string()), + }; + LoggedIn(client) + }; + return Command::perform(command, super::Message::from); + } + LoginFailed(error) => { + self.waiting = false; + self.error = Some(error); + } + LoggedIn(_) => (), + ResetError => self.error = None, + }; + Command::none() + } + + /// Generate widgets for this view + pub fn view(&mut self) -> Element { + let error_message: iced::Element<_> = match self.error { + Some(ref error) => Container::new(Text::new(error.clone())) + .center_x() + .width(Length::Fill) + .padding(5) + .style(style::container::Error) + .into(), + None => Space::new(0.into(), 0.into()).into(), + }; + let user_input = + TextInput::new(&mut self.state.user, "alice", &self.user, |i| InputUser(i).into()) + .padding(5); + + let mut password_input = + TextInput::new(&mut self.state.password, "verysecret", &self.password, |i| { + InputPassword(i).into() + }) + .padding(5); + if !self.show_password { + password_input = password_input.password(); + } + + let password_toggle = + Toggler::new(self.show_password, String::from("show password"), |b| { + TogglePassword(b).into() + }) + .text_size(15); + + let homeserver_input = TextInput::new( + &mut self.state.homeserver, + "https://matrix.org", + &self.homeserver, + |i| InputHomeserver(i).into(), + ) + .padding(5); + + let login_button = Button::new( + &mut self.state.login, + Text::new("Log in") + .horizontal_alignment(iced::alignment::Horizontal::Center) + .width(Length::Fill), + ) + .on_press(Message::Login.into()) + .width(Length::Fill); + + let mut column = Column::new() + .width(500.into()) + .push(error_message) + .push(Text::new("User name")) + .push(user_input) + .push(Space::with_height(10.into())) + .push(Text::new("Password")) + .push(password_input) + .push(password_toggle) + .push(Space::with_height(5.into())) + .push(Text::new("Homeserver address")) + .push(homeserver_input) + .push(login_button); + + if self.waiting { + column = column.push(Text::new("Logging in")); + } + + Container::new(column).center_x().center_y().width(Length::Fill).height(Length::Fill).into() + } +} + +impl From for super::Message { + fn from(message: Message) -> Self { + super::Message::Login(message) + } +} diff --git a/src/ui/prompt.rs b/src/ui/prompt.rs deleted file mode 100644 index b5305cf..0000000 --- a/src/ui/prompt.rs +++ /dev/null @@ -1,141 +0,0 @@ -//! Login prompt - -use iced::{text_input, Button, Column, Container, Element, Radio, Row, Text, TextInput}; - -use crate::ui::Message; - -/// View for the login prompt -#[derive(Debug, Clone, Default)] -pub struct PromptView { - /// Username input field - pub user_input: text_input::State, - /// Password input field - pub password_input: text_input::State, - /// Homeserver input field - pub server_input: text_input::State, - /// Device name input field - pub device_input: text_input::State, - /// Button to trigger login - pub login_button: iced::button::State, - - /// Username - pub user: String, - /// Password - pub password: String, - /// Homeserver - pub server: String, - /// Device name to create login session under - pub device_name: String, - /// Whether to log in or sign up - pub action: PromptAction, - /// Error message - pub error: Option, -} - -impl PromptView { - pub fn new() -> Self { - Self::default() - } - - pub fn view(&mut self) -> Element { - let mut content = Column::new() - .width(500.into()) - .spacing(5) - .push( - Row::new() - .spacing(15) - .push(Radio::new( - PromptAction::Login, - "Login", - Some(self.action), - Message::SetAction, - )) - .push(Radio::new( - PromptAction::Signup, - "Sign up", - Some(self.action), - Message::SetAction, - )), - ) - .push( - Column::new().push(Text::new("Username")).push( - TextInput::new( - &mut self.user_input, - "Username", - &self.user, - Message::SetUser, - ) - .padding(5), - ), - ) - .push( - Column::new().push(Text::new("Password")).push( - TextInput::new( - &mut self.password_input, - "Password", - &self.password, - Message::SetPassword, - ) - .password() - .padding(5), - ), - ) - .push( - Column::new().push(Text::new("Homeserver")).push( - TextInput::new( - &mut self.server_input, - "https://homeserver.com", - &self.server, - Message::SetServer, - ) - .padding(5), - ), - ) - .push( - Column::new().push(Text::new("Device name")).push( - TextInput::new( - &mut self.device_input, - "retrix on my laptop", - &self.device_name, - Message::SetDeviceName, - ) - .padding(5), - ), - ); - let button = match self.action { - PromptAction::Login => { - Button::new(&mut self.login_button, Text::new("Login")).on_press(Message::Login) - } - PromptAction::Signup => { - content = content.push( - Text::new("NB: Signup is very naively implemented, and prone to breaking") - .color([1.0, 0.5, 0.0]), - ); - Button::new(&mut self.login_button, Text::new("Sign up")).on_press(Message::Signup) - } - }; - content = content.push(button); - if let Some(ref error) = self.error { - content = content.push(Text::new(error).color([1.0, 0.0, 0.0])); - } - - Container::new(content) - .center_x() - .center_y() - .width(iced::Length::Fill) - .height(iced::Length::Fill) - .into() - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum PromptAction { - Login, - Signup, -} - -impl Default for PromptAction { - fn default() -> Self { - PromptAction::Login - } -} diff --git a/src/ui/session.rs b/src/ui/session.rs new file mode 100644 index 0000000..44db53c --- /dev/null +++ b/src/ui/session.rs @@ -0,0 +1,53 @@ +//! View for a logged in session + +use std::collections::HashMap; + +use iced::{Element, Row, Space}; +use matrix_sdk::{ruma::RoomId, Client}; + +/// The main view, for a logged in session +#[derive(Clone, Debug)] +pub struct View { + client: matrix_sdk::Client, + + /// List of known rooms + room_list: RoomList, + + /// Widget state + state: State, +} + +/// Widget state. +#[derive(Clone, Debug, Default)] +struct State {} + +/// The list of rooms +#[derive(Clone, Debug, Default)] +pub struct RoomList { + names: HashMap, +} + +impl RoomList { + fn view(&mut self) -> Element { + Space::new(0.into(), 0.into()).into() + } +} + +/// State change notification +#[derive(Debug)] +pub enum Message { + /// The name for a room has been recalculated. + RoomName(RoomId, String), +} + +impl View { + /// Create a new view. + pub fn with_client(client: Client) -> Self { + Self { client, room_list: RoomList::default(), state: State::default() } + } + + /// Generate widgets + pub fn view(&mut self) -> Element { + Row::new().push(self.room_list.view()).into() + } +} diff --git a/src/ui/settings.rs b/src/ui/settings.rs deleted file mode 100644 index db32793..0000000 --- a/src/ui/settings.rs +++ /dev/null @@ -1,124 +0,0 @@ -//! Settings view. - -use iced::{Button, Column, Container, Element, Length, Radio, Row, Text, TextInput}; - -use super::{Message, RoomSorting}; - -/// Settings menu -#[derive(Clone, Default, Debug)] -pub struct SettingsView { - /// Display name to set - pub display_name: String, - /// Are we saving the display name? - pub saving_name: bool, - - /// Display name text input - pub display_name_input: iced::text_input::State, - /// Button to set display name - pub display_name_button: iced::button::State, - - /// Path to import encryption keys from - pub key_path: String, - /// Password to decrypt the keys with - pub key_password: String, - - /// Encryption key path entry - pub key_path_input: iced::text_input::State, - /// Entry for key password - pub key_password_input: iced::text_input::State, - /// Button to import keys - pub key_import_button: iced::button::State, - /// Button to close settings view - pub close_button: iced::button::State, -} - -impl SettingsView { - pub fn new() -> Self { - Self::default() - } - - pub fn view(&mut self, sort: RoomSorting) -> Element { - let content = Column::new() - .width(500.into()) - .spacing(5) - .push(Text::new("Profile").size(25)) - .push( - Column::new().push(Text::new("Display name")).push( - Row::new() - .push( - TextInput::new( - &mut self.display_name_input, - "Alice", - &self.display_name, - Message::SetDisplayNameInput, - ) - .width(Length::Fill) - .padding(5), - ) - .push(match self.saving_name { - false => Button::new(&mut self.display_name_button, Text::new("Save")) - .on_press(Message::SaveDisplayName), - true => { - Button::new(&mut self.display_name_button, Text::new("Saving...")) - } - }), - ), - ) - .push(Text::new("Appearance").size(25)) - .push(Text::new("Sort messages by:")) - .push(Radio::new( - RoomSorting::Alphabetic, - "Name", - Some(sort), - Message::SetSort, - )) - .push(Radio::new( - RoomSorting::Recent, - "Activity", - Some(sort), - Message::SetSort, - )) - .push(Text::new("Encryption").size(25)) - .push( - Column::new() - .push(Text::new("Import key (enter path)")) - .push( - TextInput::new( - &mut self.key_path_input, - "/home/user/exported_keys.txt", - &self.key_path, - Message::SetKeyPath, - ) - .padding(5), - ), - ) - .push( - Column::new().push(Text::new("Key password")).push( - TextInput::new( - &mut self.key_password_input, - "SecretPassword42", - &self.key_password, - Message::SetKeyPassword, - ) - .password() - .padding(5), - ), - ) - .push( - Button::new(&mut self.key_import_button, Text::new("Import keys")) - .on_press(Message::ImportKeys), - ) - .push( - Row::new().width(Length::Fill).push( - Button::new(&mut self.close_button, Text::new("Close")) - .on_press(Message::CloseSettings), - ), - ); - Container::new(content) - .center_x() - .center_y() - .width(Length::Fill) - .height(Length::Fill) - .into() - } -} diff --git a/src/ui/theme.rs b/src/ui/theme.rs deleted file mode 100644 index d9f0bf6..0000000 --- a/src/ui/theme.rs +++ /dev/null @@ -1,6 +0,0 @@ -//! Theming for widgets. - -/// Which colorscheme to use -pub enum Theme { - Default, -}