diff --git a/Cargo.lock b/Cargo.lock index d7233f5..5b0cfd0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -96,6 +96,119 @@ dependencies = [ "serde", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + [[package]] name = "async-trait" version = "0.1.81" @@ -167,6 +280,19 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -185,6 +311,29 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +[[package]] +name = "cairo-rs" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a0ea147c94108c9613235388f540e4d14c327f7081c9e471fc8ee8a2533e69" +dependencies = [ + "bitflags 2.6.0", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428290f914b9b86089f60f5d8a9f6e440508e1bcff23b25afd51502b0a2da88f" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "cc" version = "1.1.13" @@ -194,6 +343,16 @@ dependencies = [ "shlex", ] +[[package]] +name = "cfg-expr" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345c78335be0624ed29012dc10c49102196c6882c12dde65d9f35b02da2aada8" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -267,6 +426,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console" version = "0.15.8" @@ -334,6 +502,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crunchy" version = "0.2.2" @@ -471,12 +645,49 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + [[package]] name = "flate2" version = "1.0.32" @@ -565,6 +776,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -606,6 +830,63 @@ dependencies = [ "slab", ] +[[package]] +name = "gdk-pixbuf" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8730751991b97419fc3f0c2dca2c9e45b48edf46e48e0f965964ecf33889812f" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffbf649fd5b1c8c0f0feeb015b7533c3ef92da2887fb95ddd338bc2b1644a7c" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b7d7237c1487ed4b300aac7744efcbf1319e12d60d7afcd6f505414bd5b5dea" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a67576c8ec012156d7f680e201a807b4432a77babb3157e0555e990ab6bcd878" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -633,6 +914,209 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "gio" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcacaa37401cad0a95aadd266bc39c72a131d454fc012f6dfd217f891d76cc52" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237611e97e9b86ab5768adc3eef853ae713ea797aa3835404acdfacffc9fb38" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys 0.52.0", +] + +[[package]] +name = "glib" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c1ea829497810f8e87f5ee6d05c4879af641704add879e6b6080607cceeefe4" +dependencies = [ + "bitflags 2.6.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951aa19c5e89555c0ca5e94ee874b24b2594ece8412b387bd84ee3266b8a3ea0" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92eee4531c1c9abba945d19378b205031b5890e1f99c319ba0503b6e0c06a163" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gobject-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3d1dcd8a1eb2e7c22be3d5e792b14b186f3524f79b25631730f9a8c169d49a" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80aac87f74e81c0e13433e892a047237abdc37945c86887f5eed905038356e69" +dependencies = [ + "glib", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2f91ecd32989efad60326cc20a8fb252bd2852239a08e4e70cde8c100de9ca" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3cf2091e1af185b347b3450817d93dea6fe435df7abd4c2cd7fb5bcb4cfda8" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aa69614a26d8760c186c3690f1b0fbb917572ca23ef83137445770ceddf8cde" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fe572bf318e5dbc6f5a2f8a25d853f1ae3f42768c0b08af6ca20a18f4057e1" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e7b362c8fccd2712297903717d65d30defdab2b509bc9d209cbe5ffb9fabaf" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1114a207af8ada02cf4658a76692f4190f06f093380d5be07e3ca8b43aa7c666" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + [[package]] name = "h2" version = "0.3.26" @@ -689,6 +1173,12 @@ version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "http" version = "0.2.12" @@ -953,6 +1443,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -970,10 +1469,12 @@ name = "libdistore" version = "0.2.1" dependencies = [ "anyhow", + "async-std", "colog", "colored", "dirs", "futures", + "gtk4", "indicatif", "indicatif-log-bridge", "lazy_static", @@ -985,6 +1486,7 @@ dependencies = [ "serde_json", "serenity", "thiserror", + "tokio", ] [[package]] @@ -1008,6 +1510,9 @@ name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -1015,6 +1520,15 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -1055,7 +1569,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "wasi", "windows-sys 0.52.0", @@ -1165,6 +1679,36 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "pango" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5764e5a174a5a0ec054fe5962ce6d4fc7052e2d0dcc23bbc77202b40a4a403d3" +dependencies = [ + "gio", + "glib", + "libc", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd317e1de76b14b3d3efe05518c08b360327f1ab7fec150473a89ffcad4b072d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1203,12 +1747,38 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "portable-atomic" version = "1.7.0" @@ -1230,6 +1800,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -1437,6 +2016,15 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.36" @@ -1640,6 +2228,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1808,6 +2405,25 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "7.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "070a0a5e7da2d24be457809c4b3baa57a835fd2829ad8b86f9a049052fe71031" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.12.0" @@ -1898,9 +2514,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.39.3" +version = "1.40.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9babc99b9923bfa4804bd74722ff02c0381021eafa4db9949217e3be8e84fff5" +checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" dependencies = [ "backtrace", "bytes", @@ -1994,6 +2610,40 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -2164,12 +2814,24 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -2474,6 +3136,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/libdistore/Cargo.lock b/libdistore/Cargo.lock index d46f920..bf6fce6 100644 --- a/libdistore/Cargo.lock +++ b/libdistore/Cargo.lock @@ -96,6 +96,119 @@ dependencies = [ "serde", ] +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-executor" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" +dependencies = [ + "async-task", + "concurrent-queue", + "fastrand", + "futures-lite", + "slab", +] + +[[package]] +name = "async-global-executor" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" +dependencies = [ + "async-channel 2.3.1", + "async-executor", + "async-io", + "async-lock", + "blocking", + "futures-lite", + "once_cell", +] + +[[package]] +name = "async-io" +version = "2.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "444b0228950ee6501b3568d3c93bf1176a1fdbc3b758dcd9475046d30f4dc7e8" +dependencies = [ + "async-lock", + "cfg-if", + "concurrent-queue", + "futures-io", + "futures-lite", + "parking", + "polling", + "rustix", + "slab", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.3.1", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-std" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" +dependencies = [ + "async-channel 1.9.0", + "async-global-executor", + "async-io", + "async-lock", + "crossbeam-utils", + "futures-channel", + "futures-core", + "futures-io", + "futures-lite", + "gloo-timers", + "kv-log-macro", + "log", + "memchr", + "once_cell", + "pin-project-lite", + "pin-utils", + "slab", + "wasm-bindgen-futures", +] + +[[package]] +name = "async-task" +version = "4.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" + [[package]] name = "async-trait" version = "0.1.82" @@ -167,6 +280,19 @@ dependencies = [ "generic-array", ] +[[package]] +name = "blocking" +version = "1.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" +dependencies = [ + "async-channel 2.3.1", + "async-task", + "futures-io", + "futures-lite", + "piper", +] + [[package]] name = "bumpalo" version = "3.16.0" @@ -185,6 +311,29 @@ version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" +[[package]] +name = "cairo-rs" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a0ea147c94108c9613235388f540e4d14c327f7081c9e471fc8ee8a2533e69" +dependencies = [ + "bitflags 2.6.0", + "cairo-sys-rs", + "glib", + "libc", +] + +[[package]] +name = "cairo-sys-rs" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "428290f914b9b86089f60f5d8a9f6e440508e1bcff23b25afd51502b0a2da88f" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + [[package]] name = "cc" version = "1.1.16" @@ -194,6 +343,16 @@ dependencies = [ "shlex", ] +[[package]] +name = "cfg-expr" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "345c78335be0624ed29012dc10c49102196c6882c12dde65d9f35b02da2aada8" +dependencies = [ + "smallvec", + "target-lexicon", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -227,6 +386,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + [[package]] name = "console" version = "0.15.8" @@ -294,6 +462,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crossbeam-utils" +version = "0.8.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" + [[package]] name = "crunchy" version = "0.2.2" @@ -420,12 +594,49 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" +dependencies = [ + "event-listener 5.3.1", + "pin-project-lite", +] + [[package]] name = "fastrand" version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +[[package]] +name = "field-offset" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f" +dependencies = [ + "memoffset", + "rustc_version", +] + [[package]] name = "flate2" version = "1.0.33" @@ -514,6 +725,19 @@ version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" +[[package]] +name = "futures-lite" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52527eb5074e35e9339c6b4e8d12600c7128b68fb25dcb9fa9dec18f7c25f3a5" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + [[package]] name = "futures-macro" version = "0.3.30" @@ -555,6 +779,63 @@ dependencies = [ "slab", ] +[[package]] +name = "gdk-pixbuf" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8730751991b97419fc3f0c2dca2c9e45b48edf46e48e0f965964ecf33889812f" +dependencies = [ + "gdk-pixbuf-sys", + "gio", + "glib", + "libc", +] + +[[package]] +name = "gdk-pixbuf-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ffbf649fd5b1c8c0f0feeb015b7533c3ef92da2887fb95ddd338bc2b1644a7c" +dependencies = [ + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "gdk4" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b7d7237c1487ed4b300aac7744efcbf1319e12d60d7afcd6f505414bd5b5dea" +dependencies = [ + "cairo-rs", + "gdk-pixbuf", + "gdk4-sys", + "gio", + "glib", + "libc", + "pango", +] + +[[package]] +name = "gdk4-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a67576c8ec012156d7f680e201a807b4432a77babb3157e0555e990ab6bcd878" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "libc", + "pango-sys", + "pkg-config", + "system-deps", +] + [[package]] name = "generic-array" version = "0.14.7" @@ -582,6 +863,209 @@ version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" +[[package]] +name = "gio" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcacaa37401cad0a95aadd266bc39c72a131d454fc012f6dfd217f891d76cc52" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "gio-sys", + "glib", + "libc", + "pin-project-lite", + "smallvec", +] + +[[package]] +name = "gio-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5237611e97e9b86ab5768adc3eef853ae713ea797aa3835404acdfacffc9fb38" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", + "windows-sys 0.52.0", +] + +[[package]] +name = "glib" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c1ea829497810f8e87f5ee6d05c4879af641704add879e6b6080607cceeefe4" +dependencies = [ + "bitflags 2.6.0", + "futures-channel", + "futures-core", + "futures-executor", + "futures-task", + "futures-util", + "gio-sys", + "glib-macros", + "glib-sys", + "gobject-sys", + "libc", + "memchr", + "smallvec", +] + +[[package]] +name = "glib-macros" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "951aa19c5e89555c0ca5e94ee874b24b2594ece8412b387bd84ee3266b8a3ea0" +dependencies = [ + "heck", + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glib-sys" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92eee4531c1c9abba945d19378b205031b5890e1f99c319ba0503b6e0c06a163" +dependencies = [ + "libc", + "system-deps", +] + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gobject-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa3d1dcd8a1eb2e7c22be3d5e792b14b186f3524f79b25631730f9a8c169d49a" +dependencies = [ + "glib-sys", + "libc", + "system-deps", +] + +[[package]] +name = "graphene-rs" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "80aac87f74e81c0e13433e892a047237abdc37945c86887f5eed905038356e69" +dependencies = [ + "glib", + "graphene-sys", + "libc", +] + +[[package]] +name = "graphene-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2f91ecd32989efad60326cc20a8fb252bd2852239a08e4e70cde8c100de9ca" +dependencies = [ + "glib-sys", + "libc", + "pkg-config", + "system-deps", +] + +[[package]] +name = "gsk4" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3cf2091e1af185b347b3450817d93dea6fe435df7abd4c2cd7fb5bcb4cfda8" +dependencies = [ + "cairo-rs", + "gdk4", + "glib", + "graphene-rs", + "gsk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gsk4-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aa69614a26d8760c186c3690f1b0fbb917572ca23ef83137445770ceddf8cde" +dependencies = [ + "cairo-sys-rs", + "gdk4-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "libc", + "pango-sys", + "system-deps", +] + +[[package]] +name = "gtk4" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4fe572bf318e5dbc6f5a2f8a25d853f1ae3f42768c0b08af6ca20a18f4057e1" +dependencies = [ + "cairo-rs", + "field-offset", + "futures-channel", + "gdk-pixbuf", + "gdk4", + "gio", + "glib", + "graphene-rs", + "gsk4", + "gtk4-macros", + "gtk4-sys", + "libc", + "pango", +] + +[[package]] +name = "gtk4-macros" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9e7b362c8fccd2712297903717d65d30defdab2b509bc9d209cbe5ffb9fabaf" +dependencies = [ + "proc-macro-crate", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "gtk4-sys" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1114a207af8ada02cf4658a76692f4190f06f093380d5be07e3ca8b43aa7c666" +dependencies = [ + "cairo-sys-rs", + "gdk-pixbuf-sys", + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "graphene-sys", + "gsk4-sys", + "libc", + "pango-sys", + "system-deps", +] + [[package]] name = "h2" version = "0.3.26" @@ -626,12 +1110,24 @@ version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" +[[package]] +name = "hermit-abi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" + [[package]] name = "http" version = "0.2.12" @@ -896,12 +1392,52 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "kv-log-macro" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" +dependencies = [ + "log", +] + [[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +[[package]] +name = "libadwaita" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ff9c222b5c783729de45185f07b2fec2d43a7f9c63961e777d3667e20443878" +dependencies = [ + "gdk4", + "gio", + "glib", + "gtk4", + "libadwaita-sys", + "libc", + "pango", +] + +[[package]] +name = "libadwaita-sys" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c44d8bdbad31d6639e1f20cc9c1424f1a8e02d751fc28d44659bf743fb9eca6" +dependencies = [ + "gdk4-sys", + "gio-sys", + "glib-sys", + "gobject-sys", + "gtk4-sys", + "libc", + "pango-sys", + "system-deps", +] + [[package]] name = "libc" version = "0.2.158" @@ -910,16 +1446,19 @@ checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libdistore" -version = "0.2.0" +version = "0.2.1" dependencies = [ "anyhow", + "async-std", "colog", "colored", "dirs", "futures", + "gtk4", "indicatif", "indicatif-log-bridge", "lazy_static", + "libadwaita", "log", "reqwest 0.12.7", "rust-ini", @@ -928,6 +1467,7 @@ dependencies = [ "serde_json", "serenity", "thiserror", + "tokio", ] [[package]] @@ -951,6 +1491,9 @@ name = "log" version = "0.4.22" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +dependencies = [ + "value-bag", +] [[package]] name = "memchr" @@ -958,6 +1501,15 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "memoffset" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" +dependencies = [ + "autocfg", +] + [[package]] name = "mime" version = "0.3.17" @@ -998,7 +1550,7 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ - "hermit-abi", + "hermit-abi 0.3.9", "libc", "wasi", "windows-sys 0.52.0", @@ -1108,6 +1660,36 @@ dependencies = [ "hashbrown", ] +[[package]] +name = "pango" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5764e5a174a5a0ec054fe5962ce6d4fc7052e2d0dcc23bbc77202b40a4a403d3" +dependencies = [ + "gio", + "glib", + "libc", + "pango-sys", +] + +[[package]] +name = "pango-sys" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd317e1de76b14b3d3efe05518c08b360327f1ab7fec150473a89ffcad4b072d" +dependencies = [ + "glib-sys", + "gobject-sys", + "libc", + "system-deps", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "percent-encoding" version = "2.3.1" @@ -1146,12 +1728,38 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "piper" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" +dependencies = [ + "atomic-waker", + "fastrand", + "futures-io", +] + [[package]] name = "pkg-config" version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" +[[package]] +name = "polling" +version = "3.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc2790cd301dec6cd3b7a025e4815cf825724a51c98dccfe6a3e55f05ffb6511" +dependencies = [ + "cfg-if", + "concurrent-queue", + "hermit-abi 0.4.0", + "pin-project-lite", + "rustix", + "tracing", + "windows-sys 0.59.0", +] + [[package]] name = "portable-atomic" version = "1.7.0" @@ -1173,6 +1781,15 @@ dependencies = [ "zerocopy", ] +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit", +] + [[package]] name = "proc-macro2" version = "1.0.86" @@ -1380,6 +1997,15 @@ version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + [[package]] name = "rustix" version = "0.38.36" @@ -1583,6 +2209,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" +dependencies = [ + "serde", +] + [[package]] name = "serde_urlencoded" version = "0.7.1" @@ -1745,6 +2380,25 @@ dependencies = [ "libc", ] +[[package]] +name = "system-deps" +version = "7.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "070a0a5e7da2d24be457809c4b3baa57a835fd2829ad8b86f9a049052fe71031" +dependencies = [ + "cfg-expr", + "heck", + "pkg-config", + "toml", + "version-compare", +] + +[[package]] +name = "target-lexicon" +version = "0.12.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + [[package]] name = "tempfile" version = "3.12.0" @@ -1931,6 +2585,40 @@ dependencies = [ "tokio", ] +[[package]] +name = "toml" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.22.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" +dependencies = [ + "indexmap", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + [[package]] name = "tower" version = "0.4.13" @@ -2101,12 +2789,24 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "value-bag" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a84c137d37ab0142f0f2ddfe332651fdbf252e7b7dbb4e67b6c1f1b2e925101" + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version-compare" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852e951cb7832cb45cb1169900d19760cfa39b82bc0ea9c0e5a14ae88411c98b" + [[package]] name = "version_check" version = "0.9.5" @@ -2411,6 +3111,15 @@ version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" +[[package]] +name = "winnow" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" diff --git a/libdistore/Cargo.toml b/libdistore/Cargo.toml index 8735673..be86e40 100644 --- a/libdistore/Cargo.toml +++ b/libdistore/Cargo.toml @@ -26,3 +26,6 @@ reqwest = { version = "0.12.7", features = ["json"] } serde = "1.0.210" serde_json = "1.0.128" futures = "0.3.30" +gtk = { version = "0.9.1", package = "gtk4", features = ["v4_14"] } +async-std = "1.13.0" +tokio = { version = "1.40.0", features = ["rt-multi-thread"] } diff --git a/libdistore/src/commands.rs b/libdistore/src/commands.rs index 4e931cd..29982df 100644 --- a/libdistore/src/commands.rs +++ b/libdistore/src/commands.rs @@ -25,7 +25,7 @@ use serenity::all::{ ChannelId, CreateAttachment, CreateMessage, EditMessage, GetMessages, Http, Message, }; -static PART_SIZE: usize = 1000 * 1000 * 25; +static PART_SIZE: usize = 1000 * 1000 * 20; lazy_static! { static ref VERSION: Version = { @@ -70,50 +70,77 @@ pub fn config(global: bool, key: String, val: String, dir: Option) -> R } pub fn get_config(global: bool, dir: Option) -> Result<()> { + let (token, channel) = get_config_internal(global, dir)?; + + println!("{}", token); + println!("{}", channel); + Ok(()) +} + +pub(crate) fn get_config_internal(global: bool, dir: Option) -> Result<(ConfigValue, ConfigValue)> { let mut path = dir .unwrap_or(dirs::config_dir().ok_or(ConfigError::NoConfigDir)?) .join("distore"); fs::create_dir_all(&path).context("Failed to create config directory")?; path.push("distore.ini"); - let (token, channel) = match global { + let out = match global { true => crate::config::ConfigValue::get_global_config(&path)?, false => crate::config::ConfigValue::get_current_config(&path)?, }; - - println!("{}", token); - println!("{}", channel); - Ok(()) + return Ok(out); } pub fn disassemble(path: PathBuf, output: PathBuf) -> Result<()> { colog::default_builder() .filter(Some("serenity"), log::LevelFilter::Off) .init(); + + let (_, filename, i) = disassemble_internal(path, output, |_, _| {})?; + + println!( + "{} {filename} into {i} parts", + "Disassembled".green().bold() + ); + Ok(()) +} + +pub(crate) fn disassemble_internal(path: PathBuf, output: PathBuf, callback: F) -> Result<(Vec, String, usize)> { let mut file = File::open(&path).with_context(|| format!("Cannot open file: {}", path.display()))?; let filename = path.file_name().unwrap().to_str().unwrap().to_owned(); + let mut out = Vec::new(); + let mut buf = vec![0; PART_SIZE]; - let mut i = 0; + let mut progress = 0; + let total = (file.metadata().unwrap().len() + PART_SIZE as u64 - 1) / PART_SIZE as u64; while let Ok(bytes_read) = file.read(&mut buf) { if bytes_read == 0 { break; } - let name = format!("{}.part{}", filename, i); - let mut chunk = File::create(output.join(&name))?; + let name = format!("{}.part{}", filename, progress); + let path = output.join(&name); + let mut chunk = File::create(&path)?; info!("{} {name}", "Writing".blue().bold()); chunk.write_all(&buf[..bytes_read])?; - i += 1; + progress += 1; + + out.push(path); + let fraction = if total > 0 { + progress as f64 / total as f64 + } else { + 1.0 + }; + + let fraction = fraction.clamp(0.0, 1.0); + callback(format!("Disassembling {}", filename), fraction); } - println!( - "{} {filename} into {i} parts", - "Disassembled".green().bold() - ); - Ok(()) + let len = out.len(); + Ok((out, filename, len)) } pub fn assemble(filename: String, path: PathBuf, output: Option) -> Result<()> { @@ -205,6 +232,9 @@ pub async fn upload( channel: Option, dir: Option, ) -> Result<()> { + colog::default_builder() + .filter(Some("serenity"), log::LevelFilter::Off) + .init(); let mut path = dir .unwrap_or(dirs::config_dir().ok_or(ConfigError::NoConfigDir)?) .join("distore"); @@ -230,41 +260,37 @@ pub async fn upload( let http = Http::new(&token); - let filename = file.file_name().unwrap().to_str().unwrap(); + let messages = upload_internal(&http, file, channel, |_, _| {}).await?; - let msg = format!( - "### This message is generated by Distore. Do not edit this message.\nname={}\nsize={}", - filename, - file.metadata()?.len() + println!( + "{} parts to channel id {}. Message id: {}", + "Uploaded".green().bold(), + messages[0].channel_id, + messages[0].id ); + Ok(()) +} + +pub(crate) async fn upload_internal(http: &Http, file: PathBuf, channel: u64, callback: F) -> Result> { let cache_dir = dirs::cache_dir().unwrap().join("distore"); fs::create_dir_all(&cache_dir)?; - disassemble(file.clone(), cache_dir.clone())?; - let read_dir = cache_dir.read_dir()?; - - let mut part_paths = Vec::new(); - - let look_for = format!("{filename}.part"); - - for entry in read_dir { - let entry = entry?; - if !entry.file_type()?.is_file() { - continue; - } - - if !entry.file_name().to_str().unwrap().starts_with(&look_for) { - continue; - } + let (part_paths, filename, _) = disassemble_internal(file.clone(), cache_dir.clone(), &callback)?; - part_paths.push(entry.path()); - } + let msg = format!( + "### This message is generated by Distore. Do not edit this message.\nname={}\nsize={}", + filename, + file.metadata()?.len() + ); info!("Uploading..."); let chunks: Vec> = part_paths.chunks(10).map(|chunk| chunk.to_vec()).collect(); let mut messages = Vec::new(); info!("Sending {} message(s) in total", chunks.len()); + callback(format!("Uploading {}", filename), 0.0); + let mut progress = 0; + let total = chunks.len(); for chunk in chunks { let attachment_futures: Vec<_> = chunk .into_iter() @@ -280,6 +306,17 @@ pub async fn upload( ) .await?; messages.push(msg.clone()); + progress += 1; + + let fraction = if total > 0 { + progress as f64 / total as f64 + } else { + 1.0 + }; + + let fraction = fraction.clamp(0.0, 1.0); + callback(format!("Uploading {}", filename), fraction); + info!( "Sent {}..{}", msg.attachments @@ -301,6 +338,8 @@ pub async fn upload( info!("Editing messages..."); + let mut progress = 0; + let total = messages.len(); for (i, message) in messages.iter().enumerate() { let mut content = String::new(); let next = messages.iter().cloned().nth(i + 1); @@ -317,6 +356,15 @@ pub async fn upload( .clone() .edit(&http, EditMessage::new().content(content)) .await?; + progress += 1; + + let fraction = if total > 0 { + progress as f64 / total as f64 + } else { + 1.0 + }; + + callback("Editing".to_string(), fraction); } info!("Cleaning up..."); @@ -326,14 +374,7 @@ pub async fn upload( fs::remove_file(part).context("Failed to remove file")?; } - println!( - "{} parts to channel id {}. Message id: {}", - "Uploaded".green().bold(), - messages[0].channel_id, - messages[0].id - ); - - Ok(()) + Ok(messages) } pub async fn download( @@ -368,12 +409,7 @@ pub async fn download( let http = Http::new(&token); - let msg = http.get_message(channel.into(), message_id.into()).await?; - let mut entry = FileEntry::from_str(&msg.content)?; - let name = entry.name.ok_or(anyhow!("Invalid Message"))?; - let len = entry.len.ok_or(anyhow!("Invalid Message"))?; - - let mut out = File::create(output.clone().unwrap_or(name.clone().into()))?; + let (_, _, name, len) = _get_download_variables(&http, message_id, channel).await?; let multi = MultiProgress::new(); let logger = colog::default_builder() @@ -394,14 +430,56 @@ pub async fn download( ); pb.set_message("Assembling"); + let pb_clone = pb.clone(); + download_internal(&http, message_id, channel, output.clone(), move |_| pb_clone.inc(1)).await?; + + pb.finish(); + + println!( + "{} {}", + "Downloaded".green().bold(), + output.unwrap_or(name.into()).display() + ); + + Ok(()) +} + +pub(crate) async fn _get_download_variables(http: &Http, message_id: u64, channel: u64) -> Result<(Message, FileEntry, String, usize)> { + let msg = http.get_message(channel.into(), message_id.into()).await?; + let entry = FileEntry::from_str(&msg.content)?; + let name = entry.name.clone().ok_or(anyhow!("Invalid Message"))?; + let len = entry.len.ok_or(anyhow!("Invalid Message"))?; + + Ok((msg, entry, name, len)) +} + +pub(crate) async fn download_internal(http: &Http, message_id: u64, channel: u64, output: Option, callback: F) -> Result { + let (msg, mut entry, name, len) = _get_download_variables(http, message_id, channel).await?; + + let size = entry.size.unwrap(); + + let path = output.clone().unwrap_or(name.clone().into()); + let mut out = File::create(&path)?; + let mut i = 0; let mut msg = msg; + let mut progress = 0; while entry.next.is_some() || i < len { for part in msg.attachments.iter() { info!("{} {}", "Downloading".blue().bold(), part.filename); let part = part.download().await?; + + progress += part.len(); + let fraction = if size > 0 { + progress as f64 / size as f64 + } else { + 1.0 + }; + + let fraction = fraction.clamp(0.0, 1.0); + out.write_all(&part)?; - pb.inc(1); + callback(fraction); } i += msg.attachments.len(); @@ -413,15 +491,8 @@ pub async fn download( msg = http.get_message(channel.into(), next_id.into()).await?; entry = FileEntry::from_str(&msg.content)?; } - pb.finish(); - - println!( - "{} {}", - "Downloaded".green().bold(), - output.unwrap_or(name.into()).display() - ); - Ok(()) + Ok(path) } pub async fn list(token: Option, channel: Option, dir: Option) -> Result<()> { @@ -456,7 +527,26 @@ pub async fn list(token: Option, channel: Option, dir: Option Result> { + let messages = _get_messages(channel.into(), &http).await?; + let mut out = Vec::new(); for msg in messages { if !msg.author.bot { @@ -476,17 +566,9 @@ pub async fn list(token: Option, channel: Option, dir: Option Result<()> { diff --git a/libdistore/src/config.rs b/libdistore/src/config.rs index 109cefb..fc17e62 100644 --- a/libdistore/src/config.rs +++ b/libdistore/src/config.rs @@ -9,7 +9,7 @@ use std::{ use ini::{Ini, Properties}; use thiserror::Error; -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum ConfigValue { Token(String), Channel(String), diff --git a/libdistore/src/gui.rs b/libdistore/src/gui.rs new file mode 100644 index 0000000..b1f2af0 --- /dev/null +++ b/libdistore/src/gui.rs @@ -0,0 +1,413 @@ +use std::path::PathBuf; +use std::process::exit; +use std::rc::Rc; +use std::sync::atomic::{AtomicU64, Ordering}; +use std::sync::mpsc::TryRecvError; +use std::sync::{mpsc, Arc, Mutex}; +use std::time::Duration; + +use gtk::gio::{Cancellable, FileQueryInfoFlags, FILE_ATTRIBUTE_STANDARD_NAME}; +use gtk::{glib, FileDialog, ScrolledWindow}; +use gtk::{prelude::*, Align, ApplicationWindow, Box, Label, ListBox, ListBoxRow, Orientation}; +use gtk::{AlertDialog, Application, Button, ProgressBar}; +use indicatif::HumanBytes; +use serenity::all::{ChannelId, Http}; + +use crate::commands::{self, download_internal, upload_internal}; +use crate::parser::FileEntry; + +const APP_ID: &str = "org.distore.Distore"; + +pub fn run() { + let app = Application::builder().application_id(APP_ID).build(); + + app.connect_activate(build_ui); + + let exitcode = app.run(); + exit(exitcode.into()); +} + +fn build_ui(app: &Application) { + let window = Rc::new(ApplicationWindow::new(app)); + window.set_title(Some("Distore")); + window.set_default_size(300, 200); + + let list_box = Rc::new(ListBox::new()); + let margin = 50; + list_box.set_margin_top(margin); + list_box.set_margin_bottom(margin); + list_box.set_show_separators(true); + + let scrolled_window = ScrolledWindow::builder() + .hscrollbar_policy(gtk::PolicyType::Never) + .min_content_width(200) + .min_content_height(300) + .vexpand(true) + .build(); + + scrolled_window.set_child(Some(&*list_box)); + + let parent_box = Rc::new(Box::new(Orientation::Vertical, 5)); + parent_box.set_margin_bottom(margin); + + let container = Rc::new(Box::new(Orientation::Vertical, 20)); + container.append(&scrolled_window); + + container.set_margin_start(margin); + container.set_margin_end(margin); + + let (token, channel) = commands::get_config_internal(true, None).unwrap(); + let http = Arc::new(Http::new(token.inner())); + + let components = async_std::task::block_on(commands::list_internal( + channel.inner().parse().unwrap(), + &http, + )) + .unwrap(); + + for (file, id) in components { + let row = ListBoxRow::new(); + let box_ = Box::new(Orientation::Vertical, 5); + box_.set_halign(Align::Start); + + let name_label = Label::new(file.name.as_deref()); + let id_label = Label::new(Some(&format!("ID: {}", id))); + let size_label = Label::new(Some(&format!("Size: {}", HumanBytes(file.size.unwrap())))); + + name_label.set_halign(Align::Start); + id_label.set_halign(Align::Start); + size_label.set_halign(Align::Start); + + size_label.set_opacity(0.5); + id_label.set_opacity(0.5); + + size_label.set_margin_start(20); + id_label.set_margin_start(20); + + box_.append(&name_label); + box_.append(&size_label); + box_.append(&id_label); + + row.set_child(Some(&box_)); + list_box.append(&row); + } + + let progress_box = Rc::new(Box::new(Orientation::Vertical, 20)); + progress_box.set_margin_start(margin); + progress_box.set_margin_end(margin); + + let button_box = Box::new(Orientation::Horizontal, 10); + + let download_btn = Button::builder().label("Download").build(); + let upload_btn = Button::builder().label("Upload").build(); + let delete_btn = Button::builder().label("Delete").build(); + button_box.append(&download_btn); + button_box.append(&upload_btn); + button_box.append(&delete_btn); + + let window_clone = window.clone(); + let channel_ = channel.clone(); + let progress_box_ = progress_box.clone(); + let list_box_ = list_box.clone(); + upload_btn.connect_clicked(move |_| { + let channel_clone = channel_.clone(); + let window_clone_ = window_clone.clone(); + let http_clone = http.clone(); + let progress_box_clone = progress_box_.clone(); + let list_box_ = list_box_.clone(); + FileDialog::builder() + .title("Upload") + .accept_label("Upload") + .build() + .open( + Some(&*window_clone), + Some(&Cancellable::new()), + move |res| { + if let Err(e) = res { + if e.message() == "Dismissed by user" { + return; + } + + AlertDialog::builder() + .message("Error") + .detail(format!("{}", e).as_str()) + .build() + .show(Some(&*window_clone_)); + return; + } + + let res = res.unwrap(); + let path = res.path().unwrap(); + let name = res + .query_info( + FILE_ATTRIBUTE_STANDARD_NAME, + FileQueryInfoFlags::NONE, + Some(&Cancellable::new()), + ) + .unwrap() + .name(); + println!("{}", path.display()); + + let (sender, receiver) = mpsc::channel(); + + let progressbar = Rc::new( + ProgressBar::builder() + .visible(true) + .show_text(true) + .valign(Align::Fill) + .build(), + ); + progressbar.set_text(Some(format!("Uploading {}", name.display()).as_str())); + progressbar.set_fraction(0.0); + + progress_box_clone.append(&*progressbar); + + let file = Arc::new(Mutex::new(FileEntry::default())); + let id = Arc::new(AtomicU64::new(0)); + + let http_ = http_clone.clone(); + let file_ = file.clone(); + let id_ = id.clone(); + let channel_ = channel_clone.clone(); + tokio::spawn(async move { + let res = upload_internal( + &http_, + path, + channel_.inner().parse().unwrap(), + |s, f| { + sender.send((Some((s, f)), None)).unwrap(); + }, + ) + .await; + + match res { + Ok(v) => { + let content = ChannelId::new(channel_.inner().parse().unwrap()) + .message(&http_, v[0].id) + .await + .unwrap() + .content; + let mut f_lock = file_.lock().unwrap(); + *f_lock = FileEntry::from_str(&content).unwrap(); + id_.store(v[0].id.into(), Ordering::SeqCst); + } + Err(e) => sender.send((None, Some(e))).unwrap(), + } + }); + + let progress_clone = progressbar.clone(); + let progress_box_clone = progress_box_clone.clone(); + let file_ = file.clone(); + let id_ = id.clone(); + let list_box_ = list_box_.clone(); + // let channel_ = channel_clone.clone(); + // let http_ = http_clone.clone(); + glib::timeout_add_local(Duration::from_millis(100), move || { + match receiver.try_recv() { + Ok(res) => { + if let Some(f) = res.0 { + progress_clone.set_text(Some(&f.0)); + progress_clone.set_fraction(f.1); + } + + if let Some(e) = res.1 { + progress_box_clone.remove(&*progress_clone); + + AlertDialog::builder() + .message("Error") + .detail(format!( + "An error occured during installation: {}", + e + )) + .build() + .show(Some(&*window_clone_)); + return glib::ControlFlow::Break; + } + } + Err(e) => { + if let TryRecvError::Disconnected = e { + progress_box_clone.remove(&*progress_clone); + + let row = ListBoxRow::new(); + let box_ = Box::new(Orientation::Vertical, 5); + box_.set_halign(Align::Start); + + let file = file_.lock().unwrap(); + let id = id_.load(Ordering::SeqCst); + let name_label = Label::new(file.name.as_deref()); + let id_label = Label::new(Some(&format!("ID: {}", id))); + let size_label = Label::new(Some(&format!( + "{}", + HumanBytes(file.size.unwrap()) + ))); + + name_label.set_halign(Align::Start); + id_label.set_halign(Align::Start); + size_label.set_halign(Align::Start); + + size_label.set_opacity(0.5); + id_label.set_opacity(0.5); + + size_label.set_margin_start(20); + id_label.set_margin_start(20); + + box_.append(&name_label); + box_.append(&size_label); + box_.append(&id_label); + + row.set_child(Some(&box_)); + list_box_.prepend(&row); + + // let msg = async_std::task::block_on(ChannelId::new(channel_.inner().parse().unwrap()).message(&http_, id)).unwrap(); + // let link = async_std::task::block_on(msg.link_ensured(&http_)); + AlertDialog::builder() + .message("Upload complete") + .detail(format!("Uploaded file {}", name.display())) + .build() + .show(Some(&*window_clone_)); + return glib::ControlFlow::Break; + } + } + } + glib::ControlFlow::Continue + }); + }, + ) + }); + + let list_box_clone = list_box.clone(); + let progress_box_clone = progress_box.clone(); + let window_clone = window.clone(); + let channel_ = channel.clone(); + let token_ = token.clone(); + download_btn.connect_clicked(move |_| { + if let Some(selected_row) = list_box_clone.selected_row() { + if let Some(box_) = selected_row.child().and_then(|w| w.downcast::().ok()) { + let mut labels: Vec