├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── rust.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── README.md ├── config.json └── src ├── lib ├── browser.rs ├── cli_args.rs ├── config.rs ├── errors.rs ├── lib.rs ├── station.rs └── version.rs └── main.rs /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [margual56] 4 | ko_fi: margual56 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "[BUG] - " 5 | labels: bug 6 | assignees: margual56 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | > A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | > Steps to reproduce the behavior: 15 | > 1. Go to '...' 16 | > 2. Click on '....' 17 | > 3. Scroll down to '....' 18 | > 4. See error 19 | 20 | **Expected behavior** 21 | > A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | > If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Version [e.g. 22] 29 | 30 | **Additional context** 31 | > Add any other context about the problem here. 32 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "[Feature] - " 5 | labels: enhancement 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | > A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | > A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | > A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | > Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Rust 2 | 3 | on: 4 | push: 5 | branches: [ main, dev_main ] 6 | tags: 7 | - '*' 8 | pull_request: 9 | branches: [ main ] 10 | 11 | env: 12 | CARGO_TERM_COLOR: always 13 | 14 | jobs: 15 | fmt: 16 | runs-on: ubuntu-latest 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v3 20 | 21 | - name: Install latest stable 22 | uses: actions-rs/toolchain@v1 23 | with: 24 | toolchain: stable 25 | override: true 26 | components: rustfmt 27 | 28 | - name: Check code format 29 | run: cargo fmt --all -- --check 30 | 31 | stable-build: 32 | runs-on: ubuntu-latest 33 | steps: 34 | - name: Checkout repository 35 | uses: actions/checkout@v3 36 | 37 | - name: Install latest stable 38 | uses: actions-rs/toolchain@v1 39 | with: 40 | toolchain: stable 41 | override: true 42 | components: rustfmt, clippy 43 | 44 | - name: Build debug 45 | run: cargo build --verbose 46 | 47 | - name: Build release 48 | run: cargo build --release --verbose 49 | 50 | - uses: actions/cache@v4 51 | id: stable-cargo-build 52 | with: 53 | path: | 54 | ~/.cargo/bin/ 55 | ~/.cargo/registry/index/ 56 | ~/.cargo/registry/cache/ 57 | ~/.cargo/git/db/ 58 | target/ 59 | key: ${{ runner.os }}-stable-cargo-${{ hashFiles('**/Cargo.lock') }} 60 | 61 | stable-tests: 62 | runs-on: ubuntu-latest 63 | needs: ['stable-build'] 64 | steps: 65 | - name: Restore cache 66 | uses: actions/cache@v4 67 | id: stable-cargo-build 68 | with: 69 | path: | 70 | ~/.cargo/bin/ 71 | ~/.cargo/registry/index/ 72 | ~/.cargo/registry/cache/ 73 | ~/.cargo/git/db/ 74 | target/ 75 | key: ${{ runner.os }}-stable-cargo-${{ hashFiles('**/Cargo.lock') }} 76 | 77 | - name: Checkout repository 78 | uses: actions/checkout@v3 79 | 80 | - name: Install latest stable 81 | uses: actions-rs/toolchain@v1 82 | with: 83 | toolchain: stable 84 | override: true 85 | components: rustfmt, clippy 86 | 87 | - name: Cargo test debug 88 | run: cargo test --all-features --verbose 89 | 90 | - name: Cargo test release 91 | run: cargo test --release --all-features --verbose 92 | 93 | nightly-build: 94 | runs-on: ubuntu-latest 95 | steps: 96 | - name: Checkout repository 97 | uses: actions/checkout@v3 98 | 99 | - name: Install latest nightly 100 | uses: actions-rs/toolchain@v1 101 | with: 102 | toolchain: nightly 103 | override: true 104 | components: rustfmt, clippy 105 | 106 | - name: Build debug 107 | run: cargo build --verbose 108 | 109 | - name: Build release 110 | run: cargo build --release --verbose 111 | 112 | - uses: actions/cache@v4 113 | id: nightly-cargo-build 114 | with: 115 | path: | 116 | ~/.cargo/bin/ 117 | ~/.cargo/registry/index/ 118 | ~/.cargo/registry/cache/ 119 | ~/.cargo/git/db/ 120 | target/ 121 | key: ${{ runner.os }}-stable-cargo-${{ hashFiles('**/Cargo.lock') }} 122 | 123 | nightly-tests: 124 | runs-on: ubuntu-latest 125 | needs: ['nightly-build'] 126 | steps: 127 | - name: Restore cache 128 | uses: actions/cache@v4 129 | id: nightly-cargo-build 130 | with: 131 | path: | 132 | ~/.cargo/bin/ 133 | ~/.cargo/registry/index/ 134 | ~/.cargo/registry/cache/ 135 | ~/.cargo/git/db/ 136 | target/ 137 | key: ${{ runner.os }}-stable-cargo-${{ hashFiles('**/Cargo.lock') }} 138 | 139 | - name: Checkout repository 140 | uses: actions/checkout@v3 141 | 142 | - name: Install latest nightly 143 | uses: actions-rs/toolchain@v1 144 | with: 145 | toolchain: nightly 146 | override: true 147 | components: rustfmt, clippy 148 | 149 | - name: Cargo test debug 150 | run: cargo test --all-features --verbose 151 | 152 | - name: Cargo test release 153 | run: cargo test --release --all-features --verbose 154 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | *.tar.gz 3 | PKGBUILD 4 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | margual56@gmail.com. 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing guidelines 2 | First of all, thank you for taking the time to improve this program! 3 | 4 |
5 |

Changes to the main program

6 |
12 | 13 | 14 |
15 |

Changes to the default config

