From cc318536167f928a381f97f5abd207b091987d73 Mon Sep 17 00:00:00 2001 From: Ryan Phillips Date: Thu, 6 Mar 2025 03:04:49 -0600 Subject: [PATCH 1/8] bump deps and set rust edition to 2024 (#29) * bump deps and set rust edition to 2024 bump deps and bump to 2.3.2 release version * cargo fmt * update actions --- .github/workflows/rust.yml | 8 +- Cargo.lock | 1826 ++++++++++++++++++++++++------------ Cargo.toml | 8 +- src/lib/browser.rs | 6 +- src/lib/config.rs | 8 +- src/main.rs | 3 +- 6 files changed, 1255 insertions(+), 604 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 5bc4cde..826491c 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -47,7 +47,7 @@ jobs: - name: Build release run: cargo build --release --verbose - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: stable-cargo-build with: path: | @@ -63,7 +63,7 @@ jobs: needs: ['stable-build'] steps: - name: Restore cache - uses: actions/cache@v2 + uses: actions/cache@v4 id: stable-cargo-build with: path: | @@ -109,7 +109,7 @@ jobs: - name: Build release run: cargo build --release --verbose - - uses: actions/cache@v2 + - uses: actions/cache@v4 id: nightly-cargo-build with: path: | @@ -125,7 +125,7 @@ jobs: needs: ['nightly-build'] steps: - name: Restore cache - uses: actions/cache@v2 + uses: actions/cache@v4 id: nightly-cargo-build with: path: | diff --git a/Cargo.lock b/Cargo.lock index f06d653..587ec6d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,27 +1,27 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" -version = "0.21.0" +version = "0.24.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" dependencies = [ "gimli", ] [[package]] -name = "adler" -version = "1.0.2" +name = "adler2" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" [[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", ] @@ -41,6 +41,56 @@ dependencies = [ "libc", ] +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + [[package]] name = "async-attributes" version = "1.1.2" @@ -64,12 +114,11 @@ dependencies = [ [[package]] name = "async-channel" -version = "2.1.1" +version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ca33f4bc4ed1babef42cad36cc1f51fa88be00420404e5b1e80ab1b18f7678c" +checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" dependencies = [ "concurrent-queue", - "event-listener 4.0.2", "event-listener-strategy", "futures-core", "pin-project-lite", @@ -77,15 +126,14 @@ dependencies = [ [[package]] name = "async-executor" -version = "1.8.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17ae5ebefcc48e7452b4987947920dac9450be1110cadf34d1b8c116bdbaf97c" +checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" dependencies = [ - "async-lock 3.2.0", "async-task", "concurrent-queue", - "fastrand 2.0.1", - "futures-lite 2.1.0", + "fastrand", + "futures-lite", "slab", ] @@ -95,127 +143,100 @@ version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" dependencies = [ - "async-channel 2.1.1", + "async-channel 2.3.1", "async-executor", - "async-io 2.2.2", - "async-lock 3.2.0", + "async-io", + "async-lock", "blocking", - "futures-lite 2.1.0", + "futures-lite", "once_cell", "tokio", ] [[package]] name = "async-io" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fc5b45d93ef0529756f812ca52e44c221b35341892d3dcc34132ac02f3dd2af" -dependencies = [ - "async-lock 2.8.0", - "autocfg", - "cfg-if", - "concurrent-queue", - "futures-lite 1.13.0", - "log", - "parking", - "polling 2.8.0", - "rustix 0.37.27", - "slab", - "socket2 0.4.10", - "waker-fn", -] - -[[package]] -name = "async-io" -version = "2.2.2" +version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6afaa937395a620e33dc6a742c593c01aced20aa376ffb0f628121198578ccc7" +checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" dependencies = [ - "async-lock 3.2.0", + "async-lock", "cfg-if", "concurrent-queue", "futures-io", - "futures-lite 2.1.0", + "futures-lite", "parking", - "polling 3.3.1", - "rustix 0.38.28", + "polling", + "rustix", "slab", "tracing", - "windows-sys 0.52.0", -] - -[[package]] -name = "async-lock" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" -dependencies = [ - "event-listener 2.5.3", + "windows-sys 0.59.0", ] [[package]] name = "async-lock" -version = "3.2.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7125e42787d53db9dd54261812ef17e937c95a51e4d291373b670342fa44310c" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" dependencies = [ - "event-listener 4.0.2", + "event-listener 5.4.0", "event-listener-strategy", "pin-project-lite", ] [[package]] name = "async-process" -version = "1.8.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea6438ba0a08d81529c69b36700fa2f95837bfe3e776ab39cde9c14d9149da88" +checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" dependencies = [ - "async-io 1.13.0", - "async-lock 2.8.0", + "async-channel 2.3.1", + "async-io", + "async-lock", "async-signal", + "async-task", "blocking", "cfg-if", - "event-listener 3.1.0", - "futures-lite 1.13.0", - "rustix 0.38.28", - "windows-sys 0.48.0", + "event-listener 5.4.0", + "futures-lite", + "rustix", + "tracing", ] [[package]] name = "async-signal" -version = "0.2.5" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e47d90f65a225c4527103a8d747001fc56e375203592b25ad103e1ca13124c5" +checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" dependencies = [ - "async-io 2.2.2", - "async-lock 2.8.0", + "async-io", + "async-lock", "atomic-waker", "cfg-if", "futures-core", "futures-io", - "rustix 0.38.28", + "rustix", "signal-hook-registry", "slab", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "async-std" -version = "1.12.0" +version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d" +checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" dependencies = [ "async-attributes", "async-channel 1.9.0", "async-global-executor", - "async-io 1.13.0", - "async-lock 2.8.0", + "async-io", + "async-lock", "async-process", "crossbeam-utils", "futures-channel", "futures-core", "futures-io", - "futures-lite 1.13.0", + "futures-lite", "gloo-timers", "kv-log-macro", "log", @@ -229,9 +250,9 @@ dependencies = [ [[package]] name = "async-std-resolver" -version = "0.24.0" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c0ed2b6671c13d2c28756c5a64e04759c1e0b5d3d7ac031f521c3561e21fbcb" +checksum = "b766684a183c8a439f2ca24d6973cf8bfdc1353ae9c54b2b91e81d2630dd034e" dependencies = [ "async-std", "async-trait", @@ -239,24 +260,24 @@ dependencies = [ "futures-util", "hickory-resolver", "pin-utils", - "socket2 0.5.5", + "socket2", ] [[package]] name = "async-task" -version = "4.6.0" +version = "4.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1d90cd0b264dfdd8eb5bad0a2c217c1f88fa96a8573f40e7b12de23fb468f46" +checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" [[package]] name = "async-trait" -version = "0.1.77" +version = "0.1.87" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", ] [[package]] @@ -278,30 +299,36 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.1.0" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "backtrace" -version = "0.3.69" +version = "0.3.74" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" dependencies = [ "addr2line", - "cc", "cfg-if", "libc", "miniz_oxide", "object", "rustc-demangle", + "windows-targets 0.52.6", ] [[package]] name = "base64" -version = "0.21.5" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "bitflags" @@ -311,45 +338,48 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bitflags" -version = "2.4.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "327762f6e5a765692301e5bb513e0d9fef63be86bbc14528052b1cd3e6f03e07" +checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" [[package]] name = "blocking" -version = "1.5.1" +version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118" +checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" dependencies = [ - "async-channel 2.1.1", - "async-lock 3.2.0", + "async-channel 2.3.1", "async-task", - "fastrand 2.0.1", "futures-io", - "futures-lite 2.1.0", + "futures-lite", "piper", - "tracing", ] [[package]] name = "bumpalo" -version = "3.14.0" +version = "3.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" [[package]] -name = "bytes" +name = "byteorder" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.0.83" +version = "1.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" dependencies = [ - "libc", + "shlex", ] [[package]] @@ -360,9 +390,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.31" +version = "0.4.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" +checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" dependencies = [ "android-tzdata", "iana-time-zone", @@ -370,7 +400,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.48.5", + "windows-link", ] [[package]] @@ -390,9 +420,9 @@ dependencies = [ [[package]] name = "clap-verbosity-flag" -version = "2.1.1" +version = "3.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c90e95e5bd4e8ac34fa6f37c774b0c6f8ed06ea90c79931fd448fcf941a9767" +checksum = "2678fade3b77aa3a8ff3aae87e9c008d3fb00473a41c71fbf74e91c8c7b37e84" dependencies = [ "clap", "log", @@ -404,7 +434,7 @@ version = "4.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "92289ffc6fb4a85d85c246ddb874c05a87a2e540fb6ad52f7ca07c8c1e1840b1" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-error", "proc-macro2", "quote", @@ -420,21 +450,26 @@ dependencies = [ "os_str_bytes", ] +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + [[package]] name = "colored" -version = "2.1.0" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" dependencies = [ - "lazy_static", - "windows-sys 0.48.0", + "windows-sys 0.59.0", ] [[package]] name = "concurrent-queue" -version = "2.4.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16048cd947b08fa32c24458a22f5dc5e835264f689f4f5653210c69fd107363" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" dependencies = [ "crossbeam-utils", ] @@ -451,18 +486,15 @@ 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 = "crossbeam-utils" -version = "0.8.18" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a430a770ebd84726f584a90ee7f020d28db52c6d02138900f22341f866d39c" -dependencies = [ - "cfg-if", -] +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "crossterm" @@ -473,7 +505,7 @@ dependencies = [ "bitflags 1.3.2", "crossterm_winapi", "libc", - "mio", + "mio 0.8.11", "parking_lot", "signal-hook", "signal-hook-mio", @@ -491,64 +523,85 @@ dependencies = [ [[package]] name = "data-encoding" -version = "2.5.0" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" + +[[package]] +name = "displaydoc" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] [[package]] name = "dyn-clone" -version = "1.0.16" +version = "1.0.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" +checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" [[package]] name = "encoding_rs" -version = "0.8.33" +version = "0.8.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" dependencies = [ "cfg-if", ] [[package]] name = "enum-as-inner" -version = "0.6.0" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" dependencies = [ - "heck", + "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", +] + +[[package]] +name = "env_filter" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +dependencies = [ + "log", + "regex", ] [[package]] name = "env_logger" -version = "0.10.1" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95b3f3e67048839cb0d0781f445682a35113da7121f7c949db0e2be96a4fbece" +checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" dependencies = [ + "anstream", + "anstyle", + "env_filter", "humantime", - "is-terminal", "log", - "regex", - "termcolor", ] [[package]] name = "equivalent" -version = "1.0.1" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" [[package]] name = "errno" -version = "0.3.8" +version = "0.3.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -559,20 +612,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "event-listener" -version = "3.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2" -dependencies = [ - "concurrent-queue", - "parking", - "pin-project-lite", -] - -[[package]] -name = "event-listener" -version = "4.0.2" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "218a870470cce1469024e9fb66b901aa983929d81304a1cdb299f28118e550d5" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -581,28 +623,19 @@ dependencies = [ [[package]] name = "event-listener-strategy" -version = "0.4.0" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "958e4d70b6d5e81971bebec42271ec641e7ff4e170a6fa605f2b8a8b65cb97d3" +checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" dependencies = [ - "event-listener 4.0.2", + "event-listener 5.4.0", "pin-project-lite", ] [[package]] name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - -[[package]] -name = "fastrand" -version = "2.0.1" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" [[package]] name = "fnv" @@ -636,47 +669,33 @@ dependencies = [ [[package]] name = "futures-channel" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", + "futures-sink", ] [[package]] name = "futures-core" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" [[package]] name = "futures-io" -version = "0.3.30" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" - -[[package]] -name = "futures-lite" -version = "1.13.0" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" -dependencies = [ - "fastrand 1.9.0", - "futures-core", - "futures-io", - "memchr", - "parking", - "pin-project-lite", - "waker-fn", -] +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" [[package]] name = "futures-lite" -version = "2.1.0" +version = "2.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aeee267a1883f7ebef3700f262d2d54de95dfaf38189015a74fdc4e0c7ad8143" +checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" dependencies = [ - "fastrand 2.0.1", + "fastrand", "futures-core", "futures-io", "parking", @@ -685,24 +704,25 @@ dependencies = [ [[package]] name = "futures-sink" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" [[package]] name = "futures-task" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" [[package]] name = "futures-util" -version = "0.3.30" +version = "0.3.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", + "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -710,28 +730,58 @@ dependencies = [ "slab", ] +[[package]] +name = "fuzzy-matcher" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" +dependencies = [ + "thread_local", +] + +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + +[[package]] +name = "getrandom" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", +] + [[package]] name = "getrandom" -version = "0.2.11" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f" +checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" dependencies = [ "cfg-if", "libc", - "wasi", + "wasi 0.13.3+wasi-0.2.2", + "windows-targets 0.52.6", ] [[package]] name = "gimli" -version = "0.28.1" +version = "0.31.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" [[package]] name = "gloo-timers" -version = "0.2.6" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" dependencies = [ "futures-channel", "futures-core", @@ -741,16 +791,35 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.22" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.12", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "h2" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.2.0", "indexmap", "slab", "tokio", @@ -760,9 +829,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.14.3" +version = "0.15.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" [[package]] name = "heck" @@ -770,6 +839,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -781,15 +856,15 @@ dependencies = [ [[package]] name = "hermit-abi" -version = "0.3.3" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" [[package]] name = "hickory-proto" -version = "0.24.0" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "091a6fbccf4860009355e3efc52ff4acf37a63489aad7435372d44ceeb6fbbcf" +checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" dependencies = [ "async-trait", "cfg-if", @@ -798,7 +873,7 @@ dependencies = [ "futures-channel", "futures-io", "futures-util", - "idna 0.4.0", + "idna", "ipnet", "once_cell", "rand", @@ -810,9 +885,9 @@ dependencies = [ [[package]] name = "hickory-resolver" -version = "0.24.0" +version = "0.24.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8" +checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" dependencies = [ "cfg-if", "futures-util", @@ -841,9 +916,20 @@ 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", + "itoa", +] + +[[package]] +name = "http" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" dependencies = [ "bytes", "fnv", @@ -857,15 +943,38 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http", + "http 0.2.12", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.2.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", "pin-project-lite", ] [[package]] name = "httparse" -version = "1.8.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "httpdate" @@ -881,22 +990,22 @@ checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" [[package]] name = "hyper" -version = "0.14.28" +version = "0.14.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" dependencies = [ "bytes", "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", "httparse", "httpdate", "itoa", "pin-project-lite", - "socket2 0.5.5", + "socket2", "tokio", "tower-service", "tracing", @@ -904,105 +1013,277 @@ dependencies = [ ] [[package]] -name = "hyper-tls" -version = "0.5.0" +name = "hyper" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" dependencies = [ "bytes", - "hyper", - "native-tls", + "futures-channel", + "futures-util", + "h2 0.4.8", + "http 1.2.0", + "http-body 1.0.1", + "httparse", + "itoa", + "pin-project-lite", + "smallvec", "tokio", - "tokio-native-tls", + "want", ] [[package]] -name = "iana-time-zone" -version = "0.1.59" +name = "hyper-rustls" +version = "0.27.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core", + "futures-util", + "http 1.2.0", + "hyper 1.6.0", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", ] [[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" +name = "hyper-tls" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ - "cc", + "bytes", + "hyper 0.14.32", + "native-tls", + "tokio", + "tokio-native-tls", ] [[package]] -name = "idna" -version = "0.4.0" +name = "hyper-tls" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d20d6b07bfbc108882d88ed8e37d39636dcc260e15e30c45e6ba089610b917c" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "bytes", + "http-body-util", + "hyper 1.6.0", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", ] [[package]] -name = "idna" -version = "0.5.0" +name = "hyper-util" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" dependencies = [ - "unicode-bidi", - "unicode-normalization", + "bytes", + "futures-channel", + "futures-util", + "http 1.2.0", + "http-body 1.0.1", + "hyper 1.6.0", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", ] [[package]] -name = "indexmap" -version = "2.1.0" +name = "iana-time-zone" +version = "0.1.61" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" dependencies = [ - "equivalent", - "hashbrown", + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", ] [[package]] -name = "inquire" -version = "0.6.2" +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c33e7c1ddeb15c9abcbfef6029d8e29f69b52b6d6c891031b88ed91b5065803b" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" dependencies = [ - "bitflags 1.3.2", - "crossterm", - "dyn-clone", - "lazy_static", - "newline-converter", - "thiserror", - "unicode-segmentation", - "unicode-width", + "displaydoc", + "yoke", + "zerofrom", + "zerovec", ] [[package]] -name = "instant" -version = "0.1.12" +name = "icu_locid" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" dependencies = [ - "cfg-if", + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", ] [[package]] -name = "io-lifetimes" -version = "1.0.11" +name = "icu_locid_transform" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" dependencies = [ - "hermit-abi 0.3.3", - "libc", - "windows-sys 0.48.0", + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inquire" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" +dependencies = [ + "bitflags 2.9.0", + "crossterm", + "dyn-clone", + "fuzzy-matcher", + "fxhash", + "newline-converter", + "once_cell", + "unicode-segmentation", + "unicode-width", ] [[package]] @@ -1011,7 +1292,7 @@ version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" dependencies = [ - "socket2 0.5.5", + "socket2", "widestring", "windows-sys 0.48.0", "winreg", @@ -1019,33 +1300,29 @@ dependencies = [ [[package]] name = "ipnet" -version = "2.9.0" +version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" [[package]] -name = "is-terminal" -version = "0.4.10" +name = "is_terminal_polyfill" +version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bad00257d07be169d870ab665980b06cdb366d792ad690bf2e76876dc503455" -dependencies = [ - "hermit-abi 0.3.3", - "rustix 0.38.28", - "windows-sys 0.52.0", -] +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" [[package]] name = "itoa" -version = "1.0.10" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" [[package]] name = "js-sys" -version = "0.3.66" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cee9c64da59eae3b50095c18d3e74f8b73c0b86d2792824ff01bbce68ba229ca" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" dependencies = [ + "once_cell", "wasm-bindgen", ] @@ -1058,17 +1335,11 @@ dependencies = [ "log", ] -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" -version = "0.2.151" +version = "0.2.170" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "302d7ab3130588088d277783b1e2d2e10c9e9e4a16dd9050e6ec93fb3e7048f4" +checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" [[package]] name = "linked-hash-map" @@ -1078,21 +1349,21 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" [[package]] name = "linux-raw-sys" -version = "0.3.8" +version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" [[package]] -name = "linux-raw-sys" -version = "0.4.12" +name = "litemap" +version = "0.7.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c4cd1a83af159aa67994778be9070f0ae1bd732942279cabb14f86f986a21456" +checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" [[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", @@ -1100,9 +1371,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.20" +version = "0.4.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" dependencies = [ "value-bag", ] @@ -1124,9 +1395,9 @@ checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" [[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 = "mime" @@ -1136,32 +1407,42 @@ checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" dependencies = [ - "adler", + "adler2", ] [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.48.0", ] +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + [[package]] name = "native-tls" -version = "0.2.11" +version = "0.2.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" dependencies = [ - "lazy_static", "libc", "log", "openssl", @@ -1175,54 +1456,44 @@ dependencies = [ [[package]] name = "newline-converter" -version = "0.2.2" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f71d09d5c87634207f894c6b31b6a2b2c64ea3bdcf71bd5599fdbbe1600c00f" +checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" dependencies = [ "unicode-segmentation", ] [[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_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi 0.3.3", - "libc", -] - [[package]] name = "object" -version = "0.32.2" +version = "0.36.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" dependencies = [ "memchr", ] [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" [[package]] name = "openssl" -version = "0.10.62" +version = "0.10.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" dependencies = [ - "bitflags 2.4.1", + "bitflags 2.9.0", "cfg-if", "foreign-types", "libc", @@ -1239,20 +1510,20 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", ] [[package]] name = "openssl-probe" -version = "0.1.5" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" [[package]] name = "openssl-sys" -version = "0.9.98" +version = "0.9.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" dependencies = [ "cc", "libc", @@ -1268,15 +1539,15 @@ checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" [[package]] name = "parking" -version = "2.2.0" +version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb813b8af86854136c6922af0598d719255ecb2179515e6e7730d468f05c9cae" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" [[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", @@ -1284,15 +1555,15 @@ 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", "smallvec", - "windows-targets 0.48.5", + "windows-targets 0.52.6", ] [[package]] @@ -1303,9 +1574,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" [[package]] name = "pin-project-lite" -version = "0.2.13" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] name = "pin-utils" @@ -1315,56 +1586,44 @@ checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" [[package]] name = "piper" -version = "0.2.1" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "668d31b1c4eba19242f2088b2bf3316b82ca31082a8335764db4e083db7485d4" +checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" dependencies = [ "atomic-waker", - "fastrand 2.0.1", + "fastrand", "futures-io", ] [[package]] name = "pkg-config" -version = "0.3.28" +version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69d3587f8a9e599cc7ec2c00e331f71c4e69a5f9a4b8a6efd5b07466b9736f9a" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "polling" -version = "2.8.0" +version = "3.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b2d323e8ca7996b3e23126511a523f7e62924d93ecd5ae73b333815b0eb3dce" +checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" dependencies = [ - "autocfg", - "bitflags 1.3.2", "cfg-if", "concurrent-queue", - "libc", - "log", + "hermit-abi 0.4.0", "pin-project-lite", - "windows-sys 0.48.0", -] - -[[package]] -name = "polling" -version = "3.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf63fa624ab313c11656b4cda960bfc46c410187ad493c41f6ba2d8c1e991c9e" -dependencies = [ - "cfg-if", - "concurrent-queue", - "pin-project-lite", - "rustix 0.38.28", + "rustix", "tracing", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[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 = "proc-macro-error" @@ -1392,9 +1651,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.74" +version = "1.0.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2de98502f212cfcea8d0bb305bd0f49d7ebdd75b64ba0a68f937d888f4e0d6db" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" dependencies = [ "unicode-ident", ] @@ -1407,16 +1666,16 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.35" +version = "1.0.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" dependencies = [ "proc-macro2", ] [[package]] name = "radio-cli" -version = "2.3.1" +version = "2.4.0" dependencies = [ "clap", "clap-verbosity-flag", @@ -1425,7 +1684,7 @@ dependencies = [ "inquire", "log", "radiobrowser", - "reqwest", + "reqwest 0.12.12", "serde", "serde_json", "xdg", @@ -1442,7 +1701,7 @@ dependencies = [ "chrono", "log", "rand", - "reqwest", + "reqwest 0.11.27", "serde", ] @@ -1473,23 +1732,23 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", ] [[package]] name = "redox_syscall" -version = "0.4.1" +version = "0.5.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.0", ] [[package]] name = "regex" -version = "1.10.2" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -1499,9 +1758,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1510,26 +1769,26 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.2" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "reqwest" -version = "0.11.23" +version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64", + "base64 0.21.7", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", - "hyper-tls", + "h2 0.3.26", + "http 0.2.12", + "http-body 0.4.6", + "hyper 0.14.32", + "hyper-tls 0.5.0", "ipnet", "js-sys", "log", @@ -1538,10 +1797,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", + "rustls-pemfile 1.0.4", "serde", "serde_json", "serde_urlencoded", - "system-configuration", + "sync_wrapper 0.1.2", + "system-configuration 0.5.1", "tokio", "tokio-native-tls", "tower-service", @@ -1552,6 +1813,51 @@ dependencies = [ "winreg", ] +[[package]] +name = "reqwest" +version = "0.12.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" +dependencies = [ + "base64 0.22.1", + "bytes", + "encoding_rs", + "futures-channel", + "futures-core", + "futures-util", + "h2 0.4.8", + "http 1.2.0", + "http-body 1.0.1", + "http-body-util", + "hyper 1.6.0", + "hyper-rustls", + "hyper-tls 0.6.0", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls-pemfile 2.2.0", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper 1.0.2", + "system-configuration 0.6.1", + "tokio", + "tokio-native-tls", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "windows-registry", +] + [[package]] name = "resolv-conf" version = "0.7.0" @@ -1562,52 +1868,106 @@ dependencies = [ "quick-error", ] +[[package]] +name = "ring" +version = "0.17.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed9b823fa29b721a59671b41d6b06e66b29e0628e207e8b1c3ceeda701ec928d" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.15", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + [[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 = "rustix" -version = "0.37.27" +version = "0.38.44" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fea8ca367a3a01fe35e6943c400addf443c0f57670e6ec51196f71a4b8762dd2" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" dependencies = [ - "bitflags 1.3.2", + "bitflags 2.9.0", "errno", - "io-lifetimes", "libc", - "linux-raw-sys 0.3.8", - "windows-sys 0.48.0", + "linux-raw-sys", + "windows-sys 0.59.0", ] [[package]] -name = "rustix" -version = "0.38.28" +name = "rustls" +version = "0.23.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72e572a5e8ca657d7366229cdde4bd14c4eb5499a9573d4d366fe1b599daa316" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" dependencies = [ - "bitflags 2.4.1", - "errno", - "libc", - "linux-raw-sys 0.4.12", - "windows-sys 0.52.0", + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", ] +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" + [[package]] name = "ryu" -version = "1.0.16" +version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" [[package]] name = "schannel" -version = "0.1.23" +version = "0.1.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" dependencies = [ - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -1618,11 +1978,11 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[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.9.0", "core-foundation", "core-foundation-sys", "libc", @@ -1631,9 +1991,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -1641,31 +2001,32 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.194" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b114498256798c94a0689e1a15fec6005dee8ac1f41de56404b67afc2a4b773" +checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.194" +version = "1.0.218" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a3385e45322e8f9931410f01b3031ec534c3947d0e94c18049af4d9f9907d4e0" +checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", ] [[package]] name = "serde_json" -version = "1.0.110" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6fbd975230bada99c8bb618e0c365c2eefa219158d5c6c29610fd09ff1833257" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", + "memchr", "ryu", "serde", ] @@ -1682,6 +2043,12 @@ dependencies = [ "serde", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook" version = "0.3.17" @@ -1694,20 +2061,20 @@ dependencies = [ [[package]] name = "signal-hook-mio" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" dependencies = [ "libc", - "mio", + "mio 0.8.11", "signal-hook", ] [[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", ] @@ -1723,29 +2090,25 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" +checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" [[package]] name = "socket2" -version = "0.4.10" +version = "0.5.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f7916fc008ca5542385b89a3d3ce689953c143e9304a9bf8beec1de48994c0d" +checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" dependencies = [ "libc", - "winapi", + "windows-sys 0.52.0", ] [[package]] -name = "socket2" -version = "0.5.5" +name = "stable_deref_trait" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" -dependencies = [ - "libc", - "windows-sys 0.48.0", -] +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" [[package]] name = "strsim" @@ -1753,6 +2116,12 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + [[package]] name = "syn" version = "1.0.109" @@ -1766,15 +2135,41 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.46" +version = "2.0.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "89456b690ff72fddcecf231caedbe615c59480c93358a93dfae7fc29e3ebbf0e" +checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" dependencies = [ "proc-macro2", "quote", "unicode-ident", ] +[[package]] +name = "sync_wrapper" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -1783,7 +2178,18 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys", + "system-configuration-sys 0.5.0", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.9.0", + "core-foundation", + "system-configuration-sys 0.6.0", ] [[package]] @@ -1796,53 +2202,84 @@ dependencies = [ "libc", ] +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + [[package]] name = "tempfile" -version = "3.9.0" +version = "3.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" dependencies = [ "cfg-if", - "fastrand 2.0.1", - "redox_syscall", - "rustix 0.38.28", - "windows-sys 0.52.0", + "fastrand", + "getrandom 0.3.1", + "once_cell", + "rustix", + "windows-sys 0.59.0", ] [[package]] name = "termcolor" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff1bc3d3f05aff0403e8ac0d92ced918ec05b666a43f83297ccef5bea8a3d449" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" dependencies = [ "winapi-util", ] [[package]] name = "thiserror" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.56" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", ] [[package]] name = "tinyvec" -version = "1.6.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" dependencies = [ "tinyvec_macros", ] @@ -1855,18 +2292,17 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.35.1" +version = "1.43.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" dependencies = [ "backtrace", "bytes", "libc", - "mio", - "num_cpus", + "mio 1.0.3", "pin-project-lite", - "socket2 0.5.5", - "windows-sys 0.48.0", + "socket2", + "windows-sys 0.52.0", ] [[package]] @@ -1879,31 +2315,61 @@ dependencies = [ "tokio", ] +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + [[package]] name = "tokio-util" -version = "0.7.10" +version = "0.7.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" dependencies = [ "bytes", "futures-core", "futures-sink", "pin-project-lite", "tokio", - "tracing", ] +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 1.0.2", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +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" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -1912,20 +2378,20 @@ dependencies = [ [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", ] @@ -1936,55 +2402,64 @@ version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" -[[package]] -name = "unicode-bidi" -version = "0.3.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f2528f27a9eb2b21e69c95319b30bd0efd85d09c379741b0f78ea1d86be2416" - [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" [[package]] -name = "unicode-normalization" -version = "0.1.22" +name = "unicode-segmentation" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" -dependencies = [ - "tinyvec", -] +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] -name = "unicode-segmentation" -version = "1.10.1" +name = "unicode-width" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" [[package]] -name = "unicode-width" -version = "0.1.11" +name = "untrusted" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" [[package]] name = "url" -version = "2.5.0" +version = "2.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" dependencies = [ "form_urlencoded", - "idna 0.5.0", + "idna", "percent-encoding", ] +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + [[package]] name = "value-bag" -version = "1.4.2" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a72e1902dde2bd6441347de2b70b7f5d59bf157c6c62f0c44572607a1d55bbe" +checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" [[package]] name = "vcpkg" @@ -1994,15 +2469,9 @@ checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" [[package]] name = "version_check" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" - -[[package]] -name = "waker-fn" -version = "1.1.1" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3c4517f54858c779bbcbf228f4fca63d121bf85fbecb2dc578cdf4a39395690" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "want" @@ -2019,48 +2488,59 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.13.3+wasi-0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasm-bindgen" -version = "0.2.89" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ed0d4f68a3015cc185aff4db9506a015f4b96f95303897bfa23f846db54064e" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" dependencies = [ "cfg-if", + "once_cell", + "rustversion", "wasm-bindgen-macro", ] [[package]] name = "wasm-bindgen-backend" -version = "0.2.89" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b56f625e64f3a1084ded111c4d5f477df9f8c92df113852fa5a374dbda78826" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" dependencies = [ "bumpalo", "log", - "once_cell", "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-futures" -version = "0.4.39" +version = "0.4.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac36a15a220124ac510204aec1c3e5db8a22ab06fd6706d881dc6149f8ed9a12" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" dependencies = [ "cfg-if", "js-sys", + "once_cell", "wasm-bindgen", "web-sys", ] [[package]] name = "wasm-bindgen-macro" -version = "0.2.89" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0162dbf37223cd2afce98f3d0785506dcb8d266223983e4b5b525859e6e182b2" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -2068,28 +2548,31 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.89" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.46", + "syn 2.0.99", "wasm-bindgen-backend", "wasm-bindgen-shared", ] [[package]] name = "wasm-bindgen-shared" -version = "0.2.89" +version = "0.2.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] [[package]] name = "web-sys" -version = "0.3.66" +version = "0.3.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50c24a44ec86bb68fbecd1b3efed7e85ea5621b39b35ef2766b66cd984f8010f" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" dependencies = [ "js-sys", "wasm-bindgen", @@ -2097,9 +2580,9 @@ dependencies = [ [[package]] name = "widestring" -version = "1.0.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" [[package]] name = "winapi" @@ -2119,11 +2602,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]] @@ -2138,7 +2621,43 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" dependencies = [ - "windows-targets 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-link" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" + +[[package]] +name = "windows-registry" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" +dependencies = [ + "windows-result", + "windows-strings", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result", + "windows-targets 0.52.6", ] [[package]] @@ -2156,7 +2675,16 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.0", + "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]] @@ -2176,17 +2704,18 @@ dependencies = [ [[package]] name = "windows-targets" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.0", - "windows_aarch64_msvc 0.52.0", - "windows_i686_gnu 0.52.0", - "windows_i686_msvc 0.52.0", - "windows_x86_64_gnu 0.52.0", - "windows_x86_64_gnullvm 0.52.0", - "windows_x86_64_msvc 0.52.0", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] @@ -2197,9 +2726,9 @@ checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" @@ -2209,9 +2738,9 @@ checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" @@ -2221,9 +2750,15 @@ checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.0" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" @@ -2233,9 +2768,9 @@ checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" @@ -2245,9 +2780,9 @@ checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" @@ -2257,9 +2792,9 @@ checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" @@ -2269,9 +2804,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.0" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winreg" @@ -2283,8 +2818,123 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +dependencies = [ + "bitflags 2.9.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + [[package]] name = "xdg" version = "2.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", + "synstructure", +] + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.99", +] diff --git a/Cargo.toml b/Cargo.toml index e4b7749..95b6380 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,8 +2,8 @@ authors = ["Marcos Gutiérrez Alonso "] description = "A simple radio cli for listening to your favourite streams from the console" name = "radio-cli" -version = "2.3.1" -edition = "2021" +version = "2.3.2" +edition = "2024" homepage = "https://github.com/margual56/radio-cli" repository = "https://github.com/margual56/radio-cli" license = "GPL2" @@ -18,12 +18,12 @@ serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1.0", default-features = false, features = [ "alloc", ] } -colored = "^2" +colored = "^3" xdg = "^2.5" # https://docs.rs/xdg/latest/xdg/struct.BaseDirectories.html inquire = "^0" reqwest = { version = "^0", features = ["blocking", "json"] } radiobrowser = { version = "^0", features = ["blocking"] } -clap-verbosity-flag = "^2" +clap-verbosity-flag = "^3" env_logger = "^0" log = "^0" diff --git a/src/lib/browser.rs b/src/lib/browser.rs index b0c56af..beb6b79 100644 --- a/src/lib/browser.rs +++ b/src/lib/browser.rs @@ -1,9 +1,9 @@ use std::error::Error; use std::rc::Rc; -use crate::{station::Station, Config}; -use inquire::{error::InquireError, Autocomplete, Text}; -use radiobrowser::{blocking::RadioBrowserAPI, ApiCountry, ApiStation, StationOrder}; +use crate::{Config, station::Station}; +use inquire::{Autocomplete, Text, error::InquireError}; +use radiobrowser::{ApiCountry, ApiStation, StationOrder, blocking::RadioBrowserAPI}; pub type StationCache = Rc>; diff --git a/src/lib/config.rs b/src/lib/config.rs index 644be6b..2bceba5 100644 --- a/src/lib/config.rs +++ b/src/lib/config.rs @@ -6,8 +6,8 @@ use crate::station::Station; use crate::version::Version; use colored::*; -use serde::de::{Deserializer, Error as SeError, Visitor}; use serde::Deserialize; +use serde::de::{Deserializer, Error as SeError, Visitor}; use std::fmt::{Formatter, Result as ResultFmt}; use std::fs::File; use std::io::{Read, Write}; @@ -48,7 +48,7 @@ impl Config { code: ConfigErrorCode::OpenError, message: format!("Could not open the file {:?}", file), extra: format!("{:?}", error), - }) + }); } }; @@ -61,7 +61,7 @@ impl Config { code: ConfigErrorCode::ReadError, message: format!("Couldn't read the file {:?}", file), extra: format!("{:?}", error), - }) + }); } } @@ -79,7 +79,7 @@ impl Config { code: ConfigErrorCode::ParseError, message: "Couldn't parse config".to_string(), extra: format!("{:?}", error), - }) + }); } }; diff --git a/src/main.rs b/src/main.rs index 9fa10ad..e585de0 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,9 @@ use colored::*; use inquire::{InquireError, Select}; use log::{debug, error, info, log_enabled, warn}; use radio_libs::{ + Cli, Config, ConfigError, Station, Version, browser::{Browser, StationCache}, - perror, Cli, Config, ConfigError, Station, Version, + perror, }; use std::io::Write; use std::process::{Command, Stdio}; From 491be105f8428edabdd6d8133b17c2fc09345443 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Thu, 6 Mar 2025 20:55:45 +0100 Subject: [PATCH 2/8] Update lock dependencies --- Cargo.lock | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 587ec6d..b11718c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -166,7 +166,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix", + "rustix 0.38.44", "slab", "tracing", "windows-sys 0.59.0", @@ -198,7 +198,7 @@ dependencies = [ "cfg-if", "event-listener 5.4.0", "futures-lite", - "rustix", + "rustix 0.38.44", "tracing", ] @@ -214,7 +214,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix", + "rustix 0.38.44", "signal-hook-registry", "slab", "windows-sys 0.59.0", @@ -1353,6 +1353,12 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +[[package]] +name = "linux-raw-sys" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" + [[package]] name = "litemap" version = "0.7.5" @@ -1611,7 +1617,7 @@ dependencies = [ "concurrent-queue", "hermit-abi 0.4.0", "pin-project-lite", - "rustix", + "rustix 0.38.44", "tracing", "windows-sys 0.59.0", ] @@ -1675,7 +1681,7 @@ dependencies = [ [[package]] name = "radio-cli" -version = "2.4.0" +version = "2.3.2" dependencies = [ "clap", "clap-verbosity-flag", @@ -1897,7 +1903,20 @@ dependencies = [ "bitflags 2.9.0", "errno", "libc", - "linux-raw-sys", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17f8dcd64f141950290e45c99f7710ede1b600297c91818bb30b3667c0f45dc0" +dependencies = [ + "bitflags 2.9.0", + "errno", + "libc", + "linux-raw-sys 0.9.2", "windows-sys 0.59.0", ] @@ -2214,15 +2233,15 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.17.1" +version = "3.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" +checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" dependencies = [ "cfg-if", "fastrand", "getrandom 0.3.1", "once_cell", - "rustix", + "rustix 1.0.0", "windows-sys 0.59.0", ] From 1fa235906c713da2b92aa85df153fb94bb9e0296 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Tue, 15 Apr 2025 09:15:51 +0200 Subject: [PATCH 3/8] Add subcommands; Add persistent cache --- src/lib/browser.rs | 2 +- src/lib/cache.rs | 47 ++++++++++++ src/lib/cli_args.rs | 68 ++++++++++++----- src/lib/config.rs | 2 + src/lib/lib.rs | 4 +- src/lib/station.rs | 4 +- src/lib/version.rs | 4 +- src/main.rs | 173 ++++++++++++++++++++++++++++---------------- 8 files changed, 215 insertions(+), 89 deletions(-) create mode 100644 src/lib/cache.rs diff --git a/src/lib/browser.rs b/src/lib/browser.rs index beb6b79..c0b958e 100644 --- a/src/lib/browser.rs +++ b/src/lib/browser.rs @@ -124,7 +124,7 @@ impl Browser { } } - fn search_station(&self, message: &str, placeholder: &str) -> Result { + pub fn search_station(&self, message: &str, placeholder: &str) -> Result { let max_lines = match self.config.max_lines { Some(x) => x, None => Text::DEFAULT_PAGE_SIZE, diff --git a/src/lib/cache.rs b/src/lib/cache.rs new file mode 100644 index 0000000..d792fd8 --- /dev/null +++ b/src/lib/cache.rs @@ -0,0 +1,47 @@ +extern crate xdg; + +use crate::station::Station; +use crate::version::Version; + +use serde::{Deserialize, Serialize}; +use std::fs::File; +use std::io::{Error as IOError, Read, Write}; +use std::path::PathBuf; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub struct Cache { + pub stations: Vec, + pub version: Version, +} + +impl Cache { + pub fn new(stations: Vec, version: Version) -> Self { + Cache { stations, version } + } +} + +impl Cache { + pub fn load() -> Self { + let xdg_dirs = xdg::BaseDirectories::with_prefix("radio-cli").unwrap(); + match xdg_dirs.find_cache_file("stations.cache") { + None => { + return Self { + stations: Vec::new(), + version: Version:: + }; + } + Some(path) => { + let mut config_file = match File::open(&file) { + Ok(x) => x, + Err(error) => { + } + } + } + + pub fn save(&self, path: &PathBuf) -> Result<(), IOError> { + let mut file = File::create(path)?; + let json = serde_json::to_string_pretty(self)?; + file.write_all(json.as_bytes())?; + Ok(()) + } +} diff --git a/src/lib/cli_args.rs b/src/lib/cli_args.rs index 3844ba7..37aae06 100644 --- a/src/lib/cli_args.rs +++ b/src/lib/cli_args.rs @@ -1,4 +1,4 @@ -use clap::Parser; +use clap::{Parser, Subcommand}; use std::path::PathBuf; #[derive(Parser, Debug, Clone)] @@ -9,18 +9,8 @@ use std::path::PathBuf; long_about = "Note: When playing, all the keybindings of mpv can be used, and `q` is reserved for exiting the program" )] pub struct Cli { - /// Option: -u --url : Specifies an url to be played. - #[clap(short, long, help = "Specifies an url to be played.")] - pub url: Option, - - /// Option: -s --station : Specifies the name of the station to be played - #[clap( - short, - long, - conflicts_with = "url", - help = "Specifies the name of the station to be played." - )] - pub station: Option, + #[command(subcommand)] + pub command: Subcommands, /// Flag: --show-video: If *not* present, a flag is passed down to mpv to not show the video and just play the audio. #[clap( @@ -44,13 +34,6 @@ pub struct Cli { )] pub country_code: Option, - /// Flag: --list-countries: List all the available countries and country codes to put in the config. - #[clap( - long = "list-countries", - help = "List all the available countries and country codes to put in the config." - )] - pub list_countries: bool, - /// Flag: --no-station-cache: Don't cache the station list loaded from the internet. #[clap( long = "no-station-cache", @@ -66,3 +49,48 @@ pub struct Cli { #[structopt(short, long)] pub debug: bool, } + +#[derive(Subcommand, Debug, Clone)] +pub enum Subcommands { + /// Add a new station to the config file. + Add { + /// The name of the station to add. + #[arg(short, long)] + name: String, + + /// The URL of the station to add. + #[arg(short, long)] + url: String, + }, + /// Remove a station from the config file. + Remove { + /// The name of the station to remove. + #[arg(short, long)] + name: String, + }, + /// List all the countries in the config file. + ListCountries, + + /// List all the stations in the config file. + ListStations, + /// Search for stations by name or country code. + Search { + /// The name of the station to search for. + name: Option, + }, + /// Play a station from the config file. + Play { + /// Option: -u --url : Specifies an url to be played. + #[clap(short, long, help = "Specifies an url to be played.")] + url: Option, + + /// Option: -s --station : Specifies the name of the station to be played + #[clap( + short, + long, + conflicts_with = "url", + help = "Specifies the name of the station to be played." + )] + station: Option, + }, +} diff --git a/src/lib/config.rs b/src/lib/config.rs index 2bceba5..6a8df06 100644 --- a/src/lib/config.rs +++ b/src/lib/config.rs @@ -25,6 +25,8 @@ pub struct Config { pub country_code: Option, pub data: Vec, + + pub cache: Vec, } impl Config { diff --git a/src/lib/lib.rs b/src/lib/lib.rs index d4ac15c..866d726 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -1,11 +1,13 @@ pub mod browser; +mod cache; mod cli_args; mod config; mod errors; mod station; mod version; -pub use cli_args::Cli; +pub use cache::Cache; +pub use cli_args::{Cli, Subcommands}; pub use config::Config; pub use errors::{ConfigError, ConfigErrorCode}; pub use station::Station; diff --git a/src/lib/station.rs b/src/lib/station.rs index d9a47d3..d41eceb 100644 --- a/src/lib/station.rs +++ b/src/lib/station.rs @@ -1,5 +1,5 @@ -use serde::Deserialize; -#[derive(Deserialize, Debug, Clone)] +use serde::{Deserialize, Serialize}; +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Station { pub station: String, pub url: String, diff --git a/src/lib/version.rs b/src/lib/version.rs index 7b9f5e4..c0e42e7 100644 --- a/src/lib/version.rs +++ b/src/lib/version.rs @@ -1,8 +1,8 @@ use colored::*; -use serde::Deserialize; +use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter, Result as ResultFmt}; -#[derive(Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Version { pub major: u32, pub minor: u32, diff --git a/src/main.rs b/src/main.rs index e585de0..9960943 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use colored::*; use inquire::{InquireError, Select}; use log::{debug, error, info, log_enabled, warn}; use radio_libs::{ - Cli, Config, ConfigError, Station, Version, + Cli, Config, ConfigError, Station, Subcommands, Version, browser::{Browser, StationCache}, perror, }; @@ -26,18 +26,6 @@ fn main() { .filter_level(args.verbose.log_level_filter()) .init(); - if args.list_countries { - if let Ok(countries) = Browser::get_countries() { - for country in countries { - println!("{}: \"{}\"", country.name, country.iso_3166_1.bold()); - } - } else { - error!("Could not connect to the server, please check your connection."); - } - - std::process::exit(0); - } - // Parse the config file let config_result: Result = match args.config { None => Config::load_default(), @@ -82,12 +70,12 @@ fn main() { ); if config.config_version.major < version.major { - warn!("\n{} {}\n", "Warning!".yellow().bold(), + warn!("\n{} {}\n", "Warning!".yellow().bold(), "The config version does not match the program version.\nThis might lead to parsing errors.".italic()) } if config.country_code.is_none() { - warn!("\n{} {}", "Warning!".yellow().bold(), + warn!("\n{} {}", "Warning!".yellow().bold(), "The config does not contain a valid country (for example, \"ES\" for Spain or \"US\" for the US).".italic()); info!( "{} {} {}\n", @@ -102,66 +90,65 @@ fn main() { ); } - let mut url = args.url; - let mut station_arg = args.station; let mut cached_stations = None; - loop { - let station = match url { - None => { - let (station, internet, updated_cached_stations) = - get_station(station_arg, config.clone(), cached_stations.clone()); - if !args.no_station_cache { - cached_stations = updated_cached_stations; - } - - print!("Playing {}", station.station.green()); - print!("\x1B]0;Now playing: {}\x07", station.station); - - if internet { - println!(" ({})", station.url.yellow().italic()); - } else { - println!(); - } - - station + match args.command { + Subcommands::Play { station, url } => { + play(url, station, &mut cached_stations, args.show_video, config); + } + Subcommands::Search { name } => { + let (station, internet, updated_cached_stations) = + get_station(name, config.clone(), cached_stations.clone()); + if !args.no_station_cache { + cached_stations = updated_cached_stations; } - Some(x) => { - println!("Playing url '{}'", x.blue()); + print!("Playing {}", station.station.green()); + print!("\x1B]0;Now playing: {}\x07", station.station); - Station { - station: String::from("URL"), - url: x, - } + if internet { + println!(" ({})", station.url.yellow().italic()); + } else { + println!(); } - }; - // Don't play the same station again when returning to the browser - url = None; - station_arg = None; + println!( + "{}", + "Info: press 'q' to stop playing this station" + .italic() + .bright_black() + ); - println!( - "{}", - "Info: press 'q' to stop playing this station" - .italic() - .bright_black() - ); + let output_status = run_mpv(station, args.show_video); + if !output_status.success() { + perror(format!("mpv {}", output_status).as_str()); - let output_status = run_mpv(station, args.show_video); - if !output_status.success() { - perror(format!("mpv {}", output_status).as_str()); + if !log_enabled!(log::Level::Info) { + println!( + "{}: {}", + "Hint".italic().bold(), + "Try running radio-cli with the verbose flag (-vv or -vvv)".italic() + ); + } - if !log_enabled!(log::Level::Info) { - println!( - "{}: {}", - "Hint".italic().bold(), - "Try running radio-cli with the verbose flag (-vv or -vvv)".italic() - ); + std::process::exit(2); + } + } + Subcommands::ListCountries => { + if let Ok(countries) = Browser::get_countries() { + for country in countries { + println!("{}: \"{}\"", country.name, country.iso_3166_1.bold()); + } + } else { + error!("Could not connect to the server, please check your connection."); } - std::process::exit(2); + std::process::exit(0); } - } + _ => { + error!("No station selected"); + std::process::exit(1); + } + }; } fn run_mpv(station: Station, show_video: bool) -> std::process::ExitStatus { @@ -304,3 +291,63 @@ pub fn prompt( Ok((station, internet, updated_cached_stations)) } + +fn play( + url: Option, + station_name: Option, + cached_stations: &mut Option, + show_video: bool, + config: Rc, +) { + let station = match url { + Some(url) => { + println!("Playing url '{}'", url.blue()); + + Some(Station { + station: String::from("URL"), + url, + }) + } + None => match station_name { + Some(station) => { + let (station_struct, _, updated_cached_stations) = + get_station(Some(station), config.clone(), None); + if let Some(updated_stations) = updated_cached_stations { + _ = cached_stations.insert(updated_stations.clone()); + } + + println!("Playing {}", station_struct.station.blue()); + + Some(station_struct) + } + None => None, + }, + }; + + if let Some(station) = station { + println!( + "{}", + "Info: press 'q' to stop playing this station" + .italic() + .bright_black() + ); + + let output_status = run_mpv(station, show_video); + if !output_status.success() { + perror(format!("mpv {}", output_status).as_str()); + + if !log_enabled!(log::Level::Info) { + println!( + "{}: {}", + "Hint".italic().bold(), + "Try running radio-cli with the verbose flag (-vv or -vvv)".italic() + ); + } + + std::process::exit(2); + } + } else { + error!("URL or station not found"); + std::process::exit(2); + } +} From 7c5d45234ffbab3b6c96fd8c5623300a9bf44f20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Tue, 15 Apr 2025 14:51:09 +0200 Subject: [PATCH 4/8] Implement persistent cache; Make search subcommand work --- Cargo.lock | 4 +- Cargo.toml | 6 +- src/lib/browser.rs | 17 +--- src/lib/cache.rs | 67 ++++++++++--- src/lib/config.rs | 14 +-- src/lib/station.rs | 237 +++++++++++++++++++++++++++++++++++++++++++-- src/lib/version.rs | 17 ++++ src/main.rs | 52 +++++----- 8 files changed, 343 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b11718c..c5e269c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1699,8 +1699,7 @@ dependencies = [ [[package]] name = "radiobrowser" version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "763ad5f847e3d2e3221dac4e87370297a970e3f9eb8f2760b915001b9c79023b" +source = "git+https://gitlab.com/radiobrowser/radiobrowser-lib-rust.git?rev=5270f8277b0ce7f2a868504fd6e047ca418411fb#5270f8277b0ce7f2a868504fd6e047ca418411fb" dependencies = [ "async-std", "async-std-resolver", @@ -1709,6 +1708,7 @@ dependencies = [ "rand", "reqwest 0.11.27", "serde", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 95b6380..c968f0b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,13 +16,15 @@ optdepends = ["youtube-dl"] clap = { version = "^4", features = ["derive", "clap_derive"] } serde = { version = "^1.0", features = ["derive"] } serde_json = { version = "^1.0", default-features = false, features = [ - "alloc", + "alloc", ] } colored = "^3" xdg = "^2.5" # https://docs.rs/xdg/latest/xdg/struct.BaseDirectories.html inquire = "^0" reqwest = { version = "^0", features = ["blocking", "json"] } -radiobrowser = { version = "^0", features = ["blocking"] } +radiobrowser = { git = "https://gitlab.com/radiobrowser/radiobrowser-lib-rust.git", rev = "5270f8277b0ce7f2a868504fd6e047ca418411fb", features = [ + "blocking", +] } clap-verbosity-flag = "^3" env_logger = "^0" log = "^0" diff --git a/src/lib/browser.rs b/src/lib/browser.rs index c0b958e..a05e7b6 100644 --- a/src/lib/browser.rs +++ b/src/lib/browser.rs @@ -1,9 +1,8 @@ -use std::error::Error; use std::rc::Rc; use crate::{Config, station::Station}; use inquire::{Autocomplete, Text, error::InquireError}; -use radiobrowser::{ApiCountry, ApiStation, StationOrder, blocking::RadioBrowserAPI}; +use radiobrowser::{ApiCountry, ApiStation, RbError, StationOrder, blocking::RadioBrowserAPI}; pub type StationCache = Rc>; @@ -50,7 +49,7 @@ impl Browser { pub fn new( config: Rc, cached_stations: Option, - ) -> Result<(Browser, StationCache), Box> { + ) -> Result<(Browser, StationCache), RbError> { let api = match RadioBrowserAPI::new() { Ok(r) => r, Err(e) => return Err(e), @@ -85,7 +84,7 @@ impl Browser { )) } - pub fn get_countries() -> Result, Box> { + pub fn get_countries() -> Result, RbError> { let api = match RadioBrowserAPI::new() { Ok(r) => r, Err(e) => return Err(e), @@ -98,10 +97,7 @@ impl Browser { if let Some(code) = self.config.country_code.clone() { return match self.api.get_stations().name(name).countrycode(code).send() { Ok(s) => match s.get(0) { - Some(x) => Ok(Station { - station: x.name.clone(), - url: x.url.clone(), - }), + Some(x) => Ok(Station::from(x.clone())), None => Err(InquireError::InvalidConfiguration( "Radio station does not exist".to_string(), )), @@ -111,10 +107,7 @@ impl Browser { } else { return match self.api.get_stations().name(name).send() { Ok(s) => match s.get(0) { - Some(x) => Ok(Station { - station: x.name.clone(), - url: x.url.clone(), - }), + Some(x) => Ok(Station::from(x.clone())), None => Err(InquireError::InvalidConfiguration( "Radio station does not exist".to_string(), )), diff --git a/src/lib/cache.rs b/src/lib/cache.rs index d792fd8..72119cf 100644 --- a/src/lib/cache.rs +++ b/src/lib/cache.rs @@ -1,45 +1,84 @@ extern crate xdg; -use crate::station::Station; +use crate::browser::StationCache; use crate::version::Version; +use radiobrowser::ApiStation; use serde::{Deserialize, Serialize}; use std::fs::File; use std::io::{Error as IOError, Read, Write}; use std::path::PathBuf; +use std::rc::Rc; -#[derive(Serialize, Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone, Default)] pub struct Cache { - pub stations: Vec, + pub stations: Vec, pub version: Version, + cache_folder: PathBuf, } impl Cache { - pub fn new(stations: Vec, version: Version) -> Self { - Cache { stations, version } + pub fn new(stations: Vec, version: Version) -> Self { + let xdg_dirs = xdg::BaseDirectories::with_prefix("radio-cli").unwrap(); + let cache_folder = xdg_dirs.get_cache_home().to_path_buf(); + + Cache { + stations, + version, + cache_folder, + } } } impl Cache { pub fn load() -> Self { let xdg_dirs = xdg::BaseDirectories::with_prefix("radio-cli").unwrap(); - match xdg_dirs.find_cache_file("stations.cache") { - None => { + let cache_folder = xdg_dirs.get_cache_home().to_path_buf(); + match File::open(&cache_folder.join("data.cache")) { + Err(_) => { return Self { stations: Vec::new(), - version: Version:: + version: Version::from(String::from(env!("CARGO_PKG_VERSION"))) + .unwrap_or_default(), + cache_folder, }; } - Some(path) => { - let mut config_file = match File::open(&file) { - Ok(x) => x, - Err(error) => { + Ok(mut file) => { + let mut contents = String::new(); + + if let Err(_) = file.read_to_string(&mut contents) { + return Self::default(); + } + + match serde_json::from_str(&contents) { + Ok(cache) => cache, + Err(_) => Self::default(), + } } } } - pub fn save(&self, path: &PathBuf) -> Result<(), IOError> { - let mut file = File::create(path)?; + pub fn insert(&mut self, stations: Vec) { + self.stations = stations.clone(); + } + + pub fn insert_rc(&mut self, stations: StationCache) { + self.stations = Vec::from(stations.as_slice()); + } + + pub fn get_cache(&self) -> Option { + if self.stations.is_empty() { + None + } else { + Some(Rc::from(self.stations.clone())) + } + } + + pub fn save(&self) -> Result<(), IOError> { + std::fs::create_dir_all(&self.cache_folder)?; + + let mut file = File::create(&self.cache_folder.join("data.cache"))?; + let json = serde_json::to_string_pretty(self)?; file.write_all(json.as_bytes())?; Ok(()) diff --git a/src/lib/config.rs b/src/lib/config.rs index 6a8df06..1ba48e6 100644 --- a/src/lib/config.rs +++ b/src/lib/config.rs @@ -25,8 +25,6 @@ pub struct Config { pub country_code: Option, pub data: Vec, - - pub cache: Vec, } impl Config { @@ -69,10 +67,8 @@ impl Config { let data: Config = match serde_json::from_str::(&config) { Ok(mut x) => { - x.data.push(Station { - station: "Other".to_string(), - url: "".to_string(), - }); + x.data + .push(Station::new("Other".to_string(), "".to_string())); x } @@ -135,8 +131,8 @@ impl Config { pub fn get_url_for(&self, station_name: &str) -> Option { for s in self.data.iter() { - if s.station.eq(station_name) { - return Some(s.url.clone()); + if s.0.name.eq(station_name) { + return Some(s.0.url.clone()); } } @@ -147,7 +143,7 @@ impl Config { let mut stations: Vec = Vec::new(); for s in self.data.iter() { - stations.push(s.station.clone()); + stations.push(s.0.name.clone()); } stations diff --git a/src/lib/station.rs b/src/lib/station.rs index d41eceb..ba0c50c 100644 --- a/src/lib/station.rs +++ b/src/lib/station.rs @@ -1,12 +1,237 @@ -use serde::{Deserialize, Serialize}; -#[derive(Serialize, Deserialize, Debug, Clone)] -pub struct Station { - pub station: String, - pub url: String, +use std::fmt; + +use radiobrowser::ApiStation; +use serde::{ + Deserialize, Deserializer, Serialize, + de::{self, MapAccess, Visitor}, + ser::SerializeStruct, +}; + +#[derive(Debug, Clone, PartialEq)] +pub struct Station(pub ApiStation); + +impl From for Station { + fn from(api_station: ApiStation) -> Self { + Station(api_station) + } +} + +impl Into for Station { + fn into(self) -> ApiStation { + self.0.clone() + } } impl std::fmt::Display for Station { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.station) + write!(f, "{}", self.0.name) + } +} + +impl Station { + pub fn new(name: String, url: String) -> Station { + Station::from(ApiStation { + name, + url, + changeuuid: String::default(), + stationuuid: String::default(), + serveruuid: None, + url_resolved: String::default(), + homepage: String::default(), + favicon: String::default(), + tags: String::default(), + country: String::default(), + countrycode: String::default(), + iso_3166_2: None, + state: String::default(), + language: String::default(), + languagecodes: None, + votes: 0, + lastchangetime_iso8601: None, + codec: String::default(), + bitrate: 0, + hls: 0, + lastcheckok: 0, + lastchecktime_iso8601: None, + lastcheckoktime_iso8601: None, + lastlocalchecktime_iso8601: None, + clicktimestamp_iso8601: None, + clickcount: 0, + clicktrend: 0, + ssl_error: None, + geo_lat: None, + geo_long: None, + has_extended_info: None, + }) + } +} + +impl Serialize for Station { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + // Serialize only the name and url fields of the .0 + let mut tup = serializer.serialize_struct("Station", 2)?; + tup.serialize_field("station", &self.0.name.clone())?; + tup.serialize_field("url", &self.0.url.clone())?; + tup.end() + } +} + +impl<'de> Deserialize<'de> for Station { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + #[derive(Deserialize)] + #[serde(field_identifier, rename_all = "lowercase")] + enum Field { + Station, + Url, + } + + struct StationVisitor; + + impl<'de> Visitor<'de> for StationVisitor { + type Value = Station; + + fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { + formatter.write_str("a map with fields `station` and `url`") + } + + fn visit_map(self, mut map: A) -> Result + where + A: MapAccess<'de>, + { + let mut name = None; + let mut url = None; + + while let Some(key) = map.next_key()? { + match key { + Field::Station => { + if name.is_some() { + return Err(de::Error::duplicate_field("station")); + } + name = Some(map.next_value()?); + } + Field::Url => { + if url.is_some() { + return Err(de::Error::duplicate_field("url")); + } + url = Some(map.next_value()?); + } + } + } + + let name = name.ok_or_else(|| de::Error::missing_field("station"))?; + let url = url.ok_or_else(|| de::Error::missing_field("url"))?; + + Ok(Station::new(name, url)) + } + } + + deserializer.deserialize_map(StationVisitor) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use serde_json::{from_str, to_string}; + + #[test] + fn test_serialize_station() { + let station = Station::new("My Station".to_string(), "http://example.com".to_string()); + + let expected_json = r#"{"station":"My Station","url":"http://example.com"}"#; + let serialized_json = to_string(&station).unwrap(); + assert_eq!(serialized_json, expected_json); + } + #[test] + fn test_deserialize_station() { + let json_str = r#"{ + "station": "My Station", + "url": "http://example.com" + }"#; + + let expected_station = + Station::new("My Station".to_string(), "http://example.com".to_string()); + + let deserialized_station: Result = from_str(json_str); + assert!(deserialized_station.is_ok()); + assert_eq!(deserialized_station.unwrap(), expected_station); + } + + #[test] + fn test_deserialize_station_missing_fields() { + let json_str_missing_station = r#"{ + "url": "http://example.com" + }"#; + let deserialized_station_missing_station: Result = + from_str(json_str_missing_station); + assert!(deserialized_station_missing_station.is_err()); + assert_eq!( + deserialized_station_missing_station + .unwrap_err() + .to_string(), + "missing field `station`" + ); + + let json_str_missing_url = r#"{ + "station": "My Station" + }"#; + let deserialized_station_missing_url: Result = from_str(json_str_missing_url); + assert!(deserialized_station_missing_url.is_err()); + assert_eq!( + deserialized_station_missing_url.unwrap_err().to_string(), + "missing field `url`" + ); + } + + #[test] + fn test_deserialize_station_extra_field() { + let json_str_extra_field = r#"{ + "station": "My Station", + "url": "http://example.com", + "extra": "value" + }"#; + let deserialized_station_extra_field: Result = from_str(json_str_extra_field); + assert!(deserialized_station_extra_field.is_ok()); + assert_eq!( + deserialized_station_extra_field.unwrap(), + Station::new("My Station".to_string(), "http://example.com".to_string(),) + ); + } + + #[test] + fn test_deserialize_station_duplicate_fields() { + let json_str_duplicate_station = r#"{ + "station": "My Station", + "station": "Another Station", + "url": "http://example.com" + }"#; + let deserialized_station_duplicate_station: Result = + from_str(json_str_duplicate_station); + assert!(deserialized_station_duplicate_station.is_err()); + assert_eq!( + deserialized_station_duplicate_station + .unwrap_err() + .to_string(), + "duplicate field `station`" + ); + + let json_str_duplicate_url = r#"{ + "station": "My Station", + "url": "http://example.com", + "url": "http://anotherexample.com" + }"#; + let deserialized_station_duplicate_url: Result = + from_str(json_str_duplicate_url); + assert!(deserialized_station_duplicate_url.is_err()); + assert_eq!( + deserialized_station_duplicate_url.unwrap_err().to_string(), + "duplicate field `url`" + ); } } diff --git a/src/lib/version.rs b/src/lib/version.rs index c0e42e7..d086927 100644 --- a/src/lib/version.rs +++ b/src/lib/version.rs @@ -1,4 +1,5 @@ use colored::*; +use log::error; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter, Result as ResultFmt}; @@ -15,6 +16,22 @@ impl Display for Version { } } +impl Default for Version { + fn default() -> Self { + match Version::from(String::from(env!("CARGO_PKG_VERSION"))) { + Some(v) => v, + None => { + error!("There was an error parsing the program version"); + Version { + major: 0, + minor: 0, + patch: 0, + } + } + } + } +} + impl Version { pub fn new(major: u32, minor: u32, patch: u32) -> Version { Version { diff --git a/src/main.rs b/src/main.rs index 9960943..106f72a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use colored::*; use inquire::{InquireError, Select}; use log::{debug, error, info, log_enabled, warn}; use radio_libs::{ - Cli, Config, ConfigError, Station, Subcommands, Version, + Cache, Cli, Config, ConfigError, Station, Subcommands, Version, browser::{Browser, StationCache}, perror, }; @@ -90,23 +90,26 @@ fn main() { ); } - let mut cached_stations = None; + let mut cached_stations = Cache::load(); match args.command { Subcommands::Play { station, url } => { play(url, station, &mut cached_stations, args.show_video, config); } Subcommands::Search { name } => { let (station, internet, updated_cached_stations) = - get_station(name, config.clone(), cached_stations.clone()); + get_station(name, config.clone(), &mut cached_stations); + if !args.no_station_cache { - cached_stations = updated_cached_stations; + if let Some(cache) = updated_cached_stations { + cached_stations.insert_rc(cache); + } } - print!("Playing {}", station.station.green()); - print!("\x1B]0;Now playing: {}\x07", station.station); + print!("Playing {}", station.0.name.green()); + print!("\x1B]0;Now playing: {}\x07", station.0.name); if internet { - println!(" ({})", station.url.yellow().italic()); + println!(" ({})", station.0.url.yellow().italic()); } else { println!(); } @@ -149,11 +152,15 @@ fn main() { std::process::exit(1); } }; + + if let Err(e) = cached_stations.save() { + error!("{}", format!("{}", e).red()); + } } fn run_mpv(station: Station, show_video: bool) -> std::process::ExitStatus { let mut mpv = Command::new("mpv"); - let mut mpv_args: Vec = [station.url].to_vec(); + let mut mpv_args: Vec = [station.0.url].to_vec(); if !show_video { mpv_args.push(String::from("--no-video")); @@ -183,7 +190,7 @@ fn run_mpv(station: Station, show_video: bool) -> std::process::ExitStatus { fn get_station( station: Option, config: Rc, - cached_stations: Option, + cached_stations: &mut Cache, ) -> (Station, bool, Option) { let mut internet = false; @@ -203,7 +210,7 @@ fn get_station( internet = true; let (brows, updated_cached_stations) = - match Browser::new(config, cached_stations) { + match Browser::new(config, cached_stations.get_cache()) { Ok(b) => b, Err(e) => { error!("Could not connect with the API"); @@ -215,7 +222,7 @@ fn get_station( }; match brows.get_station(x.clone()) { - Ok(s) => (s.url, Some(updated_cached_stations)), + Ok(s) => (s.0.url, Some(updated_cached_stations)), Err(e) => { error!("This station was not found :("); debug!("{}", e); @@ -226,17 +233,13 @@ fn get_station( } }; - ( - Station { station: x, url }, - internet, - updated_cached_stations, - ) + (Station::new(x, url), internet, updated_cached_stations) } // Otherwise None => { // And let the user choose one - match prompt(config, cached_stations) { + match prompt(config, cached_stations.get_cache()) { Ok((s, b, cached)) => (s, b, cached), Err(error) => { println!("\n\t{}", "Bye!".bold().green()); @@ -268,7 +271,7 @@ pub fn prompt( let internet: bool; let (station, updated_cached_stations) = match res { Ok(s) => { - if s.station.eq("Other") { + if s.0.name.eq("Other") { internet = true; let result = Browser::new(config, cached_stations); @@ -295,7 +298,7 @@ pub fn prompt( fn play( url: Option, station_name: Option, - cached_stations: &mut Option, + cached_stations: &mut Cache, show_video: bool, config: Rc, ) { @@ -303,20 +306,17 @@ fn play( Some(url) => { println!("Playing url '{}'", url.blue()); - Some(Station { - station: String::from("URL"), - url, - }) + Some(Station::new(String::from("URL"), url)) } None => match station_name { Some(station) => { let (station_struct, _, updated_cached_stations) = - get_station(Some(station), config.clone(), None); + get_station(Some(station), config.clone(), cached_stations); if let Some(updated_stations) = updated_cached_stations { - _ = cached_stations.insert(updated_stations.clone()); + _ = cached_stations.insert(updated_stations.to_vec()); } - println!("Playing {}", station_struct.station.blue()); + println!("Playing {}", station_struct.0.name.blue()); Some(station_struct) } From 15b3664a816e70d0b55524a96e55b1aa719277ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Mon, 4 Aug 2025 00:08:05 +0200 Subject: [PATCH 5/8] Add and subcommands --- src/lib/browser.rs | 2 +- src/lib/cli_args.rs | 2 +- src/lib/config.rs | 45 +++++++++++++++++++++++++++++++++++++++------ src/lib/lib.rs | 2 +- src/lib/station.rs | 36 +++++++++++++++++++++++++++++++++++- src/main.rs | 33 +++++++++++++++++++++++++++++---- 6 files changed, 106 insertions(+), 14 deletions(-) diff --git a/src/lib/browser.rs b/src/lib/browser.rs index a05e7b6..acbfcc6 100644 --- a/src/lib/browser.rs +++ b/src/lib/browser.rs @@ -8,7 +8,7 @@ pub type StationCache = Rc>; #[derive(Debug, Clone)] pub struct Stations { - stations: StationCache, + pub stations: StationCache, } impl Autocomplete for Stations { diff --git a/src/lib/cli_args.rs b/src/lib/cli_args.rs index 37aae06..731526b 100644 --- a/src/lib/cli_args.rs +++ b/src/lib/cli_args.rs @@ -65,7 +65,7 @@ pub enum Subcommands { /// Remove a station from the config file. Remove { /// The name of the station to remove. - #[arg(short, long)] + #[arg(short, long, default_value_t = String::new())] name: String, }, /// List all the countries in the config file. diff --git a/src/lib/config.rs b/src/lib/config.rs index 1ba48e6..873ff83 100644 --- a/src/lib/config.rs +++ b/src/lib/config.rs @@ -6,8 +6,8 @@ use crate::station::Station; use crate::version::Version; use colored::*; -use serde::Deserialize; use serde::de::{Deserializer, Error as SeError, Visitor}; +use serde::{Deserialize, Serialize, Serializer}; use std::fmt::{Formatter, Result as ResultFmt}; use std::fs::File; use std::io::{Read, Write}; @@ -15,7 +15,7 @@ use std::path::PathBuf; const _CONFIG_URL: &str = "https://raw.githubusercontent.com/margual56/radio-cli/main/config.json"; -#[derive(Deserialize, Debug, Clone)] +#[derive(Serialize, Deserialize, Debug, Clone)] pub struct Config { #[serde(deserialize_with = "deserialize_version")] pub config_version: Version, @@ -24,6 +24,9 @@ pub struct Config { #[serde(alias = "country")] pub country_code: Option, + #[serde(skip)] + pub config_path: Option, + pub data: Vec, } @@ -31,13 +34,17 @@ impl Config { pub fn load_default() -> Result { // Load config.json from $XDG_CONFIG_HOME/radio-cli let xdg_dirs = xdg::BaseDirectories::with_prefix("radio-cli").unwrap(); - let config_file = Config::load_config(xdg_dirs); + let config_file = Config::get_config_path(xdg_dirs); - Config::load(config_file) + let mut config = Config::load(config_file.clone())?; + config.config_path = Some(config_file); + Ok(config) } pub fn load_from_file(path: PathBuf) -> Result { - Config::load(path) + let mut config = Config::load(path.clone())?; + config.config_path = Some(path); + Ok(config) } fn load(file: PathBuf) -> Result { @@ -84,7 +91,11 @@ impl Config { Ok(data) } - fn load_config(dir: xdg::BaseDirectories) -> PathBuf { + /// Get the XDG path for the config file + /// Creates the file if it doesn't exist + /// + /// Returns the path to the config file + fn get_config_path(dir: xdg::BaseDirectories) -> PathBuf { match dir.find_config_file("config.json") { None => { // Get the name of the directory @@ -129,6 +140,21 @@ impl Config { } } + pub fn save(&self) { + let path = match &self.config_path { + Some(p) => p, + None => { + let xdg_dirs = xdg::BaseDirectories::with_prefix("radio-cli").unwrap(); + &Config::get_config_path(xdg_dirs) + } + }; + let mut file = File::create(path).unwrap(); // This is write-only!! + file.write_all(serde_json::to_string(&self).unwrap().as_bytes()) + .expect("Could not write to config"); + + drop(file); // So we close the file to be able to read it + } + pub fn get_url_for(&self, station_name: &str) -> Option { for s in self.data.iter() { if s.0.name.eq(station_name) { @@ -150,6 +176,13 @@ impl Config { } } +fn serialize_version(version: &Version, serializer: S) -> Result +where + S: Serializer, +{ + serializer.serialize_str(&version.to_string()) +} + fn deserialize_version<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, diff --git a/src/lib/lib.rs b/src/lib/lib.rs index 866d726..b3f642e 100644 --- a/src/lib/lib.rs +++ b/src/lib/lib.rs @@ -10,7 +10,7 @@ pub use cache::Cache; pub use cli_args::{Cli, Subcommands}; pub use config::Config; pub use errors::{ConfigError, ConfigErrorCode}; -pub use station::Station; +pub use station::{Station, add_station, remove_station}; pub use version::Version; use colored::*; diff --git a/src/lib/station.rs b/src/lib/station.rs index ba0c50c..8039f1c 100644 --- a/src/lib/station.rs +++ b/src/lib/station.rs @@ -1,4 +1,4 @@ -use std::fmt; +use std::{fmt, rc::Rc}; use radiobrowser::ApiStation; use serde::{ @@ -7,6 +7,8 @@ use serde::{ ser::SerializeStruct, }; +use crate::{Cache, Config}; + #[derive(Debug, Clone, PartialEq)] pub struct Station(pub ApiStation); @@ -135,6 +137,38 @@ impl<'de> Deserialize<'de> for Station { } } +pub fn add_station(name: String, url: String, config: &Config) -> Config { + let station = Station::new(name, url); + let mut new_config = config.clone(); + new_config.data.push(station); + + new_config.save(); + + new_config +} + +pub fn remove_station(station_name: String, config: &Config) { + let mut new_config = config.clone(); + let index = new_config + .data + .iter() + .position(|s| s.0.name == station_name); + + if let Some(index) = index { + new_config.data.remove(index); + new_config.save(); + } +} + +pub fn edit_station(index: usize, name: String, url: String, config: &Config) { + if index < config.data.len() { + let mut new_config = config.clone(); + new_config.data[index] = Station::new(name, url); + + new_config.save(); + } +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/main.rs b/src/main.rs index 106f72a..d6fcb66 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,11 @@ use clap::Parser; use colored::*; -use inquire::{InquireError, Select}; +use inquire::{InquireError, Select, Text}; use log::{debug, error, info, log_enabled, warn}; use radio_libs::{ - Cache, Cli, Config, ConfigError, Station, Subcommands, Version, - browser::{Browser, StationCache}, - perror, + Cache, Cli, Config, ConfigError, Station, Subcommands, Version, add_station, + browser::{Browser, StationCache, Stations}, + perror, remove_station, }; use std::io::Write; use std::process::{Command, Stdio}; @@ -92,6 +92,31 @@ fn main() { let mut cached_stations = Cache::load(); match args.command { + Subcommands::Add { name, url } => { + _ = add_station(name, url, &config); + } + Subcommands::Remove { name } => { + let station_name = if name.is_empty() { + // Show station list + Text::new("Choose a station to remove:") + .with_autocomplete(Stations { + stations: Rc::new( + (&config) + .data + .iter() + .map(|station| station.0.clone()) + .collect(), + ), + }) + .with_page_size(config.max_lines.unwrap_or(Text::DEFAULT_PAGE_SIZE)) + .prompt() + .expect("Error selecting station to remove") + } else { + name + }; + + _ = remove_station(station_name, &config); + } Subcommands::Play { station, url } => { play(url, station, &mut cached_stations, args.show_video, config); } From 6778cc7f35ea7bce8e0dd351a57687eaa42aa274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Mon, 4 Aug 2025 09:12:13 +0200 Subject: [PATCH 6/8] Fix versioning serialization --- src/lib/config.rs | 36 ++++++++++-------------------------- src/lib/station.rs | 4 ++-- src/lib/version.rs | 4 ++++ 3 files changed, 16 insertions(+), 28 deletions(-) diff --git a/src/lib/config.rs b/src/lib/config.rs index 873ff83..c69a74f 100644 --- a/src/lib/config.rs +++ b/src/lib/config.rs @@ -6,9 +6,8 @@ use crate::station::Station; use crate::version::Version; use colored::*; -use serde::de::{Deserializer, Error as SeError, Visitor}; +use serde::de::Deserializer; use serde::{Deserialize, Serialize, Serializer}; -use std::fmt::{Formatter, Result as ResultFmt}; use std::fs::File; use std::io::{Read, Write}; use std::path::PathBuf; @@ -17,7 +16,10 @@ const _CONFIG_URL: &str = "https://raw.githubusercontent.com/margual56/radio-cli #[derive(Serialize, Deserialize, Debug, Clone)] pub struct Config { - #[serde(deserialize_with = "deserialize_version")] + #[serde( + deserialize_with = "deserialize_version", + serialize_with = "serialize_version" + )] pub config_version: Version, pub max_lines: Option, @@ -187,28 +189,10 @@ fn deserialize_version<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { - struct JsonStringVisitor; - - impl<'de> Visitor<'de> for JsonStringVisitor { - type Value = Version; - - fn expecting(&self, formatter: &mut Formatter) -> ResultFmt { - formatter.write_str("a string") - } - - fn visit_str(self, v: &str) -> Result - where - E: SeError, - { - // unfortunately we lose some typed information - // from errors deserializing the json string - match Version::from(String::from(v)) { - Some(x) => Ok(x), - None => Err(SeError::custom("Could not parse version")), - } - } + // Should be in form "major.minor.patch" + let version_str = String::deserialize(deserializer)?; + match Version::from(String::from(version_str)) { + Some(version) => Ok(version), + None => Err(serde::de::Error::custom("Error parsing version")), } - - // use our visitor to deserialize an `ActualValue` - deserializer.deserialize_any(JsonStringVisitor) } diff --git a/src/lib/station.rs b/src/lib/station.rs index 8039f1c..f43dc68 100644 --- a/src/lib/station.rs +++ b/src/lib/station.rs @@ -1,4 +1,4 @@ -use std::{fmt, rc::Rc}; +use std::fmt; use radiobrowser::ApiStation; use serde::{ @@ -7,7 +7,7 @@ use serde::{ ser::SerializeStruct, }; -use crate::{Cache, Config}; +use crate::Config; #[derive(Debug, Clone, PartialEq)] pub struct Station(pub ApiStation); diff --git a/src/lib/version.rs b/src/lib/version.rs index d086927..d96283a 100644 --- a/src/lib/version.rs +++ b/src/lib/version.rs @@ -88,4 +88,8 @@ impl Version { patch, }) } + + pub fn to_string(&self) -> String { + format!("{}.{}.{}", self.major, self.minor, self.patch) + } } From d9e80aca503f495dc8e11a913907f1551f5e9f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Mon, 4 Aug 2025 09:40:11 +0200 Subject: [PATCH 7/8] Fix 'Other' station being duplicated every time the program runs --- Cargo.lock | 380 +++------------------------------------------ Cargo.toml | 2 +- config.json | 2 +- src/lib/config.rs | 7 +- src/lib/station.rs | 16 +- src/main.rs | 22 ++- 6 files changed, 49 insertions(+), 380 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c5e269c..b87d0af 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -324,12 +324,6 @@ version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" -[[package]] -name = "base64" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" - [[package]] name = "bitflags" version = "1.3.2" @@ -674,7 +668,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" dependencies = [ "futures-core", - "futures-sink", ] [[package]] @@ -722,7 +715,6 @@ checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" dependencies = [ "futures-core", "futures-io", - "futures-sink", "futures-task", "memchr", "pin-project-lite", @@ -800,26 +792,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.12", - "indexmap", - "slab", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "h2" -version = "0.4.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" -dependencies = [ - "atomic-waker", - "bytes", - "fnv", - "futures-core", - "futures-sink", - "http 1.2.0", + "http", "indexmap", "slab", "tokio", @@ -925,17 +898,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" -dependencies = [ - "bytes", - "fnv", - "itoa", -] - [[package]] name = "http-body" version = "0.4.6" @@ -943,30 +905,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" dependencies = [ "bytes", - "http 0.2.12", - "pin-project-lite", -] - -[[package]] -name = "http-body" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" -dependencies = [ - "bytes", - "http 1.2.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" -dependencies = [ - "bytes", - "futures-util", - "http 1.2.0", - "http-body 1.0.1", + "http", "pin-project-lite", ] @@ -998,9 +937,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", + "h2", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -1012,43 +951,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper" -version = "1.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "h2 0.4.8", - "http 1.2.0", - "http-body 1.0.1", - "httparse", - "itoa", - "pin-project-lite", - "smallvec", - "tokio", - "want", -] - -[[package]] -name = "hyper-rustls" -version = "0.27.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" -dependencies = [ - "futures-util", - "http 1.2.0", - "hyper 1.6.0", - "hyper-util", - "rustls", - "rustls-pki-types", - "tokio", - "tokio-rustls", - "tower-service", -] - [[package]] name = "hyper-tls" version = "0.5.0" @@ -1056,47 +958,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper 0.14.32", + "hyper", "native-tls", "tokio", "tokio-native-tls", ] -[[package]] -name = "hyper-tls" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" -dependencies = [ - "bytes", - "http-body-util", - "hyper 1.6.0", - "hyper-util", - "native-tls", - "tokio", - "tokio-native-tls", - "tower-service", -] - -[[package]] -name = "hyper-util" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.2.0", - "http-body 1.0.1", - "hyper 1.6.0", - "pin-project-lite", - "socket2", - "tokio", - "tower-service", - "tracing", -] - [[package]] name = "iana-time-zone" version = "0.1.61" @@ -1681,7 +1548,7 @@ dependencies = [ [[package]] name = "radio-cli" -version = "2.3.2" +version = "2.4.0" dependencies = [ "clap", "clap-verbosity-flag", @@ -1690,7 +1557,7 @@ dependencies = [ "inquire", "log", "radiobrowser", - "reqwest 0.12.12", + "reqwest", "serde", "serde_json", "xdg", @@ -1706,7 +1573,7 @@ dependencies = [ "chrono", "log", "rand", - "reqwest 0.11.27", + "reqwest", "serde", "serde_json", ] @@ -1785,16 +1652,16 @@ version = "0.11.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" dependencies = [ - "base64 0.21.7", + "base64", "bytes", "encoding_rs", "futures-core", "futures-util", - "h2 0.3.26", - "http 0.2.12", - "http-body 0.4.6", - "hyper 0.14.32", - "hyper-tls 0.5.0", + "h2", + "http", + "http-body", + "hyper", + "hyper-tls", "ipnet", "js-sys", "log", @@ -1803,12 +1670,12 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite", - "rustls-pemfile 1.0.4", + "rustls-pemfile", "serde", "serde_json", "serde_urlencoded", - "sync_wrapper 0.1.2", - "system-configuration 0.5.1", + "sync_wrapper", + "system-configuration", "tokio", "tokio-native-tls", "tower-service", @@ -1819,51 +1686,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "reqwest" -version = "0.12.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" -dependencies = [ - "base64 0.22.1", - "bytes", - "encoding_rs", - "futures-channel", - "futures-core", - "futures-util", - "h2 0.4.8", - "http 1.2.0", - "http-body 1.0.1", - "http-body-util", - "hyper 1.6.0", - "hyper-rustls", - "hyper-tls 0.6.0", - "hyper-util", - "ipnet", - "js-sys", - "log", - "mime", - "native-tls", - "once_cell", - "percent-encoding", - "pin-project-lite", - "rustls-pemfile 2.2.0", - "serde", - "serde_json", - "serde_urlencoded", - "sync_wrapper 1.0.2", - "system-configuration 0.6.1", - "tokio", - "tokio-native-tls", - "tower", - "tower-service", - "url", - "wasm-bindgen", - "wasm-bindgen-futures", - "web-sys", - "windows-registry", -] - [[package]] name = "resolv-conf" version = "0.7.0" @@ -1874,20 +1696,6 @@ dependencies = [ "quick-error", ] -[[package]] -name = "ring" -version = "0.17.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9b823fa29b721a59671b41d6b06e66b29e0628e207e8b1c3ceeda701ec928d" -dependencies = [ - "cc", - "cfg-if", - "getrandom 0.2.15", - "libc", - "untrusted", - "windows-sys 0.52.0", -] - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -1920,52 +1728,13 @@ dependencies = [ "windows-sys 0.59.0", ] -[[package]] -name = "rustls" -version = "0.23.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" -dependencies = [ - "once_cell", - "rustls-pki-types", - "rustls-webpki", - "subtle", - "zeroize", -] - [[package]] name = "rustls-pemfile" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" dependencies = [ - "base64 0.21.7", -] - -[[package]] -name = "rustls-pemfile" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" -dependencies = [ - "rustls-pki-types", -] - -[[package]] -name = "rustls-pki-types" -version = "1.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" - -[[package]] -name = "rustls-webpki" -version = "0.102.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" -dependencies = [ - "ring", - "rustls-pki-types", - "untrusted", + "base64", ] [[package]] @@ -2135,12 +1904,6 @@ version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" -[[package]] -name = "subtle" -version = "2.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" - [[package]] name = "syn" version = "1.0.109" @@ -2169,15 +1932,6 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" -[[package]] -name = "sync_wrapper" -version = "1.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" -dependencies = [ - "futures-core", -] - [[package]] name = "synstructure" version = "0.13.1" @@ -2197,18 +1951,7 @@ checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" dependencies = [ "bitflags 1.3.2", "core-foundation", - "system-configuration-sys 0.5.0", -] - -[[package]] -name = "system-configuration" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" -dependencies = [ - "bitflags 2.9.0", - "core-foundation", - "system-configuration-sys 0.6.0", + "system-configuration-sys", ] [[package]] @@ -2221,16 +1964,6 @@ dependencies = [ "libc", ] -[[package]] -name = "system-configuration-sys" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "tempfile" version = "3.18.0" @@ -2334,16 +2067,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tokio-rustls" -version = "0.26.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" -dependencies = [ - "rustls", - "tokio", -] - [[package]] name = "tokio-util" version = "0.7.13" @@ -2357,27 +2080,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "tower" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" -dependencies = [ - "futures-core", - "futures-util", - "pin-project-lite", - "sync_wrapper 1.0.2", - "tokio", - "tower-layer", - "tower-service", -] - -[[package]] -name = "tower-layer" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" - [[package]] name = "tower-service" version = "0.3.3" @@ -2439,12 +2141,6 @@ version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.5.4" @@ -2649,36 +2345,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" -[[package]] -name = "windows-registry" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" -dependencies = [ - "windows-result", - "windows-strings", - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-result" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" -dependencies = [ - "windows-targets 0.52.6", -] - -[[package]] -name = "windows-strings" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" -dependencies = [ - "windows-result", - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -2930,12 +2596,6 @@ dependencies = [ "synstructure", ] -[[package]] -name = "zeroize" -version = "1.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" - [[package]] name = "zerovec" version = "0.10.4" diff --git a/Cargo.toml b/Cargo.toml index c968f0b..4c46e16 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,7 +2,7 @@ authors = ["Marcos Gutiérrez Alonso "] description = "A simple radio cli for listening to your favourite streams from the console" name = "radio-cli" -version = "2.3.2" +version = "2.4.0" edition = "2024" homepage = "https://github.com/margual56/radio-cli" repository = "https://github.com/margual56/radio-cli" diff --git a/config.json b/config.json index c8fbf33..12b44aa 100644 --- a/config.json +++ b/config.json @@ -1,5 +1,5 @@ { - "config_version": "2.3.0", + "config_version": "2.4.0", "max_lines": 7, "country": "ES", "data": [ diff --git a/src/lib/config.rs b/src/lib/config.rs index c69a74f..4bba807 100644 --- a/src/lib/config.rs +++ b/src/lib/config.rs @@ -75,12 +75,7 @@ impl Config { } let data: Config = match serde_json::from_str::(&config) { - Ok(mut x) => { - x.data - .push(Station::new("Other".to_string(), "".to_string())); - - x - } + Ok(x) => x, Err(error) => { return Err(ConfigError { code: ConfigErrorCode::ParseError, diff --git a/src/lib/station.rs b/src/lib/station.rs index f43dc68..0788bca 100644 --- a/src/lib/station.rs +++ b/src/lib/station.rs @@ -160,14 +160,14 @@ pub fn remove_station(station_name: String, config: &Config) { } } -pub fn edit_station(index: usize, name: String, url: String, config: &Config) { - if index < config.data.len() { - let mut new_config = config.clone(); - new_config.data[index] = Station::new(name, url); - - new_config.save(); - } -} +// pub fn edit_station(index: usize, name: String, url: String, config: &Config) { +// if index < config.data.len() { +// let mut new_config = config.clone(); +// new_config.data[index] = Station::new(name, url); + +// new_config.save(); +// } +// } #[cfg(test)] mod tests { diff --git a/src/main.rs b/src/main.rs index d6fcb66..bac9e4f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,13 @@ use clap::Parser; use colored::*; -use inquire::{InquireError, Select, Text}; +use inquire::{InquireError, Select, Text, formatter::MultiOptionFormatter}; use log::{debug, error, info, log_enabled, warn}; use radio_libs::{ Cache, Cli, Config, ConfigError, Station, Subcommands, Version, add_station, browser::{Browser, StationCache, Stations}, perror, remove_station, }; +use radiobrowser::ApiStation; use std::io::Write; use std::process::{Command, Stdio}; use std::rc::Rc; @@ -98,7 +99,7 @@ fn main() { Subcommands::Remove { name } => { let station_name = if name.is_empty() { // Show station list - Text::new("Choose a station to remove:") + match Text::new("Choose a station to remove:") .with_autocomplete(Stations { stations: Rc::new( (&config) @@ -110,7 +111,17 @@ fn main() { }) .with_page_size(config.max_lines.unwrap_or(Text::DEFAULT_PAGE_SIZE)) .prompt() - .expect("Error selecting station to remove") + { + Err(_) => { + println!( + "\n{}\n\t{}", + "Operation cancelled".bold().yellow(), + "Bye!".bold().green() + ); + return; + } + Ok(station_name) => station_name, + } } else { name }; @@ -289,7 +300,10 @@ pub fn prompt( None => Select::::DEFAULT_PAGE_SIZE, }; - let res = Select::new(&"Select a station to play:".bold(), config.data.clone()) + let mut stations = config.data.clone(); + stations.push(Station::new(String::from("Other"), String::new())); + + let res = Select::new(&"Select a station to play:".bold(), stations) .with_page_size(max_lines) .prompt(); From d32489ad94bfd41944bf315e8ae00e52604269bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marcos=20Guti=C3=A9rrez=20Alonso?= Date: Mon, 4 Aug 2025 09:50:45 +0200 Subject: [PATCH 8/8] Add error handling for duplicated or incorrect stations --- src/lib/errors.rs | 2 ++ src/lib/station.rs | 22 +++++++++++++++++++--- src/main.rs | 15 ++++++++++----- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/lib/errors.rs b/src/lib/errors.rs index 62b66c6..68e51a0 100644 --- a/src/lib/errors.rs +++ b/src/lib/errors.rs @@ -6,6 +6,8 @@ pub enum ConfigErrorCode { ReadError, CloseError, ParseError, + InvalidStation, + DuplicateStation, } pub struct ConfigError { diff --git a/src/lib/station.rs b/src/lib/station.rs index 0788bca..17f8512 100644 --- a/src/lib/station.rs +++ b/src/lib/station.rs @@ -7,7 +7,7 @@ use serde::{ ser::SerializeStruct, }; -use crate::Config; +use crate::{Config, ConfigError, ConfigErrorCode}; #[derive(Debug, Clone, PartialEq)] pub struct Station(pub ApiStation); @@ -137,14 +137,30 @@ impl<'de> Deserialize<'de> for Station { } } -pub fn add_station(name: String, url: String, config: &Config) -> Config { +pub fn add_station(name: String, url: String, config: &Config) -> Result { + if name.is_empty() || url.is_empty() { + return Err(ConfigError { + code: ConfigErrorCode::InvalidStation, + message: String::from("Invalid station"), + extra: String::from("Station name and URL cannot be empty"), + }); + } + + if config.data.iter().any(|s| s.0.name == name) { + return Err(ConfigError { + code: ConfigErrorCode::DuplicateStation, + message: String::from("Duplicate station"), + extra: String::from("Station name already exists"), + }); + } + let station = Station::new(name, url); let mut new_config = config.clone(); new_config.data.push(station); new_config.save(); - new_config + Ok(new_config) } pub fn remove_station(station_name: String, config: &Config) { diff --git a/src/main.rs b/src/main.rs index bac9e4f..2ef72fc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,12 @@ use clap::Parser; use colored::*; -use inquire::{InquireError, Select, Text, formatter::MultiOptionFormatter}; +use inquire::{InquireError, Select, Text}; use log::{debug, error, info, log_enabled, warn}; use radio_libs::{ Cache, Cli, Config, ConfigError, Station, Subcommands, Version, add_station, browser::{Browser, StationCache, Stations}, perror, remove_station, }; -use radiobrowser::ApiStation; use std::io::Write; use std::process::{Command, Stdio}; use std::rc::Rc; @@ -93,9 +92,14 @@ fn main() { let mut cached_stations = Cache::load(); match args.command { - Subcommands::Add { name, url } => { - _ = add_station(name, url, &config); - } + Subcommands::Add { name, url } => match add_station(name, url, &config) { + Ok(_) => { + println!("Station added successfully ✅"); + } + Err(e) => { + error!("Error adding station: {}", e); + } + }, Subcommands::Remove { name } => { let station_name = if name.is_empty() { // Show station list @@ -127,6 +131,7 @@ fn main() { }; _ = remove_station(station_name, &config); + info!("Station removed successfully ✅"); } Subcommands::Play { station, url } => { play(url, station, &mut cached_stations, args.show_video, config);