From d259137e323549cdfcc52cbc196a7833174db352 Mon Sep 17 00:00:00 2001 From: SamTV12345 <40429738+SamTV12345@users.noreply.github.com> Date: Thu, 29 Aug 2024 22:51:52 +0200 Subject: [PATCH] Migrate/actix ws (#907) * Began migrating to actix ws. * Fixed cargo clippy --------- Co-authored-by: SamTV12345 --- Cargo.lock | 1085 ++++++++--------- Cargo.toml | 8 +- src/constants/inner_constants.rs | 3 + src/controllers/mod.rs | 1 + src/controllers/podcast_controller.rs | 80 +- src/controllers/podcast_episode_controller.rs | 11 +- src/controllers/server.rs | 346 ++++++ src/controllers/web_socket.rs | 227 ++-- src/controllers/websocket_controller.rs | 27 +- src/main.rs | 19 +- src/models/messages.rs | 21 +- src/models/mod.rs | 1 - src/models/web_socket_message.rs | 48 - src/service/podcast_episode_service.rs | 16 +- src/service/rust_service.rs | 28 +- ui/src/App.tsx | 6 +- 16 files changed, 1079 insertions(+), 848 deletions(-) create mode 100644 src/controllers/server.rs delete mode 100644 src/models/web_socket_message.rs diff --git a/Cargo.lock b/Cargo.lock index 95aebe03..f2cc24aa 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11,7 +11,7 @@ dependencies = [ "actix-macros", "actix-rt", "actix_derive", - "bitflags 2.4.2", + "bitflags 2.6.0", "bytes", "crossbeam-channel", "futures-core", @@ -33,7 +33,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "bytes", "futures-core", "futures-sink", @@ -54,7 +54,7 @@ dependencies = [ "actix-service", "actix-utils", "actix-web", - "bitflags 2.4.2", + "bitflags 2.6.0", "bytes", "derive_more", "futures-core", @@ -69,9 +69,9 @@ dependencies = [ [[package]] name = "actix-http" -version = "3.7.0" +version = "3.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4eb9843d84c775696c37d9a418bbb01b932629d01870722c0f13eb3f95e2536d" +checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" dependencies = [ "actix-codec", "actix-rt", @@ -80,7 +80,7 @@ dependencies = [ "actix-utils", "ahash", "base64 0.22.1", - "bitflags 2.4.2", + "bitflags 2.6.0", "brotli", "bytes", "bytestring", @@ -89,7 +89,7 @@ dependencies = [ "flate2", "futures-core", "h2 0.3.26", - "http 0.2.11", + "http 0.2.12", "httparse", "httpdate", "itoa", @@ -114,7 +114,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" dependencies = [ "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -125,7 +125,7 @@ checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" dependencies = [ "bytestring", "cfg-if", - "http 0.2.11", + "http 0.2.12", "regex", "regex-lite", "serde", @@ -134,9 +134,9 @@ dependencies = [ [[package]] name = "actix-rt" -version = "2.9.0" +version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" dependencies = [ "futures-core", "tokio", @@ -144,16 +144,16 @@ dependencies = [ [[package]] name = "actix-server" -version = "2.3.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" dependencies = [ "actix-rt", "actix-service", "actix-utils", "futures-core", "futures-util", - "mio 0.8.11", + "mio", "socket2", "tokio", "tracing", @@ -180,8 +180,8 @@ dependencies = [ "actix-service", "actix-utils", "futures-core", - "http 0.2.11", - "http 1.0.0", + "http 0.2.12", + "http 1.1.0", "impl-more", "pin-project-lite", "tokio", @@ -244,24 +244,6 @@ dependencies = [ "url", ] -[[package]] -name = "actix-web-actors" -version = "4.3.1+deprecated" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98c5300b38fd004fe7d2a964f9a90813fdbe8a81fed500587e78b1b71c6f980" -dependencies = [ - "actix", - "actix-codec", - "actix-http", - "actix-web", - "bytes", - "bytestring", - "futures-core", - "pin-project-lite", - "tokio", - "tokio-util", -] - [[package]] name = "actix-web-codegen" version = "4.3.0" @@ -271,7 +253,21 @@ dependencies = [ "actix-router", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", +] + +[[package]] +name = "actix-ws" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3a1fb4f9f2794b0aadaf2ba5f14a6f034c7e86957b458c506a8cb75953f2d99" +dependencies = [ + "actix-codec", + "actix-http", + "actix-web", + "bytestring", + "futures-core", + "tokio", ] [[package]] @@ -282,14 +278,14 @@ checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "addr2line" -version = "0.21.0" +version = "0.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" dependencies = [ "gimli", ] @@ -300,11 +296,17 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + [[package]] name = "ahash" -version = "0.8.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", "getrandom", @@ -315,9 +317,9 @@ dependencies = [ [[package]] name = "aho-corasick" -version = "1.1.2" +version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" dependencies = [ "memchr", ] @@ -354,47 +356,48 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.11" +version = "0.6.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +checksum = "64e15c1ab1f89faffbf04a634d5e1962e9074f2741eef6d97f3c4e322426d526" dependencies = [ "anstyle", "anstyle-parse", "anstyle-query", "anstyle-wincon", "colorchoice", + "is_terminal_polyfill", "utf8parse", ] [[package]] name = "anstyle" -version = "1.0.6" +version = "1.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" +checksum = "1bec1de6f59aedf83baf9ff929c98f2ad654b97c9510f4e70cf6f661d49fd5b1" [[package]] name = "anstyle-parse" -version = "0.2.3" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +checksum = "eb47de1e80c2b463c735db5b217a0ddc39d612e7ac9e2e96a5aed1f57616c1cb" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.0.2" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +checksum = "6d36fc52c7f6c869915e99412912f22093507da8d9e942ceaf66fe4b7c14422a" dependencies = [ "windows-sys 0.52.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.2" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +checksum = "5bf74e1b6e971609db8ca7a9ce79fd5768ab6ae46441c572e46cf596f59e57f8" dependencies = [ "anstyle", "windows-sys 0.52.0", @@ -417,38 +420,44 @@ checksum = "3b43422f69d8ff38f95f1b2bb76517c91589a924d1559a0e935d7c8ce0274c11" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.81" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "atom_syndication" -version = "0.12.2" +version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "571832dcff775e26562e8e6930cd483de5587301d40d3a3b85d532b6383e15a7" +checksum = "2a3a5ed3201df5658d1aa45060c5a57dc9dba8a8ada20d696d67cb0c479ee043" dependencies = [ "chrono", - "derive_builder 0.12.0", + "derive_builder", "diligent-date-parser", "never", - "quick-xml 0.30.0", + "quick-xml", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "autocfg" -version = "1.1.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" [[package]] name = "awc" @@ -470,7 +479,7 @@ dependencies = [ "futures-core", "futures-util", "h2 0.3.26", - "http 0.2.11", + "http 0.2.12", "itoa", "log", "mime", @@ -486,15 +495,15 @@ dependencies = [ [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.73" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" dependencies = [ "addr2line", "cc", "cfg-if", "libc", - "miniz_oxide", + "miniz_oxide 0.7.4", "object", "rustc-demangle", ] @@ -519,9 +528,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.2" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" +checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "block-buffer" @@ -545,9 +554,9 @@ dependencies = [ [[package]] name = "brotli-decompressor" -version = "4.0.0" +version = "4.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6221fe77a248b9117d431ad93761222e1cf8ff282d9d1d5d9f53d6299a1cf76" +checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" dependencies = [ "alloc-no-stdlib", "alloc-stdlib", @@ -566,9 +575,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "byteorder" @@ -578,9 +587,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.5.0" +version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" [[package]] name = "bytestring" @@ -605,9 +614,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.1.14" +version = "1.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50d2eb3cd3d1bf4529e31c215ee6f93ec5a3d536d9f578f93d9d33ee19562932" +checksum = "57b6a275aa2903740dc87da01c62040406b8812552e97129a63ea8850a17c6e6" dependencies = [ "jobserver", "libc", @@ -644,9 +653,9 @@ dependencies = [ [[package]] name = "colorchoice" -version = "1.0.0" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" +checksum = "d3fd119d74b830634cea2a0f58bbd0d54540518a14397557951e79340abc28c0" [[package]] name = "convert_case" @@ -677,33 +686,33 @@ dependencies = [ [[package]] name = "core-foundation-sys" -version = "0.8.6" +version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.12" +version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +checksum = "51e852e6dc9a5bed1fae92dd2375037bf2b768725bf3be87811edee3249d09ad" dependencies = [ "libc", ] [[package]] name = "crc32fast" -version = "1.4.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3855a8a784b474f333699ef2bbca9db2c4a1f6d9088a90a2d25b1eb53111eaa" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] [[package]] name = "crossbeam-channel" -version = "0.5.11" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" +checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" dependencies = [ "crossbeam-utils", ] @@ -729,9 +738,9 @@ dependencies = [ [[package]] name = "crossbeam-utils" -version = "0.8.19" +version = "0.8.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" +checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" [[package]] name = "crypto-common" @@ -745,72 +754,37 @@ dependencies = [ [[package]] name = "darling" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b750cb3417fd1b327431a470f388520309479ab0bf5e323505daf0290cd3850" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" dependencies = [ - "darling_core 0.14.4", - "darling_macro 0.14.4", -] - -[[package]] -name = "darling" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54e36fcd13ed84ffdfda6f5be89b31287cbb80c439841fe69e04841435464391" -dependencies = [ - "darling_core 0.20.8", - "darling_macro 0.20.8", -] - -[[package]] -name = "darling_core" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109c1ca6e6b7f82cc233a97004ea8ed7ca123a9af07a8230878fcfda9b158bf0" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 1.0.109", + "darling_core", + "darling_macro", ] [[package]] name = "darling_core" -version = "0.20.8" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c2cf1c23a687a1feeb728783b993c4e1ad83d99f351801977dd809b48d0a70f" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "darling_macro" -version = "0.14.4" +version = "0.20.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4aab4dbc9f7611d8b55048a3a16d2d010c2c8334e46304b40ac1cc14bf3b48e" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ - "darling_core 0.14.4", + "darling_core", "quote", - "syn 1.0.109", -] - -[[package]] -name = "darling_macro" -version = "0.20.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a668eda54683121533a393014d8692171709ff57a7d61f187b6e782719f8933f" -dependencies = [ - "darling_core 0.20.8", - "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -830,82 +804,51 @@ checksum = "67e77553c4162a157adbf834ebae5b415acbecbeafc7a74b0e886657506a7611" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "derive_builder" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d67778784b508018359cbc8696edb3db78160bab2c2a28ba7f56ef6932997f8" -dependencies = [ - "derive_builder_macro 0.12.0", + "syn 2.0.76", ] [[package]] name = "derive_builder" -version = "0.20.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0350b5cb0331628a5916d6c5c0b72e97393b8b6b03b47a9284f4e7f5a405ffd7" -dependencies = [ - "derive_builder_macro 0.20.0", -] - -[[package]] -name = "derive_builder_core" -version = "0.12.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c11bdc11a0c47bc7d37d582b5285da6849c96681023680b906673c5707af7b0f" +checksum = "cd33f37ee6a119146a1781d3356a7c26028f83d779b2e04ecd45fdc75c76877b" dependencies = [ - "darling 0.14.4", - "proc-macro2", - "quote", - "syn 1.0.109", + "derive_builder_macro", ] [[package]] name = "derive_builder_core" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d48cda787f839151732d396ac69e3473923d54312c070ee21e9effcaa8ca0b1d" +checksum = "7431fa049613920234f22c47fdc33e6cf3ee83067091ea4277a3f8c4587aae38" dependencies = [ - "darling 0.20.8", + "darling", "proc-macro2", "quote", - "syn 2.0.48", -] - -[[package]] -name = "derive_builder_macro" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebcda35c7a396850a55ffeac740804b40ffec779b98fffbb1738f4033f0ee79e" -dependencies = [ - "derive_builder_core 0.12.0", - "syn 1.0.109", + "syn 2.0.76", ] [[package]] name = "derive_builder_macro" -version = "0.20.0" +version = "0.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "206868b8242f27cecce124c19fd88157fbd0dd334df2587f36417bafbc85097b" +checksum = "4abae7035bf79b9877b779505d8cf3749285b80c43941eda66604841889451dc" dependencies = [ - "derive_builder_core 0.20.0", - "syn 2.0.48", + "derive_builder_core", + "syn 2.0.76", ] [[package]] name = "derive_more" -version = "0.99.17" +version = "0.99.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" dependencies = [ "convert_case", "proc-macro2", "quote", "rustc_version", - "syn 1.0.109", + "syn 2.0.76", ] [[package]] @@ -914,7 +857,7 @@ version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "65e13bab2796f412722112327f3e575601a3e9cdcbe426f0d30dbf43f3f5dc71" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "byteorder", "chrono", "diesel_derives", @@ -930,15 +873,15 @@ dependencies = [ [[package]] name = "diesel_derives" -version = "2.2.1" +version = "2.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59de76a222c2b8059f789cbe07afbfd8deb8c31dd0bc2a21f85e256c1def8259" +checksum = "e7f2c3de51e2ba6bf2a648285696137aaf0f5f487bcbea93972fe8a364e131a4" dependencies = [ "diesel_table_macro_syntax", "dsl_auto_type", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -958,7 +901,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "209c735641a413bc68c4923a9d6ad4bcb3ca306b794edaa7eb0b3228a99ffb25" dependencies = [ - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -983,13 +926,13 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.4" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -1000,38 +943,38 @@ checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" [[package]] name = "dsl_auto_type" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0892a17df262a24294c382f0d5997571006e7a4348b4327557c4ff1cd4a8bccc" +checksum = "c5d9abe6314103864cc2d8901b7ae224e0ab1a103a0a416661b4097b0779b607" dependencies = [ - "darling 0.20.8", + "darling", "either", "heck", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "either" -version = "1.9.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" dependencies = [ "cfg-if", ] [[package]] name = "env_filter" -version = "0.1.0" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a009aa4810eb158359dda09d0c87378e4bbb89b5a801f016885a4707ba24f7ea" +checksum = "4f2c92ceda6ceec50f43169f9ee8424fe2db276791afde7b2cd8bc084cb376ab" dependencies = [ "log", "regex", @@ -1058,9 +1001,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", "windows-sys 0.52.0", @@ -1074,9 +1017,9 @@ checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" [[package]] name = "fastrand" -version = "2.0.1" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" [[package]] name = "file-format" @@ -1084,20 +1027,14 @@ version = "0.25.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ffe3a660c3a1b10e96f304a9413d673b2118d62e4520f7ddf4a4faccfe8b9b9" -[[package]] -name = "finl_unicode" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" - [[package]] name = "flate2" -version = "1.0.28" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" dependencies = [ "crc32fast", - "miniz_oxide", + "miniz_oxide 0.8.0", ] [[package]] @@ -1207,7 +1144,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -1252,9 +1189,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.12" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", "js-sys", @@ -1265,9 +1202,9 @@ dependencies = [ [[package]] name = "gimli" -version = "0.28.1" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" [[package]] name = "h2" @@ -1280,7 +1217,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.11", + "http 0.2.12", "indexmap", "slab", "tokio", @@ -1290,16 +1227,16 @@ dependencies = [ [[package]] name = "h2" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", - "http 1.0.0", + "http 1.1.0", "indexmap", "slab", "tokio", @@ -1309,9 +1246,9 @@ dependencies = [ [[package]] name = "hard-xml" -version = "1.34.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fafc2bcb74049535eb6fab49eb20164a427867a9e809516ef95a98e961164432" +checksum = "a344e0cef8802f37dc47f17c01a04354d3e66d9f6c8744108b0912f616efe266" dependencies = [ "hard-xml-derive", "jetscii", @@ -1322,11 +1259,11 @@ dependencies = [ [[package]] name = "hard-xml-derive" -version = "1.34.0" +version = "1.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57a345b327da51b997c94f841d9db6b2d292c7632713bd8a1b8b191e8b819df7" +checksum = "1bfae7cdfe23e50ea96929ccf1948d9ae1d8608353556461e5de247463d3a4f6" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "proc-macro2", "quote", "syn 1.0.109", @@ -1334,9 +1271,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" [[package]] name = "heck" @@ -1367,9 +1304,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" dependencies = [ "bytes", "fnv", @@ -1378,9 +1315,9 @@ dependencies = [ [[package]] name = "http" -version = "1.0.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b32afd38673a8016f7c9ae69e5af41a58f81b1d31689040f2f1959594ce194ea" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -1389,23 +1326,23 @@ dependencies = [ [[package]] name = "http-body" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http 1.0.0", + "http 1.1.0", ] [[package]] name = "http-body-util" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" dependencies = [ "bytes", - "futures-core", - "http 1.0.0", + "futures-util", + "http 1.1.0", "http-body", "pin-project-lite", ] @@ -1418,9 +1355,9 @@ checksum = "21dec9db110f5f872ed9699c3ecf50cf16f423502706ba5c72462e28d3157573" [[package]] name = "httparse" -version = "1.8.0" +version = "1.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" [[package]] name = "httpdate" @@ -1436,15 +1373,15 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "1.2.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.3", - "http 1.0.0", + "h2 0.4.6", + "http 1.1.0", "http-body", "httparse", "itoa", @@ -1461,15 +1398,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5ee4be2c948921a1a5320b629c4193916ed787a7f7f293fd3f7f5a6c9de74155" dependencies = [ "futures-util", - "http 1.0.0", + "http 1.1.0", "hyper", "hyper-util", - "rustls 0.23.10", + "rustls 0.23.12", "rustls-pki-types", "tokio", "tokio-rustls 0.26.0", "tower-service", - "webpki-roots 0.26.1", + "webpki-roots 0.26.3", ] [[package]] @@ -1490,14 +1427,14 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.3" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" dependencies = [ "bytes", "futures-channel", "futures-util", - "http 1.0.0", + "http 1.1.0", "http-body", "hyper", "pin-project-lite", @@ -1510,9 +1447,9 @@ dependencies = [ [[package]] name = "iana-time-zone" -version = "0.1.59" +version = "0.1.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" dependencies = [ "android_system_properties", "core-foundation-sys", @@ -1537,7 +1474,7 @@ version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55f4e785f2c700217ee82a1c727c720449421742abd5fcb2f1df04e1244760e9" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "byteorder", "flate2", ] @@ -1566,9 +1503,9 @@ checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" [[package]] name = "indexmap" -version = "2.2.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520" +checksum = "93ead53efc7ea8ed3cfb0c79fc8023fbb782a5432b52830b6518941cebe6505c" dependencies = [ "equivalent", "hashbrown", @@ -1581,11 +1518,17 @@ version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" [[package]] name = "jetscii" @@ -1604,9 +1547,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.67" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" dependencies = [ "wasm-bindgen", ] @@ -1620,7 +1563,7 @@ dependencies = [ "base64 0.21.7", "js-sys", "pem", - "ring 0.17.7", + "ring 0.17.8", "serde", "serde_json", "simple_asn1", @@ -1634,15 +1577,15 @@ checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" [[package]] name = "lazy_static" -version = "1.4.0" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.153" +version = "0.2.158" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" [[package]] name = "libsqlite3-sys" @@ -1657,9 +1600,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.13" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "local-channel" @@ -1680,9 +1623,9 @@ checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" [[package]] name = "lock_api" -version = "0.4.11" +version = "0.4.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" dependencies = [ "autocfg", "scopeguard", @@ -1706,9 +1649,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.7.1" +version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" [[package]] name = "migrations_internals" @@ -1717,7 +1660,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd01039851e82f8799046eabbb354056283fb265c8ec0996af940f4e85a380ff" dependencies = [ "serde", - "toml 0.8.12", + "toml 0.8.19", ] [[package]] @@ -1739,9 +1682,9 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "mime_guess" -version = "2.0.4" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +checksum = "f7c44f8e672c00fe5308fa235f821cb4198414e1c77935c1ab6948d3fd78550e" dependencies = [ "mime", "unicase", @@ -1749,33 +1692,31 @@ dependencies = [ [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] [[package]] -name = "mio" -version = "0.8.11" +name = "miniz_oxide" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" dependencies = [ - "libc", - "log", - "wasi", - "windows-sys 0.48.0", + "adler2", ] [[package]] name = "mio" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4" +checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" dependencies = [ "hermit-abi", "libc", + "log", "wasi", "windows-sys 0.52.0", ] @@ -1811,9 +1752,9 @@ dependencies = [ [[package]] name = "mysqlclient-sys" -version = "0.2.5" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61b381528ba293005c42a409dd73d034508e273bf90481f17ec2e964a6e969b" +checksum = "478e2040dbc35c73927b77a2be91a496de19deab376a6982ed61e89592434619" dependencies = [ "pkg-config", "vcpkg", @@ -1821,11 +1762,10 @@ dependencies = [ [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "a8614eb2c83d59d1c8cc974dd3f920198647674a0a035e1af1fa58707e317466" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1854,11 +1794,10 @@ dependencies = [ [[package]] name = "num-bigint" -version = "0.4.4" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" dependencies = [ - "autocfg", "num-integer", "num-traits", ] @@ -1871,49 +1810,48 @@ checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" [[package]] name = "num-integer" -version = "0.1.45" +version = "0.1.46" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" dependencies = [ - "autocfg", "num-traits", ] [[package]] name = "num-traits" -version = "0.2.17" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", ] [[package]] name = "num_enum" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02339744ee7253741199f897151b38e72257d13802d4ee837285cc2990a90845" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" dependencies = [ "num_enum_derive", ] [[package]] name = "num_enum_derive" -version = "0.7.2" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "object" -version = "0.32.2" +version = "0.36.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9" dependencies = [ "memchr", ] @@ -1930,7 +1868,7 @@ version = "0.10.66" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9529f4786b70a3e8c61e11179af17ab6188ad8d0ded78c5529441ed39d4bd9c1" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "cfg-if", "foreign-types", "libc", @@ -1947,7 +1885,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -1958,9 +1896,9 @@ checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" [[package]] name = "openssl-src" -version = "300.2.2+3.2.1" +version = "300.3.1+3.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8bbfad0063610ac26ee79f7484739e2b07555a75c42453b89263830b5c8103bc" +checksum = "7259953d42a81bf137fbbd73bd30a8e1914d6dce43c2b90ed575783a22608b91" dependencies = [ "cc", ] @@ -1991,9 +1929,9 @@ dependencies = [ [[package]] name = "parking_lot" -version = "0.12.1" +version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" dependencies = [ "lock_api", "parking_lot_core", @@ -2001,30 +1939,30 @@ dependencies = [ [[package]] name = "parking_lot_core" -version = "0.9.9" +version = "0.9.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.5.3", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] name = "paste" -version = "1.0.14" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" [[package]] name = "pem" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "serde", ] @@ -2069,14 +2007,14 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" [[package]] name = "pin-utils" @@ -2086,9 +2024,9 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "podfetch" @@ -2097,7 +2035,7 @@ dependencies = [ "actix", "actix-files", "actix-web", - "actix-web-actors", + "actix-ws", "async-recursion", "awc", "base64 0.22.1", @@ -2148,9 +2086,9 @@ dependencies = [ [[package]] name = "postgres" -version = "0.19.7" +version = "0.19.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7915b33ed60abc46040cbcaa25ffa1c7ec240668e0477c4f3070786f5916d451" +checksum = "6c9ec84ab55b0f9e418675de50052d494ba893fd28c65769a6e68fcdacbee2b8" dependencies = [ "bytes", "fallible-iterator", @@ -2162,11 +2100,11 @@ dependencies = [ [[package]] name = "postgres-protocol" -version = "0.6.6" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49b6c5ef183cd3ab4ba005f1ca64c21e8bd97ce4699cfea9e8d9a2c4958ca520" +checksum = "acda0ebdebc28befa84bee35e651e4c5f09073d668c7aed4cf7e23c3cda84b23" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "byteorder", "bytes", "fallible-iterator", @@ -2180,9 +2118,9 @@ dependencies = [ [[package]] name = "postgres-types" -version = "0.2.6" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d2234cdee9408b523530a9b6d2d6b373d1db34f6a8e51dc03ded1828d7fb67c" +checksum = "02048d9e032fb3cc3413bbf7b83a15d84a5d419778e2628751896d856498eee9" dependencies = [ "bytes", "fallible-iterator", @@ -2197,26 +2135,29 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.17" +version = "0.2.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] [[package]] name = "pq-sys" -version = "0.4.8" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31c0052426df997c0cbd30789eb44ca097e3541717a7b8fa36b1c464ee7edebd" +checksum = "a24ff9e4cf6945c988f0db7005d87747bf72864965c3529d259ad155ac41d584" dependencies = [ "vcpkg", ] [[package]] name = "proc-macro-crate" -version = "3.1.0" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d37c51ca738a55da99dc0c4a34860fd675453b8b36209178c2249bb13651284" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.21.1", + "toml_edit 0.22.20", ] [[package]] @@ -2245,28 +2186,18 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.78" +version = "1.0.86" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" dependencies = [ "unicode-ident", ] [[package]] name = "quick-xml" -version = "0.30.0" +version = "0.36.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eff6510e86862b57b210fd8cbe8ed3f0d7d600b9c2863cd4549a2e033c66e956" -dependencies = [ - "encoding_rs", - "memchr", -] - -[[package]] -name = "quick-xml" -version = "0.31.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" +checksum = "96a05e2e8efddfa51a84ca47cec303fac86c8541b686d37cac5efc0e094417bc" dependencies = [ "encoding_rs", "memchr", @@ -2274,16 +2205,17 @@ dependencies = [ [[package]] name = "quinn" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4ceeeeabace7857413798eb1ffa1e9c905a9946a57d81fb69b4b71c4d8eb3ad" +checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" dependencies = [ "bytes", "pin-project-lite", "quinn-proto", "quinn-udp", "rustc-hash", - "rustls 0.23.10", + "rustls 0.23.12", + "socket2", "thiserror", "tokio", "tracing", @@ -2291,15 +2223,15 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.11.3" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf517c03a109db8100448a4be38d498df8a210a99fe0e1b9eaf39e78c640efe" +checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" dependencies = [ "bytes", "rand", - "ring 0.17.7", + "ring 0.17.8", "rustc-hash", - "rustls 0.23.10", + "rustls 0.23.12", "slab", "thiserror", "tinyvec", @@ -2308,9 +2240,9 @@ dependencies = [ [[package]] name = "quinn-udp" -version = "0.5.2" +version = "0.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46" +checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" dependencies = [ "libc", "once_cell", @@ -2321,9 +2253,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -2381,9 +2313,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.8.1" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -2408,6 +2340,15 @@ dependencies = [ "bitflags 1.3.2", ] +[[package]] +name = "redox_syscall" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "regex" version = "1.10.6" @@ -2422,9 +2363,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -2433,15 +2374,15 @@ dependencies = [ [[package]] name = "regex-lite" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b661b2f27137bdbc16f00eda72866a92bb28af1753ffbd56744fb6e2e9cd8e" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" [[package]] name = "reqwest" @@ -2455,8 +2396,8 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.4.3", - "http 1.0.0", + "h2 0.4.6", + "http 1.1.0", "http-body", "http-body-util", "hyper", @@ -2472,7 +2413,7 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.10", + "rustls 0.23.12", "rustls-pemfile", "rustls-pki-types", "serde", @@ -2490,7 +2431,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.26.1", + "webpki-roots 0.26.3", "windows-registry", ] @@ -2511,16 +2452,17 @@ dependencies = [ [[package]] name = "ring" -version = "0.17.7" +version = "0.17.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", + "cfg-if", "getrandom", "libc", "spin 0.9.8", "untrusted 0.9.0", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2536,14 +2478,14 @@ dependencies = [ [[package]] name = "rss" -version = "2.0.8" +version = "2.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f374fd66bb795938b78c021db1662d43a8ffbc42ec1ac25429fc4833b732751" +checksum = "27e92048f840d98c6d6dd870af9101610ea9ff413f11f1bcebf4f4c31d96d957" dependencies = [ "atom_syndication", - "derive_builder 0.20.0", + "derive_builder", "never", - "quick-xml 0.31.0", + "quick-xml", ] [[package]] @@ -2558,9 +2500,9 @@ dependencies = [ [[package]] name = "rust-embed" -version = "8.2.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82c0bbc10308ed323529fd3c1dce8badda635aa319a5ff0e6466f33b8101e3f" +checksum = "fa66af4a4fdd5e7ebc276f115e895611a34739a9c1c01028383d612d550953c0" dependencies = [ "rust-embed-impl", "rust-embed-utils", @@ -2569,22 +2511,22 @@ dependencies = [ [[package]] name = "rust-embed-impl" -version = "8.2.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6227c01b1783cdfee1bcf844eb44594cd16ec71c35305bf1c9fb5aade2735e16" +checksum = "6125dbc8867951125eec87294137f4e9c2c96566e61bf72c45095a7c77761478" dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.48", + "syn 2.0.76", "walkdir", ] [[package]] name = "rust-embed-utils" -version = "8.2.0" +version = "8.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cb0a25bfbb2d4b4402179c2cf030387d9990857ce08a32592c6238db9fa8665" +checksum = "2e5347777e9aacb56039b0e1f28785929a8a3b709e87482e7442c72e7c12529d" dependencies = [ "sha2", "walkdir", @@ -2592,32 +2534,32 @@ dependencies = [ [[package]] name = "rustc-demangle" -version = "0.1.23" +version = "0.1.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustc-hash" -version = "1.1.0" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" +checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" [[package]] name = "rustc_version" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ "semver", ] [[package]] name = "rustix" -version = "0.38.30" +version = "0.38.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +checksum = "a85d50532239da68e9addb745ba38ff4612a242c1c7ceea689c4bc7c2f43c36f" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "errno", "libc", "linux-raw-sys", @@ -2638,35 +2580,24 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.23.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "c58f8c84392efc0a126acce10fa59ff7b3d2ac06ab451a33f2741989b806b044" dependencies = [ "log", - "ring 0.17.7", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402" -dependencies = [ "once_cell", - "ring 0.17.7", + "ring 0.17.8", "rustls-pki-types", - "rustls-webpki 0.102.4", + "rustls-webpki", "subtle", "zeroize", ] [[package]] name = "rustls-pemfile" -version = "2.1.2" +version = "2.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29993a25686778eb88d4189742cd713c9bce943bc54251a33509dc63cbacf73d" +checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" dependencies = [ "base64 0.22.1", "rustls-pki-types", @@ -2674,36 +2605,26 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "976295e77ce332211c0d24d92c0e83e50f5c5f046d11082cea19f3df13a3562d" - -[[package]] -name = "rustls-webpki" -version = "0.101.7" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.7", - "untrusted 0.9.0", -] +checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" [[package]] name = "rustls-webpki" -version = "0.102.4" +version = "0.102.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff448f7e92e913c4b7d4c6d8e4540a1724b319b4152b8aef6d4cf8339712b33e" +checksum = "84678086bd54edf2b415183ed7a94d0efb049f1b646a33e22a36f3794be6ae56" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "rustls-pki-types", "untrusted 0.9.0", ] [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" [[package]] name = "same-file" @@ -2716,9 +2637,9 @@ dependencies = [ [[package]] name = "scc" -version = "2.1.0" +version = "2.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec96560eea317a9cc4e0bb1f6a2c93c09a19b8c4fc5cb3fcc0ec1c094cd783e2" +checksum = "aeb7ac86243095b70a7920639507b71d51a63390d1ba26c4f60a552fbb914a37" dependencies = [ "sdd", ] @@ -2753,23 +2674,23 @@ version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] [[package]] name = "sdd" -version = "0.2.0" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b84345e4c9bd703274a082fb80caaa99b7612be48dfaa1dd9266577ec412309d" +checksum = "0495e4577c672de8254beb68d01a9b62d0e8a13c099edecdbedccce3223cd29f" [[package]] name = "security-framework" -version = "2.9.2" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.6.0", "core-foundation", "core-foundation-sys", "libc", @@ -2778,9 +2699,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf" dependencies = [ "core-foundation-sys", "libc", @@ -2788,9 +2709,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" dependencies = [ "serde", ] @@ -2812,7 +2733,7 @@ checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -2829,9 +2750,9 @@ dependencies = [ [[package]] name = "serde_spanned" -version = "0.6.5" +version = "0.6.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +checksum = "eb5b1b31579f3811bf615c144393417496f152e12ac8b7663bf664f4a815306d" dependencies = [ "serde", ] @@ -2870,7 +2791,7 @@ checksum = "82fe9db325bcef1fbcde82e078a5cc4efdf787e96b3b9cf45b50b529f2083d67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -2916,9 +2837,9 @@ checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" [[package]] name = "signal-hook-registry" -version = "1.4.1" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" dependencies = [ "libc", ] @@ -2952,18 +2873,18 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.5" +version = "0.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2986,20 +2907,20 @@ checksum = "7a8348af2d9fc3258c8733b8d9d8db2e56f54b2363a4b5b81585c7875ed65e65" [[package]] name = "stringprep" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +checksum = "7b4df3d392d81bd458a8a621b8bffbd2302a12ffe288a9d931670948749463b1" dependencies = [ - "finl_unicode", "unicode-bidi", "unicode-normalization", + "unicode-properties", ] [[package]] name = "strsim" -version = "0.10.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" [[package]] name = "substring" @@ -3012,9 +2933,9 @@ dependencies = [ [[package]] name = "subtle" -version = "2.5.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" @@ -3029,9 +2950,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.48" +version = "2.0.76" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +checksum = "578e081a14e0cefc3279b0472138c513f37b41a08d5a3cca9b6e4e8ceb6cd525" dependencies = [ "proc-macro2", "quote", @@ -3049,9 +2970,9 @@ dependencies = [ [[package]] name = "sysinfo" -version = "0.31.3" +version = "0.31.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b92e0bdf838cbc1c4c9ba14f9c97a7ec6cdcd1ae66b10e1e42775a25553f45d" +checksum = "355dbe4f8799b304b05e1b0f05fc59b2a18d36645cf169607da45bde2f69a1be" dependencies = [ "core-foundation-sys", "libc", @@ -3068,7 +2989,7 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" dependencies = [ - "bitflags 2.4.2", + "bitflags 2.6.0", "core-foundation", "system-configuration-sys", ] @@ -3085,15 +3006,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.9.0" +version = "3.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" dependencies = [ "cfg-if", "fastrand", - "redox_syscall", + "once_cell", "rustix", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -3113,7 +3034,7 @@ checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -3149,9 +3070,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" dependencies = [ "tinyvec_macros", ] @@ -3171,7 +3092,7 @@ dependencies = [ "backtrace", "bytes", "libc", - "mio 1.0.1", + "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -3188,7 +3109,7 @@ checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -3203,9 +3124,9 @@ dependencies = [ [[package]] name = "tokio-postgres" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d340244b32d920260ae7448cb72b6e238bddc3d4f7603394e7dd46ed8e48f5b8" +checksum = "03adcf0147e203b6032c0b2d30be1415ba03bc348901f3ff1cc0df6a733e60c3" dependencies = [ "async-trait", "byteorder", @@ -3244,7 +3165,7 @@ version = "0.26.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" dependencies = [ - "rustls 0.23.10", + "rustls 0.23.12", "rustls-pki-types", "tokio", ] @@ -3263,16 +3184,15 @@ dependencies = [ [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] [[package]] @@ -3289,21 +3209,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.12" +version = "0.8.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" +checksum = "a1ed1f98e3fdc28d6d910e6737ae6ab1a93bf1985935a1193e68f93eeb68d24e" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.22.12", + "toml_edit 0.22.20", ] [[package]] name = "toml_datetime" -version = "0.6.5" +version = "0.6.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" dependencies = [ "serde", ] @@ -3318,31 +3238,20 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow 0.5.36", + "winnow 0.5.40", ] [[package]] name = "toml_edit" -version = "0.21.1" +version = "0.22.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a8534fd7f78b5405e860340ad6575217ce99f38d4d5c8f2442cb5ecb50090e1" -dependencies = [ - "indexmap", - "toml_datetime", - "winnow 0.5.36", -] - -[[package]] -name = "toml_edit" -version = "0.22.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3328d4f68a705b2a4498da1d580585d39a6510f98318a2cec3018a7ec61ddef" +checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" dependencies = [ "indexmap", "serde", "serde_spanned", "toml_datetime", - "winnow 0.6.13", + "winnow 0.6.18", ] [[package]] @@ -3358,20 +3267,19 @@ dependencies = [ "tokio", "tower-layer", "tower-service", - "tracing", ] [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tracing" @@ -3381,21 +3289,9 @@ checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" dependencies = [ "log", "pin-project-lite", - "tracing-attributes", "tracing-core", ] -[[package]] -name = "tracing-attributes" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.48", -] - [[package]] name = "tracing-core" version = "0.1.32" @@ -3428,7 +3324,7 @@ checksum = "f9534daa9fd3ed0bd911d462a37f172228077e7abf18c18a5f67199d959205f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -3460,13 +3356,19 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "unicode-normalization" -version = "0.1.22" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-properties" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52ea75f83c0137a9b98608359a5f1af8144876eb67bcb1ce837368e906a9f524" + [[package]] name = "untrusted" version = "0.7.1" @@ -3481,25 +3383,25 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "ureq" -version = "2.9.1" +version = "2.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8cdd25c339e200129fe4de81451814e5228c9b771d57378817d6117cc2b3f97" +checksum = "b74fc6b57825be3373f7054754755f03ac3a8f5d70015ccad699ba2029956f4a" dependencies = [ - "base64 0.21.7", + "base64 0.22.1", "flate2", "log", "once_cell", - "rustls 0.21.10", - "rustls-webpki 0.101.7", + "rustls 0.23.12", + "rustls-pki-types", "url", - "webpki-roots 0.25.3", + "webpki-roots 0.26.3", ] [[package]] name = "url" -version = "2.5.0" +version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" dependencies = [ "form_urlencoded", "idna", @@ -3514,9 +3416,9 @@ checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" [[package]] name = "utf8parse" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "utoipa" @@ -3540,7 +3442,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -3585,15 +3487,15 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "walkdir" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" dependencies = [ "same-file", "winapi-util", @@ -3622,34 +3524,35 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" dependencies = [ "cfg-if", + "once_cell", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" dependencies = [ "bumpalo", "log", "once_cell", "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.40" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" dependencies = [ "cfg-if", "js-sys", @@ -3659,9 +3562,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3669,22 +3572,22 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.90" +version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" +checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" [[package]] name = "wasm-streams" @@ -3701,9 +3604,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.67" +version = "0.3.70" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" dependencies = [ "js-sys", "wasm-bindgen", @@ -3715,7 +3618,7 @@ version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" dependencies = [ - "ring 0.17.7", + "ring 0.17.8", "untrusted 0.9.0", ] @@ -3730,15 +3633,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.25.3" +version = "0.26.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1778a42e8b3b90bff8d0f5032bf22250792889a5cdc752aa0020c84abe3aaf10" - -[[package]] -name = "webpki-roots" -version = "0.26.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009" +checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" dependencies = [ "rustls-pki-types", ] @@ -3749,7 +3646,7 @@ version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a44ab49fad634e88f55bf8f9bb3abd2f27d7204172a112c7c9987e01c1c94ea9" dependencies = [ - "redox_syscall", + "redox_syscall 0.4.1", "wasite", "web-sys", ] @@ -3772,11 +3669,11 @@ checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" [[package]] name = "winapi-util" -version = "0.1.6" +version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" dependencies = [ - "winapi", + "windows-sys 0.59.0", ] [[package]] @@ -3824,7 +3721,7 @@ checksum = "9107ddc059d5b6fbfbffdfa7a7fe3e22a226def0b2608f72e9d552763d3e1ad7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -3835,7 +3732,7 @@ checksum = "29bee4b38ea3cde66011baa44dba677c432a78593e202392d1e9070cf2a7fca7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] @@ -3895,6 +3792,15 @@ dependencies = [ "windows-targets 0.52.6", ] +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -4018,27 +3924,27 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" -version = "0.5.36" +version = "0.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "818ce546a11a9986bc24f93d0cdf38a8a1a400f1473ea8c82e59f6e0ffab9249" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" dependencies = [ "memchr", ] [[package]] name = "winnow" -version = "0.6.13" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1" +checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" dependencies = [ "memchr", ] [[package]] name = "xml-builder" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efc4f1a86af7800dfc4056c7833648ea4515ae21502060b5c98114d828f5333b" +checksum = "5ef5f40cd674b9d9814545203f175ac29ffdcb6e006727f4d95797d7badd72e2" [[package]] name = "xmlparser" @@ -4048,29 +3954,30 @@ checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" [[package]] name = "zerocopy" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" dependencies = [ + "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.32" +version = "0.7.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.48", + "syn 2.0.76", ] [[package]] name = "zeroize" -version = "1.7.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" [[package]] name = "zip" @@ -4090,27 +3997,27 @@ dependencies = [ [[package]] name = "zstd" -version = "0.13.0" +version = "0.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110" +checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" dependencies = [ "zstd-safe", ] [[package]] name = "zstd-safe" -version = "7.0.0" +version = "7.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e" +checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" dependencies = [ "zstd-sys", ] [[package]] name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" +version = "2.0.13+zstd.1.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" dependencies = [ "cc", "pkg-config", diff --git a/Cargo.toml b/Cargo.toml index 01f4cf9f..60a3ee06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,14 +32,14 @@ actix-files = "0.6.6" actix-web = {version="4.9.0", features=["rustls"]} jsonwebtoken = {version="9.3.0"} log = "0.4.22" -futures-util = "0.3.29" +futures-util = "0.3.30" substring = "1.4.5" opml = "1.1.6" rand = "0.8.5" env_logger = "0.11.5" chrono = {version = "0.4.38", default-features=false, features = ["serde"]} -actix-web-actors = "4.3.1" -rss = "2.0.8" +rss = "2.0.9" +actix-ws = "0.3.0" frankenstein = "0.32.4" regex = "1.10.6" xml-builder = "0.5.2" @@ -58,7 +58,7 @@ serde_json = "1.0.127" dotenv = "0.15.0" thiserror = "1.0.63" sha1 = "0.10.6" -sha256 = "1.4.0" +sha256 = "1.5.0" strfmt="0.2.4" urlencoding="2.1.3" id3 = "1.14.0" diff --git a/src/constants/inner_constants.rs b/src/constants/inner_constants.rs index 230fbddd..7d313644 100644 --- a/src/constants/inner_constants.rs +++ b/src/constants/inner_constants.rs @@ -142,3 +142,6 @@ pub static ITUNES: &str = "itunes"; pub const REVERSE_PROXY: &str = "REVERSE_PROXY"; pub const REVERSE_PROXY_HEADER: &str = "REVERSE_PROXY_HEADER"; pub const REVERSE_PROXY_AUTO_SIGN_UP: &str = "REVERSE_PROXY_AUTO_SIGN_UP"; + + +pub const MAIN_ROOM: &str = "main"; \ No newline at end of file diff --git a/src/controllers/mod.rs b/src/controllers/mod.rs index 14cb9ba5..2295b9ee 100644 --- a/src/controllers/mod.rs +++ b/src/controllers/mod.rs @@ -10,3 +10,4 @@ pub mod user_controller; pub mod watch_time_controller; pub mod web_socket; pub mod websocket_controller; +pub mod server; diff --git a/src/controllers/podcast_controller.rs b/src/controllers/podcast_controller.rs index f2f48f2e..553df0ca 100644 --- a/src/controllers/podcast_controller.rs +++ b/src/controllers/podcast_controller.rs @@ -1,17 +1,13 @@ -use crate::constants::inner_constants::{ - PodcastType, BASIC_AUTH, COMMON_USER_AGENT, DEFAULT_IMAGE_URL, ENVIRONMENT_SERVICE, OIDC_AUTH, -}; +use crate::constants::inner_constants::{PodcastType, BASIC_AUTH, COMMON_USER_AGENT, DEFAULT_IMAGE_URL, ENVIRONMENT_SERVICE, MAIN_ROOM, OIDC_AUTH}; use crate::models::dto_models::PodcastFavorUpdateModel; use crate::models::misc_models::{PodcastAddModel, PodcastInsertModel}; use crate::models::opml_model::OpmlModel; use crate::models::search_type::SearchType::{ITunes, Podindex}; -use crate::models::web_socket_message::Lobby; use crate::service::environment_service::EnvironmentService; use crate::service::mapping_service::MappingService; use crate::service::podcast_episode_service::PodcastEpisodeService; use crate::service::rust_service::PodcastService; use crate::{get_default_image, unwrap_string, DbPool}; -use actix::Addr; use actix_web::dev::PeerAddr; use actix_web::http::Method; use actix_web::web::{Data, Json, Path}; @@ -239,7 +235,7 @@ tag="podcasts" #[post("/podcast/itunes")] pub async fn add_podcast( track_id: web::Json, - lobby: Data>, + lobby: Data, conn: Data, requester: Option>, ) -> Result { @@ -290,7 +286,7 @@ tag="podcasts" #[post("/podcast/feed")] pub async fn add_podcast_by_feed( rss_feed: web::Json, - lobby: Data>, + lobby: Data, podcast_service: Data>, conn: Data, requester: Option>, @@ -349,7 +345,7 @@ tag="podcasts" #[post("/podcast/opml")] pub async fn import_podcasts_from_opml( opml: web::Json, - lobby: Data>, + lobby: Data, conn: Data, requester: Option>, ) -> Result { @@ -388,7 +384,7 @@ tag="podcasts" #[post("/podcast/podindex")] pub async fn add_podcast_from_podindex( id: web::Json, - lobby: Data>, + lobby: Data, conn: Data, requester: Option>, ) -> Result { @@ -424,7 +420,7 @@ pub async fn add_podcast_from_podindex( fn start_download_podindex( id: i32, - lobby: Data>, + lobby: Data, conn: &mut DbConnection, ) -> Result { let rt = tokio::runtime::Runtime::new().unwrap(); @@ -464,7 +460,7 @@ tag="podcasts" )] #[post("/podcast/all")] pub async fn refresh_all_podcasts( - lobby: Data>, + lobby: Data, podcast_service: Data>, conn: Data, requester: Option>, @@ -485,13 +481,13 @@ pub async fn refresh_all_podcasts( conn.get().map_err(map_r2d2_error).unwrap().deref_mut(), ) .unwrap(); - lobby.clone().do_send(BroadcastMessage { + lobby.send_broadcast_sync(MAIN_ROOM.parse().unwrap(), serde_json::to_string(&BroadcastMessage { podcast_episode: None, type_of: PodcastType::RefreshPodcast, message: format!("Refreshed podcast: {}", podcast.name), podcast: Option::from(podcast.clone()), podcast_episodes: None, - }); + }).unwrap()); } }); Ok(HttpResponse::Ok().into()) @@ -506,7 +502,7 @@ tag="podcasts" #[post("/podcast/{id}/refresh")] pub async fn download_podcast( id: Path, - lobby: Data>, + lobby: Data, podcast_service: Data>, conn: Data, requester: Option>, @@ -621,7 +617,7 @@ pub async fn update_active_podcast( async fn insert_outline( podcast: Outline, client: Client, - lobby: Data>, + lobby: Data, mut rng: ThreadRng, environment: EnvironmentService, conn: Data, @@ -647,13 +643,13 @@ async fn insert_outline( let feed_response = client.get(feed_url.unwrap()).send().await; if feed_response.is_err() { - lobby.do_send(BroadcastMessage { + lobby.send_broadcast(MAIN_ROOM.parse().unwrap(),serde_json::to_string(&BroadcastMessage { type_of: PodcastType::OpmlErrored, message: feed_response.err().unwrap().to_string(), podcast: None, podcast_episodes: None, podcast_episode: None, - }); + }).unwrap()).await; return; } let content = feed_response.unwrap().bytes().await.unwrap(); @@ -689,35 +685,43 @@ async fn insert_outline( ) .await; match inserted_podcast { - Ok(podcast) => lobby.do_send(BroadcastMessage { - type_of: PodcastType::OpmlAdded, - message: "Refreshed podcasts".to_string(), - podcast: Option::from(podcast), - podcast_episodes: None, - podcast_episode: None, - }), - Err(e) => lobby.do_send(BroadcastMessage { - type_of: PodcastType::OpmlErrored, - message: e.to_string(), - podcast: None, - podcast_episodes: None, - podcast_episode: None, - }), + Ok(podcast) => { + + let _ = lobby.send_broadcast(MAIN_ROOM.parse().unwrap(), serde_json::to_string(&BroadcastMessage { + type_of: PodcastType::OpmlAdded, + message: "Refreshed podcasts".to_string(), + podcast: Option::from(podcast), + podcast_episodes: None, + podcast_episode: None, + }).unwrap()).await; + }, + Err(e) => { + let _ = lobby.send_broadcast(MAIN_ROOM.parse().unwrap(), serde_json::to_string(&BroadcastMessage { + type_of: PodcastType::OpmlErrored, + message: e.to_string(), + podcast: None, + podcast_episodes: None, + podcast_episode: None, + }).unwrap()).await; + }, } } - Err(e) => lobby.do_send(BroadcastMessage { - type_of: PodcastType::OpmlErrored, - message: e.to_string(), - podcast: None, - podcast_episodes: None, - podcast_episode: None, - }), + Err(e) => { + let _ = lobby.send_broadcast(MAIN_ROOM.parse().unwrap(),serde_json::to_string(&BroadcastMessage { + type_of: PodcastType::OpmlErrored, + message: e.to_string(), + podcast: None, + podcast_episodes: None, + podcast_episode: None, + }).unwrap()).await; + }, } } use crate::models::episode::Episode; use utoipa::ToSchema; use crate::controllers::podcast_episode_controller::EpisodeFormatDto; +use crate::controllers::server::ChatServerHandle; use crate::controllers::websocket_controller::RSSAPiKey; use crate::models::podcast_settings::PodcastSetting; use crate::models::settings::Setting; diff --git a/src/controllers/podcast_episode_controller.rs b/src/controllers/podcast_episode_controller.rs index 9bfde8ac..a1e8940f 100644 --- a/src/controllers/podcast_episode_controller.rs +++ b/src/controllers/podcast_episode_controller.rs @@ -1,4 +1,4 @@ -use crate::constants::inner_constants::PodcastType; +use crate::constants::inner_constants::{PodcastType, MAIN_ROOM}; use crate::db::TimelineItem; use crate::models::episode::Episode; use crate::models::favorites::Favorite; @@ -6,13 +6,11 @@ use crate::models::messages::BroadcastMessage; use crate::models::podcast_episode::PodcastEpisode; use crate::models::podcasts::Podcast; use crate::models::user::User; -use crate::models::web_socket_message::Lobby; use crate::service::mapping_service::MappingService; use crate::service::podcast_episode_service::PodcastEpisodeService; use crate::utils::error::{map_r2d2_error, CustomError}; use crate::DbPool; -use actix::Addr; use actix_web::web::{Data, Json, Query}; use actix_web::{delete, get, post, put}; use actix_web::{web, HttpResponse}; @@ -22,6 +20,7 @@ use std::ops::DerefMut; use crate::models::settings::Setting; use crate::service::file_service::perform_episode_variable_replacement; use std::thread; +use crate::controllers::server::ChatServerHandle; #[derive(Debug, Serialize, Deserialize, Clone)] pub struct OptionalId { @@ -214,7 +213,7 @@ pub async fn delete_podcast_episode_locally( id: web::Path, requester: Option>, db: Data, - lobby: Data>, + lobby: Data, ) -> Result { if !requester.unwrap().is_privileged_user() { return Err(CustomError::Forbidden); @@ -224,13 +223,13 @@ pub async fn delete_podcast_episode_locally( &id.into_inner(), &mut db.get().unwrap(), )?; - lobby.do_send(BroadcastMessage { + lobby.send_broadcast(MAIN_ROOM.parse().unwrap(),serde_json::to_string(&BroadcastMessage { podcast_episode: Some(delted_podcast_episode), podcast_episodes: None, type_of: PodcastType::DeletePodcastEpisode, podcast: None, message: "Deleted podcast episode locally".to_string(), - }); + }).unwrap()).await; Ok(HttpResponse::NoContent().finish()) } diff --git a/src/controllers/server.rs b/src/controllers/server.rs new file mode 100644 index 00000000..597c9d85 --- /dev/null +++ b/src/controllers/server.rs @@ -0,0 +1,346 @@ +use std::collections::{HashMap, HashSet}; +use std::io; +use rand::{random}; +use tokio::sync::{mpsc, oneshot}; +use crate::constants::inner_constants::MAIN_ROOM; + +type RoomId = String; +pub type ConnId = usize; + +pub type Msg = String; + +/// A command received by the [`ChatServer`]. +#[derive(Debug)] +enum Command { + Broadcast { + room: RoomId, + msg: Msg, + res_tx: Option>, + }, + Connect { + conn_tx: mpsc::UnboundedSender, + res_tx: oneshot::Sender, + }, + + Disconnect { + conn: ConnId, + }, + + List { + res_tx: oneshot::Sender>, + }, + + Join { + conn: ConnId, + room: RoomId, + res_tx: oneshot::Sender<()>, + }, + + Message { + msg: Msg, + conn: ConnId, + res_tx: oneshot::Sender<()>, + }, +} + + + +/// A multi-room chat server. +/// +/// Contains the logic of how connections chat with each other plus room management. +/// +/// Call and spawn [`run`](Self::run) to start processing commands. +#[derive(Debug)] +pub struct ChatServer { + /// Map of connection IDs to their message receivers. + sessions: HashMap>, + + /// Map of room name to participant IDs in that room. + rooms: HashMap>, + + /// Tracks total number of historical connections established. + //visitor_count: Arc, + + /// Command receiver. + cmd_rx: mpsc::UnboundedReceiver, +} + + +impl ChatServer { + pub fn new() -> (Self, ChatServerHandle) { + // create empty server + let mut rooms = HashMap::with_capacity(4); + + // create default room + rooms.insert(MAIN_ROOM.parse().unwrap(), HashSet::new()); + + let (cmd_tx, cmd_rx) = mpsc::unbounded_channel(); + + ( + Self { + sessions: HashMap::new(), + rooms, + //visitor_count: Arc::new(AtomicUsize::new(0)), + cmd_rx, + }, + ChatServerHandle { cmd_tx }, + ) + } + + + + /// Send message to specific room, also to the user itself + async fn send_broadcast_to_room(&self, room_id: &str, msg: impl Into) { + if let Some(sessions) = self.rooms.get(room_id) { + let msg = msg.into(); + + for conn_id in sessions { + if let Some(tx) = self.sessions.get(conn_id) { + // errors if client disconnected abruptly and hasn't been timed-out yet + let _ = tx.send(msg.clone()); + } + } + } + } + + /// Send message to users in a room. + /// + /// `skip` is used to prevent messages triggered by a connection also being received by it. + async fn send_system_message(&self, room: &str, skip: ConnId, msg: impl Into) { + if let Some(sessions) = self.rooms.get(room) { + let msg = msg.into(); + + for conn_id in sessions { + if *conn_id != skip { + if let Some(tx) = self.sessions.get(conn_id) { + // errors if client disconnected abruptly and hasn't been timed-out yet + let _ = tx.send(msg.clone()); + } + } + } + } + } + + /// Send message to all other users in current room. + /// + /// `conn` is used to find current room and prevent messages sent by a connection also being + /// received by it. + async fn send_message(&self, conn: ConnId, msg: impl Into) { + if let Some(room) = self + .rooms + .iter() + .find_map(|(room, participants)| participants.contains(&conn).then_some(room)) + { + self.send_system_message(room, conn, msg).await; + }; + } + + /// Register new session and assign unique ID to this session + async fn connect(&mut self, tx: mpsc::UnboundedSender) -> ConnId { + log::info!("Someone joined"); + + // notify all users in same room + //self.send_system_message("main", 0, "Someone joined").await; + + // register session with random connection ID + let id = random::(); + self.sessions.insert(id, tx); + + // auto join session to main room + self.rooms.entry(MAIN_ROOM.parse().unwrap()).or_default().insert(id); + log::info!("Joined main room"); + + //let count = self.visitor_count.fetch_add(1, Ordering::SeqCst); + /*self.send_system_message("main", 0, format!("Total visitors {count}")) + .await;*/ + + // send id back + id + } + + /// Unregister connection from room map and broadcast disconnection message. + async fn disconnect(&mut self, conn_id: ConnId) { + println!("Someone disconnected"); + + let mut rooms: Vec = Vec::new(); + + // remove sender + if self.sessions.remove(&conn_id).is_some() { + // remove session from all rooms + for (name, sessions) in &mut self.rooms { + if sessions.remove(&conn_id) { + rooms.push(name.to_owned()); + } + } + } + + // send message to other users + for room in rooms { + self.send_system_message(&room, 0, "Someone disconnected") + .await; + } + } + + /// Returns list of created room names. + fn list_rooms(&mut self) -> Vec { + self.rooms.keys().cloned().collect() + } + + /// Join room, send disconnect message to old room send join message to new room. + async fn join_room(&mut self, conn_id: ConnId, room: RoomId) { + let mut rooms = Vec::new(); + + // remove session from all rooms + for (n, sessions) in &mut self.rooms { + if sessions.remove(&conn_id) { + rooms.push(n.to_owned()); + } + } + // send message to other users + for room in rooms { + self.send_system_message(&room, 0, "Someone disconnected") + .await; + } + + self.rooms.entry(room.clone()).or_default().insert(conn_id); + + self.send_system_message(&room, conn_id, "Someone connected") + .await; + } + + pub async fn run(mut self) -> io::Result<()> { + while let Some(cmd) = self.cmd_rx.recv().await { + match cmd { + Command::Broadcast{msg,room, res_tx}=>{ + let res = self.send_broadcast_to_room(&room, msg).await; + + if let Some(res_tx) = res_tx { + let _ = res_tx.send(res); + } + } + Command::Connect { conn_tx, res_tx } => { + let conn_id = self.connect(conn_tx).await; + let _ = res_tx.send(conn_id); + } + Command::Disconnect { conn } => { + self.disconnect(conn).await; + } + + Command::List { res_tx } => { + let _ = res_tx.send(self.list_rooms()); + } + + Command::Join { conn, room, res_tx } => { + self.join_room(conn, room).await; + let _ = res_tx.send(()); + } + Command::Message { conn, msg, res_tx } => { + self.send_message(conn, msg).await; + let _ = res_tx.send(()); + } + } + } + + Ok(()) + } +} + + +/// Handle and command sender for chat server. +/// +/// Reduces boilerplate of setting up response channels in WebSocket handlers. +#[derive(Debug, Clone)] +pub struct ChatServerHandle { + cmd_tx: mpsc::UnboundedSender, +} + + +impl ChatServerHandle { + /// Register client message sender and obtain connection ID. + pub async fn connect(&self, conn_tx: mpsc::UnboundedSender) -> ConnId { + let (res_tx, res_rx) = oneshot::channel(); + + // unwrap: chat server should not have been dropped + self.cmd_tx + .send(Command::Connect { conn_tx, res_tx }) + .unwrap(); + + // unwrap: chat server does not drop out response channel + res_rx.await.unwrap() + } + + /// List all created rooms. + pub async fn list_rooms(&self) -> Vec { + let (res_tx, res_rx) = oneshot::channel(); + + // unwrap: chat server should not have been dropped + self.cmd_tx.send(Command::List { res_tx }).unwrap(); + + // unwrap: chat server does not drop our response channel + res_rx.await.unwrap() + } + + /// Join `room`, creating it if it does not exist. + pub async fn join_room(&self, conn: ConnId, room: impl Into) { + let (res_tx, res_rx) = oneshot::channel(); + + // unwrap: chat server should not have been dropped + self.cmd_tx + .send(Command::Join { + conn, + room: room.into(), + res_tx, + }) + .unwrap(); + + // unwrap: chat server does not drop our response channel + res_rx.await.unwrap(); + } + + pub async fn send_broadcast(&self, room_id: RoomId, msg: impl Into) { + let (res_tx, res_rx) = oneshot::channel(); + + self.cmd_tx.send(Command::Broadcast { + msg: msg.into(), + room: room_id, + res_tx: Some(res_tx), + }).unwrap(); + + // unwrap: chat server does not drop our response channel + res_rx.await.unwrap(); + } + + + pub fn send_broadcast_sync(&self, room_id: RoomId, msg: impl Into) { + + self.cmd_tx.send(Command::Broadcast { + msg: msg.into(), + room: room_id, + res_tx: None, + }).unwrap(); + } + + + /// Broadcast message to current room. + pub async fn send_message(&self, conn: ConnId, msg: impl Into) { + let (res_tx, res_rx) = oneshot::channel(); + + // unwrap: chat server should not have been dropped + self.cmd_tx + .send(Command::Message { + msg: msg.into(), + conn, + res_tx, + }) + .unwrap(); + + // unwrap: chat server does not drop our response channel + res_rx.await.unwrap(); + } + + /// Unregister message sender and broadcast disconnection message to current room. + pub fn disconnect(&self, conn: ConnId) { + // unwrap: chat server should not have been dropped + self.cmd_tx.send(Command::Disconnect { conn }).unwrap(); + } +} \ No newline at end of file diff --git a/src/controllers/web_socket.rs b/src/controllers/web_socket.rs index 80c50849..b1f0b6cb 100644 --- a/src/controllers/web_socket.rs +++ b/src/controllers/web_socket.rs @@ -1,111 +1,152 @@ -use crate::models::messages::{Connect, Disconnect, WsMessage}; -use crate::models::web_socket_message::Lobby; -use actix::{ - fut, Actor, ActorContext, ActorFutureExt, Addr, AsyncContext, ContextFutureSpawner, Handler, - Running, StreamHandler, WrapFuture, -}; -use actix_web_actors::ws; -use actix_web_actors::ws::Message; -use actix_web_actors::ws::Message::Text; +use std::pin::pin; use std::time::{Duration, Instant}; -use uuid::Uuid; +use actix_ws::AggregatedMessage; +use futures_util::future::{select, Either}; +use futures_util::StreamExt; +use tokio::sync::mpsc; +use tokio::time::interval; +use crate::controllers::server::{ChatServerHandle, ConnId}; +/// How often heartbeat pings are sent const HEARTBEAT_INTERVAL: Duration = Duration::from_secs(5); + +/// How long before lack of client response causes a timeout const CLIENT_TIMEOUT: Duration = Duration::from_secs(10); -#[derive(Clone)] -pub struct WsConn { - hb: Instant, - id: Uuid, - addr: Addr, -} +/// Echo text & binary messages received from the client, respond to ping messages, and monitor +/// connection health to detect network issues and free up resources. +pub async fn chat_ws( + chat_server: ChatServerHandle, + mut session: actix_ws::Session, + msg_stream: actix_ws::MessageStream, +) { + log::info!("connected"); -impl WsConn { - pub fn new(addr: Addr) -> Self { - Self { - hb: Instant::now(), - id: Uuid::new_v4(), - addr, - } - } + let mut name = None; + let mut last_heartbeat = Instant::now(); + let mut interval = interval(HEARTBEAT_INTERVAL); - // This function will run on an interval, every 5 seconds to check - // that the connection is still alive. If it's been more than - // 10 seconds since the last ping, we'll close the connection. - fn hb(&self, ctx: &mut ::Context) { - ctx.run_interval(HEARTBEAT_INTERVAL, |act, ctx| { - if Instant::now().duration_since(act.hb) > CLIENT_TIMEOUT { - ctx.stop(); - return; - } + let (conn_tx, mut conn_rx) = mpsc::unbounded_channel(); - ctx.ping(b""); - }); - } -} + // unwrap: chat server is not dropped before the HTTP server + let conn_id = chat_server.connect(conn_tx).await; -impl Actor for WsConn { - type Context = ws::WebsocketContext; - - // Start the heartbeat process for this connection - fn started(&mut self, ctx: &mut Self::Context) { - self.hb(ctx); - - let addr = ctx.address(); - self.addr - .send(Connect { - addr: addr.recipient(), - self_id: self.id, - }) - .into_actor(self) - .then(|res, _, ctx| { - match res { - Ok(_res) => (), - _ => ctx.stop(), - } - fut::ready(()) - }) - .wait(ctx); - } + let msg_stream = msg_stream + .max_frame_size(128 * 1024) + .aggregate_continuations() + .max_continuation_size(2 * 1024 * 1024); - fn stopping(&mut self, _: &mut Self::Context) -> Running { - self.addr.do_send(Disconnect { id: self.id }); - Running::Stop - } -} + let mut msg_stream = pin!(msg_stream); + + let close_reason = loop { + // most of the futures we process need to be stack-pinned to work with select() + + let tick = pin!(interval.tick()); + let msg_rx = pin!(conn_rx.recv()); + + // TODO: nested select is pretty gross for readability on the match + let messages = pin!(select(msg_stream.next(), msg_rx)); + + match select(messages, tick).await { + // commands & messages received from client + Either::Left((Either::Left((Some(Ok(msg)), _)), _)) => { + log::debug!("msg: {msg:?}"); + + match msg { + AggregatedMessage::Ping(bytes) => { + last_heartbeat = Instant::now(); + // unwrap: + session.pong(&bytes).await.unwrap(); + } + + AggregatedMessage::Pong(_) => { + last_heartbeat = Instant::now(); + } + + AggregatedMessage::Text(text) => { + process_text_msg(&chat_server, &mut session, &text, conn_id, &mut name) + .await; + } -// The `StreamHandler` trait is used to handle the messages that are sent over the socket. -impl StreamHandler> for WsConn { - // The `handle()` function is where we'll determine the response - // to the client's messages. So, for example, if we ping the client, - // it should respond with a pong. These two messages are necessary - // for the `hb()` function to maintain the connection status. - fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { - match msg { - // Ping/Pong will be used to make sure the connection is still alive - Ok(Message::Ping(msg)) => { - self.hb = Instant::now(); - ctx.pong(&msg); + AggregatedMessage::Binary(_bin) => { + log::warn!("unexpected binary message"); + } + + AggregatedMessage::Close(reason) => break reason, + } } - Ok(Message::Pong(_)) => { - self.hb = Instant::now(); + + // client WebSocket stream error + Either::Left((Either::Left((Some(Err(err)), _)), _)) => { + log::error!("{}", err); + break None; } - // Text will echo any text received back to the client (for now) - Ok(Text(text)) => ctx.text(text), - // Close will close the socket - Ok(Message::Close(reason)) => { - ctx.close(reason); - ctx.stop(); + + // client WebSocket stream ended + Either::Left((Either::Left((None, _)), _)) => break None, + + // chat messages received from other room participants + Either::Left((Either::Right((Some(chat_msg), _)), _)) => { + session.text(chat_msg).await.unwrap(); } - _ => ctx.stop(), - } - } + + // all connection's message senders were dropped + Either::Left((Either::Right((None, _)), _)) => unreachable!( + "all connection message senders were dropped; chat server may have panicked" + ), + + // heartbeat internal tick + Either::Right((_inst, _)) => { + // if no heartbeat ping/pong received recently, close the connection + if Instant::now().duration_since(last_heartbeat) > CLIENT_TIMEOUT { + log::info!( + "client has not sent heartbeat in over {CLIENT_TIMEOUT:?}; disconnecting" + ); + break None; + } + + // send heartbeat ping + let _ = session.ping(b"").await; + } + }; + }; + + chat_server.disconnect(conn_id); + + // attempt to close connection gracefully + let _ = session.close(close_reason).await; } -impl Handler for WsConn { - type Result = (); +async fn process_text_msg( + chat_server: &ChatServerHandle, + session: &mut actix_ws::Session, + text: &str, + conn: ConnId, + name: &mut Option, +) { + // strip leading and trailing whitespace (spaces, newlines, etc.) + let msg = text.trim(); - fn handle(&mut self, msg: WsMessage, ctx: &mut Self::Context) { - ctx.text(msg.0); + // we check for / type of messages + if msg.starts_with('/') { + let mut cmd_args = msg.splitn(2, ' '); + + // unwrap: we have guaranteed non-zero string length already + cmd_args.next().unwrap(); + { + session + .text(format!("!!! unknown command: {msg}")) + .await + .unwrap(); + } + + } else { + // prefix message with our name, if assigned + let msg = match name { + Some(ref name) => format!("{name}: {msg}"), + None => msg.to_owned(), + }; + + chat_server.send_message(conn, msg).await } -} +} \ No newline at end of file diff --git a/src/controllers/websocket_controller.rs b/src/controllers/websocket_controller.rs index 5841f0a9..5c3e199a 100644 --- a/src/controllers/websocket_controller.rs +++ b/src/controllers/websocket_controller.rs @@ -1,18 +1,15 @@ -use crate::controllers::web_socket::WsConn; +use crate::controllers::web_socket::{chat_ws}; use std::ops::DerefMut; use crate::models::podcast_episode::PodcastEpisode; use crate::models::podcasts::Podcast; -use crate::models::web_socket_message::Lobby; use crate::service::environment_service::EnvironmentService; use crate::service::podcast_episode_service::PodcastEpisodeService; use crate::utils::error::{map_r2d2_error, CustomError}; use crate::DbPool; -use actix::Addr; use actix_web::web::Query; -use actix_web::{get, web, web::Data, web::Payload, Error, HttpRequest, HttpResponse}; -use actix_web_actors::ws; +use actix_web::{get, web, web::Data, Error, HttpRequest, HttpResponse}; use rss::extension::itunes::{ ITunesCategory, ITunesCategoryBuilder, ITunesChannelExtension, ITunesChannelExtensionBuilder, ITunesItemExtensionBuilder, ITunesOwner, ITunesOwnerBuilder, @@ -21,8 +18,9 @@ use rss::{ Category, CategoryBuilder, Channel, ChannelBuilder, EnclosureBuilder, GuidBuilder, Item, ItemBuilder, }; - +use tokio::task::spawn_local; use crate::constants::inner_constants::ENVIRONMENT_SERVICE; +use crate::controllers::server::ChatServerHandle; use crate::models::user::User; #[utoipa::path( @@ -33,12 +31,19 @@ responses( #[get("/ws")] pub async fn start_connection( req: HttpRequest, - stream: Payload, - lobby: Data>, + body: web::Payload, + chat_server: web::Data, ) -> Result { - let ws = WsConn::new(lobby.get_ref().clone()); - let resp = ws::start(ws, &req, stream)?; - Ok(resp) + let (res, session, msg_stream) = actix_ws::handle(&req, body)?; + + // spawn websocket handler (and don't await it) so that the response is returned immediately + spawn_local(chat_ws( + (**chat_server).clone(), + session, + msg_stream, + )); + + Ok(res) } #[derive(Deserialize, Serialize)] diff --git a/src/main.rs b/src/main.rs index 7aadf4d9..ccfcaa81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,7 +5,6 @@ extern crate serde_derive; extern crate core; extern crate serde_json; -use actix::Actor; use actix_files::{Files, NamedFile}; use actix_web::dev::{fn_service, ServiceFactory, ServiceRequest, ServiceResponse}; use actix_web::middleware::{Condition, Logger}; @@ -29,6 +28,7 @@ use r2d2::Pool; use regex::Regex; use std::process::exit; use tokio::task::spawn_blocking; +use tokio::{spawn, try_join}; use utoipa::OpenApi; use utoipa_swagger_ui::SwaggerUi; @@ -66,6 +66,7 @@ use crate::controllers::websocket_controller::{ }; use crate::dbconfig::DBType; pub use controllers::controller_utils::*; +use crate::controllers::server::ChatServer; mod constants; mod db; @@ -78,7 +79,6 @@ use crate::models::podcasts::Podcast; use crate::models::session::Session; use crate::models::settings::Setting; -use crate::models::web_socket_message::Lobby; use crate::service::environment_service::EnvironmentService; use crate::service::file_service::FileService; use crate::service::logging_service::init_logging; @@ -196,9 +196,10 @@ async fn main() -> std::io::Result<()> { let file_service = FileService::new_db(); let notification_service = NotificationService::new(); let settings_service = SettingsService::new(); - let lobby = Lobby::default(); - let chat_server = lobby.start(); + let (chat_server, server_tx) = ChatServer::new(); + + let chat_server = spawn(chat_server.run()); EnvironmentService::print_banner(); match FileService::create_podcast_root_directory_exists() { @@ -336,15 +337,16 @@ async fn main() -> std::io::Result<()> { hash.insert(oidc_config.client_id); } - HttpServer::new(move || { + + let http_server = HttpServer::new(move || { App::new() + .app_data(Data::new(server_tx.clone())) .app_data(Data::new(key_param.clone())) .app_data(Data::new(jwk.clone())) .app_data(Data::new(hash.clone())) .service(redirect("/", var("SUB_DIRECTORY").unwrap() + "/ui/")) .service(get_gpodder_api()) .service(get_global_scope()) - .app_data(Data::new(chat_server.clone())) .app_data(Data::new(Mutex::new(podcast_service.clone()))) .app_data(Data::new(Mutex::new(file_service.clone()))) .app_data(Data::new(Mutex::new(notification_service.clone()))) @@ -354,8 +356,9 @@ async fn main() -> std::io::Result<()> { }) .workers(4) .bind(("0.0.0.0", 8000))? - .run() - .await + .run(); + try_join!(http_server, async move { chat_server.await.unwrap() })?; + Ok(()) } pub fn get_api_config() -> Scope { diff --git a/src/models/messages.rs b/src/models/messages.rs index 0652e5c6..ac498f2e 100644 --- a/src/models/messages.rs +++ b/src/models/messages.rs @@ -2,22 +2,8 @@ use crate::constants::inner_constants::PodcastType; use crate::models::podcast_episode::PodcastEpisode; use crate::models::podcasts::Podcast; -use actix::prelude::{Message, Recipient}; -use uuid::Uuid; -#[derive(Message)] -#[rtype(result = "()")] -pub struct WsMessage(pub String); - -#[derive(Message)] -#[rtype(result = "()")] -pub struct Connect { - pub addr: Recipient, - pub self_id: Uuid, -} - -#[derive(Message, Serialize, Deserialize)] -#[rtype(result = "()")] +#[derive(Serialize, Deserialize)] pub struct BroadcastMessage { pub type_of: PodcastType, pub message: String, @@ -25,8 +11,3 @@ pub struct BroadcastMessage { pub podcast_episodes: Option>, pub podcast_episode: Option, } -#[derive(Message)] -#[rtype(result = "()")] -pub struct Disconnect { - pub id: Uuid, -} diff --git a/src/models/mod.rs b/src/models/mod.rs index 8b6b6657..7e24ae80 100644 --- a/src/models/mod.rs +++ b/src/models/mod.rs @@ -25,6 +25,5 @@ pub mod settings; pub mod subscription; pub mod subscription_changes_from_client; pub mod user; -pub mod web_socket_message; pub mod podcast_settings; pub mod gpodder_available_podcasts; diff --git a/src/models/web_socket_message.rs b/src/models/web_socket_message.rs deleted file mode 100644 index 7ea082f8..00000000 --- a/src/models/web_socket_message.rs +++ /dev/null @@ -1,48 +0,0 @@ -use crate::models::messages::{BroadcastMessage, Connect, Disconnect, WsMessage}; -use actix::prelude::{Recipient}; -use actix::{Actor, Context, Handler}; -use serde_json::json; -use std::collections::HashMap; -use uuid::Uuid; - -type Socket = Recipient; - -#[derive(Default)] -pub struct Lobby { - sessions: HashMap, -} - -impl Handler for Lobby { - type Result = (); - - fn handle(&mut self, msg: BroadcastMessage, _: &mut Context) { - self.sessions.clone().into_values().for_each(|socket| { - log::debug!("Sending message to socket: {}", msg.message); - socket.do_send(WsMessage(json!(msg).to_string())); - }); - } -} - -impl Actor for Lobby { - type Context = Context; -} - -impl Handler for Lobby { - type Result = (); - - fn handle(&mut self, msg: Disconnect, _: &mut Context) { - if self.sessions.remove(&msg.id).is_some() { - self.sessions.clone().into_values().for_each(|_| { - log::debug!("Disconnected web client"); - }); - } - } -} - -impl Handler for Lobby { - type Result = (); - - fn handle(&mut self, msg: Connect, _: &mut Context) -> Self::Result { - self.sessions.insert(msg.self_id, msg.addr); - } -} diff --git a/src/service/podcast_episode_service.rs b/src/service/podcast_episode_service.rs index bb8543ef..7231c146 100644 --- a/src/service/podcast_episode_service.rs +++ b/src/service/podcast_episode_service.rs @@ -1,11 +1,7 @@ -use crate::constants::inner_constants::{ - PodcastType, COMMON_USER_AGENT, DEFAULT_IMAGE_URL, ENVIRONMENT_SERVICE, ITUNES, - TELEGRAM_API_ENABLED, -}; +use crate::constants::inner_constants::{PodcastType, COMMON_USER_AGENT, DEFAULT_IMAGE_URL, ENVIRONMENT_SERVICE, ITUNES, MAIN_ROOM, TELEGRAM_API_ENABLED}; use crate::models::messages::BroadcastMessage; use crate::models::podcast_episode::PodcastEpisode; use crate::models::podcasts::Podcast; -use crate::models::web_socket_message::Lobby; use crate::service::download_service::DownloadService; use crate::service::file_service::FileService; use crate::service::mapping_service::MappingService; @@ -13,8 +9,6 @@ use std::io::Error; use std::sync::{Arc, Mutex}; use crate::utils::podcast_builder::PodcastBuilder; -use actix::Addr; - use actix_web::web; use diesel::{ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl}; use log::error; @@ -22,7 +16,7 @@ use regex::Regex; use reqwest::header::{HeaderMap, ACCEPT}; use reqwest::redirect::Policy; use rss::{Channel, Item}; - +use crate::controllers::server::ChatServerHandle; use crate::models::episode::Episode; use crate::models::notification::Notification; use crate::models::user::User; @@ -42,7 +36,7 @@ impl PodcastEpisodeService { pub fn download_podcast_episode_if_not_locally_available( podcast_episode: PodcastEpisode, podcast: Podcast, - lobby: Option>>, + lobby: Option>, conn: &mut DbConnection, ) -> Result<(), CustomError> { let podcast_episode_cloned = podcast_episode.clone(); @@ -55,7 +49,7 @@ impl PodcastEpisodeService { Self::perform_download(&podcast_episode_cloned, podcast_cloned, conn)?; let mapped_dto = MappingService::map_podcastepisode_to_dto(&podcast_inserted); if let Some(lobby) = lobby { - lobby.do_send(BroadcastMessage { + lobby.send_broadcast_sync(MAIN_ROOM.parse().unwrap(), serde_json::to_string(&BroadcastMessage { message: format!( "Episode {} is now available offline", podcast_episode.name @@ -64,7 +58,7 @@ impl PodcastEpisodeService { type_of: PodcastType::AddPodcastEpisode, podcast_episode: Some(mapped_dto), podcast_episodes: None, - }) + }).unwrap()); } if is_env_var_present_and_true(TELEGRAM_API_ENABLED) { diff --git a/src/service/rust_service.rs b/src/service/rust_service.rs index 63b08f4a..a0cbde15 100644 --- a/src/service/rust_service.rs +++ b/src/service/rust_service.rs @@ -1,18 +1,14 @@ -use crate::constants::inner_constants::{ - PodcastType, COMMON_USER_AGENT, ENVIRONMENT_SERVICE, ITUNES_URL, -}; +use crate::constants::inner_constants::{PodcastType, COMMON_USER_AGENT, ENVIRONMENT_SERVICE, ITUNES_URL, MAIN_ROOM}; use crate::models::podcast_dto::PodcastDto; use crate::models::podcasts::Podcast; use crate::models::messages::BroadcastMessage; use crate::models::misc_models::PodcastInsertModel; -use crate::models::web_socket_message::Lobby; use crate::service::file_service::FileService; use crate::service::mapping_service::MappingService; use crate::service::podcast_episode_service::PodcastEpisodeService; use crate::unwrap_string; -use actix::Addr; use actix_web::web::Data; use reqwest::header::{HeaderMap, HeaderValue}; use rss::Channel; @@ -23,7 +19,7 @@ use reqwest::Client; use crate::config::dbconfig::establish_connection; use serde::Serialize; use tokio::task::spawn_blocking; - +use crate::controllers::server::ChatServerHandle; use crate::models::favorites::Favorite; use crate::models::order_criteria::{OrderCriteria, OrderOption}; use crate::models::settings::Setting; @@ -95,7 +91,7 @@ impl PodcastService { &mut self, conn: &mut DbConnection, id: i32, - lobby: Data>, + lobby: Data, ) -> Result { let resp = self .client @@ -130,7 +126,7 @@ impl PodcastService { &mut self, conn: &mut DbConnection, podcast_insert: PodcastInsertModel, - lobby: Data>, + lobby: Data, channel: Option, ) -> Result { let opt_podcast = Podcast::find_by_rss_feed_url(conn, &podcast_insert.feed_url.clone()); @@ -165,8 +161,7 @@ impl PodcastService { .await; let podcast = Podcast::get_podcast_by_track_id(conn, podcast_insert.id).unwrap(); lobby - .get_ref() - .send(BroadcastMessage { + .send_broadcast(MAIN_ROOM.parse().unwrap(), serde_json::to_string(&BroadcastMessage { podcast_episode: None, type_of: PodcastType::AddPodcast, message: format!("Added podcast: {}", inserted_podcast.name), @@ -174,9 +169,7 @@ impl PodcastService { &podcast.clone().unwrap(), )), podcast_episodes: None, - }) - .await - .unwrap(); + }).unwrap()).await; match podcast { Some(podcast) => { spawn_blocking(move || { @@ -188,13 +181,14 @@ impl PodcastService { PodcastEpisodeService::insert_podcast_episodes(&mut conn, podcast.clone()) .unwrap(); - lobby.get_ref().do_send(BroadcastMessage { + lobby.send_broadcast_sync(MAIN_ROOM.parse().unwrap(), serde_json::to_string + (&BroadcastMessage { podcast_episode: None, type_of: PodcastType::AddPodcastEpisodes, message: format!("Added podcast episodes: {}", podcast.name), podcast: Option::from(podcast.clone()), podcast_episodes: Option::from(inserted_podcasts), - }); + }).unwrap()); if let Err(e) = podcast_service.schedule_episode_download(podcast, Some(lobby), &mut conn) { @@ -214,7 +208,7 @@ impl PodcastService { pub fn schedule_episode_download( &mut self, podcast: Podcast, - lobby: Option>>, + lobby: Option>, conn: &mut DbConnection, ) -> Result<(), CustomError> { let settings = Setting::get_settings(conn)?; @@ -250,7 +244,7 @@ impl PodcastService { pub fn refresh_podcast( &mut self, podcast: Podcast, - lobby: Data>, + lobby: Data, conn: &mut DbConnection, ) -> Result<(), CustomError> { log::info!("Refreshing podcast: {}", podcast.name); diff --git a/ui/src/App.tsx b/ui/src/App.tsx index fee058a3..a8923460 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -191,9 +191,11 @@ const App: FC = ({ children }) => { } }, [podcasts, socket, config]) + let ws: WebSocket useEffect(() => { - if (config) { - setSocket(new WebSocket(configWSUrl(config?.serverUrl!))) + if (config && !ws) { + ws = new WebSocket(configWSUrl(config?.serverUrl!)) + setSocket(ws) } }, [config])