16 | 26 |
27 | 28 | 29 | ## The usual stuff 30 | - Please, respect the [code of conduct](https://github.com/margual56/radio-cli/blob/main/CODE_OF_CONDUCT.md) 31 | - Be patient with my response times to issues and PRs 32 | - Have fun! 33 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 4 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.24.2" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler2" 16 | version = "2.0.0" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 19 | 20 | [[package]] 21 | name = "aho-corasick" 22 | version = "1.1.3" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 25 | dependencies = [ 26 | "memchr", 27 | ] 28 | 29 | [[package]] 30 | name = "android-tzdata" 31 | version = "0.1.1" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 34 | 35 | [[package]] 36 | name = "android_system_properties" 37 | version = "0.1.5" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 40 | dependencies = [ 41 | "libc", 42 | ] 43 | 44 | [[package]] 45 | name = "anstream" 46 | version = "0.6.18" 47 | source = "registry+https://github.com/rust-lang/crates.io-index" 48 | checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" 49 | dependencies = [ 50 | "anstyle", 51 | "anstyle-parse", 52 | "anstyle-query", 53 | "anstyle-wincon", 54 | "colorchoice", 55 | "is_terminal_polyfill", 56 | "utf8parse", 57 | ] 58 | 59 | [[package]] 60 | name = "anstyle" 61 | version = "1.0.10" 62 | source = "registry+https://github.com/rust-lang/crates.io-index" 63 | checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" 64 | 65 | [[package]] 66 | name = "anstyle-parse" 67 | version = "0.2.6" 68 | source = "registry+https://github.com/rust-lang/crates.io-index" 69 | checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" 70 | dependencies = [ 71 | "utf8parse", 72 | ] 73 | 74 | [[package]] 75 | name = "anstyle-query" 76 | version = "1.1.2" 77 | source = "registry+https://github.com/rust-lang/crates.io-index" 78 | checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" 79 | dependencies = [ 80 | "windows-sys 0.59.0", 81 | ] 82 | 83 | [[package]] 84 | name = "anstyle-wincon" 85 | version = "3.0.7" 86 | source = "registry+https://github.com/rust-lang/crates.io-index" 87 | checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" 88 | dependencies = [ 89 | "anstyle", 90 | "once_cell", 91 | "windows-sys 0.59.0", 92 | ] 93 | 94 | [[package]] 95 | name = "async-attributes" 96 | version = "1.1.2" 97 | source = "registry+https://github.com/rust-lang/crates.io-index" 98 | checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5" 99 | dependencies = [ 100 | "quote", 101 | "syn 1.0.109", 102 | ] 103 | 104 | [[package]] 105 | name = "async-channel" 106 | version = "1.9.0" 107 | source = "registry+https://github.com/rust-lang/crates.io-index" 108 | checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" 109 | dependencies = [ 110 | "concurrent-queue", 111 | "event-listener 2.5.3", 112 | "futures-core", 113 | ] 114 | 115 | [[package]] 116 | name = "async-channel" 117 | version = "2.3.1" 118 | source = "registry+https://github.com/rust-lang/crates.io-index" 119 | checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 120 | dependencies = [ 121 | "concurrent-queue", 122 | "event-listener-strategy", 123 | "futures-core", 124 | "pin-project-lite", 125 | ] 126 | 127 | [[package]] 128 | name = "async-executor" 129 | version = "1.13.1" 130 | source = "registry+https://github.com/rust-lang/crates.io-index" 131 | checksum = "30ca9a001c1e8ba5149f91a74362376cc6bc5b919d92d988668657bd570bdcec" 132 | dependencies = [ 133 | "async-task", 134 | "concurrent-queue", 135 | "fastrand", 136 | "futures-lite", 137 | "slab", 138 | ] 139 | 140 | [[package]] 141 | name = "async-global-executor" 142 | version = "2.4.1" 143 | source = "registry+https://github.com/rust-lang/crates.io-index" 144 | checksum = "05b1b633a2115cd122d73b955eadd9916c18c8f510ec9cd1686404c60ad1c29c" 145 | dependencies = [ 146 | "async-channel 2.3.1", 147 | "async-executor", 148 | "async-io", 149 | "async-lock", 150 | "blocking", 151 | "futures-lite", 152 | "once_cell", 153 | "tokio", 154 | ] 155 | 156 | [[package]] 157 | name = "async-io" 158 | version = "2.4.0" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "43a2b323ccce0a1d90b449fd71f2a06ca7faa7c54c2751f06c9bd851fc061059" 161 | dependencies = [ 162 | "async-lock", 163 | "cfg-if", 164 | "concurrent-queue", 165 | "futures-io", 166 | "futures-lite", 167 | "parking", 168 | "polling", 169 | "rustix 0.38.44", 170 | "slab", 171 | "tracing", 172 | "windows-sys 0.59.0", 173 | ] 174 | 175 | [[package]] 176 | name = "async-lock" 177 | version = "3.4.0" 178 | source = "registry+https://github.com/rust-lang/crates.io-index" 179 | checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" 180 | dependencies = [ 181 | "event-listener 5.4.0", 182 | "event-listener-strategy", 183 | "pin-project-lite", 184 | ] 185 | 186 | [[package]] 187 | name = "async-process" 188 | version = "2.3.0" 189 | source = "registry+https://github.com/rust-lang/crates.io-index" 190 | checksum = "63255f1dc2381611000436537bbedfe83183faa303a5a0edaf191edef06526bb" 191 | dependencies = [ 192 | "async-channel 2.3.1", 193 | "async-io", 194 | "async-lock", 195 | "async-signal", 196 | "async-task", 197 | "blocking", 198 | "cfg-if", 199 | "event-listener 5.4.0", 200 | "futures-lite", 201 | "rustix 0.38.44", 202 | "tracing", 203 | ] 204 | 205 | [[package]] 206 | name = "async-signal" 207 | version = "0.2.10" 208 | source = "registry+https://github.com/rust-lang/crates.io-index" 209 | checksum = "637e00349800c0bdf8bfc21ebbc0b6524abea702b0da4168ac00d070d0c0b9f3" 210 | dependencies = [ 211 | "async-io", 212 | "async-lock", 213 | "atomic-waker", 214 | "cfg-if", 215 | "futures-core", 216 | "futures-io", 217 | "rustix 0.38.44", 218 | "signal-hook-registry", 219 | "slab", 220 | "windows-sys 0.59.0", 221 | ] 222 | 223 | [[package]] 224 | name = "async-std" 225 | version = "1.13.0" 226 | source = "registry+https://github.com/rust-lang/crates.io-index" 227 | checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615" 228 | dependencies = [ 229 | "async-attributes", 230 | "async-channel 1.9.0", 231 | "async-global-executor", 232 | "async-io", 233 | "async-lock", 234 | "async-process", 235 | "crossbeam-utils", 236 | "futures-channel", 237 | "futures-core", 238 | "futures-io", 239 | "futures-lite", 240 | "gloo-timers", 241 | "kv-log-macro", 242 | "log", 243 | "memchr", 244 | "once_cell", 245 | "pin-project-lite", 246 | "pin-utils", 247 | "slab", 248 | "wasm-bindgen-futures", 249 | ] 250 | 251 | [[package]] 252 | name = "async-std-resolver" 253 | version = "0.24.4" 254 | source = "registry+https://github.com/rust-lang/crates.io-index" 255 | checksum = "b766684a183c8a439f2ca24d6973cf8bfdc1353ae9c54b2b91e81d2630dd034e" 256 | dependencies = [ 257 | "async-std", 258 | "async-trait", 259 | "futures-io", 260 | "futures-util", 261 | "hickory-resolver", 262 | "pin-utils", 263 | "socket2", 264 | ] 265 | 266 | [[package]] 267 | name = "async-task" 268 | version = "4.7.1" 269 | source = "registry+https://github.com/rust-lang/crates.io-index" 270 | checksum = "8b75356056920673b02621b35afd0f7dda9306d03c79a30f5c56c44cf256e3de" 271 | 272 | [[package]] 273 | name = "async-trait" 274 | version = "0.1.87" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97" 277 | dependencies = [ 278 | "proc-macro2", 279 | "quote", 280 | "syn 2.0.99", 281 | ] 282 | 283 | [[package]] 284 | name = "atomic-waker" 285 | version = "1.1.2" 286 | source = "registry+https://github.com/rust-lang/crates.io-index" 287 | checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 288 | 289 | [[package]] 290 | name = "atty" 291 | version = "0.2.14" 292 | source = "registry+https://github.com/rust-lang/crates.io-index" 293 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" 294 | dependencies = [ 295 | "hermit-abi 0.1.19", 296 | "libc", 297 | "winapi", 298 | ] 299 | 300 | [[package]] 301 | name = "autocfg" 302 | version = "1.4.0" 303 | source = "registry+https://github.com/rust-lang/crates.io-index" 304 | checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" 305 | 306 | [[package]] 307 | name = "backtrace" 308 | version = "0.3.74" 309 | source = "registry+https://github.com/rust-lang/crates.io-index" 310 | checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 311 | dependencies = [ 312 | "addr2line", 313 | "cfg-if", 314 | "libc", 315 | "miniz_oxide", 316 | "object", 317 | "rustc-demangle", 318 | "windows-targets 0.52.6", 319 | ] 320 | 321 | [[package]] 322 | name = "base64" 323 | version = "0.21.7" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" 326 | 327 | [[package]] 328 | name = "base64" 329 | version = "0.22.1" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 332 | 333 | [[package]] 334 | name = "bitflags" 335 | version = "1.3.2" 336 | source = "registry+https://github.com/rust-lang/crates.io-index" 337 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 338 | 339 | [[package]] 340 | name = "bitflags" 341 | version = "2.9.0" 342 | source = "registry+https://github.com/rust-lang/crates.io-index" 343 | checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd" 344 | 345 | [[package]] 346 | name = "blocking" 347 | version = "1.6.1" 348 | source = "registry+https://github.com/rust-lang/crates.io-index" 349 | checksum = "703f41c54fc768e63e091340b424302bb1c29ef4aa0c7f10fe849dfb114d29ea" 350 | dependencies = [ 351 | "async-channel 2.3.1", 352 | "async-task", 353 | "futures-io", 354 | "futures-lite", 355 | "piper", 356 | ] 357 | 358 | [[package]] 359 | name = "bumpalo" 360 | version = "3.17.0" 361 | source = "registry+https://github.com/rust-lang/crates.io-index" 362 | checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" 363 | 364 | [[package]] 365 | name = "byteorder" 366 | version = "1.5.0" 367 | source = "registry+https://github.com/rust-lang/crates.io-index" 368 | checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 369 | 370 | [[package]] 371 | name = "bytes" 372 | version = "1.10.1" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" 375 | 376 | [[package]] 377 | name = "cc" 378 | version = "1.2.16" 379 | source = "registry+https://github.com/rust-lang/crates.io-index" 380 | checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" 381 | dependencies = [ 382 | "shlex", 383 | ] 384 | 385 | [[package]] 386 | name = "cfg-if" 387 | version = "1.0.0" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 390 | 391 | [[package]] 392 | name = "chrono" 393 | version = "0.4.40" 394 | source = "registry+https://github.com/rust-lang/crates.io-index" 395 | checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c" 396 | dependencies = [ 397 | "android-tzdata", 398 | "iana-time-zone", 399 | "js-sys", 400 | "num-traits", 401 | "serde", 402 | "wasm-bindgen", 403 | "windows-link", 404 | ] 405 | 406 | [[package]] 407 | name = "clap" 408 | version = "4.0.8" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "5840cd9093aabeabf7fd932754c435b7674520fc3ddc935c397837050f0f1e4b" 411 | dependencies = [ 412 | "atty", 413 | "bitflags 1.3.2", 414 | "clap_derive", 415 | "clap_lex", 416 | "once_cell", 417 | "strsim", 418 | "termcolor", 419 | ] 420 | 421 | [[package]] 422 | name = "clap-verbosity-flag" 423 | version = "3.0.2" 424 | source = "registry+https://github.com/rust-lang/crates.io-index" 425 | checksum = "2678fade3b77aa3a8ff3aae87e9c008d3fb00473a41c71fbf74e91c8c7b37e84" 426 | dependencies = [ 427 | "clap", 428 | "log", 429 | ] 430 | 431 | [[package]] 432 | name = "clap_derive" 433 | version = "4.0.8" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "92289ffc6fb4a85d85c246ddb874c05a87a2e540fb6ad52f7ca07c8c1e1840b1" 436 | dependencies = [ 437 | "heck 0.4.1", 438 | "proc-macro-error", 439 | "proc-macro2", 440 | "quote", 441 | "syn 1.0.109", 442 | ] 443 | 444 | [[package]] 445 | name = "clap_lex" 446 | version = "0.3.3" 447 | source = "registry+https://github.com/rust-lang/crates.io-index" 448 | checksum = "033f6b7a4acb1f358c742aaca805c939ee73b4c6209ae4318ec7aca81c42e646" 449 | dependencies = [ 450 | "os_str_bytes", 451 | ] 452 | 453 | [[package]] 454 | name = "colorchoice" 455 | version = "1.0.3" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" 458 | 459 | [[package]] 460 | name = "colored" 461 | version = "3.0.0" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "fde0e0ec90c9dfb3b4b1a0891a7dcd0e2bffde2f7efed5fe7c9bb00e5bfb915e" 464 | dependencies = [ 465 | "windows-sys 0.59.0", 466 | ] 467 | 468 | [[package]] 469 | name = "concurrent-queue" 470 | version = "2.5.0" 471 | source = "registry+https://github.com/rust-lang/crates.io-index" 472 | checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 473 | dependencies = [ 474 | "crossbeam-utils", 475 | ] 476 | 477 | [[package]] 478 | name = "core-foundation" 479 | version = "0.9.4" 480 | source = "registry+https://github.com/rust-lang/crates.io-index" 481 | checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" 482 | dependencies = [ 483 | "core-foundation-sys", 484 | "libc", 485 | ] 486 | 487 | [[package]] 488 | name = "core-foundation-sys" 489 | version = "0.8.7" 490 | source = "registry+https://github.com/rust-lang/crates.io-index" 491 | checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" 492 | 493 | [[package]] 494 | name = "crossbeam-utils" 495 | version = "0.8.21" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" 498 | 499 | [[package]] 500 | name = "crossterm" 501 | version = "0.25.0" 502 | source = "registry+https://github.com/rust-lang/crates.io-index" 503 | checksum = "e64e6c0fbe2c17357405f7c758c1ef960fce08bdfb2c03d88d2a18d7e09c4b67" 504 | dependencies = [ 505 | "bitflags 1.3.2", 506 | "crossterm_winapi", 507 | "libc", 508 | "mio 0.8.11", 509 | "parking_lot", 510 | "signal-hook", 511 | "signal-hook-mio", 512 | "winapi", 513 | ] 514 | 515 | [[package]] 516 | name = "crossterm_winapi" 517 | version = "0.9.1" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" 520 | dependencies = [ 521 | "winapi", 522 | ] 523 | 524 | [[package]] 525 | name = "data-encoding" 526 | version = "2.8.0" 527 | source = "registry+https://github.com/rust-lang/crates.io-index" 528 | checksum = "575f75dfd25738df5b91b8e43e14d44bda14637a58fae779fd2b064f8bf3e010" 529 | 530 | [[package]] 531 | name = "displaydoc" 532 | version = "0.2.5" 533 | source = "registry+https://github.com/rust-lang/crates.io-index" 534 | checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" 535 | dependencies = [ 536 | "proc-macro2", 537 | "quote", 538 | "syn 2.0.99", 539 | ] 540 | 541 | [[package]] 542 | name = "dyn-clone" 543 | version = "1.0.19" 544 | source = "registry+https://github.com/rust-lang/crates.io-index" 545 | checksum = "1c7a8fb8a9fbf66c1f703fe16184d10ca0ee9d23be5b4436400408ba54a95005" 546 | 547 | [[package]] 548 | name = "encoding_rs" 549 | version = "0.8.35" 550 | source = "registry+https://github.com/rust-lang/crates.io-index" 551 | checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" 552 | dependencies = [ 553 | "cfg-if", 554 | ] 555 | 556 | [[package]] 557 | name = "enum-as-inner" 558 | version = "0.6.1" 559 | source = "registry+https://github.com/rust-lang/crates.io-index" 560 | checksum = "a1e6a265c649f3f5979b601d26f1d05ada116434c87741c9493cb56218f76cbc" 561 | dependencies = [ 562 | "heck 0.5.0", 563 | "proc-macro2", 564 | "quote", 565 | "syn 2.0.99", 566 | ] 567 | 568 | [[package]] 569 | name = "env_filter" 570 | version = "0.1.3" 571 | source = "registry+https://github.com/rust-lang/crates.io-index" 572 | checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" 573 | dependencies = [ 574 | "log", 575 | "regex", 576 | ] 577 | 578 | [[package]] 579 | name = "env_logger" 580 | version = "0.11.6" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" 583 | dependencies = [ 584 | "anstream", 585 | "anstyle", 586 | "env_filter", 587 | "humantime", 588 | "log", 589 | ] 590 | 591 | [[package]] 592 | name = "equivalent" 593 | version = "1.0.2" 594 | source = "registry+https://github.com/rust-lang/crates.io-index" 595 | checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" 596 | 597 | [[package]] 598 | name = "errno" 599 | version = "0.3.10" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" 602 | dependencies = [ 603 | "libc", 604 | "windows-sys 0.59.0", 605 | ] 606 | 607 | [[package]] 608 | name = "event-listener" 609 | version = "2.5.3" 610 | source = "registry+https://github.com/rust-lang/crates.io-index" 611 | checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" 612 | 613 | [[package]] 614 | name = "event-listener" 615 | version = "5.4.0" 616 | source = "registry+https://github.com/rust-lang/crates.io-index" 617 | checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" 618 | dependencies = [ 619 | "concurrent-queue", 620 | "parking", 621 | "pin-project-lite", 622 | ] 623 | 624 | [[package]] 625 | name = "event-listener-strategy" 626 | version = "0.5.3" 627 | source = "registry+https://github.com/rust-lang/crates.io-index" 628 | checksum = "3c3e4e0dd3673c1139bf041f3008816d9cf2946bbfac2945c09e523b8d7b05b2" 629 | dependencies = [ 630 | "event-listener 5.4.0", 631 | "pin-project-lite", 632 | ] 633 | 634 | [[package]] 635 | name = "fastrand" 636 | version = "2.3.0" 637 | source = "registry+https://github.com/rust-lang/crates.io-index" 638 | checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" 639 | 640 | [[package]] 641 | name = "fnv" 642 | version = "1.0.7" 643 | source = "registry+https://github.com/rust-lang/crates.io-index" 644 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 645 | 646 | [[package]] 647 | name = "foreign-types" 648 | version = "0.3.2" 649 | source = "registry+https://github.com/rust-lang/crates.io-index" 650 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" 651 | dependencies = [ 652 | "foreign-types-shared", 653 | ] 654 | 655 | [[package]] 656 | name = "foreign-types-shared" 657 | version = "0.1.1" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" 660 | 661 | [[package]] 662 | name = "form_urlencoded" 663 | version = "1.2.1" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 666 | dependencies = [ 667 | "percent-encoding", 668 | ] 669 | 670 | [[package]] 671 | name = "futures-channel" 672 | version = "0.3.31" 673 | source = "registry+https://github.com/rust-lang/crates.io-index" 674 | checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" 675 | dependencies = [ 676 | "futures-core", 677 | "futures-sink", 678 | ] 679 | 680 | [[package]] 681 | name = "futures-core" 682 | version = "0.3.31" 683 | source = "registry+https://github.com/rust-lang/crates.io-index" 684 | checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" 685 | 686 | [[package]] 687 | name = "futures-io" 688 | version = "0.3.31" 689 | source = "registry+https://github.com/rust-lang/crates.io-index" 690 | checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" 691 | 692 | [[package]] 693 | name = "futures-lite" 694 | version = "2.6.0" 695 | source = "registry+https://github.com/rust-lang/crates.io-index" 696 | checksum = "f5edaec856126859abb19ed65f39e90fea3a9574b9707f13539acf4abf7eb532" 697 | dependencies = [ 698 | "fastrand", 699 | "futures-core", 700 | "futures-io", 701 | "parking", 702 | "pin-project-lite", 703 | ] 704 | 705 | [[package]] 706 | name = "futures-sink" 707 | version = "0.3.31" 708 | source = "registry+https://github.com/rust-lang/crates.io-index" 709 | checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" 710 | 711 | [[package]] 712 | name = "futures-task" 713 | version = "0.3.31" 714 | source = "registry+https://github.com/rust-lang/crates.io-index" 715 | checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" 716 | 717 | [[package]] 718 | name = "futures-util" 719 | version = "0.3.31" 720 | source = "registry+https://github.com/rust-lang/crates.io-index" 721 | checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" 722 | dependencies = [ 723 | "futures-core", 724 | "futures-io", 725 | "futures-sink", 726 | "futures-task", 727 | "memchr", 728 | "pin-project-lite", 729 | "pin-utils", 730 | "slab", 731 | ] 732 | 733 | [[package]] 734 | name = "fuzzy-matcher" 735 | version = "0.3.7" 736 | source = "registry+https://github.com/rust-lang/crates.io-index" 737 | checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94" 738 | dependencies = [ 739 | "thread_local", 740 | ] 741 | 742 | [[package]] 743 | name = "fxhash" 744 | version = "0.2.1" 745 | source = "registry+https://github.com/rust-lang/crates.io-index" 746 | checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" 747 | dependencies = [ 748 | "byteorder", 749 | ] 750 | 751 | [[package]] 752 | name = "getrandom" 753 | version = "0.2.15" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 756 | dependencies = [ 757 | "cfg-if", 758 | "libc", 759 | "wasi 0.11.0+wasi-snapshot-preview1", 760 | ] 761 | 762 | [[package]] 763 | name = "getrandom" 764 | version = "0.3.1" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" 767 | dependencies = [ 768 | "cfg-if", 769 | "libc", 770 | "wasi 0.13.3+wasi-0.2.2", 771 | "windows-targets 0.52.6", 772 | ] 773 | 774 | [[package]] 775 | name = "gimli" 776 | version = "0.31.1" 777 | source = "registry+https://github.com/rust-lang/crates.io-index" 778 | checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" 779 | 780 | [[package]] 781 | name = "gloo-timers" 782 | version = "0.3.0" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" 785 | dependencies = [ 786 | "futures-channel", 787 | "futures-core", 788 | "js-sys", 789 | "wasm-bindgen", 790 | ] 791 | 792 | [[package]] 793 | name = "h2" 794 | version = "0.3.26" 795 | source = "registry+https://github.com/rust-lang/crates.io-index" 796 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 797 | dependencies = [ 798 | "bytes", 799 | "fnv", 800 | "futures-core", 801 | "futures-sink", 802 | "futures-util", 803 | "http 0.2.12", 804 | "indexmap", 805 | "slab", 806 | "tokio", 807 | "tokio-util", 808 | "tracing", 809 | ] 810 | 811 | [[package]] 812 | name = "h2" 813 | version = "0.4.8" 814 | source = "registry+https://github.com/rust-lang/crates.io-index" 815 | checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2" 816 | dependencies = [ 817 | "atomic-waker", 818 | "bytes", 819 | "fnv", 820 | "futures-core", 821 | "futures-sink", 822 | "http 1.2.0", 823 | "indexmap", 824 | "slab", 825 | "tokio", 826 | "tokio-util", 827 | "tracing", 828 | ] 829 | 830 | [[package]] 831 | name = "hashbrown" 832 | version = "0.15.2" 833 | source = "registry+https://github.com/rust-lang/crates.io-index" 834 | checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289" 835 | 836 | [[package]] 837 | name = "heck" 838 | version = "0.4.1" 839 | source = "registry+https://github.com/rust-lang/crates.io-index" 840 | checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" 841 | 842 | [[package]] 843 | name = "heck" 844 | version = "0.5.0" 845 | source = "registry+https://github.com/rust-lang/crates.io-index" 846 | checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 847 | 848 | [[package]] 849 | name = "hermit-abi" 850 | version = "0.1.19" 851 | source = "registry+https://github.com/rust-lang/crates.io-index" 852 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" 853 | dependencies = [ 854 | "libc", 855 | ] 856 | 857 | [[package]] 858 | name = "hermit-abi" 859 | version = "0.4.0" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "fbf6a919d6cf397374f7dfeeea91d974c7c0a7221d0d0f4f20d859d329e53fcc" 862 | 863 | [[package]] 864 | name = "hickory-proto" 865 | version = "0.24.4" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "92652067c9ce6f66ce53cc38d1169daa36e6e7eb7dd3b63b5103bd9d97117248" 868 | dependencies = [ 869 | "async-trait", 870 | "cfg-if", 871 | "data-encoding", 872 | "enum-as-inner", 873 | "futures-channel", 874 | "futures-io", 875 | "futures-util", 876 | "idna", 877 | "ipnet", 878 | "once_cell", 879 | "rand", 880 | "thiserror", 881 | "tinyvec", 882 | "tracing", 883 | "url", 884 | ] 885 | 886 | [[package]] 887 | name = "hickory-resolver" 888 | version = "0.24.4" 889 | source = "registry+https://github.com/rust-lang/crates.io-index" 890 | checksum = "cbb117a1ca520e111743ab2f6688eddee69db4e0ea242545a604dce8a66fd22e" 891 | dependencies = [ 892 | "cfg-if", 893 | "futures-util", 894 | "hickory-proto", 895 | "ipconfig", 896 | "lru-cache", 897 | "once_cell", 898 | "parking_lot", 899 | "rand", 900 | "resolv-conf", 901 | "smallvec", 902 | "thiserror", 903 | "tracing", 904 | ] 905 | 906 | [[package]] 907 | name = "hostname" 908 | version = "0.3.1" 909 | source = "registry+https://github.com/rust-lang/crates.io-index" 910 | checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" 911 | dependencies = [ 912 | "libc", 913 | "match_cfg", 914 | "winapi", 915 | ] 916 | 917 | [[package]] 918 | name = "http" 919 | version = "0.2.12" 920 | source = "registry+https://github.com/rust-lang/crates.io-index" 921 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 922 | dependencies = [ 923 | "bytes", 924 | "fnv", 925 | "itoa", 926 | ] 927 | 928 | [[package]] 929 | name = "http" 930 | version = "1.2.0" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" 933 | dependencies = [ 934 | "bytes", 935 | "fnv", 936 | "itoa", 937 | ] 938 | 939 | [[package]] 940 | name = "http-body" 941 | version = "0.4.6" 942 | source = "registry+https://github.com/rust-lang/crates.io-index" 943 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 944 | dependencies = [ 945 | "bytes", 946 | "http 0.2.12", 947 | "pin-project-lite", 948 | ] 949 | 950 | [[package]] 951 | name = "http-body" 952 | version = "1.0.1" 953 | source = "registry+https://github.com/rust-lang/crates.io-index" 954 | checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 955 | dependencies = [ 956 | "bytes", 957 | "http 1.2.0", 958 | ] 959 | 960 | [[package]] 961 | name = "http-body-util" 962 | version = "0.1.2" 963 | source = "registry+https://github.com/rust-lang/crates.io-index" 964 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 965 | dependencies = [ 966 | "bytes", 967 | "futures-util", 968 | "http 1.2.0", 969 | "http-body 1.0.1", 970 | "pin-project-lite", 971 | ] 972 | 973 | [[package]] 974 | name = "httparse" 975 | version = "1.10.1" 976 | source = "registry+https://github.com/rust-lang/crates.io-index" 977 | checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" 978 | 979 | [[package]] 980 | name = "httpdate" 981 | version = "1.0.3" 982 | source = "registry+https://github.com/rust-lang/crates.io-index" 983 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 984 | 985 | [[package]] 986 | name = "humantime" 987 | version = "2.1.0" 988 | source = "registry+https://github.com/rust-lang/crates.io-index" 989 | checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" 990 | 991 | [[package]] 992 | name = "hyper" 993 | version = "0.14.32" 994 | source = "registry+https://github.com/rust-lang/crates.io-index" 995 | checksum = "41dfc780fdec9373c01bae43289ea34c972e40ee3c9f6b3c8801a35f35586ce7" 996 | dependencies = [ 997 | "bytes", 998 | "futures-channel", 999 | "futures-core", 1000 | "futures-util", 1001 | "h2 0.3.26", 1002 | "http 0.2.12", 1003 | "http-body 0.4.6", 1004 | "httparse", 1005 | "httpdate", 1006 | "itoa", 1007 | "pin-project-lite", 1008 | "socket2", 1009 | "tokio", 1010 | "tower-service", 1011 | "tracing", 1012 | "want", 1013 | ] 1014 | 1015 | [[package]] 1016 | name = "hyper" 1017 | version = "1.6.0" 1018 | source = "registry+https://github.com/rust-lang/crates.io-index" 1019 | checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80" 1020 | dependencies = [ 1021 | "bytes", 1022 | "futures-channel", 1023 | "futures-util", 1024 | "h2 0.4.8", 1025 | "http 1.2.0", 1026 | "http-body 1.0.1", 1027 | "httparse", 1028 | "itoa", 1029 | "pin-project-lite", 1030 | "smallvec", 1031 | "tokio", 1032 | "want", 1033 | ] 1034 | 1035 | [[package]] 1036 | name = "hyper-rustls" 1037 | version = "0.27.5" 1038 | source = "registry+https://github.com/rust-lang/crates.io-index" 1039 | checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" 1040 | dependencies = [ 1041 | "futures-util", 1042 | "http 1.2.0", 1043 | "hyper 1.6.0", 1044 | "hyper-util", 1045 | "rustls", 1046 | "rustls-pki-types", 1047 | "tokio", 1048 | "tokio-rustls", 1049 | "tower-service", 1050 | ] 1051 | 1052 | [[package]] 1053 | name = "hyper-tls" 1054 | version = "0.5.0" 1055 | source = "registry+https://github.com/rust-lang/crates.io-index" 1056 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" 1057 | dependencies = [ 1058 | "bytes", 1059 | "hyper 0.14.32", 1060 | "native-tls", 1061 | "tokio", 1062 | "tokio-native-tls", 1063 | ] 1064 | 1065 | [[package]] 1066 | name = "hyper-tls" 1067 | version = "0.6.0" 1068 | source = "registry+https://github.com/rust-lang/crates.io-index" 1069 | checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" 1070 | dependencies = [ 1071 | "bytes", 1072 | "http-body-util", 1073 | "hyper 1.6.0", 1074 | "hyper-util", 1075 | "native-tls", 1076 | "tokio", 1077 | "tokio-native-tls", 1078 | "tower-service", 1079 | ] 1080 | 1081 | [[package]] 1082 | name = "hyper-util" 1083 | version = "0.1.10" 1084 | source = "registry+https://github.com/rust-lang/crates.io-index" 1085 | checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4" 1086 | dependencies = [ 1087 | "bytes", 1088 | "futures-channel", 1089 | "futures-util", 1090 | "http 1.2.0", 1091 | "http-body 1.0.1", 1092 | "hyper 1.6.0", 1093 | "pin-project-lite", 1094 | "socket2", 1095 | "tokio", 1096 | "tower-service", 1097 | "tracing", 1098 | ] 1099 | 1100 | [[package]] 1101 | name = "iana-time-zone" 1102 | version = "0.1.61" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" 1105 | dependencies = [ 1106 | "android_system_properties", 1107 | "core-foundation-sys", 1108 | "iana-time-zone-haiku", 1109 | "js-sys", 1110 | "wasm-bindgen", 1111 | "windows-core", 1112 | ] 1113 | 1114 | [[package]] 1115 | name = "iana-time-zone-haiku" 1116 | version = "0.1.2" 1117 | source = "registry+https://github.com/rust-lang/crates.io-index" 1118 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 1119 | dependencies = [ 1120 | "cc", 1121 | ] 1122 | 1123 | [[package]] 1124 | name = "icu_collections" 1125 | version = "1.5.0" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" 1128 | dependencies = [ 1129 | "displaydoc", 1130 | "yoke", 1131 | "zerofrom", 1132 | "zerovec", 1133 | ] 1134 | 1135 | [[package]] 1136 | name = "icu_locid" 1137 | version = "1.5.0" 1138 | source = "registry+https://github.com/rust-lang/crates.io-index" 1139 | checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" 1140 | dependencies = [ 1141 | "displaydoc", 1142 | "litemap", 1143 | "tinystr", 1144 | "writeable", 1145 | "zerovec", 1146 | ] 1147 | 1148 | [[package]] 1149 | name = "icu_locid_transform" 1150 | version = "1.5.0" 1151 | source = "registry+https://github.com/rust-lang/crates.io-index" 1152 | checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" 1153 | dependencies = [ 1154 | "displaydoc", 1155 | "icu_locid", 1156 | "icu_locid_transform_data", 1157 | "icu_provider", 1158 | "tinystr", 1159 | "zerovec", 1160 | ] 1161 | 1162 | [[package]] 1163 | name = "icu_locid_transform_data" 1164 | version = "1.5.0" 1165 | source = "registry+https://github.com/rust-lang/crates.io-index" 1166 | checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" 1167 | 1168 | [[package]] 1169 | name = "icu_normalizer" 1170 | version = "1.5.0" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" 1173 | dependencies = [ 1174 | "displaydoc", 1175 | "icu_collections", 1176 | "icu_normalizer_data", 1177 | "icu_properties", 1178 | "icu_provider", 1179 | "smallvec", 1180 | "utf16_iter", 1181 | "utf8_iter", 1182 | "write16", 1183 | "zerovec", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "icu_normalizer_data" 1188 | version = "1.5.0" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" 1191 | 1192 | [[package]] 1193 | name = "icu_properties" 1194 | version = "1.5.1" 1195 | source = "registry+https://github.com/rust-lang/crates.io-index" 1196 | checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" 1197 | dependencies = [ 1198 | "displaydoc", 1199 | "icu_collections", 1200 | "icu_locid_transform", 1201 | "icu_properties_data", 1202 | "icu_provider", 1203 | "tinystr", 1204 | "zerovec", 1205 | ] 1206 | 1207 | [[package]] 1208 | name = "icu_properties_data" 1209 | version = "1.5.0" 1210 | source = "registry+https://github.com/rust-lang/crates.io-index" 1211 | checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" 1212 | 1213 | [[package]] 1214 | name = "icu_provider" 1215 | version = "1.5.0" 1216 | source = "registry+https://github.com/rust-lang/crates.io-index" 1217 | checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" 1218 | dependencies = [ 1219 | "displaydoc", 1220 | "icu_locid", 1221 | "icu_provider_macros", 1222 | "stable_deref_trait", 1223 | "tinystr", 1224 | "writeable", 1225 | "yoke", 1226 | "zerofrom", 1227 | "zerovec", 1228 | ] 1229 | 1230 | [[package]] 1231 | name = "icu_provider_macros" 1232 | version = "1.5.0" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" 1235 | dependencies = [ 1236 | "proc-macro2", 1237 | "quote", 1238 | "syn 2.0.99", 1239 | ] 1240 | 1241 | [[package]] 1242 | name = "idna" 1243 | version = "1.0.3" 1244 | source = "registry+https://github.com/rust-lang/crates.io-index" 1245 | checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" 1246 | dependencies = [ 1247 | "idna_adapter", 1248 | "smallvec", 1249 | "utf8_iter", 1250 | ] 1251 | 1252 | [[package]] 1253 | name = "idna_adapter" 1254 | version = "1.2.0" 1255 | source = "registry+https://github.com/rust-lang/crates.io-index" 1256 | checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" 1257 | dependencies = [ 1258 | "icu_normalizer", 1259 | "icu_properties", 1260 | ] 1261 | 1262 | [[package]] 1263 | name = "indexmap" 1264 | version = "2.7.1" 1265 | source = "registry+https://github.com/rust-lang/crates.io-index" 1266 | checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" 1267 | dependencies = [ 1268 | "equivalent", 1269 | "hashbrown", 1270 | ] 1271 | 1272 | [[package]] 1273 | name = "inquire" 1274 | version = "0.7.5" 1275 | source = "registry+https://github.com/rust-lang/crates.io-index" 1276 | checksum = "0fddf93031af70e75410a2511ec04d49e758ed2f26dad3404a934e0fb45cc12a" 1277 | dependencies = [ 1278 | "bitflags 2.9.0", 1279 | "crossterm", 1280 | "dyn-clone", 1281 | "fuzzy-matcher", 1282 | "fxhash", 1283 | "newline-converter", 1284 | "once_cell", 1285 | "unicode-segmentation", 1286 | "unicode-width", 1287 | ] 1288 | 1289 | [[package]] 1290 | name = "ipconfig" 1291 | version = "0.3.2" 1292 | source = "registry+https://github.com/rust-lang/crates.io-index" 1293 | checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" 1294 | dependencies = [ 1295 | "socket2", 1296 | "widestring", 1297 | "windows-sys 0.48.0", 1298 | "winreg", 1299 | ] 1300 | 1301 | [[package]] 1302 | name = "ipnet" 1303 | version = "2.11.0" 1304 | source = "registry+https://github.com/rust-lang/crates.io-index" 1305 | checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" 1306 | 1307 | [[package]] 1308 | name = "is_terminal_polyfill" 1309 | version = "1.70.1" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" 1312 | 1313 | [[package]] 1314 | name = "itoa" 1315 | version = "1.0.15" 1316 | source = "registry+https://github.com/rust-lang/crates.io-index" 1317 | checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" 1318 | 1319 | [[package]] 1320 | name = "js-sys" 1321 | version = "0.3.77" 1322 | source = "registry+https://github.com/rust-lang/crates.io-index" 1323 | checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" 1324 | dependencies = [ 1325 | "once_cell", 1326 | "wasm-bindgen", 1327 | ] 1328 | 1329 | [[package]] 1330 | name = "kv-log-macro" 1331 | version = "1.0.7" 1332 | source = "registry+https://github.com/rust-lang/crates.io-index" 1333 | checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f" 1334 | dependencies = [ 1335 | "log", 1336 | ] 1337 | 1338 | [[package]] 1339 | name = "libc" 1340 | version = "0.2.170" 1341 | source = "registry+https://github.com/rust-lang/crates.io-index" 1342 | checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" 1343 | 1344 | [[package]] 1345 | name = "linked-hash-map" 1346 | version = "0.5.6" 1347 | source = "registry+https://github.com/rust-lang/crates.io-index" 1348 | checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" 1349 | 1350 | [[package]] 1351 | name = "linux-raw-sys" 1352 | version = "0.4.15" 1353 | source = "registry+https://github.com/rust-lang/crates.io-index" 1354 | checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" 1355 | 1356 | [[package]] 1357 | name = "linux-raw-sys" 1358 | version = "0.9.2" 1359 | source = "registry+https://github.com/rust-lang/crates.io-index" 1360 | checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9" 1361 | 1362 | [[package]] 1363 | name = "litemap" 1364 | version = "0.7.5" 1365 | source = "registry+https://github.com/rust-lang/crates.io-index" 1366 | checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856" 1367 | 1368 | [[package]] 1369 | name = "lock_api" 1370 | version = "0.4.12" 1371 | source = "registry+https://github.com/rust-lang/crates.io-index" 1372 | checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1373 | dependencies = [ 1374 | "autocfg", 1375 | "scopeguard", 1376 | ] 1377 | 1378 | [[package]] 1379 | name = "log" 1380 | version = "0.4.26" 1381 | source = "registry+https://github.com/rust-lang/crates.io-index" 1382 | checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" 1383 | dependencies = [ 1384 | "value-bag", 1385 | ] 1386 | 1387 | [[package]] 1388 | name = "lru-cache" 1389 | version = "0.1.2" 1390 | source = "registry+https://github.com/rust-lang/crates.io-index" 1391 | checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" 1392 | dependencies = [ 1393 | "linked-hash-map", 1394 | ] 1395 | 1396 | [[package]] 1397 | name = "match_cfg" 1398 | version = "0.1.0" 1399 | source = "registry+https://github.com/rust-lang/crates.io-index" 1400 | checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" 1401 | 1402 | [[package]] 1403 | name = "memchr" 1404 | version = "2.7.4" 1405 | source = "registry+https://github.com/rust-lang/crates.io-index" 1406 | checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1407 | 1408 | [[package]] 1409 | name = "mime" 1410 | version = "0.3.17" 1411 | source = "registry+https://github.com/rust-lang/crates.io-index" 1412 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1413 | 1414 | [[package]] 1415 | name = "miniz_oxide" 1416 | version = "0.8.5" 1417 | source = "registry+https://github.com/rust-lang/crates.io-index" 1418 | checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5" 1419 | dependencies = [ 1420 | "adler2", 1421 | ] 1422 | 1423 | [[package]] 1424 | name = "mio" 1425 | version = "0.8.11" 1426 | source = "registry+https://github.com/rust-lang/crates.io-index" 1427 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 1428 | dependencies = [ 1429 | "libc", 1430 | "log", 1431 | "wasi 0.11.0+wasi-snapshot-preview1", 1432 | "windows-sys 0.48.0", 1433 | ] 1434 | 1435 | [[package]] 1436 | name = "mio" 1437 | version = "1.0.3" 1438 | source = "registry+https://github.com/rust-lang/crates.io-index" 1439 | checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" 1440 | dependencies = [ 1441 | "libc", 1442 | "wasi 0.11.0+wasi-snapshot-preview1", 1443 | "windows-sys 0.52.0", 1444 | ] 1445 | 1446 | [[package]] 1447 | name = "native-tls" 1448 | version = "0.2.14" 1449 | source = "registry+https://github.com/rust-lang/crates.io-index" 1450 | checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" 1451 | dependencies = [ 1452 | "libc", 1453 | "log", 1454 | "openssl", 1455 | "openssl-probe", 1456 | "openssl-sys", 1457 | "schannel", 1458 | "security-framework", 1459 | "security-framework-sys", 1460 | "tempfile", 1461 | ] 1462 | 1463 | [[package]] 1464 | name = "newline-converter" 1465 | version = "0.3.0" 1466 | source = "registry+https://github.com/rust-lang/crates.io-index" 1467 | checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f" 1468 | dependencies = [ 1469 | "unicode-segmentation", 1470 | ] 1471 | 1472 | [[package]] 1473 | name = "num-traits" 1474 | version = "0.2.19" 1475 | source = "registry+https://github.com/rust-lang/crates.io-index" 1476 | checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1477 | dependencies = [ 1478 | "autocfg", 1479 | ] 1480 | 1481 | [[package]] 1482 | name = "object" 1483 | version = "0.36.7" 1484 | source = "registry+https://github.com/rust-lang/crates.io-index" 1485 | checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" 1486 | dependencies = [ 1487 | "memchr", 1488 | ] 1489 | 1490 | [[package]] 1491 | name = "once_cell" 1492 | version = "1.20.3" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" 1495 | 1496 | [[package]] 1497 | name = "openssl" 1498 | version = "0.10.71" 1499 | source = "registry+https://github.com/rust-lang/crates.io-index" 1500 | checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd" 1501 | dependencies = [ 1502 | "bitflags 2.9.0", 1503 | "cfg-if", 1504 | "foreign-types", 1505 | "libc", 1506 | "once_cell", 1507 | "openssl-macros", 1508 | "openssl-sys", 1509 | ] 1510 | 1511 | [[package]] 1512 | name = "openssl-macros" 1513 | version = "0.1.1" 1514 | source = "registry+https://github.com/rust-lang/crates.io-index" 1515 | checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" 1516 | dependencies = [ 1517 | "proc-macro2", 1518 | "quote", 1519 | "syn 2.0.99", 1520 | ] 1521 | 1522 | [[package]] 1523 | name = "openssl-probe" 1524 | version = "0.1.6" 1525 | source = "registry+https://github.com/rust-lang/crates.io-index" 1526 | checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" 1527 | 1528 | [[package]] 1529 | name = "openssl-sys" 1530 | version = "0.9.106" 1531 | source = "registry+https://github.com/rust-lang/crates.io-index" 1532 | checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd" 1533 | dependencies = [ 1534 | "cc", 1535 | "libc", 1536 | "pkg-config", 1537 | "vcpkg", 1538 | ] 1539 | 1540 | [[package]] 1541 | name = "os_str_bytes" 1542 | version = "6.6.1" 1543 | source = "registry+https://github.com/rust-lang/crates.io-index" 1544 | checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" 1545 | 1546 | [[package]] 1547 | name = "parking" 1548 | version = "2.2.1" 1549 | source = "registry+https://github.com/rust-lang/crates.io-index" 1550 | checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1551 | 1552 | [[package]] 1553 | name = "parking_lot" 1554 | version = "0.12.3" 1555 | source = "registry+https://github.com/rust-lang/crates.io-index" 1556 | checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1557 | dependencies = [ 1558 | "lock_api", 1559 | "parking_lot_core", 1560 | ] 1561 | 1562 | [[package]] 1563 | name = "parking_lot_core" 1564 | version = "0.9.10" 1565 | source = "registry+https://github.com/rust-lang/crates.io-index" 1566 | checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1567 | dependencies = [ 1568 | "cfg-if", 1569 | "libc", 1570 | "redox_syscall", 1571 | "smallvec", 1572 | "windows-targets 0.52.6", 1573 | ] 1574 | 1575 | [[package]] 1576 | name = "percent-encoding" 1577 | version = "2.3.1" 1578 | source = "registry+https://github.com/rust-lang/crates.io-index" 1579 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1580 | 1581 | [[package]] 1582 | name = "pin-project-lite" 1583 | version = "0.2.16" 1584 | source = "registry+https://github.com/rust-lang/crates.io-index" 1585 | checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" 1586 | 1587 | [[package]] 1588 | name = "pin-utils" 1589 | version = "0.1.0" 1590 | source = "registry+https://github.com/rust-lang/crates.io-index" 1591 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1592 | 1593 | [[package]] 1594 | name = "piper" 1595 | version = "0.2.4" 1596 | source = "registry+https://github.com/rust-lang/crates.io-index" 1597 | checksum = "96c8c490f422ef9a4efd2cb5b42b76c8613d7e7dfc1caf667b8a3350a5acc066" 1598 | dependencies = [ 1599 | "atomic-waker", 1600 | "fastrand", 1601 | "futures-io", 1602 | ] 1603 | 1604 | [[package]] 1605 | name = "pkg-config" 1606 | version = "0.3.32" 1607 | source = "registry+https://github.com/rust-lang/crates.io-index" 1608 | checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" 1609 | 1610 | [[package]] 1611 | name = "polling" 1612 | version = "3.7.4" 1613 | source = "registry+https://github.com/rust-lang/crates.io-index" 1614 | checksum = "a604568c3202727d1507653cb121dbd627a58684eb09a820fd746bee38b4442f" 1615 | dependencies = [ 1616 | "cfg-if", 1617 | "concurrent-queue", 1618 | "hermit-abi 0.4.0", 1619 | "pin-project-lite", 1620 | "rustix 0.38.44", 1621 | "tracing", 1622 | "windows-sys 0.59.0", 1623 | ] 1624 | 1625 | [[package]] 1626 | name = "ppv-lite86" 1627 | version = "0.2.20" 1628 | source = "registry+https://github.com/rust-lang/crates.io-index" 1629 | checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1630 | dependencies = [ 1631 | "zerocopy", 1632 | ] 1633 | 1634 | [[package]] 1635 | name = "proc-macro-error" 1636 | version = "1.0.4" 1637 | source = "registry+https://github.com/rust-lang/crates.io-index" 1638 | checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" 1639 | dependencies = [ 1640 | "proc-macro-error-attr", 1641 | "proc-macro2", 1642 | "quote", 1643 | "syn 1.0.109", 1644 | "version_check", 1645 | ] 1646 | 1647 | [[package]] 1648 | name = "proc-macro-error-attr" 1649 | version = "1.0.4" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" 1652 | dependencies = [ 1653 | "proc-macro2", 1654 | "quote", 1655 | "version_check", 1656 | ] 1657 | 1658 | [[package]] 1659 | name = "proc-macro2" 1660 | version = "1.0.94" 1661 | source = "registry+https://github.com/rust-lang/crates.io-index" 1662 | checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" 1663 | dependencies = [ 1664 | "unicode-ident", 1665 | ] 1666 | 1667 | [[package]] 1668 | name = "quick-error" 1669 | version = "1.2.3" 1670 | source = "registry+https://github.com/rust-lang/crates.io-index" 1671 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" 1672 | 1673 | [[package]] 1674 | name = "quote" 1675 | version = "1.0.39" 1676 | source = "registry+https://github.com/rust-lang/crates.io-index" 1677 | checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" 1678 | dependencies = [ 1679 | "proc-macro2", 1680 | ] 1681 | 1682 | [[package]] 1683 | name = "radio-cli" 1684 | version = "2.3.2" 1685 | dependencies = [ 1686 | "clap", 1687 | "clap-verbosity-flag", 1688 | "colored", 1689 | "env_logger", 1690 | "inquire", 1691 | "log", 1692 | "radiobrowser", 1693 | "reqwest 0.12.12", 1694 | "serde", 1695 | "serde_json", 1696 | "xdg", 1697 | ] 1698 | 1699 | [[package]] 1700 | name = "radiobrowser" 1701 | version = "0.6.1" 1702 | source = "registry+https://github.com/rust-lang/crates.io-index" 1703 | checksum = "763ad5f847e3d2e3221dac4e87370297a970e3f9eb8f2760b915001b9c79023b" 1704 | dependencies = [ 1705 | "async-std", 1706 | "async-std-resolver", 1707 | "chrono", 1708 | "log", 1709 | "rand", 1710 | "reqwest 0.11.27", 1711 | "serde", 1712 | ] 1713 | 1714 | [[package]] 1715 | name = "rand" 1716 | version = "0.8.5" 1717 | source = "registry+https://github.com/rust-lang/crates.io-index" 1718 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1719 | dependencies = [ 1720 | "libc", 1721 | "rand_chacha", 1722 | "rand_core", 1723 | ] 1724 | 1725 | [[package]] 1726 | name = "rand_chacha" 1727 | version = "0.3.1" 1728 | source = "registry+https://github.com/rust-lang/crates.io-index" 1729 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1730 | dependencies = [ 1731 | "ppv-lite86", 1732 | "rand_core", 1733 | ] 1734 | 1735 | [[package]] 1736 | name = "rand_core" 1737 | version = "0.6.4" 1738 | source = "registry+https://github.com/rust-lang/crates.io-index" 1739 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1740 | dependencies = [ 1741 | "getrandom 0.2.15", 1742 | ] 1743 | 1744 | [[package]] 1745 | name = "redox_syscall" 1746 | version = "0.5.10" 1747 | source = "registry+https://github.com/rust-lang/crates.io-index" 1748 | checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1" 1749 | dependencies = [ 1750 | "bitflags 2.9.0", 1751 | ] 1752 | 1753 | [[package]] 1754 | name = "regex" 1755 | version = "1.11.1" 1756 | source = "registry+https://github.com/rust-lang/crates.io-index" 1757 | checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" 1758 | dependencies = [ 1759 | "aho-corasick", 1760 | "memchr", 1761 | "regex-automata", 1762 | "regex-syntax", 1763 | ] 1764 | 1765 | [[package]] 1766 | name = "regex-automata" 1767 | version = "0.4.9" 1768 | source = "registry+https://github.com/rust-lang/crates.io-index" 1769 | checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" 1770 | dependencies = [ 1771 | "aho-corasick", 1772 | "memchr", 1773 | "regex-syntax", 1774 | ] 1775 | 1776 | [[package]] 1777 | name = "regex-syntax" 1778 | version = "0.8.5" 1779 | source = "registry+https://github.com/rust-lang/crates.io-index" 1780 | checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" 1781 | 1782 | [[package]] 1783 | name = "reqwest" 1784 | version = "0.11.27" 1785 | source = "registry+https://github.com/rust-lang/crates.io-index" 1786 | checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62" 1787 | dependencies = [ 1788 | "base64 0.21.7", 1789 | "bytes", 1790 | "encoding_rs", 1791 | "futures-core", 1792 | "futures-util", 1793 | "h2 0.3.26", 1794 | "http 0.2.12", 1795 | "http-body 0.4.6", 1796 | "hyper 0.14.32", 1797 | "hyper-tls 0.5.0", 1798 | "ipnet", 1799 | "js-sys", 1800 | "log", 1801 | "mime", 1802 | "native-tls", 1803 | "once_cell", 1804 | "percent-encoding", 1805 | "pin-project-lite", 1806 | "rustls-pemfile 1.0.4", 1807 | "serde", 1808 | "serde_json", 1809 | "serde_urlencoded", 1810 | "sync_wrapper 0.1.2", 1811 | "system-configuration 0.5.1", 1812 | "tokio", 1813 | "tokio-native-tls", 1814 | "tower-service", 1815 | "url", 1816 | "wasm-bindgen", 1817 | "wasm-bindgen-futures", 1818 | "web-sys", 1819 | "winreg", 1820 | ] 1821 | 1822 | [[package]] 1823 | name = "reqwest" 1824 | version = "0.12.12" 1825 | source = "registry+https://github.com/rust-lang/crates.io-index" 1826 | checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da" 1827 | dependencies = [ 1828 | "base64 0.22.1", 1829 | "bytes", 1830 | "encoding_rs", 1831 | "futures-channel", 1832 | "futures-core", 1833 | "futures-util", 1834 | "h2 0.4.8", 1835 | "http 1.2.0", 1836 | "http-body 1.0.1", 1837 | "http-body-util", 1838 | "hyper 1.6.0", 1839 | "hyper-rustls", 1840 | "hyper-tls 0.6.0", 1841 | "hyper-util", 1842 | "ipnet", 1843 | "js-sys", 1844 | "log", 1845 | "mime", 1846 | "native-tls", 1847 | "once_cell", 1848 | "percent-encoding", 1849 | "pin-project-lite", 1850 | "rustls-pemfile 2.2.0", 1851 | "serde", 1852 | "serde_json", 1853 | "serde_urlencoded", 1854 | "sync_wrapper 1.0.2", 1855 | "system-configuration 0.6.1", 1856 | "tokio", 1857 | "tokio-native-tls", 1858 | "tower", 1859 | "tower-service", 1860 | "url", 1861 | "wasm-bindgen", 1862 | "wasm-bindgen-futures", 1863 | "web-sys", 1864 | "windows-registry", 1865 | ] 1866 | 1867 | [[package]] 1868 | name = "resolv-conf" 1869 | version = "0.7.0" 1870 | source = "registry+https://github.com/rust-lang/crates.io-index" 1871 | checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" 1872 | dependencies = [ 1873 | "hostname", 1874 | "quick-error", 1875 | ] 1876 | 1877 | [[package]] 1878 | name = "ring" 1879 | version = "0.17.12" 1880 | source = "registry+https://github.com/rust-lang/crates.io-index" 1881 | checksum = "ed9b823fa29b721a59671b41d6b06e66b29e0628e207e8b1c3ceeda701ec928d" 1882 | dependencies = [ 1883 | "cc", 1884 | "cfg-if", 1885 | "getrandom 0.2.15", 1886 | "libc", 1887 | "untrusted", 1888 | "windows-sys 0.52.0", 1889 | ] 1890 | 1891 | [[package]] 1892 | name = "rustc-demangle" 1893 | version = "0.1.24" 1894 | source = "registry+https://github.com/rust-lang/crates.io-index" 1895 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1896 | 1897 | [[package]] 1898 | name = "rustix" 1899 | version = "0.38.44" 1900 | source = "registry+https://github.com/rust-lang/crates.io-index" 1901 | checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" 1902 | dependencies = [ 1903 | "bitflags 2.9.0", 1904 | "errno", 1905 | "libc", 1906 | "linux-raw-sys 0.4.15", 1907 | "windows-sys 0.59.0", 1908 | ] 1909 | 1910 | [[package]] 1911 | name = "rustix" 1912 | version = "1.0.0" 1913 | source = "registry+https://github.com/rust-lang/crates.io-index" 1914 | checksum = "17f8dcd64f141950290e45c99f7710ede1b600297c91818bb30b3667c0f45dc0" 1915 | dependencies = [ 1916 | "bitflags 2.9.0", 1917 | "errno", 1918 | "libc", 1919 | "linux-raw-sys 0.9.2", 1920 | "windows-sys 0.59.0", 1921 | ] 1922 | 1923 | [[package]] 1924 | name = "rustls" 1925 | version = "0.23.23" 1926 | source = "registry+https://github.com/rust-lang/crates.io-index" 1927 | checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" 1928 | dependencies = [ 1929 | "once_cell", 1930 | "rustls-pki-types", 1931 | "rustls-webpki", 1932 | "subtle", 1933 | "zeroize", 1934 | ] 1935 | 1936 | [[package]] 1937 | name = "rustls-pemfile" 1938 | version = "1.0.4" 1939 | source = "registry+https://github.com/rust-lang/crates.io-index" 1940 | checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" 1941 | dependencies = [ 1942 | "base64 0.21.7", 1943 | ] 1944 | 1945 | [[package]] 1946 | name = "rustls-pemfile" 1947 | version = "2.2.0" 1948 | source = "registry+https://github.com/rust-lang/crates.io-index" 1949 | checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" 1950 | dependencies = [ 1951 | "rustls-pki-types", 1952 | ] 1953 | 1954 | [[package]] 1955 | name = "rustls-pki-types" 1956 | version = "1.11.0" 1957 | source = "registry+https://github.com/rust-lang/crates.io-index" 1958 | checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" 1959 | 1960 | [[package]] 1961 | name = "rustls-webpki" 1962 | version = "0.102.8" 1963 | source = "registry+https://github.com/rust-lang/crates.io-index" 1964 | checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1965 | dependencies = [ 1966 | "ring", 1967 | "rustls-pki-types", 1968 | "untrusted", 1969 | ] 1970 | 1971 | [[package]] 1972 | name = "rustversion" 1973 | version = "1.0.20" 1974 | source = "registry+https://github.com/rust-lang/crates.io-index" 1975 | checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" 1976 | 1977 | [[package]] 1978 | name = "ryu" 1979 | version = "1.0.20" 1980 | source = "registry+https://github.com/rust-lang/crates.io-index" 1981 | checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" 1982 | 1983 | [[package]] 1984 | name = "schannel" 1985 | version = "0.1.27" 1986 | source = "registry+https://github.com/rust-lang/crates.io-index" 1987 | checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" 1988 | dependencies = [ 1989 | "windows-sys 0.59.0", 1990 | ] 1991 | 1992 | [[package]] 1993 | name = "scopeguard" 1994 | version = "1.2.0" 1995 | source = "registry+https://github.com/rust-lang/crates.io-index" 1996 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1997 | 1998 | [[package]] 1999 | name = "security-framework" 2000 | version = "2.11.1" 2001 | source = "registry+https://github.com/rust-lang/crates.io-index" 2002 | checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" 2003 | dependencies = [ 2004 | "bitflags 2.9.0", 2005 | "core-foundation", 2006 | "core-foundation-sys", 2007 | "libc", 2008 | "security-framework-sys", 2009 | ] 2010 | 2011 | [[package]] 2012 | name = "security-framework-sys" 2013 | version = "2.14.0" 2014 | source = "registry+https://github.com/rust-lang/crates.io-index" 2015 | checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" 2016 | dependencies = [ 2017 | "core-foundation-sys", 2018 | "libc", 2019 | ] 2020 | 2021 | [[package]] 2022 | name = "serde" 2023 | version = "1.0.218" 2024 | source = "registry+https://github.com/rust-lang/crates.io-index" 2025 | checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" 2026 | dependencies = [ 2027 | "serde_derive", 2028 | ] 2029 | 2030 | [[package]] 2031 | name = "serde_derive" 2032 | version = "1.0.218" 2033 | source = "registry+https://github.com/rust-lang/crates.io-index" 2034 | checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" 2035 | dependencies = [ 2036 | "proc-macro2", 2037 | "quote", 2038 | "syn 2.0.99", 2039 | ] 2040 | 2041 | [[package]] 2042 | name = "serde_json" 2043 | version = "1.0.140" 2044 | source = "registry+https://github.com/rust-lang/crates.io-index" 2045 | checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" 2046 | dependencies = [ 2047 | "itoa", 2048 | "memchr", 2049 | "ryu", 2050 | "serde", 2051 | ] 2052 | 2053 | [[package]] 2054 | name = "serde_urlencoded" 2055 | version = "0.7.1" 2056 | source = "registry+https://github.com/rust-lang/crates.io-index" 2057 | checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 2058 | dependencies = [ 2059 | "form_urlencoded", 2060 | "itoa", 2061 | "ryu", 2062 | "serde", 2063 | ] 2064 | 2065 | [[package]] 2066 | name = "shlex" 2067 | version = "1.3.0" 2068 | source = "registry+https://github.com/rust-lang/crates.io-index" 2069 | checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 2070 | 2071 | [[package]] 2072 | name = "signal-hook" 2073 | version = "0.3.17" 2074 | source = "registry+https://github.com/rust-lang/crates.io-index" 2075 | checksum = "8621587d4798caf8eb44879d42e56b9a93ea5dcd315a6487c357130095b62801" 2076 | dependencies = [ 2077 | "libc", 2078 | "signal-hook-registry", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "signal-hook-mio" 2083 | version = "0.2.4" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" 2086 | dependencies = [ 2087 | "libc", 2088 | "mio 0.8.11", 2089 | "signal-hook", 2090 | ] 2091 | 2092 | [[package]] 2093 | name = "signal-hook-registry" 2094 | version = "1.4.2" 2095 | source = "registry+https://github.com/rust-lang/crates.io-index" 2096 | checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 2097 | dependencies = [ 2098 | "libc", 2099 | ] 2100 | 2101 | [[package]] 2102 | name = "slab" 2103 | version = "0.4.9" 2104 | source = "registry+https://github.com/rust-lang/crates.io-index" 2105 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2106 | dependencies = [ 2107 | "autocfg", 2108 | ] 2109 | 2110 | [[package]] 2111 | name = "smallvec" 2112 | version = "1.14.0" 2113 | source = "registry+https://github.com/rust-lang/crates.io-index" 2114 | checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd" 2115 | 2116 | [[package]] 2117 | name = "socket2" 2118 | version = "0.5.8" 2119 | source = "registry+https://github.com/rust-lang/crates.io-index" 2120 | checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" 2121 | dependencies = [ 2122 | "libc", 2123 | "windows-sys 0.52.0", 2124 | ] 2125 | 2126 | [[package]] 2127 | name = "stable_deref_trait" 2128 | version = "1.2.0" 2129 | source = "registry+https://github.com/rust-lang/crates.io-index" 2130 | checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" 2131 | 2132 | [[package]] 2133 | name = "strsim" 2134 | version = "0.10.0" 2135 | source = "registry+https://github.com/rust-lang/crates.io-index" 2136 | checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" 2137 | 2138 | [[package]] 2139 | name = "subtle" 2140 | version = "2.6.1" 2141 | source = "registry+https://github.com/rust-lang/crates.io-index" 2142 | checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 2143 | 2144 | [[package]] 2145 | name = "syn" 2146 | version = "1.0.109" 2147 | source = "registry+https://github.com/rust-lang/crates.io-index" 2148 | checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" 2149 | dependencies = [ 2150 | "proc-macro2", 2151 | "quote", 2152 | "unicode-ident", 2153 | ] 2154 | 2155 | [[package]] 2156 | name = "syn" 2157 | version = "2.0.99" 2158 | source = "registry+https://github.com/rust-lang/crates.io-index" 2159 | checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" 2160 | dependencies = [ 2161 | "proc-macro2", 2162 | "quote", 2163 | "unicode-ident", 2164 | ] 2165 | 2166 | [[package]] 2167 | name = "sync_wrapper" 2168 | version = "0.1.2" 2169 | source = "registry+https://github.com/rust-lang/crates.io-index" 2170 | checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 2171 | 2172 | [[package]] 2173 | name = "sync_wrapper" 2174 | version = "1.0.2" 2175 | source = "registry+https://github.com/rust-lang/crates.io-index" 2176 | checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" 2177 | dependencies = [ 2178 | "futures-core", 2179 | ] 2180 | 2181 | [[package]] 2182 | name = "synstructure" 2183 | version = "0.13.1" 2184 | source = "registry+https://github.com/rust-lang/crates.io-index" 2185 | checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" 2186 | dependencies = [ 2187 | "proc-macro2", 2188 | "quote", 2189 | "syn 2.0.99", 2190 | ] 2191 | 2192 | [[package]] 2193 | name = "system-configuration" 2194 | version = "0.5.1" 2195 | source = "registry+https://github.com/rust-lang/crates.io-index" 2196 | checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" 2197 | dependencies = [ 2198 | "bitflags 1.3.2", 2199 | "core-foundation", 2200 | "system-configuration-sys 0.5.0", 2201 | ] 2202 | 2203 | [[package]] 2204 | name = "system-configuration" 2205 | version = "0.6.1" 2206 | source = "registry+https://github.com/rust-lang/crates.io-index" 2207 | checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" 2208 | dependencies = [ 2209 | "bitflags 2.9.0", 2210 | "core-foundation", 2211 | "system-configuration-sys 0.6.0", 2212 | ] 2213 | 2214 | [[package]] 2215 | name = "system-configuration-sys" 2216 | version = "0.5.0" 2217 | source = "registry+https://github.com/rust-lang/crates.io-index" 2218 | checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" 2219 | dependencies = [ 2220 | "core-foundation-sys", 2221 | "libc", 2222 | ] 2223 | 2224 | [[package]] 2225 | name = "system-configuration-sys" 2226 | version = "0.6.0" 2227 | source = "registry+https://github.com/rust-lang/crates.io-index" 2228 | checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" 2229 | dependencies = [ 2230 | "core-foundation-sys", 2231 | "libc", 2232 | ] 2233 | 2234 | [[package]] 2235 | name = "tempfile" 2236 | version = "3.18.0" 2237 | source = "registry+https://github.com/rust-lang/crates.io-index" 2238 | checksum = "2c317e0a526ee6120d8dabad239c8dadca62b24b6f168914bbbc8e2fb1f0e567" 2239 | dependencies = [ 2240 | "cfg-if", 2241 | "fastrand", 2242 | "getrandom 0.3.1", 2243 | "once_cell", 2244 | "rustix 1.0.0", 2245 | "windows-sys 0.59.0", 2246 | ] 2247 | 2248 | [[package]] 2249 | name = "termcolor" 2250 | version = "1.4.1" 2251 | source = "registry+https://github.com/rust-lang/crates.io-index" 2252 | checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" 2253 | dependencies = [ 2254 | "winapi-util", 2255 | ] 2256 | 2257 | [[package]] 2258 | name = "thiserror" 2259 | version = "1.0.69" 2260 | source = "registry+https://github.com/rust-lang/crates.io-index" 2261 | checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" 2262 | dependencies = [ 2263 | "thiserror-impl", 2264 | ] 2265 | 2266 | [[package]] 2267 | name = "thiserror-impl" 2268 | version = "1.0.69" 2269 | source = "registry+https://github.com/rust-lang/crates.io-index" 2270 | checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" 2271 | dependencies = [ 2272 | "proc-macro2", 2273 | "quote", 2274 | "syn 2.0.99", 2275 | ] 2276 | 2277 | [[package]] 2278 | name = "thread_local" 2279 | version = "1.1.8" 2280 | source = "registry+https://github.com/rust-lang/crates.io-index" 2281 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 2282 | dependencies = [ 2283 | "cfg-if", 2284 | "once_cell", 2285 | ] 2286 | 2287 | [[package]] 2288 | name = "tinystr" 2289 | version = "0.7.6" 2290 | source = "registry+https://github.com/rust-lang/crates.io-index" 2291 | checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" 2292 | dependencies = [ 2293 | "displaydoc", 2294 | "zerovec", 2295 | ] 2296 | 2297 | [[package]] 2298 | name = "tinyvec" 2299 | version = "1.9.0" 2300 | source = "registry+https://github.com/rust-lang/crates.io-index" 2301 | checksum = "09b3661f17e86524eccd4371ab0429194e0d7c008abb45f7a7495b1719463c71" 2302 | dependencies = [ 2303 | "tinyvec_macros", 2304 | ] 2305 | 2306 | [[package]] 2307 | name = "tinyvec_macros" 2308 | version = "0.1.1" 2309 | source = "registry+https://github.com/rust-lang/crates.io-index" 2310 | checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2311 | 2312 | [[package]] 2313 | name = "tokio" 2314 | version = "1.43.0" 2315 | source = "registry+https://github.com/rust-lang/crates.io-index" 2316 | checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" 2317 | dependencies = [ 2318 | "backtrace", 2319 | "bytes", 2320 | "libc", 2321 | "mio 1.0.3", 2322 | "pin-project-lite", 2323 | "socket2", 2324 | "windows-sys 0.52.0", 2325 | ] 2326 | 2327 | [[package]] 2328 | name = "tokio-native-tls" 2329 | version = "0.3.1" 2330 | source = "registry+https://github.com/rust-lang/crates.io-index" 2331 | checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" 2332 | dependencies = [ 2333 | "native-tls", 2334 | "tokio", 2335 | ] 2336 | 2337 | [[package]] 2338 | name = "tokio-rustls" 2339 | version = "0.26.2" 2340 | source = "registry+https://github.com/rust-lang/crates.io-index" 2341 | checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" 2342 | dependencies = [ 2343 | "rustls", 2344 | "tokio", 2345 | ] 2346 | 2347 | [[package]] 2348 | name = "tokio-util" 2349 | version = "0.7.13" 2350 | source = "registry+https://github.com/rust-lang/crates.io-index" 2351 | checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078" 2352 | dependencies = [ 2353 | "bytes", 2354 | "futures-core", 2355 | "futures-sink", 2356 | "pin-project-lite", 2357 | "tokio", 2358 | ] 2359 | 2360 | [[package]] 2361 | name = "tower" 2362 | version = "0.5.2" 2363 | source = "registry+https://github.com/rust-lang/crates.io-index" 2364 | checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" 2365 | dependencies = [ 2366 | "futures-core", 2367 | "futures-util", 2368 | "pin-project-lite", 2369 | "sync_wrapper 1.0.2", 2370 | "tokio", 2371 | "tower-layer", 2372 | "tower-service", 2373 | ] 2374 | 2375 | [[package]] 2376 | name = "tower-layer" 2377 | version = "0.3.3" 2378 | source = "registry+https://github.com/rust-lang/crates.io-index" 2379 | checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 2380 | 2381 | [[package]] 2382 | name = "tower-service" 2383 | version = "0.3.3" 2384 | source = "registry+https://github.com/rust-lang/crates.io-index" 2385 | checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 2386 | 2387 | [[package]] 2388 | name = "tracing" 2389 | version = "0.1.41" 2390 | source = "registry+https://github.com/rust-lang/crates.io-index" 2391 | checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" 2392 | dependencies = [ 2393 | "pin-project-lite", 2394 | "tracing-attributes", 2395 | "tracing-core", 2396 | ] 2397 | 2398 | [[package]] 2399 | name = "tracing-attributes" 2400 | version = "0.1.28" 2401 | source = "registry+https://github.com/rust-lang/crates.io-index" 2402 | checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" 2403 | dependencies = [ 2404 | "proc-macro2", 2405 | "quote", 2406 | "syn 2.0.99", 2407 | ] 2408 | 2409 | [[package]] 2410 | name = "tracing-core" 2411 | version = "0.1.33" 2412 | source = "registry+https://github.com/rust-lang/crates.io-index" 2413 | checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" 2414 | dependencies = [ 2415 | "once_cell", 2416 | ] 2417 | 2418 | [[package]] 2419 | name = "try-lock" 2420 | version = "0.2.5" 2421 | source = "registry+https://github.com/rust-lang/crates.io-index" 2422 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2423 | 2424 | [[package]] 2425 | name = "unicode-ident" 2426 | version = "1.0.18" 2427 | source = "registry+https://github.com/rust-lang/crates.io-index" 2428 | checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" 2429 | 2430 | [[package]] 2431 | name = "unicode-segmentation" 2432 | version = "1.12.0" 2433 | source = "registry+https://github.com/rust-lang/crates.io-index" 2434 | checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" 2435 | 2436 | [[package]] 2437 | name = "unicode-width" 2438 | version = "0.1.14" 2439 | source = "registry+https://github.com/rust-lang/crates.io-index" 2440 | checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" 2441 | 2442 | [[package]] 2443 | name = "untrusted" 2444 | version = "0.9.0" 2445 | source = "registry+https://github.com/rust-lang/crates.io-index" 2446 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2447 | 2448 | [[package]] 2449 | name = "url" 2450 | version = "2.5.4" 2451 | source = "registry+https://github.com/rust-lang/crates.io-index" 2452 | checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" 2453 | dependencies = [ 2454 | "form_urlencoded", 2455 | "idna", 2456 | "percent-encoding", 2457 | ] 2458 | 2459 | [[package]] 2460 | name = "utf16_iter" 2461 | version = "1.0.5" 2462 | source = "registry+https://github.com/rust-lang/crates.io-index" 2463 | checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" 2464 | 2465 | [[package]] 2466 | name = "utf8_iter" 2467 | version = "1.0.4" 2468 | source = "registry+https://github.com/rust-lang/crates.io-index" 2469 | checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" 2470 | 2471 | [[package]] 2472 | name = "utf8parse" 2473 | version = "0.2.2" 2474 | source = "registry+https://github.com/rust-lang/crates.io-index" 2475 | checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" 2476 | 2477 | [[package]] 2478 | name = "value-bag" 2479 | version = "1.10.0" 2480 | source = "registry+https://github.com/rust-lang/crates.io-index" 2481 | checksum = "3ef4c4aa54d5d05a279399bfa921ec387b7aba77caf7a682ae8d86785b8fdad2" 2482 | 2483 | [[package]] 2484 | name = "vcpkg" 2485 | version = "0.2.15" 2486 | source = "registry+https://github.com/rust-lang/crates.io-index" 2487 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" 2488 | 2489 | [[package]] 2490 | name = "version_check" 2491 | version = "0.9.5" 2492 | source = "registry+https://github.com/rust-lang/crates.io-index" 2493 | checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2494 | 2495 | [[package]] 2496 | name = "want" 2497 | version = "0.3.1" 2498 | source = "registry+https://github.com/rust-lang/crates.io-index" 2499 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2500 | dependencies = [ 2501 | "try-lock", 2502 | ] 2503 | 2504 | [[package]] 2505 | name = "wasi" 2506 | version = "0.11.0+wasi-snapshot-preview1" 2507 | source = "registry+https://github.com/rust-lang/crates.io-index" 2508 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2509 | 2510 | [[package]] 2511 | name = "wasi" 2512 | version = "0.13.3+wasi-0.2.2" 2513 | source = "registry+https://github.com/rust-lang/crates.io-index" 2514 | checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" 2515 | dependencies = [ 2516 | "wit-bindgen-rt", 2517 | ] 2518 | 2519 | [[package]] 2520 | name = "wasm-bindgen" 2521 | version = "0.2.100" 2522 | source = "registry+https://github.com/rust-lang/crates.io-index" 2523 | checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" 2524 | dependencies = [ 2525 | "cfg-if", 2526 | "once_cell", 2527 | "rustversion", 2528 | "wasm-bindgen-macro", 2529 | ] 2530 | 2531 | [[package]] 2532 | name = "wasm-bindgen-backend" 2533 | version = "0.2.100" 2534 | source = "registry+https://github.com/rust-lang/crates.io-index" 2535 | checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" 2536 | dependencies = [ 2537 | "bumpalo", 2538 | "log", 2539 | "proc-macro2", 2540 | "quote", 2541 | "syn 2.0.99", 2542 | "wasm-bindgen-shared", 2543 | ] 2544 | 2545 | [[package]] 2546 | name = "wasm-bindgen-futures" 2547 | version = "0.4.50" 2548 | source = "registry+https://github.com/rust-lang/crates.io-index" 2549 | checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" 2550 | dependencies = [ 2551 | "cfg-if", 2552 | "js-sys", 2553 | "once_cell", 2554 | "wasm-bindgen", 2555 | "web-sys", 2556 | ] 2557 | 2558 | [[package]] 2559 | name = "wasm-bindgen-macro" 2560 | version = "0.2.100" 2561 | source = "registry+https://github.com/rust-lang/crates.io-index" 2562 | checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" 2563 | dependencies = [ 2564 | "quote", 2565 | "wasm-bindgen-macro-support", 2566 | ] 2567 | 2568 | [[package]] 2569 | name = "wasm-bindgen-macro-support" 2570 | version = "0.2.100" 2571 | source = "registry+https://github.com/rust-lang/crates.io-index" 2572 | checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" 2573 | dependencies = [ 2574 | "proc-macro2", 2575 | "quote", 2576 | "syn 2.0.99", 2577 | "wasm-bindgen-backend", 2578 | "wasm-bindgen-shared", 2579 | ] 2580 | 2581 | [[package]] 2582 | name = "wasm-bindgen-shared" 2583 | version = "0.2.100" 2584 | source = "registry+https://github.com/rust-lang/crates.io-index" 2585 | checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" 2586 | dependencies = [ 2587 | "unicode-ident", 2588 | ] 2589 | 2590 | [[package]] 2591 | name = "web-sys" 2592 | version = "0.3.77" 2593 | source = "registry+https://github.com/rust-lang/crates.io-index" 2594 | checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" 2595 | dependencies = [ 2596 | "js-sys", 2597 | "wasm-bindgen", 2598 | ] 2599 | 2600 | [[package]] 2601 | name = "widestring" 2602 | version = "1.1.0" 2603 | source = "registry+https://github.com/rust-lang/crates.io-index" 2604 | checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" 2605 | 2606 | [[package]] 2607 | name = "winapi" 2608 | version = "0.3.9" 2609 | source = "registry+https://github.com/rust-lang/crates.io-index" 2610 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2611 | dependencies = [ 2612 | "winapi-i686-pc-windows-gnu", 2613 | "winapi-x86_64-pc-windows-gnu", 2614 | ] 2615 | 2616 | [[package]] 2617 | name = "winapi-i686-pc-windows-gnu" 2618 | version = "0.4.0" 2619 | source = "registry+https://github.com/rust-lang/crates.io-index" 2620 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2621 | 2622 | [[package]] 2623 | name = "winapi-util" 2624 | version = "0.1.9" 2625 | source = "registry+https://github.com/rust-lang/crates.io-index" 2626 | checksum = "cf221c93e13a30d793f7645a0e7762c55d169dbb0a49671918a2319d289b10bb" 2627 | dependencies = [ 2628 | "windows-sys 0.59.0", 2629 | ] 2630 | 2631 | [[package]] 2632 | name = "winapi-x86_64-pc-windows-gnu" 2633 | version = "0.4.0" 2634 | source = "registry+https://github.com/rust-lang/crates.io-index" 2635 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2636 | 2637 | [[package]] 2638 | name = "windows-core" 2639 | version = "0.52.0" 2640 | source = "registry+https://github.com/rust-lang/crates.io-index" 2641 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 2642 | dependencies = [ 2643 | "windows-targets 0.52.6", 2644 | ] 2645 | 2646 | [[package]] 2647 | name = "windows-link" 2648 | version = "0.1.0" 2649 | source = "registry+https://github.com/rust-lang/crates.io-index" 2650 | checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3" 2651 | 2652 | [[package]] 2653 | name = "windows-registry" 2654 | version = "0.2.0" 2655 | source = "registry+https://github.com/rust-lang/crates.io-index" 2656 | checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" 2657 | dependencies = [ 2658 | "windows-result", 2659 | "windows-strings", 2660 | "windows-targets 0.52.6", 2661 | ] 2662 | 2663 | [[package]] 2664 | name = "windows-result" 2665 | version = "0.2.0" 2666 | source = "registry+https://github.com/rust-lang/crates.io-index" 2667 | checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 2668 | dependencies = [ 2669 | "windows-targets 0.52.6", 2670 | ] 2671 | 2672 | [[package]] 2673 | name = "windows-strings" 2674 | version = "0.1.0" 2675 | source = "registry+https://github.com/rust-lang/crates.io-index" 2676 | checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 2677 | dependencies = [ 2678 | "windows-result", 2679 | "windows-targets 0.52.6", 2680 | ] 2681 | 2682 | [[package]] 2683 | name = "windows-sys" 2684 | version = "0.48.0" 2685 | source = "registry+https://github.com/rust-lang/crates.io-index" 2686 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2687 | dependencies = [ 2688 | "windows-targets 0.48.5", 2689 | ] 2690 | 2691 | [[package]] 2692 | name = "windows-sys" 2693 | version = "0.52.0" 2694 | source = "registry+https://github.com/rust-lang/crates.io-index" 2695 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2696 | dependencies = [ 2697 | "windows-targets 0.52.6", 2698 | ] 2699 | 2700 | [[package]] 2701 | name = "windows-sys" 2702 | version = "0.59.0" 2703 | source = "registry+https://github.com/rust-lang/crates.io-index" 2704 | checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2705 | dependencies = [ 2706 | "windows-targets 0.52.6", 2707 | ] 2708 | 2709 | [[package]] 2710 | name = "windows-targets" 2711 | version = "0.48.5" 2712 | source = "registry+https://github.com/rust-lang/crates.io-index" 2713 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2714 | dependencies = [ 2715 | "windows_aarch64_gnullvm 0.48.5", 2716 | "windows_aarch64_msvc 0.48.5", 2717 | "windows_i686_gnu 0.48.5", 2718 | "windows_i686_msvc 0.48.5", 2719 | "windows_x86_64_gnu 0.48.5", 2720 | "windows_x86_64_gnullvm 0.48.5", 2721 | "windows_x86_64_msvc 0.48.5", 2722 | ] 2723 | 2724 | [[package]] 2725 | name = "windows-targets" 2726 | version = "0.52.6" 2727 | source = "registry+https://github.com/rust-lang/crates.io-index" 2728 | checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2729 | dependencies = [ 2730 | "windows_aarch64_gnullvm 0.52.6", 2731 | "windows_aarch64_msvc 0.52.6", 2732 | "windows_i686_gnu 0.52.6", 2733 | "windows_i686_gnullvm", 2734 | "windows_i686_msvc 0.52.6", 2735 | "windows_x86_64_gnu 0.52.6", 2736 | "windows_x86_64_gnullvm 0.52.6", 2737 | "windows_x86_64_msvc 0.52.6", 2738 | ] 2739 | 2740 | [[package]] 2741 | name = "windows_aarch64_gnullvm" 2742 | version = "0.48.5" 2743 | source = "registry+https://github.com/rust-lang/crates.io-index" 2744 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2745 | 2746 | [[package]] 2747 | name = "windows_aarch64_gnullvm" 2748 | version = "0.52.6" 2749 | source = "registry+https://github.com/rust-lang/crates.io-index" 2750 | checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2751 | 2752 | [[package]] 2753 | name = "windows_aarch64_msvc" 2754 | version = "0.48.5" 2755 | source = "registry+https://github.com/rust-lang/crates.io-index" 2756 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2757 | 2758 | [[package]] 2759 | name = "windows_aarch64_msvc" 2760 | version = "0.52.6" 2761 | source = "registry+https://github.com/rust-lang/crates.io-index" 2762 | checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2763 | 2764 | [[package]] 2765 | name = "windows_i686_gnu" 2766 | version = "0.48.5" 2767 | source = "registry+https://github.com/rust-lang/crates.io-index" 2768 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2769 | 2770 | [[package]] 2771 | name = "windows_i686_gnu" 2772 | version = "0.52.6" 2773 | source = "registry+https://github.com/rust-lang/crates.io-index" 2774 | checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2775 | 2776 | [[package]] 2777 | name = "windows_i686_gnullvm" 2778 | version = "0.52.6" 2779 | source = "registry+https://github.com/rust-lang/crates.io-index" 2780 | checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2781 | 2782 | [[package]] 2783 | name = "windows_i686_msvc" 2784 | version = "0.48.5" 2785 | source = "registry+https://github.com/rust-lang/crates.io-index" 2786 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2787 | 2788 | [[package]] 2789 | name = "windows_i686_msvc" 2790 | version = "0.52.6" 2791 | source = "registry+https://github.com/rust-lang/crates.io-index" 2792 | checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2793 | 2794 | [[package]] 2795 | name = "windows_x86_64_gnu" 2796 | version = "0.48.5" 2797 | source = "registry+https://github.com/rust-lang/crates.io-index" 2798 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2799 | 2800 | [[package]] 2801 | name = "windows_x86_64_gnu" 2802 | version = "0.52.6" 2803 | source = "registry+https://github.com/rust-lang/crates.io-index" 2804 | checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2805 | 2806 | [[package]] 2807 | name = "windows_x86_64_gnullvm" 2808 | version = "0.48.5" 2809 | source = "registry+https://github.com/rust-lang/crates.io-index" 2810 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2811 | 2812 | [[package]] 2813 | name = "windows_x86_64_gnullvm" 2814 | version = "0.52.6" 2815 | source = "registry+https://github.com/rust-lang/crates.io-index" 2816 | checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2817 | 2818 | [[package]] 2819 | name = "windows_x86_64_msvc" 2820 | version = "0.48.5" 2821 | source = "registry+https://github.com/rust-lang/crates.io-index" 2822 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2823 | 2824 | [[package]] 2825 | name = "windows_x86_64_msvc" 2826 | version = "0.52.6" 2827 | source = "registry+https://github.com/rust-lang/crates.io-index" 2828 | checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2829 | 2830 | [[package]] 2831 | name = "winreg" 2832 | version = "0.50.0" 2833 | source = "registry+https://github.com/rust-lang/crates.io-index" 2834 | checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" 2835 | dependencies = [ 2836 | "cfg-if", 2837 | "windows-sys 0.48.0", 2838 | ] 2839 | 2840 | [[package]] 2841 | name = "wit-bindgen-rt" 2842 | version = "0.33.0" 2843 | source = "registry+https://github.com/rust-lang/crates.io-index" 2844 | checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" 2845 | dependencies = [ 2846 | "bitflags 2.9.0", 2847 | ] 2848 | 2849 | [[package]] 2850 | name = "write16" 2851 | version = "1.0.0" 2852 | source = "registry+https://github.com/rust-lang/crates.io-index" 2853 | checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" 2854 | 2855 | [[package]] 2856 | name = "writeable" 2857 | version = "0.5.5" 2858 | source = "registry+https://github.com/rust-lang/crates.io-index" 2859 | checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" 2860 | 2861 | [[package]] 2862 | name = "xdg" 2863 | version = "2.5.2" 2864 | source = "registry+https://github.com/rust-lang/crates.io-index" 2865 | checksum = "213b7324336b53d2414b2db8537e56544d981803139155afa84f76eeebb7a546" 2866 | 2867 | [[package]] 2868 | name = "yoke" 2869 | version = "0.7.5" 2870 | source = "registry+https://github.com/rust-lang/crates.io-index" 2871 | checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" 2872 | dependencies = [ 2873 | "serde", 2874 | "stable_deref_trait", 2875 | "yoke-derive", 2876 | "zerofrom", 2877 | ] 2878 | 2879 | [[package]] 2880 | name = "yoke-derive" 2881 | version = "0.7.5" 2882 | source = "registry+https://github.com/rust-lang/crates.io-index" 2883 | checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" 2884 | dependencies = [ 2885 | "proc-macro2", 2886 | "quote", 2887 | "syn 2.0.99", 2888 | "synstructure", 2889 | ] 2890 | 2891 | [[package]] 2892 | name = "zerocopy" 2893 | version = "0.7.35" 2894 | source = "registry+https://github.com/rust-lang/crates.io-index" 2895 | checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2896 | dependencies = [ 2897 | "byteorder", 2898 | "zerocopy-derive", 2899 | ] 2900 | 2901 | [[package]] 2902 | name = "zerocopy-derive" 2903 | version = "0.7.35" 2904 | source = "registry+https://github.com/rust-lang/crates.io-index" 2905 | checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2906 | dependencies = [ 2907 | "proc-macro2", 2908 | "quote", 2909 | "syn 2.0.99", 2910 | ] 2911 | 2912 | [[package]] 2913 | name = "zerofrom" 2914 | version = "0.1.6" 2915 | source = "registry+https://github.com/rust-lang/crates.io-index" 2916 | checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" 2917 | dependencies = [ 2918 | "zerofrom-derive", 2919 | ] 2920 | 2921 | [[package]] 2922 | name = "zerofrom-derive" 2923 | version = "0.1.6" 2924 | source = "registry+https://github.com/rust-lang/crates.io-index" 2925 | checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" 2926 | dependencies = [ 2927 | "proc-macro2", 2928 | "quote", 2929 | "syn 2.0.99", 2930 | "synstructure", 2931 | ] 2932 | 2933 | [[package]] 2934 | name = "zeroize" 2935 | version = "1.8.1" 2936 | source = "registry+https://github.com/rust-lang/crates.io-index" 2937 | checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2938 | 2939 | [[package]] 2940 | name = "zerovec" 2941 | version = "0.10.4" 2942 | source = "registry+https://github.com/rust-lang/crates.io-index" 2943 | checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" 2944 | dependencies = [ 2945 | "yoke", 2946 | "zerofrom", 2947 | "zerovec-derive", 2948 | ] 2949 | 2950 | [[package]] 2951 | name = "zerovec-derive" 2952 | version = "0.10.3" 2953 | source = "registry+https://github.com/rust-lang/crates.io-index" 2954 | checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" 2955 | dependencies = [ 2956 | "proc-macro2", 2957 | "quote", 2958 | "syn 2.0.99", 2959 | ] 2960 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | authors = ["Marcos Gutiérrez Alonso "] 3 | description = "A simple radio cli for listening to your favourite streams from the console" 4 | name = "radio-cli" 5 | version = "2.3.2" 6 | edition = "2024" 7 | homepage = "https://github.com/margual56/radio-cli" 8 | repository = "https://github.com/margual56/radio-cli" 9 | license = "GPL2" 10 | 11 | [package.metadata] 12 | depends = ["mpv"] 13 | optdepends = ["youtube-dl"] 14 | 15 | [dependencies] 16 | clap = { version = "^4", features = ["derive", "clap_derive"] } 17 | serde = { version = "^1.0", features = ["derive"] } 18 | serde_json = { version = "^1.0", default-features = false, features = [ 19 | "alloc", 20 | ] } 21 | colored = "^3" 22 | xdg = "^2.5" # https://docs.rs/xdg/latest/xdg/struct.BaseDirectories.html 23 | inquire = "^0" 24 | reqwest = { version = "^0", features = ["blocking", "json"] } 25 | radiobrowser = { version = "^0", features = ["blocking"] } 26 | clap-verbosity-flag = "^3" 27 | env_logger = "^0" 28 | log = "^0" 29 | 30 | [lib] 31 | path = "src/lib/lib.rs" 32 | name = "radio_libs" 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![GitHub](https://img.shields.io/github/license/margual56/radio-cli) [![Rust](https://github.com/margual56/radio-cli/actions/workflows/rust.yml/badge.svg?branch=main)](https://github.com/margual56/radio-cli/actions/workflows/rust.yml) 2 | 3 | 4 | # radio-cli 5 | A simple radio CLI written in rust. 6 | 7 | **NEW**: Now it can search for any radio station! Just select the "Other" option to be prompted for the search. 8 | 9 | [![asciicast](https://asciinema.org/a/Kt0CP53YO0IWPyUs1p2S45zO7.svg)](https://asciinema.org/a/Kt0CP53YO0IWPyUs1p2S45zO7) 10 | 11 | ### Warning! (**DEPENDENCIES**) 12 | - *Needed*: `mpv` is called to play the audio/video. (See the [How it works](https://github.com/margual56/radio-cli#how-it-works) section). 13 | - *Optional dependency*: To play youtube music you need to have `yt-dlp` or `youtube-dl` installed! 14 | 15 | ## Contributing and code of conduct 16 | Please, take a look at the [Contributing](https://github.com/margual56/radio-cli/blob/main/CONTRIBUTING.md) and [Code of Conduct](https://github.com/margual56/radio-cli/blob/main/CODE_OF_CONDUCT.md) guidelines 17 | 18 | ## Usage 19 | To use it, just type `radio-cli` after installing it and the program will guide you. 20 | 21 | When playing music, __you can use the mpv keybindings__ to control it (spacebar to play/pause, etc). 22 | 23 | You can add a country to your config (optional) and search for any radio station! 24 | 25 | # Installation 26 | - On Arch (and derivatives such as Manjaro), you can just install it through [the AUR package](https://aur.archlinux.org/cgit/aur.git/tree/PKGBUILD?h=radio-cli-bin) called **radio-cli-bin**. If you have an AUR helper: 27 | ```bash 28 | $ yay -S radio-cli-bin 29 | ``` 30 | _Note: radio-cli-git is now unsupported_ 31 | 32 | - On other systems you can: 33 | - Install it manually, without automatic update capabilities: 34 | ```bash 35 | git clone https://github.com/margual56/radio-cli.git radio-cli 36 | cd radio-cli 37 | cargo build --release 38 | sudo cp "./target/release/radio-cli" "/usr/bin/radio" 39 | mkdir -p "${XDG_CONFIG_HOME}/radio-cli/" 40 | cp "./config.json" "${XDG_CONFIG_HOME}/radio-cli/" 41 | ``` 42 | - Install it through cargo: `cargo install --git https://github.com/margual56/radio-cli` 43 | 44 | ## How it works... 45 | ...is very simple. The idea is to have a compilation of radio stations in [the config file](https://github.com/margual56/radio-cli/blob/main/config.json) and have a tool to be able to easily select one or the other. 46 | 47 | The rest is thanks to the **wonderful** and **amazing** [mpv player](https://github.com/mpv-player/mpv). mpv is the one that does all the heavy-lifting and plays whatever you throw at it. 48 | 49 | Let's say this is just a cli frontend for playing things on mpv 😄, kinda like [ani-cli](https://github.com/pystardust/ani-cli) but without search functionalities and focused on radio stations. 50 | 51 | If the station you want was not defined in the config, you will be able to search for it! 52 | 53 | ## Configurability 54 | As said before, this app is just a compilation of radios + a search prompt for online radios. It can be found in [the config file](https://github.com/margual56/radio-cli/blob/main/config.json) as a JSON, with a list of station names and their URLs. 55 | 56 | 57 | Of course you can add literally WHATEVER you want, even youtube videos (again, all thanks to mpv). 58 | 59 | 60 | Otherwise, you can just use the online search functionality. 61 | 62 | ## Fork me! 63 | If you (wrongfully xD) think mpv is not the best player, go ahead, fork me and change it :) 64 | 65 | The license is GPLv2 66 | 67 | ## Planned features 68 | Don't be surprised if these are not implemented in the end hehe (if there is no interest in the project, certainly not) 69 | 70 | - [x] ~Audio (mpv) controls when not in verbose mode~ 71 | - [x] Loop to selection list when pressing `q` while playing 72 | - [x] ~Some kind of online updating of the list of stations~ _(kind of)_ 73 | - [x] ~Code optimizations/beautification~ 74 | - [x] ~Search international online radios~ 75 | - Languages: 76 | - [x] ~English~ 77 | - [ ] Spanish 78 | - [ ] Others(?) 79 | - [x] ~An AUR installer~ 80 | 81 | # Honorable mentions 82 | - A **BIG** thank you to the amazing developer/s of [Radio Browser](https://www.radio-browser.info/) and its wonderful [API](http://api.radio-browser.info/) and [rust library](https://crates.io/crates/radiobrowser). 83 | -------------------------------------------------------------------------------- /config.json: -------------------------------------------------------------------------------- 1 | { 2 | "config_version": "2.3.0", 3 | "max_lines": 7, 4 | "country": "ES", 5 | "data": [ 6 | { 7 | "station": "lofi", 8 | "url": "https://www.youtube.com/live/jfKfPfyJRdk?si=WDl-XdfuhxBfe6XN" 9 | } 10 | ] 11 | } 12 | -------------------------------------------------------------------------------- /src/lib/browser.rs: -------------------------------------------------------------------------------- 1 | use std::error::Error; 2 | use std::rc::Rc; 3 | 4 | use crate::{Config, station::Station}; 5 | use inquire::{Autocomplete, Text, error::InquireError}; 6 | use radiobrowser::{ApiCountry, ApiStation, StationOrder, blocking::RadioBrowserAPI}; 7 | 8 | pub type StationCache = Rc>; 9 | 10 | #[derive(Debug, Clone)] 11 | pub struct Stations { 12 | stations: StationCache, 13 | } 14 | 15 | impl Autocomplete for Stations { 16 | fn get_suggestions(&mut self, input: &str) -> Result, inquire::CustomUserError> { 17 | let suggestions: Vec = self 18 | .stations 19 | .iter() 20 | .filter_map(|station| { 21 | if station.name.to_lowercase().contains(&input.to_lowercase()) { 22 | Some(station.name.clone()) 23 | } else { 24 | None 25 | } 26 | }) 27 | .collect(); 28 | Ok(suggestions) 29 | } 30 | 31 | fn get_completion( 32 | &mut self, 33 | _input: &str, 34 | highlighted_suggestion: Option, 35 | ) -> Result { 36 | match highlighted_suggestion { 37 | Some(suggestion) => Ok(Some(suggestion)), 38 | None => Err(inquire::CustomUserError::from("No suggestion available")), 39 | } 40 | } 41 | } 42 | 43 | pub struct Browser { 44 | api: RadioBrowserAPI, 45 | config: Rc, 46 | stations: StationCache, 47 | } 48 | 49 | impl Browser { 50 | pub fn new( 51 | config: Rc, 52 | cached_stations: Option, 53 | ) -> Result<(Browser, StationCache), Box> { 54 | let api = match RadioBrowserAPI::new() { 55 | Ok(r) => r, 56 | Err(e) => return Err(e), 57 | }; 58 | 59 | let stations = cached_stations.unwrap_or_else(|| { 60 | Rc::new(if let Some(code) = &config.country_code { 61 | match api 62 | .get_stations() 63 | .countrycode(code) 64 | .order(StationOrder::Clickcount) 65 | .send() 66 | { 67 | Ok(s) => s, 68 | Err(_e) => Vec::new(), 69 | } 70 | } else { 71 | match api.get_stations().order(StationOrder::Clickcount).send() { 72 | Ok(s) => s, 73 | Err(_e) => Vec::new(), 74 | } 75 | }) 76 | }); 77 | 78 | Ok(( 79 | Browser { 80 | api, 81 | config, 82 | stations: stations.clone(), 83 | }, 84 | stations, 85 | )) 86 | } 87 | 88 | pub fn get_countries() -> Result, Box> { 89 | let api = match RadioBrowserAPI::new() { 90 | Ok(r) => r, 91 | Err(e) => return Err(e), 92 | }; 93 | 94 | api.get_countries().send() 95 | } 96 | 97 | pub fn get_station(&self, name: String) -> Result { 98 | if let Some(code) = self.config.country_code.clone() { 99 | return match self.api.get_stations().name(name).countrycode(code).send() { 100 | Ok(s) => match s.get(0) { 101 | Some(x) => Ok(Station { 102 | station: x.name.clone(), 103 | url: x.url.clone(), 104 | }), 105 | None => Err(InquireError::InvalidConfiguration( 106 | "Radio station does not exist".to_string(), 107 | )), 108 | }, 109 | Err(_e) => Err(InquireError::OperationInterrupted), 110 | }; 111 | } else { 112 | return match self.api.get_stations().name(name).send() { 113 | Ok(s) => match s.get(0) { 114 | Some(x) => Ok(Station { 115 | station: x.name.clone(), 116 | url: x.url.clone(), 117 | }), 118 | None => Err(InquireError::InvalidConfiguration( 119 | "Radio station does not exist".to_string(), 120 | )), 121 | }, 122 | Err(_e) => Err(InquireError::OperationInterrupted), 123 | }; 124 | } 125 | } 126 | 127 | fn search_station(&self, message: &str, placeholder: &str) -> Result { 128 | let max_lines = match self.config.max_lines { 129 | Some(x) => x, 130 | None => Text::DEFAULT_PAGE_SIZE, 131 | }; 132 | 133 | Text::new(message) 134 | .with_placeholder(placeholder) 135 | // Deprecated: need to change to `with_autosuggester` 136 | // But for that, ApiStation needs to implement the Clone trait 137 | .with_autocomplete(Stations { 138 | stations: self.stations.clone(), 139 | }) 140 | .with_page_size(max_lines) 141 | .prompt() 142 | } 143 | 144 | pub fn prompt(self) -> Result { 145 | let station = self.search_station("Search for a station: ", "Names or keywords"); 146 | 147 | match station { 148 | Ok(s) => self.get_station(s.to_string()), 149 | Err(e) => Err(e), 150 | } 151 | } 152 | } 153 | -------------------------------------------------------------------------------- /src/lib/cli_args.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use std::path::PathBuf; 3 | 4 | #[derive(Parser, Debug, Clone)] 5 | #[clap( 6 | author, 7 | version, 8 | about, 9 | long_about = "Note: When playing, all the keybindings of mpv can be used, and `q` is reserved for exiting the program" 10 | )] 11 | pub struct Cli { 12 | /// Option: -u --url : Specifies an url to be played. 13 | #[clap(short, long, help = "Specifies an url to be played.")] 14 | pub url: Option, 15 | 16 | /// Option: -s --station : Specifies the name of the station to be played 17 | #[clap( 18 | short, 19 | long, 20 | conflicts_with = "url", 21 | help = "Specifies the name of the station to be played." 22 | )] 23 | pub station: Option, 24 | 25 | /// Flag: --show-video: If *not* present, a flag is passed down to mpv to not show the video and just play the audio. 26 | #[clap( 27 | long = "show-video", 28 | help = "If *not* present, a flag is passed down to mpv to not show the video and just play the audio." 29 | )] 30 | pub show_video: bool, 31 | 32 | /// Option: -c --config: Specify a config file other than the default. 33 | #[clap( 34 | long, 35 | short, 36 | help = "Specify a different config file from the default one." 37 | )] 38 | pub config: Option, 39 | 40 | /// Option: --country-code : Specify a country code to filter the search results 41 | #[clap( 42 | long = "country-code", 43 | help = "Specify a country code to filter the search." 44 | )] 45 | pub country_code: Option, 46 | 47 | /// Flag: --list-countries: List all the available countries and country codes to put in the config. 48 | #[clap( 49 | long = "list-countries", 50 | help = "List all the available countries and country codes to put in the config." 51 | )] 52 | pub list_countries: bool, 53 | 54 | /// Flag: --no-station-cache: Don't cache the station list loaded from the internet. 55 | #[clap( 56 | long = "no-station-cache", 57 | help = "Don't cache the station list loaded from the internet." 58 | )] 59 | pub no_station_cache: bool, 60 | 61 | /// Show extra info 62 | #[clap(flatten)] 63 | pub verbose: clap_verbosity_flag::Verbosity, 64 | 65 | /// Show debug info 66 | #[structopt(short, long)] 67 | pub debug: bool, 68 | } 69 | -------------------------------------------------------------------------------- /src/lib/config.rs: -------------------------------------------------------------------------------- 1 | extern crate xdg; 2 | 3 | use crate::errors::{ConfigError, ConfigErrorCode}; 4 | use crate::perror; 5 | use crate::station::Station; 6 | use crate::version::Version; 7 | 8 | use colored::*; 9 | use serde::Deserialize; 10 | use serde::de::{Deserializer, Error as SeError, Visitor}; 11 | use std::fmt::{Formatter, Result as ResultFmt}; 12 | use std::fs::File; 13 | use std::io::{Read, Write}; 14 | use std::path::PathBuf; 15 | 16 | const _CONFIG_URL: &str = "https://raw.githubusercontent.com/margual56/radio-cli/main/config.json"; 17 | 18 | #[derive(Deserialize, Debug, Clone)] 19 | pub struct Config { 20 | #[serde(deserialize_with = "deserialize_version")] 21 | pub config_version: Version, 22 | pub max_lines: Option, 23 | 24 | #[serde(alias = "country")] 25 | pub country_code: Option, 26 | 27 | pub data: Vec, 28 | } 29 | 30 | impl Config { 31 | pub fn load_default() -> Result { 32 | // Load config.json from $XDG_CONFIG_HOME/radio-cli 33 | let xdg_dirs = xdg::BaseDirectories::with_prefix("radio-cli").unwrap(); 34 | let config_file = Config::load_config(xdg_dirs); 35 | 36 | Config::load(config_file) 37 | } 38 | 39 | pub fn load_from_file(path: PathBuf) -> Result { 40 | Config::load(path) 41 | } 42 | 43 | fn load(file: PathBuf) -> Result { 44 | let mut config_file = match File::open(&file) { 45 | Ok(x) => x, 46 | Err(error) => { 47 | return Err(ConfigError { 48 | code: ConfigErrorCode::OpenError, 49 | message: format!("Could not open the file {:?}", file), 50 | extra: format!("{:?}", error), 51 | }); 52 | } 53 | }; 54 | 55 | // Read and parse the config into the `cfg` variable 56 | let mut config: String = String::new(); 57 | match config_file.read_to_string(&mut config) { 58 | Ok(_) => {} 59 | Err(error) => { 60 | return Err(ConfigError { 61 | code: ConfigErrorCode::ReadError, 62 | message: format!("Couldn't read the file {:?}", file), 63 | extra: format!("{:?}", error), 64 | }); 65 | } 66 | } 67 | 68 | let data: Config = match serde_json::from_str::(&config) { 69 | Ok(mut x) => { 70 | x.data.push(Station { 71 | station: "Other".to_string(), 72 | url: "".to_string(), 73 | }); 74 | 75 | x 76 | } 77 | Err(error) => { 78 | return Err(ConfigError { 79 | code: ConfigErrorCode::ParseError, 80 | message: "Couldn't parse config".to_string(), 81 | extra: format!("{:?}", error), 82 | }); 83 | } 84 | }; 85 | 86 | Ok(data) 87 | } 88 | 89 | fn load_config(dir: xdg::BaseDirectories) -> PathBuf { 90 | match dir.find_config_file("config.json") { 91 | None => { 92 | // Get the name of the directory 93 | let tmp = dir.get_config_file(""); 94 | let dir_name: &str = match tmp.to_str() { 95 | Some(x) => x, 96 | None => "??", 97 | }; 98 | 99 | // Print an error message 100 | let msg = format!("The config file does not exist in \"{}\"", dir_name); 101 | perror(msg.as_str()); 102 | 103 | // Download the file 104 | println!("\tLoading file from {}...", _CONFIG_URL.italic()); 105 | let resp = reqwest::blocking::get(_CONFIG_URL).expect("Request failed"); 106 | let body = resp.text().expect("Body invalid"); 107 | 108 | // Create the new config file 109 | let file_ref = dir 110 | .place_config_file("config.json") 111 | .expect("Could not create config file"); 112 | 113 | println!("\tDone loading!"); 114 | 115 | println!( 116 | "\tTrying to open {} to write the config...", 117 | file_ref.to_str().expect("msg: &str").bold() 118 | ); 119 | 120 | let mut file = File::create(file_ref.clone()).unwrap(); // This is write-only!! 121 | file.write_all(body.as_bytes()) 122 | .expect("Could not write to config"); 123 | 124 | drop(file); // So we close the file to be able to read it 125 | 126 | println!("\tFinished writing config. Enjoy! :)\n\n"); 127 | 128 | file_ref 129 | } 130 | Some(x) => x, 131 | } 132 | } 133 | 134 | pub fn get_url_for(&self, station_name: &str) -> Option { 135 | for s in self.data.iter() { 136 | if s.station.eq(station_name) { 137 | return Some(s.url.clone()); 138 | } 139 | } 140 | 141 | None 142 | } 143 | 144 | pub fn get_all_stations(self) -> Vec { 145 | let mut stations: Vec = Vec::new(); 146 | 147 | for s in self.data.iter() { 148 | stations.push(s.station.clone()); 149 | } 150 | 151 | stations 152 | } 153 | } 154 | 155 | fn deserialize_version<'de, D>(deserializer: D) -> Result 156 | where 157 | D: Deserializer<'de>, 158 | { 159 | struct JsonStringVisitor; 160 | 161 | impl<'de> Visitor<'de> for JsonStringVisitor { 162 | type Value = Version; 163 | 164 | fn expecting(&self, formatter: &mut Formatter) -> ResultFmt { 165 | formatter.write_str("a string") 166 | } 167 | 168 | fn visit_str(self, v: &str) -> Result 169 | where 170 | E: SeError, 171 | { 172 | // unfortunately we lose some typed information 173 | // from errors deserializing the json string 174 | match Version::from(String::from(v)) { 175 | Some(x) => Ok(x), 176 | None => Err(SeError::custom("Could not parse version")), 177 | } 178 | } 179 | } 180 | 181 | // use our visitor to deserialize an `ActualValue` 182 | deserializer.deserialize_any(JsonStringVisitor) 183 | } 184 | -------------------------------------------------------------------------------- /src/lib/errors.rs: -------------------------------------------------------------------------------- 1 | use std::fmt::{Debug, Display, Formatter, Result}; 2 | 3 | #[derive(Debug)] 4 | pub enum ConfigErrorCode { 5 | OpenError, 6 | ReadError, 7 | CloseError, 8 | ParseError, 9 | } 10 | 11 | pub struct ConfigError { 12 | pub code: ConfigErrorCode, 13 | pub message: String, 14 | pub extra: String, 15 | } 16 | 17 | // Implement std::fmt::Display for ConfigError 18 | impl Display for ConfigError { 19 | fn fmt(&self, f: &mut Formatter) -> Result { 20 | write!(f, "{}", self.message) // user-facing output 21 | } 22 | } 23 | 24 | // Implement std::fmt::Debug for ConfigError 25 | impl Debug for ConfigError { 26 | fn fmt(&self, f: &mut Formatter) -> Result { 27 | write!( 28 | f, 29 | "{{ code: {:?}, message: \"{}\", info: {} }}", 30 | self.code, self.message, self.extra 31 | ) // programmer-facing output 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/lib/lib.rs: -------------------------------------------------------------------------------- 1 | pub mod browser; 2 | mod cli_args; 3 | mod config; 4 | mod errors; 5 | mod station; 6 | mod version; 7 | 8 | pub use cli_args::Cli; 9 | pub use config::Config; 10 | pub use errors::{ConfigError, ConfigErrorCode}; 11 | pub use station::Station; 12 | pub use version::Version; 13 | 14 | use colored::*; 15 | 16 | pub fn perror(msg: &str) { 17 | println!("{} {}", "Error:".red().bold(), msg); 18 | } 19 | -------------------------------------------------------------------------------- /src/lib/station.rs: -------------------------------------------------------------------------------- 1 | use serde::Deserialize; 2 | #[derive(Deserialize, Debug, Clone)] 3 | pub struct Station { 4 | pub station: String, 5 | pub url: String, 6 | } 7 | 8 | impl std::fmt::Display for Station { 9 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { 10 | write!(f, "{}", self.station) 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/lib/version.rs: -------------------------------------------------------------------------------- 1 | use colored::*; 2 | use serde::Deserialize; 3 | use std::fmt::{Display, Formatter, Result as ResultFmt}; 4 | 5 | #[derive(Deserialize, Debug, Clone)] 6 | pub struct Version { 7 | pub major: u32, 8 | pub minor: u32, 9 | pub patch: u32, 10 | } 11 | 12 | impl Display for Version { 13 | fn fmt(&self, f: &mut Formatter<'_>) -> ResultFmt { 14 | write!(f, "{}.{}.{}", self.major, self.minor, self.patch) 15 | } 16 | } 17 | 18 | impl Version { 19 | pub fn new(major: u32, minor: u32, patch: u32) -> Version { 20 | Version { 21 | major, 22 | minor, 23 | patch, 24 | } 25 | } 26 | pub fn from(v: String) -> Option { 27 | let nums: Vec<&str> = v.split('.').collect(); 28 | 29 | if nums.len() < 3 {} 30 | 31 | let major = match nums[0].parse::() { 32 | Ok(n) => n, 33 | Err(e) => { 34 | println!( 35 | "{} ({}): {}", 36 | "Version error".bright_red(), 37 | "major".italic(), 38 | e 39 | ); 40 | return None; 41 | } 42 | }; 43 | let minor = match nums[1].parse::() { 44 | Ok(n) => n, 45 | Err(e) => { 46 | println!( 47 | "{} ({}): {}", 48 | "Version error".bright_red(), 49 | "minor".italic(), 50 | e 51 | ); 52 | return None; 53 | } 54 | }; 55 | let patch = match nums[2].parse::() { 56 | Ok(n) => n, 57 | Err(e) => { 58 | println!( 59 | "{} ({}): {}", 60 | "Version error".bright_red(), 61 | "patch".italic(), 62 | e 63 | ); 64 | return None; 65 | } 66 | }; 67 | 68 | Some(Version { 69 | major, 70 | minor, 71 | patch, 72 | }) 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | use clap::Parser; 2 | use colored::*; 3 | use inquire::{InquireError, Select}; 4 | use log::{debug, error, info, log_enabled, warn}; 5 | use radio_libs::{ 6 | Cli, Config, ConfigError, Station, Version, 7 | browser::{Browser, StationCache}, 8 | perror, 9 | }; 10 | use std::io::Write; 11 | use std::process::{Command, Stdio}; 12 | use std::rc::Rc; 13 | 14 | fn main() { 15 | let version = match Version::from(String::from(env!("CARGO_PKG_VERSION"))) { 16 | Some(v) => v, 17 | None => { 18 | error!("There was an error parsing the program version"); 19 | std::process::exit(1); 20 | } 21 | }; 22 | 23 | // Parse the arguments 24 | let args = Cli::parse(); 25 | env_logger::Builder::new() 26 | .filter_level(args.verbose.log_level_filter()) 27 | .init(); 28 | 29 | if args.list_countries { 30 | if let Ok(countries) = Browser::get_countries() { 31 | for country in countries { 32 | println!("{}: \"{}\"", country.name, country.iso_3166_1.bold()); 33 | } 34 | } else { 35 | error!("Could not connect to the server, please check your connection."); 36 | } 37 | 38 | std::process::exit(0); 39 | } 40 | 41 | // Parse the config file 42 | let config_result: Result = match args.config { 43 | None => Config::load_default(), 44 | Some(x) => Config::load_from_file(x), 45 | }; 46 | 47 | let config = match config_result { 48 | Ok(mut x) => { 49 | if let Some(cc) = args.country_code { 50 | x.country_code = Some(cc); 51 | } 52 | 53 | x 54 | } 55 | Err(error) => { 56 | debug!("{:?}", error); 57 | error!("{}", error); 58 | info!("{}", "Try passing the debug flag (-vvv). ".yellow()); 59 | 60 | info!( 61 | "{}", 62 | "Deleting your config will download the updated one." 63 | .yellow() 64 | .bold() 65 | ); 66 | 67 | std::process::exit(1); 68 | } 69 | }; 70 | let config = Rc::new(config); 71 | 72 | debug!( 73 | "{} {}", 74 | "Program version:".bright_black().bold().italic(), 75 | format!("{}", version).bright_black().italic() 76 | ); 77 | 78 | debug!( 79 | "{} {}", 80 | "Config version:".bright_black().bold().italic(), 81 | format!("{}", config.config_version).bright_black().italic() 82 | ); 83 | 84 | if config.config_version.major < version.major { 85 | warn!("\n{} {}\n", "Warning!".yellow().bold(), 86 | "The config version does not match the program version.\nThis might lead to parsing errors.".italic()) 87 | } 88 | 89 | if config.country_code.is_none() { 90 | warn!("\n{} {}", "Warning!".yellow().bold(), 91 | "The config does not contain a valid country (for example, \"ES\" for Spain or \"US\" for the US).".italic()); 92 | info!( 93 | "{} {} {}\n", 94 | "You can use the option".italic(), 95 | "--list-countries".bold().italic(), 96 | "to see the available options.".italic() 97 | ); 98 | warn!( 99 | "{}", 100 | "No country filter will be used, so searches could be slower and less accurate." 101 | .italic() 102 | ); 103 | } 104 | 105 | let mut url = args.url; 106 | let mut station_arg = args.station; 107 | let mut cached_stations = None; 108 | loop { 109 | let station = match url { 110 | None => { 111 | let (station, internet, updated_cached_stations) = 112 | get_station(station_arg, config.clone(), cached_stations.clone()); 113 | if !args.no_station_cache { 114 | cached_stations = updated_cached_stations; 115 | } 116 | 117 | print!("Playing {}", station.station.green()); 118 | print!("\x1B]0;Now playing: {}\x07", station.station); 119 | 120 | if internet { 121 | println!(" ({})", station.url.yellow().italic()); 122 | } else { 123 | println!(); 124 | } 125 | 126 | station 127 | } 128 | 129 | Some(x) => { 130 | println!("Playing url '{}'", x.blue()); 131 | 132 | Station { 133 | station: String::from("URL"), 134 | url: x, 135 | } 136 | } 137 | }; 138 | 139 | // Don't play the same station again when returning to the browser 140 | url = None; 141 | station_arg = None; 142 | 143 | println!( 144 | "{}", 145 | "Info: press 'q' to stop playing this station" 146 | .italic() 147 | .bright_black() 148 | ); 149 | 150 | let output_status = run_mpv(station, args.show_video); 151 | if !output_status.success() { 152 | perror(format!("mpv {}", output_status).as_str()); 153 | 154 | if !log_enabled!(log::Level::Info) { 155 | println!( 156 | "{}: {}", 157 | "Hint".italic().bold(), 158 | "Try running radio-cli with the verbose flag (-vv or -vvv)".italic() 159 | ); 160 | } 161 | 162 | std::process::exit(2); 163 | } 164 | } 165 | } 166 | 167 | fn run_mpv(station: Station, show_video: bool) -> std::process::ExitStatus { 168 | let mut mpv = Command::new("mpv"); 169 | let mut mpv_args: Vec = [station.url].to_vec(); 170 | 171 | if !show_video { 172 | mpv_args.push(String::from("--no-video")); 173 | } 174 | 175 | if !log_enabled!(log::Level::Info) { 176 | mpv_args.push(String::from("--really-quiet")); 177 | } 178 | 179 | let output = mpv 180 | .args(mpv_args) 181 | .stdin(Stdio::inherit()) 182 | .stdout(Stdio::inherit()) 183 | .output() 184 | .expect("Failed to execute mpv. Is it installed?"); 185 | 186 | if !output.status.success() { 187 | eprintln!("mpv error: {:?}", output.status); 188 | std::io::stderr().write_all(&output.stderr).unwrap(); 189 | } else { 190 | std::io::stdout().write_all(&output.stdout).unwrap(); 191 | } 192 | 193 | output.status 194 | } 195 | 196 | fn get_station( 197 | station: Option, 198 | config: Rc, 199 | cached_stations: Option, 200 | ) -> (Station, bool, Option) { 201 | let mut internet = false; 202 | 203 | match station { 204 | // If the station name is passed as an argument: 205 | Some(x) => { 206 | let (url, updated_cached_stations) = match config.get_url_for(&x) { 207 | Some(u) => (u, None), 208 | None => { 209 | println!( 210 | "{}", 211 | "Station not found in local config, searching on the internet..." 212 | .yellow() 213 | .italic() 214 | ); 215 | 216 | internet = true; 217 | 218 | let (brows, updated_cached_stations) = 219 | match Browser::new(config, cached_stations) { 220 | Ok(b) => b, 221 | Err(e) => { 222 | error!("Could not connect with the API"); 223 | 224 | debug!("{}", e); 225 | 226 | std::process::exit(1); 227 | } 228 | }; 229 | 230 | match brows.get_station(x.clone()) { 231 | Ok(s) => (s.url, Some(updated_cached_stations)), 232 | Err(e) => { 233 | error!("This station was not found :("); 234 | debug!("{}", e); 235 | 236 | std::process::exit(1); 237 | } 238 | } 239 | } 240 | }; 241 | 242 | ( 243 | Station { station: x, url }, 244 | internet, 245 | updated_cached_stations, 246 | ) 247 | } 248 | 249 | // Otherwise 250 | None => { 251 | // And let the user choose one 252 | match prompt(config, cached_stations) { 253 | Ok((s, b, cached)) => (s, b, cached), 254 | Err(error) => { 255 | println!("\n\t{}", "Bye!".bold().green()); 256 | 257 | info!("({:?})", error); 258 | 259 | std::process::exit(0); 260 | } 261 | } 262 | } 263 | } 264 | } 265 | 266 | /// Prompts the user to select a station. 267 | /// Returns a station and if the station was taken from the internet. 268 | pub fn prompt( 269 | config: Rc, 270 | cached_stations: Option, 271 | ) -> Result<(Station, bool, Option), InquireError> { 272 | let max_lines: usize = match config.max_lines { 273 | Some(x) => x, 274 | None => Select::::DEFAULT_PAGE_SIZE, 275 | }; 276 | 277 | let res = Select::new(&"Select a station to play:".bold(), config.data.clone()) 278 | .with_page_size(max_lines) 279 | .prompt(); 280 | 281 | let internet: bool; 282 | let (station, updated_cached_stations) = match res { 283 | Ok(s) => { 284 | if s.station.eq("Other") { 285 | internet = true; 286 | let result = Browser::new(config, cached_stations); 287 | 288 | let (brow, updated_cached_stations) = match result { 289 | Ok((b, updated_cached_stations)) => (b, updated_cached_stations), 290 | Err(_e) => return Err(InquireError::OperationInterrupted), 291 | }; 292 | 293 | match brow.prompt() { 294 | Ok(r) => (r, Some(updated_cached_stations)), 295 | Err(e) => return Err(e), 296 | } 297 | } else { 298 | internet = false; 299 | (s, None) 300 | } 301 | } 302 | Err(e) => return Err(e), 303 | }; 304 | 305 | Ok((station, internet, updated_cached_stations)) 306 | } 307 | --------------------------------------------------------------------------------