Rockbox open source high quality audio player as a Music Player Daemon
mpris rockbox mpd libadwaita audio rust zig deno
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge pull request #5 from tsirysndr/feat/rockbox-server

feat: implement a GraphQL and gRPC API

authored by

Tsiry Sandratraina and committed by
GitHub
13662228 23dba177

+17398 -6
+3
.gitignore
··· 21 21 .zig-cache 22 22 zig-out 23 23 24 + # Rust build artifacts 25 + target 26 + 24 27 # Intermediate language files 25 28 /apps/lang/*.update 26 29 /apps/lang/*.new
+132
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, caste, color, religion, or sexual 10 + identity 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 overall 26 + community 27 + 28 + Examples of unacceptable behavior include: 29 + 30 + - The use of sexualized language or imagery, and sexual attention or advances of 31 + 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 address, 35 + 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 + [GitHub Issues](https://github.com/tsirysndr/rockbox-zig/issues). All 64 + 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 of 86 + 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 permanent 93 + 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 the 113 + community. 114 + 115 + ## Attribution 116 + 117 + This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 + version 2.1, available at 119 + [https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. 120 + 121 + Community Impact Guidelines were inspired by 122 + [Mozilla's code of conduct enforcement ladder][Mozilla CoC]. 123 + 124 + For answers to common questions about this code of conduct, see the FAQ at 125 + [https://www.contributor-covenant.org/faq][FAQ]. Translations are available at 126 + [https://www.contributor-covenant.org/translations][translations]. 127 + 128 + [homepage]: https://www.contributor-covenant.org 129 + [v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html 130 + [Mozilla CoC]: https://github.com/mozilla/diversity 131 + [FAQ]: https://www.contributor-covenant.org/faq 132 + [translations]: https://www.contributor-covenant.org/translations
+70
CONTRIBUTING.md
··· 1 + # Contributing Guidelines 2 + 3 + Thank you for your interest in contributing to our project. Whether it's a bug 4 + report, new feature, correction, or additional documentation, we greatly value 5 + feedback and contributions from our community. 6 + 7 + Please read through this document before submitting any issues or pull requests 8 + to ensure we have all the necessary information to effectively respond to your 9 + bug report or contribution. 10 + 11 + ## Reporting Bugs/Feature Requests 12 + 13 + We welcome you to use the GitHub issue tracker to report bugs or suggest 14 + features. 15 + 16 + When filing an issue, please check existing open, or recently closed, issues to 17 + make sure somebody else hasn't already reported the issue. Please try to include 18 + as much information as you can. Details like these are incredibly useful: 19 + 20 + - A reproducible test case or series of steps 21 + - The version of our code being used 22 + - Any modifications you've made relevant to the bug 23 + - Anything unusual about your environment or deployment 24 + 25 + ## Contributing via Pull Requests 26 + 27 + Contributions via pull requests are much appreciated. Before sending us a pull 28 + request, please ensure that: 29 + 30 + 1. You are working against the latest source on the _master_ branch. 31 + 2. You check existing open, and recently merged, pull requests to make sure 32 + someone else hasn't addressed the problem already. 33 + 3. You open an issue to discuss any significant work - we would hate for your 34 + time to be wasted. 35 + 36 + To send us a pull request, please: 37 + 38 + 1. Fork the repository. 39 + 2. Modify the source; please focus on the specific change you are contributing. 40 + If you also reformat all the code, it will be hard for us to focus on your 41 + change. 42 + 3. Ensure local tests pass. 43 + 4. Commit to your fork using clear commit messages. 44 + 5. Send us a pull request, answering any default questions in the pull request 45 + interface. 46 + 6. Pay attention to any automated CI failures reported in the pull request, and 47 + stay involved in the conversation. 48 + 49 + GitHub provides additional document on 50 + [forking a repository](https://help.github.com/articles/fork-a-repo/) and 51 + [creating a pull request](https://help.github.com/articles/creating-a-pull-request/). 52 + 53 + ## Finding contributions to work on 54 + 55 + Looking at the existing issues is a great way to find something to contribute 56 + on. As our projects, by default, use the default GitHub issue labels 57 + (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 58 + 'help wanted' issues is a great place to start. 59 + 60 + ## Code of Conduct 61 + 62 + This project has adopted the 63 + [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1, 64 + available at 65 + https://www.contributor-covenant.org/version/2/1/code_of_conduct.html. 66 + 67 + ## Licensing 68 + 69 + See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to 70 + confirm the licensing of your contribution.
+2812
Cargo.lock
··· 1 + # This file is automatically @generated by Cargo. 2 + # It is not intended for manual editing. 3 + version = 3 4 + 5 + [[package]] 6 + name = "Inflector" 7 + version = "0.11.4" 8 + source = "registry+https://github.com/rust-lang/crates.io-index" 9 + checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" 10 + dependencies = [ 11 + "lazy_static", 12 + "regex", 13 + ] 14 + 15 + [[package]] 16 + name = "actix" 17 + version = "0.13.5" 18 + source = "registry+https://github.com/rust-lang/crates.io-index" 19 + checksum = "de7fa236829ba0841304542f7614c42b80fca007455315c45c785ccfa873a85b" 20 + dependencies = [ 21 + "actix-macros", 22 + "actix-rt", 23 + "actix_derive", 24 + "bitflags", 25 + "bytes", 26 + "crossbeam-channel", 27 + "futures-core", 28 + "futures-sink", 29 + "futures-task", 30 + "futures-util", 31 + "log", 32 + "once_cell", 33 + "parking_lot", 34 + "pin-project-lite", 35 + "smallvec", 36 + "tokio", 37 + "tokio-util", 38 + ] 39 + 40 + [[package]] 41 + name = "actix-codec" 42 + version = "0.5.2" 43 + source = "registry+https://github.com/rust-lang/crates.io-index" 44 + checksum = "5f7b0a21988c1bf877cf4759ef5ddaac04c1c9fe808c9142ecb78ba97d97a28a" 45 + dependencies = [ 46 + "bitflags", 47 + "bytes", 48 + "futures-core", 49 + "futures-sink", 50 + "memchr", 51 + "pin-project-lite", 52 + "tokio", 53 + "tokio-util", 54 + "tracing", 55 + ] 56 + 57 + [[package]] 58 + name = "actix-cors" 59 + version = "0.7.0" 60 + source = "registry+https://github.com/rust-lang/crates.io-index" 61 + checksum = "f9e772b3bcafe335042b5db010ab7c09013dad6eac4915c91d8d50902769f331" 62 + dependencies = [ 63 + "actix-utils", 64 + "actix-web", 65 + "derive_more", 66 + "futures-util", 67 + "log", 68 + "once_cell", 69 + "smallvec", 70 + ] 71 + 72 + [[package]] 73 + name = "actix-http" 74 + version = "3.9.0" 75 + source = "registry+https://github.com/rust-lang/crates.io-index" 76 + checksum = "d48f96fc3003717aeb9856ca3d02a8c7de502667ad76eeacd830b48d2e91fac4" 77 + dependencies = [ 78 + "actix-codec", 79 + "actix-rt", 80 + "actix-service", 81 + "actix-utils", 82 + "ahash", 83 + "base64", 84 + "bitflags", 85 + "brotli", 86 + "bytes", 87 + "bytestring", 88 + "derive_more", 89 + "encoding_rs", 90 + "flate2", 91 + "futures-core", 92 + "h2 0.3.26", 93 + "http 0.2.12", 94 + "httparse", 95 + "httpdate", 96 + "itoa", 97 + "language-tags", 98 + "local-channel", 99 + "mime", 100 + "percent-encoding", 101 + "pin-project-lite", 102 + "rand", 103 + "sha1", 104 + "smallvec", 105 + "tokio", 106 + "tokio-util", 107 + "tracing", 108 + "zstd", 109 + ] 110 + 111 + [[package]] 112 + name = "actix-macros" 113 + version = "0.2.4" 114 + source = "registry+https://github.com/rust-lang/crates.io-index" 115 + checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" 116 + dependencies = [ 117 + "quote", 118 + "syn", 119 + ] 120 + 121 + [[package]] 122 + name = "actix-router" 123 + version = "0.5.3" 124 + source = "registry+https://github.com/rust-lang/crates.io-index" 125 + checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8" 126 + dependencies = [ 127 + "bytestring", 128 + "cfg-if", 129 + "http 0.2.12", 130 + "regex", 131 + "regex-lite", 132 + "serde", 133 + "tracing", 134 + ] 135 + 136 + [[package]] 137 + name = "actix-rt" 138 + version = "2.10.0" 139 + source = "registry+https://github.com/rust-lang/crates.io-index" 140 + checksum = "24eda4e2a6e042aa4e55ac438a2ae052d3b5da0ecf83d7411e1a368946925208" 141 + dependencies = [ 142 + "futures-core", 143 + "tokio", 144 + ] 145 + 146 + [[package]] 147 + name = "actix-server" 148 + version = "2.5.0" 149 + source = "registry+https://github.com/rust-lang/crates.io-index" 150 + checksum = "7ca2549781d8dd6d75c40cf6b6051260a2cc2f3c62343d761a969a0640646894" 151 + dependencies = [ 152 + "actix-rt", 153 + "actix-service", 154 + "actix-utils", 155 + "futures-core", 156 + "futures-util", 157 + "mio", 158 + "socket2", 159 + "tokio", 160 + "tracing", 161 + ] 162 + 163 + [[package]] 164 + name = "actix-service" 165 + version = "2.0.2" 166 + source = "registry+https://github.com/rust-lang/crates.io-index" 167 + checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" 168 + dependencies = [ 169 + "futures-core", 170 + "paste", 171 + "pin-project-lite", 172 + ] 173 + 174 + [[package]] 175 + name = "actix-utils" 176 + version = "3.0.1" 177 + source = "registry+https://github.com/rust-lang/crates.io-index" 178 + checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" 179 + dependencies = [ 180 + "local-waker", 181 + "pin-project-lite", 182 + ] 183 + 184 + [[package]] 185 + name = "actix-web" 186 + version = "4.9.0" 187 + source = "registry+https://github.com/rust-lang/crates.io-index" 188 + checksum = "9180d76e5cc7ccbc4d60a506f2c727730b154010262df5b910eb17dbe4b8cb38" 189 + dependencies = [ 190 + "actix-codec", 191 + "actix-http", 192 + "actix-macros", 193 + "actix-router", 194 + "actix-rt", 195 + "actix-server", 196 + "actix-service", 197 + "actix-utils", 198 + "actix-web-codegen", 199 + "ahash", 200 + "bytes", 201 + "bytestring", 202 + "cfg-if", 203 + "cookie", 204 + "derive_more", 205 + "encoding_rs", 206 + "futures-core", 207 + "futures-util", 208 + "impl-more", 209 + "itoa", 210 + "language-tags", 211 + "log", 212 + "mime", 213 + "once_cell", 214 + "pin-project-lite", 215 + "regex", 216 + "regex-lite", 217 + "serde", 218 + "serde_json", 219 + "serde_urlencoded", 220 + "smallvec", 221 + "socket2", 222 + "time", 223 + "url", 224 + ] 225 + 226 + [[package]] 227 + name = "actix-web-actors" 228 + version = "4.3.1+deprecated" 229 + source = "registry+https://github.com/rust-lang/crates.io-index" 230 + checksum = "f98c5300b38fd004fe7d2a964f9a90813fdbe8a81fed500587e78b1b71c6f980" 231 + dependencies = [ 232 + "actix", 233 + "actix-codec", 234 + "actix-http", 235 + "actix-web", 236 + "bytes", 237 + "bytestring", 238 + "futures-core", 239 + "pin-project-lite", 240 + "tokio", 241 + "tokio-util", 242 + ] 243 + 244 + [[package]] 245 + name = "actix-web-codegen" 246 + version = "4.3.0" 247 + source = "registry+https://github.com/rust-lang/crates.io-index" 248 + checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8" 249 + dependencies = [ 250 + "actix-router", 251 + "proc-macro2", 252 + "quote", 253 + "syn", 254 + ] 255 + 256 + [[package]] 257 + name = "actix_derive" 258 + version = "0.6.1" 259 + source = "registry+https://github.com/rust-lang/crates.io-index" 260 + checksum = "7c7db3d5a9718568e4cf4a537cfd7070e6e6ff7481510d0237fb529ac850f6d3" 261 + dependencies = [ 262 + "proc-macro2", 263 + "quote", 264 + "syn", 265 + ] 266 + 267 + [[package]] 268 + name = "addr2line" 269 + version = "0.24.1" 270 + source = "registry+https://github.com/rust-lang/crates.io-index" 271 + checksum = "f5fb1d8e4442bd405fdfd1dacb42792696b0cf9cb15882e5d097b742a676d375" 272 + dependencies = [ 273 + "gimli", 274 + ] 275 + 276 + [[package]] 277 + name = "adler2" 278 + version = "2.0.0" 279 + source = "registry+https://github.com/rust-lang/crates.io-index" 280 + checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" 281 + 282 + [[package]] 283 + name = "ahash" 284 + version = "0.8.11" 285 + source = "registry+https://github.com/rust-lang/crates.io-index" 286 + checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" 287 + dependencies = [ 288 + "cfg-if", 289 + "getrandom", 290 + "once_cell", 291 + "version_check", 292 + "zerocopy", 293 + ] 294 + 295 + [[package]] 296 + name = "aho-corasick" 297 + version = "1.1.3" 298 + source = "registry+https://github.com/rust-lang/crates.io-index" 299 + checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" 300 + dependencies = [ 301 + "memchr", 302 + ] 303 + 304 + [[package]] 305 + name = "alloc-no-stdlib" 306 + version = "2.0.4" 307 + source = "registry+https://github.com/rust-lang/crates.io-index" 308 + checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" 309 + 310 + [[package]] 311 + name = "alloc-stdlib" 312 + version = "0.2.2" 313 + source = "registry+https://github.com/rust-lang/crates.io-index" 314 + checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" 315 + dependencies = [ 316 + "alloc-no-stdlib", 317 + ] 318 + 319 + [[package]] 320 + name = "anyhow" 321 + version = "1.0.87" 322 + source = "registry+https://github.com/rust-lang/crates.io-index" 323 + checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" 324 + 325 + [[package]] 326 + name = "ascii_utils" 327 + version = "0.9.3" 328 + source = "registry+https://github.com/rust-lang/crates.io-index" 329 + checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a" 330 + 331 + [[package]] 332 + name = "async-channel" 333 + version = "2.3.1" 334 + source = "registry+https://github.com/rust-lang/crates.io-index" 335 + checksum = "89b47800b0be77592da0afd425cc03468052844aff33b84e33cc696f64e77b6a" 336 + dependencies = [ 337 + "concurrent-queue", 338 + "event-listener-strategy", 339 + "futures-core", 340 + "pin-project-lite", 341 + ] 342 + 343 + [[package]] 344 + name = "async-graphql" 345 + version = "7.0.9" 346 + source = "registry+https://github.com/rust-lang/crates.io-index" 347 + checksum = "9d37c3e9ba322eb00e9e5e997d58f08e8b6de037325b9367ac59bca8e3cd46af" 348 + dependencies = [ 349 + "async-graphql-derive", 350 + "async-graphql-parser", 351 + "async-graphql-value", 352 + "async-stream", 353 + "async-trait", 354 + "base64", 355 + "bytes", 356 + "fast_chemail", 357 + "fnv", 358 + "futures-timer", 359 + "futures-util", 360 + "handlebars", 361 + "http 1.1.0", 362 + "indexmap 2.5.0", 363 + "mime", 364 + "multer", 365 + "num-traits", 366 + "once_cell", 367 + "pin-project-lite", 368 + "regex", 369 + "serde", 370 + "serde_json", 371 + "serde_urlencoded", 372 + "static_assertions_next", 373 + "tempfile", 374 + "thiserror", 375 + ] 376 + 377 + [[package]] 378 + name = "async-graphql-actix-web" 379 + version = "7.0.9" 380 + source = "registry+https://github.com/rust-lang/crates.io-index" 381 + checksum = "b84194aa7c13d234db9eb496945a345f2e76cf14b60de15ce95610207df2e93d" 382 + dependencies = [ 383 + "actix", 384 + "actix-http", 385 + "actix-web", 386 + "actix-web-actors", 387 + "async-channel", 388 + "async-graphql", 389 + "async-stream", 390 + "futures-channel", 391 + "futures-util", 392 + "serde_json", 393 + "thiserror", 394 + ] 395 + 396 + [[package]] 397 + name = "async-graphql-derive" 398 + version = "7.0.9" 399 + source = "registry+https://github.com/rust-lang/crates.io-index" 400 + checksum = "f1141703c11c6ad4fa9b3b0e1e476dea01dbd18a44db00f949b804afaab2f344" 401 + dependencies = [ 402 + "Inflector", 403 + "async-graphql-parser", 404 + "darling", 405 + "proc-macro-crate", 406 + "proc-macro2", 407 + "quote", 408 + "strum", 409 + "syn", 410 + "thiserror", 411 + ] 412 + 413 + [[package]] 414 + name = "async-graphql-parser" 415 + version = "7.0.9" 416 + source = "registry+https://github.com/rust-lang/crates.io-index" 417 + checksum = "2f66edcce4c38c18f7eb181fdf561c3d3aa2d644ce7358fc7a928c00a4ffef17" 418 + dependencies = [ 419 + "async-graphql-value", 420 + "pest", 421 + "serde", 422 + "serde_json", 423 + ] 424 + 425 + [[package]] 426 + name = "async-graphql-value" 427 + version = "7.0.9" 428 + source = "registry+https://github.com/rust-lang/crates.io-index" 429 + checksum = "3b0206011cad065420c27988f17dd7fe201a0e056b20c262209b7bffcd6fa176" 430 + dependencies = [ 431 + "bytes", 432 + "indexmap 2.5.0", 433 + "serde", 434 + "serde_json", 435 + ] 436 + 437 + [[package]] 438 + name = "async-stream" 439 + version = "0.3.5" 440 + source = "registry+https://github.com/rust-lang/crates.io-index" 441 + checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 442 + dependencies = [ 443 + "async-stream-impl", 444 + "futures-core", 445 + "pin-project-lite", 446 + ] 447 + 448 + [[package]] 449 + name = "async-stream-impl" 450 + version = "0.3.5" 451 + source = "registry+https://github.com/rust-lang/crates.io-index" 452 + checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 453 + dependencies = [ 454 + "proc-macro2", 455 + "quote", 456 + "syn", 457 + ] 458 + 459 + [[package]] 460 + name = "async-trait" 461 + version = "0.1.82" 462 + source = "registry+https://github.com/rust-lang/crates.io-index" 463 + checksum = "a27b8a3a6e1a44fa4c8baf1f653e4172e81486d4941f2237e20dc2d0cf4ddff1" 464 + dependencies = [ 465 + "proc-macro2", 466 + "quote", 467 + "syn", 468 + ] 469 + 470 + [[package]] 471 + name = "atomic-waker" 472 + version = "1.1.2" 473 + source = "registry+https://github.com/rust-lang/crates.io-index" 474 + checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" 475 + 476 + [[package]] 477 + name = "autocfg" 478 + version = "1.3.0" 479 + source = "registry+https://github.com/rust-lang/crates.io-index" 480 + checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" 481 + 482 + [[package]] 483 + name = "axum" 484 + version = "0.7.5" 485 + source = "registry+https://github.com/rust-lang/crates.io-index" 486 + checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" 487 + dependencies = [ 488 + "async-trait", 489 + "axum-core", 490 + "bytes", 491 + "futures-util", 492 + "http 1.1.0", 493 + "http-body", 494 + "http-body-util", 495 + "itoa", 496 + "matchit", 497 + "memchr", 498 + "mime", 499 + "percent-encoding", 500 + "pin-project-lite", 501 + "rustversion", 502 + "serde", 503 + "sync_wrapper 1.0.1", 504 + "tower", 505 + "tower-layer", 506 + "tower-service", 507 + ] 508 + 509 + [[package]] 510 + name = "axum-core" 511 + version = "0.4.3" 512 + source = "registry+https://github.com/rust-lang/crates.io-index" 513 + checksum = "a15c63fd72d41492dc4f497196f5da1fb04fb7529e631d73630d1b491e47a2e3" 514 + dependencies = [ 515 + "async-trait", 516 + "bytes", 517 + "futures-util", 518 + "http 1.1.0", 519 + "http-body", 520 + "http-body-util", 521 + "mime", 522 + "pin-project-lite", 523 + "rustversion", 524 + "sync_wrapper 0.1.2", 525 + "tower-layer", 526 + "tower-service", 527 + ] 528 + 529 + [[package]] 530 + name = "backtrace" 531 + version = "0.3.74" 532 + source = "registry+https://github.com/rust-lang/crates.io-index" 533 + checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" 534 + dependencies = [ 535 + "addr2line", 536 + "cfg-if", 537 + "libc", 538 + "miniz_oxide", 539 + "object", 540 + "rustc-demangle", 541 + "windows-targets", 542 + ] 543 + 544 + [[package]] 545 + name = "base64" 546 + version = "0.22.1" 547 + source = "registry+https://github.com/rust-lang/crates.io-index" 548 + checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" 549 + 550 + [[package]] 551 + name = "bitflags" 552 + version = "2.6.0" 553 + source = "registry+https://github.com/rust-lang/crates.io-index" 554 + checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" 555 + 556 + [[package]] 557 + name = "block-buffer" 558 + version = "0.10.4" 559 + source = "registry+https://github.com/rust-lang/crates.io-index" 560 + checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 561 + dependencies = [ 562 + "generic-array", 563 + ] 564 + 565 + [[package]] 566 + name = "brotli" 567 + version = "6.0.0" 568 + source = "registry+https://github.com/rust-lang/crates.io-index" 569 + checksum = "74f7971dbd9326d58187408ab83117d8ac1bb9c17b085fdacd1cf2f598719b6b" 570 + dependencies = [ 571 + "alloc-no-stdlib", 572 + "alloc-stdlib", 573 + "brotli-decompressor", 574 + ] 575 + 576 + [[package]] 577 + name = "brotli-decompressor" 578 + version = "4.0.1" 579 + source = "registry+https://github.com/rust-lang/crates.io-index" 580 + checksum = "9a45bd2e4095a8b518033b128020dd4a55aab1c0a381ba4404a472630f4bc362" 581 + dependencies = [ 582 + "alloc-no-stdlib", 583 + "alloc-stdlib", 584 + ] 585 + 586 + [[package]] 587 + name = "bumpalo" 588 + version = "3.16.0" 589 + source = "registry+https://github.com/rust-lang/crates.io-index" 590 + checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" 591 + 592 + [[package]] 593 + name = "byteorder" 594 + version = "1.5.0" 595 + source = "registry+https://github.com/rust-lang/crates.io-index" 596 + checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" 597 + 598 + [[package]] 599 + name = "bytes" 600 + version = "1.7.1" 601 + source = "registry+https://github.com/rust-lang/crates.io-index" 602 + checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50" 603 + dependencies = [ 604 + "serde", 605 + ] 606 + 607 + [[package]] 608 + name = "bytestring" 609 + version = "1.3.1" 610 + source = "registry+https://github.com/rust-lang/crates.io-index" 611 + checksum = "74d80203ea6b29df88012294f62733de21cfeab47f17b41af3a38bc30a03ee72" 612 + dependencies = [ 613 + "bytes", 614 + ] 615 + 616 + [[package]] 617 + name = "cc" 618 + version = "1.1.18" 619 + source = "registry+https://github.com/rust-lang/crates.io-index" 620 + checksum = "b62ac837cdb5cb22e10a256099b4fc502b1dfe560cb282963a974d7abd80e476" 621 + dependencies = [ 622 + "jobserver", 623 + "libc", 624 + "shlex", 625 + ] 626 + 627 + [[package]] 628 + name = "cfg-if" 629 + version = "1.0.0" 630 + source = "registry+https://github.com/rust-lang/crates.io-index" 631 + checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 632 + 633 + [[package]] 634 + name = "concurrent-queue" 635 + version = "2.5.0" 636 + source = "registry+https://github.com/rust-lang/crates.io-index" 637 + checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" 638 + dependencies = [ 639 + "crossbeam-utils", 640 + ] 641 + 642 + [[package]] 643 + name = "convert_case" 644 + version = "0.4.0" 645 + source = "registry+https://github.com/rust-lang/crates.io-index" 646 + checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" 647 + 648 + [[package]] 649 + name = "cookie" 650 + version = "0.16.2" 651 + source = "registry+https://github.com/rust-lang/crates.io-index" 652 + checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" 653 + dependencies = [ 654 + "percent-encoding", 655 + "time", 656 + "version_check", 657 + ] 658 + 659 + [[package]] 660 + name = "cpufeatures" 661 + version = "0.2.14" 662 + source = "registry+https://github.com/rust-lang/crates.io-index" 663 + checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" 664 + dependencies = [ 665 + "libc", 666 + ] 667 + 668 + [[package]] 669 + name = "crc32fast" 670 + version = "1.4.2" 671 + source = "registry+https://github.com/rust-lang/crates.io-index" 672 + checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" 673 + dependencies = [ 674 + "cfg-if", 675 + ] 676 + 677 + [[package]] 678 + name = "crossbeam-channel" 679 + version = "0.5.13" 680 + source = "registry+https://github.com/rust-lang/crates.io-index" 681 + checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" 682 + dependencies = [ 683 + "crossbeam-utils", 684 + ] 685 + 686 + [[package]] 687 + name = "crossbeam-utils" 688 + version = "0.8.20" 689 + source = "registry+https://github.com/rust-lang/crates.io-index" 690 + checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" 691 + 692 + [[package]] 693 + name = "crypto-common" 694 + version = "0.1.6" 695 + source = "registry+https://github.com/rust-lang/crates.io-index" 696 + checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 697 + dependencies = [ 698 + "generic-array", 699 + "typenum", 700 + ] 701 + 702 + [[package]] 703 + name = "darling" 704 + version = "0.20.10" 705 + source = "registry+https://github.com/rust-lang/crates.io-index" 706 + checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" 707 + dependencies = [ 708 + "darling_core", 709 + "darling_macro", 710 + ] 711 + 712 + [[package]] 713 + name = "darling_core" 714 + version = "0.20.10" 715 + source = "registry+https://github.com/rust-lang/crates.io-index" 716 + checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" 717 + dependencies = [ 718 + "fnv", 719 + "ident_case", 720 + "proc-macro2", 721 + "quote", 722 + "strsim", 723 + "syn", 724 + ] 725 + 726 + [[package]] 727 + name = "darling_macro" 728 + version = "0.20.10" 729 + source = "registry+https://github.com/rust-lang/crates.io-index" 730 + checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" 731 + dependencies = [ 732 + "darling_core", 733 + "quote", 734 + "syn", 735 + ] 736 + 737 + [[package]] 738 + name = "deranged" 739 + version = "0.3.11" 740 + source = "registry+https://github.com/rust-lang/crates.io-index" 741 + checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 742 + dependencies = [ 743 + "powerfmt", 744 + ] 745 + 746 + [[package]] 747 + name = "derive_more" 748 + version = "0.99.18" 749 + source = "registry+https://github.com/rust-lang/crates.io-index" 750 + checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" 751 + dependencies = [ 752 + "convert_case", 753 + "proc-macro2", 754 + "quote", 755 + "rustc_version", 756 + "syn", 757 + ] 758 + 759 + [[package]] 760 + name = "digest" 761 + version = "0.10.7" 762 + source = "registry+https://github.com/rust-lang/crates.io-index" 763 + checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 764 + dependencies = [ 765 + "block-buffer", 766 + "crypto-common", 767 + ] 768 + 769 + [[package]] 770 + name = "either" 771 + version = "1.13.0" 772 + source = "registry+https://github.com/rust-lang/crates.io-index" 773 + checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" 774 + 775 + [[package]] 776 + name = "encoding_rs" 777 + version = "0.8.34" 778 + source = "registry+https://github.com/rust-lang/crates.io-index" 779 + checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" 780 + dependencies = [ 781 + "cfg-if", 782 + ] 783 + 784 + [[package]] 785 + name = "equivalent" 786 + version = "1.0.1" 787 + source = "registry+https://github.com/rust-lang/crates.io-index" 788 + checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 789 + 790 + [[package]] 791 + name = "errno" 792 + version = "0.3.9" 793 + source = "registry+https://github.com/rust-lang/crates.io-index" 794 + checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" 795 + dependencies = [ 796 + "libc", 797 + "windows-sys 0.52.0", 798 + ] 799 + 800 + [[package]] 801 + name = "event-listener" 802 + version = "5.3.1" 803 + source = "registry+https://github.com/rust-lang/crates.io-index" 804 + checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" 805 + dependencies = [ 806 + "concurrent-queue", 807 + "parking", 808 + "pin-project-lite", 809 + ] 810 + 811 + [[package]] 812 + name = "event-listener-strategy" 813 + version = "0.5.2" 814 + source = "registry+https://github.com/rust-lang/crates.io-index" 815 + checksum = "0f214dc438f977e6d4e3500aaa277f5ad94ca83fbbd9b1a15713ce2344ccc5a1" 816 + dependencies = [ 817 + "event-listener", 818 + "pin-project-lite", 819 + ] 820 + 821 + [[package]] 822 + name = "fast_chemail" 823 + version = "0.9.6" 824 + source = "registry+https://github.com/rust-lang/crates.io-index" 825 + checksum = "495a39d30d624c2caabe6312bfead73e7717692b44e0b32df168c275a2e8e9e4" 826 + dependencies = [ 827 + "ascii_utils", 828 + ] 829 + 830 + [[package]] 831 + name = "fastrand" 832 + version = "2.1.1" 833 + source = "registry+https://github.com/rust-lang/crates.io-index" 834 + checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" 835 + 836 + [[package]] 837 + name = "fixedbitset" 838 + version = "0.4.2" 839 + source = "registry+https://github.com/rust-lang/crates.io-index" 840 + checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80" 841 + 842 + [[package]] 843 + name = "flate2" 844 + version = "1.0.33" 845 + source = "registry+https://github.com/rust-lang/crates.io-index" 846 + checksum = "324a1be68054ef05ad64b861cc9eaf1d623d2d8cb25b4bf2cb9cdd902b4bf253" 847 + dependencies = [ 848 + "crc32fast", 849 + "miniz_oxide", 850 + ] 851 + 852 + [[package]] 853 + name = "fnv" 854 + version = "1.0.7" 855 + source = "registry+https://github.com/rust-lang/crates.io-index" 856 + checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 857 + 858 + [[package]] 859 + name = "form_urlencoded" 860 + version = "1.2.1" 861 + source = "registry+https://github.com/rust-lang/crates.io-index" 862 + checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" 863 + dependencies = [ 864 + "percent-encoding", 865 + ] 866 + 867 + [[package]] 868 + name = "futures-channel" 869 + version = "0.3.30" 870 + source = "registry+https://github.com/rust-lang/crates.io-index" 871 + checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 872 + dependencies = [ 873 + "futures-core", 874 + "futures-sink", 875 + ] 876 + 877 + [[package]] 878 + name = "futures-core" 879 + version = "0.3.30" 880 + source = "registry+https://github.com/rust-lang/crates.io-index" 881 + checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 882 + 883 + [[package]] 884 + name = "futures-io" 885 + version = "0.3.30" 886 + source = "registry+https://github.com/rust-lang/crates.io-index" 887 + checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 888 + 889 + [[package]] 890 + name = "futures-macro" 891 + version = "0.3.30" 892 + source = "registry+https://github.com/rust-lang/crates.io-index" 893 + checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 894 + dependencies = [ 895 + "proc-macro2", 896 + "quote", 897 + "syn", 898 + ] 899 + 900 + [[package]] 901 + name = "futures-sink" 902 + version = "0.3.30" 903 + source = "registry+https://github.com/rust-lang/crates.io-index" 904 + checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 905 + 906 + [[package]] 907 + name = "futures-task" 908 + version = "0.3.30" 909 + source = "registry+https://github.com/rust-lang/crates.io-index" 910 + checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 911 + 912 + [[package]] 913 + name = "futures-timer" 914 + version = "3.0.3" 915 + source = "registry+https://github.com/rust-lang/crates.io-index" 916 + checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" 917 + 918 + [[package]] 919 + name = "futures-util" 920 + version = "0.3.30" 921 + source = "registry+https://github.com/rust-lang/crates.io-index" 922 + checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 923 + dependencies = [ 924 + "futures-core", 925 + "futures-io", 926 + "futures-macro", 927 + "futures-sink", 928 + "futures-task", 929 + "memchr", 930 + "pin-project-lite", 931 + "pin-utils", 932 + "slab", 933 + ] 934 + 935 + [[package]] 936 + name = "generic-array" 937 + version = "0.14.7" 938 + source = "registry+https://github.com/rust-lang/crates.io-index" 939 + checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 940 + dependencies = [ 941 + "typenum", 942 + "version_check", 943 + ] 944 + 945 + [[package]] 946 + name = "getrandom" 947 + version = "0.2.15" 948 + source = "registry+https://github.com/rust-lang/crates.io-index" 949 + checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 950 + dependencies = [ 951 + "cfg-if", 952 + "libc", 953 + "wasi", 954 + ] 955 + 956 + [[package]] 957 + name = "gimli" 958 + version = "0.31.0" 959 + source = "registry+https://github.com/rust-lang/crates.io-index" 960 + checksum = "32085ea23f3234fc7846555e85283ba4de91e21016dc0455a16286d87a292d64" 961 + 962 + [[package]] 963 + name = "h2" 964 + version = "0.3.26" 965 + source = "registry+https://github.com/rust-lang/crates.io-index" 966 + checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 967 + dependencies = [ 968 + "bytes", 969 + "fnv", 970 + "futures-core", 971 + "futures-sink", 972 + "futures-util", 973 + "http 0.2.12", 974 + "indexmap 2.5.0", 975 + "slab", 976 + "tokio", 977 + "tokio-util", 978 + "tracing", 979 + ] 980 + 981 + [[package]] 982 + name = "h2" 983 + version = "0.4.6" 984 + source = "registry+https://github.com/rust-lang/crates.io-index" 985 + checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" 986 + dependencies = [ 987 + "atomic-waker", 988 + "bytes", 989 + "fnv", 990 + "futures-core", 991 + "futures-sink", 992 + "http 1.1.0", 993 + "indexmap 2.5.0", 994 + "slab", 995 + "tokio", 996 + "tokio-util", 997 + "tracing", 998 + ] 999 + 1000 + [[package]] 1001 + name = "handlebars" 1002 + version = "5.1.2" 1003 + source = "registry+https://github.com/rust-lang/crates.io-index" 1004 + checksum = "d08485b96a0e6393e9e4d1b8d48cf74ad6c063cd905eb33f42c1ce3f0377539b" 1005 + dependencies = [ 1006 + "log", 1007 + "pest", 1008 + "pest_derive", 1009 + "serde", 1010 + "serde_json", 1011 + "thiserror", 1012 + ] 1013 + 1014 + [[package]] 1015 + name = "hashbrown" 1016 + version = "0.12.3" 1017 + source = "registry+https://github.com/rust-lang/crates.io-index" 1018 + checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" 1019 + 1020 + [[package]] 1021 + name = "hashbrown" 1022 + version = "0.14.5" 1023 + source = "registry+https://github.com/rust-lang/crates.io-index" 1024 + checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 1025 + 1026 + [[package]] 1027 + name = "heck" 1028 + version = "0.5.0" 1029 + source = "registry+https://github.com/rust-lang/crates.io-index" 1030 + checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" 1031 + 1032 + [[package]] 1033 + name = "hermit-abi" 1034 + version = "0.3.9" 1035 + source = "registry+https://github.com/rust-lang/crates.io-index" 1036 + checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" 1037 + 1038 + [[package]] 1039 + name = "http" 1040 + version = "0.2.12" 1041 + source = "registry+https://github.com/rust-lang/crates.io-index" 1042 + checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 1043 + dependencies = [ 1044 + "bytes", 1045 + "fnv", 1046 + "itoa", 1047 + ] 1048 + 1049 + [[package]] 1050 + name = "http" 1051 + version = "1.1.0" 1052 + source = "registry+https://github.com/rust-lang/crates.io-index" 1053 + checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 1054 + dependencies = [ 1055 + "bytes", 1056 + "fnv", 1057 + "itoa", 1058 + ] 1059 + 1060 + [[package]] 1061 + name = "http-body" 1062 + version = "1.0.1" 1063 + source = "registry+https://github.com/rust-lang/crates.io-index" 1064 + checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" 1065 + dependencies = [ 1066 + "bytes", 1067 + "http 1.1.0", 1068 + ] 1069 + 1070 + [[package]] 1071 + name = "http-body-util" 1072 + version = "0.1.2" 1073 + source = "registry+https://github.com/rust-lang/crates.io-index" 1074 + checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 1075 + dependencies = [ 1076 + "bytes", 1077 + "futures-util", 1078 + "http 1.1.0", 1079 + "http-body", 1080 + "pin-project-lite", 1081 + ] 1082 + 1083 + [[package]] 1084 + name = "httparse" 1085 + version = "1.9.4" 1086 + source = "registry+https://github.com/rust-lang/crates.io-index" 1087 + checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9" 1088 + 1089 + [[package]] 1090 + name = "httpdate" 1091 + version = "1.0.3" 1092 + source = "registry+https://github.com/rust-lang/crates.io-index" 1093 + checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 1094 + 1095 + [[package]] 1096 + name = "hyper" 1097 + version = "1.4.1" 1098 + source = "registry+https://github.com/rust-lang/crates.io-index" 1099 + checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" 1100 + dependencies = [ 1101 + "bytes", 1102 + "futures-channel", 1103 + "futures-util", 1104 + "h2 0.4.6", 1105 + "http 1.1.0", 1106 + "http-body", 1107 + "httparse", 1108 + "httpdate", 1109 + "itoa", 1110 + "pin-project-lite", 1111 + "smallvec", 1112 + "tokio", 1113 + "want", 1114 + ] 1115 + 1116 + [[package]] 1117 + name = "hyper-rustls" 1118 + version = "0.27.3" 1119 + source = "registry+https://github.com/rust-lang/crates.io-index" 1120 + checksum = "08afdbb5c31130e3034af566421053ab03787c640246a446327f550d11bcb333" 1121 + dependencies = [ 1122 + "futures-util", 1123 + "http 1.1.0", 1124 + "hyper", 1125 + "hyper-util", 1126 + "rustls", 1127 + "rustls-pki-types", 1128 + "tokio", 1129 + "tokio-rustls", 1130 + "tower-service", 1131 + "webpki-roots", 1132 + ] 1133 + 1134 + [[package]] 1135 + name = "hyper-timeout" 1136 + version = "0.5.1" 1137 + source = "registry+https://github.com/rust-lang/crates.io-index" 1138 + checksum = "3203a961e5c83b6f5498933e78b6b263e208c197b63e9c6c53cc82ffd3f63793" 1139 + dependencies = [ 1140 + "hyper", 1141 + "hyper-util", 1142 + "pin-project-lite", 1143 + "tokio", 1144 + "tower-service", 1145 + ] 1146 + 1147 + [[package]] 1148 + name = "hyper-util" 1149 + version = "0.1.8" 1150 + source = "registry+https://github.com/rust-lang/crates.io-index" 1151 + checksum = "da62f120a8a37763efb0cf8fdf264b884c7b8b9ac8660b900c8661030c00e6ba" 1152 + dependencies = [ 1153 + "bytes", 1154 + "futures-channel", 1155 + "futures-util", 1156 + "http 1.1.0", 1157 + "http-body", 1158 + "hyper", 1159 + "pin-project-lite", 1160 + "socket2", 1161 + "tokio", 1162 + "tower", 1163 + "tower-service", 1164 + "tracing", 1165 + ] 1166 + 1167 + [[package]] 1168 + name = "ident_case" 1169 + version = "1.0.1" 1170 + source = "registry+https://github.com/rust-lang/crates.io-index" 1171 + checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" 1172 + 1173 + [[package]] 1174 + name = "idna" 1175 + version = "0.5.0" 1176 + source = "registry+https://github.com/rust-lang/crates.io-index" 1177 + checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" 1178 + dependencies = [ 1179 + "unicode-bidi", 1180 + "unicode-normalization", 1181 + ] 1182 + 1183 + [[package]] 1184 + name = "impl-more" 1185 + version = "0.1.6" 1186 + source = "registry+https://github.com/rust-lang/crates.io-index" 1187 + checksum = "206ca75c9c03ba3d4ace2460e57b189f39f43de612c2f85836e65c929701bb2d" 1188 + 1189 + [[package]] 1190 + name = "indexmap" 1191 + version = "1.9.3" 1192 + source = "registry+https://github.com/rust-lang/crates.io-index" 1193 + checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" 1194 + dependencies = [ 1195 + "autocfg", 1196 + "hashbrown 0.12.3", 1197 + ] 1198 + 1199 + [[package]] 1200 + name = "indexmap" 1201 + version = "2.5.0" 1202 + source = "registry+https://github.com/rust-lang/crates.io-index" 1203 + checksum = "68b900aa2f7301e21c36462b170ee99994de34dff39a4a6a528e80e7376d07e5" 1204 + dependencies = [ 1205 + "equivalent", 1206 + "hashbrown 0.14.5", 1207 + "serde", 1208 + ] 1209 + 1210 + [[package]] 1211 + name = "ipnet" 1212 + version = "2.10.0" 1213 + source = "registry+https://github.com/rust-lang/crates.io-index" 1214 + checksum = "187674a687eed5fe42285b40c6291f9a01517d415fad1c3cbc6a9f778af7fcd4" 1215 + 1216 + [[package]] 1217 + name = "itertools" 1218 + version = "0.13.0" 1219 + source = "registry+https://github.com/rust-lang/crates.io-index" 1220 + checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" 1221 + dependencies = [ 1222 + "either", 1223 + ] 1224 + 1225 + [[package]] 1226 + name = "itoa" 1227 + version = "1.0.11" 1228 + source = "registry+https://github.com/rust-lang/crates.io-index" 1229 + checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" 1230 + 1231 + [[package]] 1232 + name = "jobserver" 1233 + version = "0.1.32" 1234 + source = "registry+https://github.com/rust-lang/crates.io-index" 1235 + checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0" 1236 + dependencies = [ 1237 + "libc", 1238 + ] 1239 + 1240 + [[package]] 1241 + name = "js-sys" 1242 + version = "0.3.70" 1243 + source = "registry+https://github.com/rust-lang/crates.io-index" 1244 + checksum = "1868808506b929d7b0cfa8f75951347aa71bb21144b7791bae35d9bccfcfe37a" 1245 + dependencies = [ 1246 + "wasm-bindgen", 1247 + ] 1248 + 1249 + [[package]] 1250 + name = "language-tags" 1251 + version = "0.3.2" 1252 + source = "registry+https://github.com/rust-lang/crates.io-index" 1253 + checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" 1254 + 1255 + [[package]] 1256 + name = "lazy_static" 1257 + version = "1.5.0" 1258 + source = "registry+https://github.com/rust-lang/crates.io-index" 1259 + checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" 1260 + 1261 + [[package]] 1262 + name = "libc" 1263 + version = "0.2.158" 1264 + source = "registry+https://github.com/rust-lang/crates.io-index" 1265 + checksum = "d8adc4bb1803a324070e64a98ae98f38934d91957a99cfb3a43dcbc01bc56439" 1266 + 1267 + [[package]] 1268 + name = "linux-raw-sys" 1269 + version = "0.4.14" 1270 + source = "registry+https://github.com/rust-lang/crates.io-index" 1271 + checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" 1272 + 1273 + [[package]] 1274 + name = "local-channel" 1275 + version = "0.1.5" 1276 + source = "registry+https://github.com/rust-lang/crates.io-index" 1277 + checksum = "b6cbc85e69b8df4b8bb8b89ec634e7189099cea8927a276b7384ce5488e53ec8" 1278 + dependencies = [ 1279 + "futures-core", 1280 + "futures-sink", 1281 + "local-waker", 1282 + ] 1283 + 1284 + [[package]] 1285 + name = "local-waker" 1286 + version = "0.1.4" 1287 + source = "registry+https://github.com/rust-lang/crates.io-index" 1288 + checksum = "4d873d7c67ce09b42110d801813efbc9364414e356be9935700d368351657487" 1289 + 1290 + [[package]] 1291 + name = "lock_api" 1292 + version = "0.4.12" 1293 + source = "registry+https://github.com/rust-lang/crates.io-index" 1294 + checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" 1295 + dependencies = [ 1296 + "autocfg", 1297 + "scopeguard", 1298 + ] 1299 + 1300 + [[package]] 1301 + name = "log" 1302 + version = "0.4.22" 1303 + source = "registry+https://github.com/rust-lang/crates.io-index" 1304 + checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" 1305 + 1306 + [[package]] 1307 + name = "matchit" 1308 + version = "0.7.3" 1309 + source = "registry+https://github.com/rust-lang/crates.io-index" 1310 + checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" 1311 + 1312 + [[package]] 1313 + name = "memchr" 1314 + version = "2.7.4" 1315 + source = "registry+https://github.com/rust-lang/crates.io-index" 1316 + checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" 1317 + 1318 + [[package]] 1319 + name = "mime" 1320 + version = "0.3.17" 1321 + source = "registry+https://github.com/rust-lang/crates.io-index" 1322 + checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 1323 + 1324 + [[package]] 1325 + name = "miniz_oxide" 1326 + version = "0.8.0" 1327 + source = "registry+https://github.com/rust-lang/crates.io-index" 1328 + checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1" 1329 + dependencies = [ 1330 + "adler2", 1331 + ] 1332 + 1333 + [[package]] 1334 + name = "mio" 1335 + version = "1.0.2" 1336 + source = "registry+https://github.com/rust-lang/crates.io-index" 1337 + checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec" 1338 + dependencies = [ 1339 + "hermit-abi", 1340 + "libc", 1341 + "log", 1342 + "wasi", 1343 + "windows-sys 0.52.0", 1344 + ] 1345 + 1346 + [[package]] 1347 + name = "multer" 1348 + version = "3.1.0" 1349 + source = "registry+https://github.com/rust-lang/crates.io-index" 1350 + checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" 1351 + dependencies = [ 1352 + "bytes", 1353 + "encoding_rs", 1354 + "futures-util", 1355 + "http 1.1.0", 1356 + "httparse", 1357 + "memchr", 1358 + "mime", 1359 + "spin", 1360 + "version_check", 1361 + ] 1362 + 1363 + [[package]] 1364 + name = "multimap" 1365 + version = "0.10.0" 1366 + source = "registry+https://github.com/rust-lang/crates.io-index" 1367 + checksum = "defc4c55412d89136f966bbb339008b474350e5e6e78d2714439c386b3137a03" 1368 + 1369 + [[package]] 1370 + name = "num-conv" 1371 + version = "0.1.0" 1372 + source = "registry+https://github.com/rust-lang/crates.io-index" 1373 + checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1374 + 1375 + [[package]] 1376 + name = "num-traits" 1377 + version = "0.2.19" 1378 + source = "registry+https://github.com/rust-lang/crates.io-index" 1379 + checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" 1380 + dependencies = [ 1381 + "autocfg", 1382 + ] 1383 + 1384 + [[package]] 1385 + name = "object" 1386 + version = "0.36.4" 1387 + source = "registry+https://github.com/rust-lang/crates.io-index" 1388 + checksum = "084f1a5821ac4c651660a94a7153d27ac9d8a53736203f58b31945ded098070a" 1389 + dependencies = [ 1390 + "memchr", 1391 + ] 1392 + 1393 + [[package]] 1394 + name = "once_cell" 1395 + version = "1.19.0" 1396 + source = "registry+https://github.com/rust-lang/crates.io-index" 1397 + checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1398 + 1399 + [[package]] 1400 + name = "owo-colors" 1401 + version = "4.1.0" 1402 + source = "registry+https://github.com/rust-lang/crates.io-index" 1403 + checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" 1404 + 1405 + [[package]] 1406 + name = "owo-colors" 1407 + version = "5.0.0" 1408 + source = "registry+https://github.com/rust-lang/crates.io-index" 1409 + checksum = "8f1fd1e2f6b8c2caa4ede09a3c1b8fcab7b8b3c0c82987e685eb0df047b044f5" 1410 + 1411 + [[package]] 1412 + name = "parking" 1413 + version = "2.2.1" 1414 + source = "registry+https://github.com/rust-lang/crates.io-index" 1415 + checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" 1416 + 1417 + [[package]] 1418 + name = "parking_lot" 1419 + version = "0.12.3" 1420 + source = "registry+https://github.com/rust-lang/crates.io-index" 1421 + checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" 1422 + dependencies = [ 1423 + "lock_api", 1424 + "parking_lot_core", 1425 + ] 1426 + 1427 + [[package]] 1428 + name = "parking_lot_core" 1429 + version = "0.9.10" 1430 + source = "registry+https://github.com/rust-lang/crates.io-index" 1431 + checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" 1432 + dependencies = [ 1433 + "cfg-if", 1434 + "libc", 1435 + "redox_syscall", 1436 + "smallvec", 1437 + "windows-targets", 1438 + ] 1439 + 1440 + [[package]] 1441 + name = "paste" 1442 + version = "1.0.15" 1443 + source = "registry+https://github.com/rust-lang/crates.io-index" 1444 + checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" 1445 + 1446 + [[package]] 1447 + name = "percent-encoding" 1448 + version = "2.3.1" 1449 + source = "registry+https://github.com/rust-lang/crates.io-index" 1450 + checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1451 + 1452 + [[package]] 1453 + name = "pest" 1454 + version = "2.7.12" 1455 + source = "registry+https://github.com/rust-lang/crates.io-index" 1456 + checksum = "9c73c26c01b8c87956cea613c907c9d6ecffd8d18a2a5908e5de0adfaa185cea" 1457 + dependencies = [ 1458 + "memchr", 1459 + "thiserror", 1460 + "ucd-trie", 1461 + ] 1462 + 1463 + [[package]] 1464 + name = "pest_derive" 1465 + version = "2.7.12" 1466 + source = "registry+https://github.com/rust-lang/crates.io-index" 1467 + checksum = "664d22978e2815783adbdd2c588b455b1bd625299ce36b2a99881ac9627e6d8d" 1468 + dependencies = [ 1469 + "pest", 1470 + "pest_generator", 1471 + ] 1472 + 1473 + [[package]] 1474 + name = "pest_generator" 1475 + version = "2.7.12" 1476 + source = "registry+https://github.com/rust-lang/crates.io-index" 1477 + checksum = "a2d5487022d5d33f4c30d91c22afa240ce2a644e87fe08caad974d4eab6badbe" 1478 + dependencies = [ 1479 + "pest", 1480 + "pest_meta", 1481 + "proc-macro2", 1482 + "quote", 1483 + "syn", 1484 + ] 1485 + 1486 + [[package]] 1487 + name = "pest_meta" 1488 + version = "2.7.12" 1489 + source = "registry+https://github.com/rust-lang/crates.io-index" 1490 + checksum = "0091754bbd0ea592c4deb3a122ce8ecbb0753b738aa82bc055fcc2eccc8d8174" 1491 + dependencies = [ 1492 + "once_cell", 1493 + "pest", 1494 + "sha2", 1495 + ] 1496 + 1497 + [[package]] 1498 + name = "petgraph" 1499 + version = "0.6.5" 1500 + source = "registry+https://github.com/rust-lang/crates.io-index" 1501 + checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" 1502 + dependencies = [ 1503 + "fixedbitset", 1504 + "indexmap 2.5.0", 1505 + ] 1506 + 1507 + [[package]] 1508 + name = "pin-project" 1509 + version = "1.1.5" 1510 + source = "registry+https://github.com/rust-lang/crates.io-index" 1511 + checksum = "b6bf43b791c5b9e34c3d182969b4abb522f9343702850a2e57f460d00d09b4b3" 1512 + dependencies = [ 1513 + "pin-project-internal", 1514 + ] 1515 + 1516 + [[package]] 1517 + name = "pin-project-internal" 1518 + version = "1.1.5" 1519 + source = "registry+https://github.com/rust-lang/crates.io-index" 1520 + checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" 1521 + dependencies = [ 1522 + "proc-macro2", 1523 + "quote", 1524 + "syn", 1525 + ] 1526 + 1527 + [[package]] 1528 + name = "pin-project-lite" 1529 + version = "0.2.14" 1530 + source = "registry+https://github.com/rust-lang/crates.io-index" 1531 + checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1532 + 1533 + [[package]] 1534 + name = "pin-utils" 1535 + version = "0.1.0" 1536 + source = "registry+https://github.com/rust-lang/crates.io-index" 1537 + checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1538 + 1539 + [[package]] 1540 + name = "pkg-config" 1541 + version = "0.3.30" 1542 + source = "registry+https://github.com/rust-lang/crates.io-index" 1543 + checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" 1544 + 1545 + [[package]] 1546 + name = "powerfmt" 1547 + version = "0.2.0" 1548 + source = "registry+https://github.com/rust-lang/crates.io-index" 1549 + checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1550 + 1551 + [[package]] 1552 + name = "ppv-lite86" 1553 + version = "0.2.20" 1554 + source = "registry+https://github.com/rust-lang/crates.io-index" 1555 + checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" 1556 + dependencies = [ 1557 + "zerocopy", 1558 + ] 1559 + 1560 + [[package]] 1561 + name = "prettyplease" 1562 + version = "0.2.22" 1563 + source = "registry+https://github.com/rust-lang/crates.io-index" 1564 + checksum = "479cf940fbbb3426c32c5d5176f62ad57549a0bb84773423ba8be9d089f5faba" 1565 + dependencies = [ 1566 + "proc-macro2", 1567 + "syn", 1568 + ] 1569 + 1570 + [[package]] 1571 + name = "proc-macro-crate" 1572 + version = "3.2.0" 1573 + source = "registry+https://github.com/rust-lang/crates.io-index" 1574 + checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" 1575 + dependencies = [ 1576 + "toml_edit", 1577 + ] 1578 + 1579 + [[package]] 1580 + name = "proc-macro2" 1581 + version = "1.0.86" 1582 + source = "registry+https://github.com/rust-lang/crates.io-index" 1583 + checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" 1584 + dependencies = [ 1585 + "unicode-ident", 1586 + ] 1587 + 1588 + [[package]] 1589 + name = "prost" 1590 + version = "0.13.2" 1591 + source = "registry+https://github.com/rust-lang/crates.io-index" 1592 + checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" 1593 + dependencies = [ 1594 + "bytes", 1595 + "prost-derive", 1596 + ] 1597 + 1598 + [[package]] 1599 + name = "prost-build" 1600 + version = "0.13.2" 1601 + source = "registry+https://github.com/rust-lang/crates.io-index" 1602 + checksum = "f8650aabb6c35b860610e9cff5dc1af886c9e25073b7b1712a68972af4281302" 1603 + dependencies = [ 1604 + "bytes", 1605 + "heck", 1606 + "itertools", 1607 + "log", 1608 + "multimap", 1609 + "once_cell", 1610 + "petgraph", 1611 + "prettyplease", 1612 + "prost", 1613 + "prost-types", 1614 + "regex", 1615 + "syn", 1616 + "tempfile", 1617 + ] 1618 + 1619 + [[package]] 1620 + name = "prost-derive" 1621 + version = "0.13.2" 1622 + source = "registry+https://github.com/rust-lang/crates.io-index" 1623 + checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" 1624 + dependencies = [ 1625 + "anyhow", 1626 + "itertools", 1627 + "proc-macro2", 1628 + "quote", 1629 + "syn", 1630 + ] 1631 + 1632 + [[package]] 1633 + name = "prost-types" 1634 + version = "0.13.2" 1635 + source = "registry+https://github.com/rust-lang/crates.io-index" 1636 + checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" 1637 + dependencies = [ 1638 + "prost", 1639 + ] 1640 + 1641 + [[package]] 1642 + name = "quinn" 1643 + version = "0.11.3" 1644 + source = "registry+https://github.com/rust-lang/crates.io-index" 1645 + checksum = "b22d8e7369034b9a7132bc2008cac12f2013c8132b45e0554e6e20e2617f2156" 1646 + dependencies = [ 1647 + "bytes", 1648 + "pin-project-lite", 1649 + "quinn-proto", 1650 + "quinn-udp", 1651 + "rustc-hash", 1652 + "rustls", 1653 + "socket2", 1654 + "thiserror", 1655 + "tokio", 1656 + "tracing", 1657 + ] 1658 + 1659 + [[package]] 1660 + name = "quinn-proto" 1661 + version = "0.11.6" 1662 + source = "registry+https://github.com/rust-lang/crates.io-index" 1663 + checksum = "ba92fb39ec7ad06ca2582c0ca834dfeadcaf06ddfc8e635c80aa7e1c05315fdd" 1664 + dependencies = [ 1665 + "bytes", 1666 + "rand", 1667 + "ring", 1668 + "rustc-hash", 1669 + "rustls", 1670 + "slab", 1671 + "thiserror", 1672 + "tinyvec", 1673 + "tracing", 1674 + ] 1675 + 1676 + [[package]] 1677 + name = "quinn-udp" 1678 + version = "0.5.4" 1679 + source = "registry+https://github.com/rust-lang/crates.io-index" 1680 + checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285" 1681 + dependencies = [ 1682 + "libc", 1683 + "once_cell", 1684 + "socket2", 1685 + "tracing", 1686 + "windows-sys 0.52.0", 1687 + ] 1688 + 1689 + [[package]] 1690 + name = "quote" 1691 + version = "1.0.37" 1692 + source = "registry+https://github.com/rust-lang/crates.io-index" 1693 + checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" 1694 + dependencies = [ 1695 + "proc-macro2", 1696 + ] 1697 + 1698 + [[package]] 1699 + name = "rand" 1700 + version = "0.8.5" 1701 + source = "registry+https://github.com/rust-lang/crates.io-index" 1702 + checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1703 + dependencies = [ 1704 + "libc", 1705 + "rand_chacha", 1706 + "rand_core", 1707 + ] 1708 + 1709 + [[package]] 1710 + name = "rand_chacha" 1711 + version = "0.3.1" 1712 + source = "registry+https://github.com/rust-lang/crates.io-index" 1713 + checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1714 + dependencies = [ 1715 + "ppv-lite86", 1716 + "rand_core", 1717 + ] 1718 + 1719 + [[package]] 1720 + name = "rand_core" 1721 + version = "0.6.4" 1722 + source = "registry+https://github.com/rust-lang/crates.io-index" 1723 + checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1724 + dependencies = [ 1725 + "getrandom", 1726 + ] 1727 + 1728 + [[package]] 1729 + name = "redox_syscall" 1730 + version = "0.5.3" 1731 + source = "registry+https://github.com/rust-lang/crates.io-index" 1732 + checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" 1733 + dependencies = [ 1734 + "bitflags", 1735 + ] 1736 + 1737 + [[package]] 1738 + name = "regex" 1739 + version = "1.10.6" 1740 + source = "registry+https://github.com/rust-lang/crates.io-index" 1741 + checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619" 1742 + dependencies = [ 1743 + "aho-corasick", 1744 + "memchr", 1745 + "regex-automata", 1746 + "regex-syntax", 1747 + ] 1748 + 1749 + [[package]] 1750 + name = "regex-automata" 1751 + version = "0.4.7" 1752 + source = "registry+https://github.com/rust-lang/crates.io-index" 1753 + checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" 1754 + dependencies = [ 1755 + "aho-corasick", 1756 + "memchr", 1757 + "regex-syntax", 1758 + ] 1759 + 1760 + [[package]] 1761 + name = "regex-lite" 1762 + version = "0.1.6" 1763 + source = "registry+https://github.com/rust-lang/crates.io-index" 1764 + checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" 1765 + 1766 + [[package]] 1767 + name = "regex-syntax" 1768 + version = "0.8.4" 1769 + source = "registry+https://github.com/rust-lang/crates.io-index" 1770 + checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" 1771 + 1772 + [[package]] 1773 + name = "reqwest" 1774 + version = "0.12.7" 1775 + source = "registry+https://github.com/rust-lang/crates.io-index" 1776 + checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" 1777 + dependencies = [ 1778 + "base64", 1779 + "bytes", 1780 + "futures-channel", 1781 + "futures-core", 1782 + "futures-util", 1783 + "http 1.1.0", 1784 + "http-body", 1785 + "http-body-util", 1786 + "hyper", 1787 + "hyper-rustls", 1788 + "hyper-util", 1789 + "ipnet", 1790 + "js-sys", 1791 + "log", 1792 + "mime", 1793 + "once_cell", 1794 + "percent-encoding", 1795 + "pin-project-lite", 1796 + "quinn", 1797 + "rustls", 1798 + "rustls-pemfile", 1799 + "rustls-pki-types", 1800 + "serde", 1801 + "serde_json", 1802 + "serde_urlencoded", 1803 + "sync_wrapper 1.0.1", 1804 + "tokio", 1805 + "tokio-rustls", 1806 + "tower-service", 1807 + "url", 1808 + "wasm-bindgen", 1809 + "wasm-bindgen-futures", 1810 + "web-sys", 1811 + "webpki-roots", 1812 + "windows-registry", 1813 + ] 1814 + 1815 + [[package]] 1816 + name = "ring" 1817 + version = "0.17.8" 1818 + source = "registry+https://github.com/rust-lang/crates.io-index" 1819 + checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1820 + dependencies = [ 1821 + "cc", 1822 + "cfg-if", 1823 + "getrandom", 1824 + "libc", 1825 + "spin", 1826 + "untrusted", 1827 + "windows-sys 0.52.0", 1828 + ] 1829 + 1830 + [[package]] 1831 + name = "rockbox-graphql" 1832 + version = "0.1.0" 1833 + dependencies = [ 1834 + "actix-cors", 1835 + "actix-web", 1836 + "anyhow", 1837 + "async-graphql", 1838 + "async-graphql-actix-web", 1839 + "owo-colors 4.1.0", 1840 + "reqwest", 1841 + "rockbox-sys", 1842 + "serde", 1843 + "tokio", 1844 + ] 1845 + 1846 + [[package]] 1847 + name = "rockbox-rpc" 1848 + version = "0.1.0" 1849 + dependencies = [ 1850 + "owo-colors 5.0.0", 1851 + "prost", 1852 + "reqwest", 1853 + "rockbox-sys", 1854 + "serde", 1855 + "tokio", 1856 + "tonic", 1857 + "tonic-build", 1858 + "tonic-reflection", 1859 + "tonic-web", 1860 + ] 1861 + 1862 + [[package]] 1863 + name = "rockbox-server" 1864 + version = "0.1.0" 1865 + dependencies = [ 1866 + "owo-colors 4.1.0", 1867 + "reqwest", 1868 + "rockbox-graphql", 1869 + "rockbox-rpc", 1870 + "rockbox-sys", 1871 + "serde_json", 1872 + "tokio", 1873 + ] 1874 + 1875 + [[package]] 1876 + name = "rockbox-sys" 1877 + version = "0.1.0" 1878 + dependencies = [ 1879 + "serde", 1880 + ] 1881 + 1882 + [[package]] 1883 + name = "rustc-demangle" 1884 + version = "0.1.24" 1885 + source = "registry+https://github.com/rust-lang/crates.io-index" 1886 + checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1887 + 1888 + [[package]] 1889 + name = "rustc-hash" 1890 + version = "2.0.0" 1891 + source = "registry+https://github.com/rust-lang/crates.io-index" 1892 + checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152" 1893 + 1894 + [[package]] 1895 + name = "rustc_version" 1896 + version = "0.4.1" 1897 + source = "registry+https://github.com/rust-lang/crates.io-index" 1898 + checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" 1899 + dependencies = [ 1900 + "semver", 1901 + ] 1902 + 1903 + [[package]] 1904 + name = "rustix" 1905 + version = "0.38.36" 1906 + source = "registry+https://github.com/rust-lang/crates.io-index" 1907 + checksum = "3f55e80d50763938498dd5ebb18647174e0c76dc38c5505294bb224624f30f36" 1908 + dependencies = [ 1909 + "bitflags", 1910 + "errno", 1911 + "libc", 1912 + "linux-raw-sys", 1913 + "windows-sys 0.52.0", 1914 + ] 1915 + 1916 + [[package]] 1917 + name = "rustls" 1918 + version = "0.23.13" 1919 + source = "registry+https://github.com/rust-lang/crates.io-index" 1920 + checksum = "f2dabaac7466917e566adb06783a81ca48944c6898a1b08b9374106dd671f4c8" 1921 + dependencies = [ 1922 + "once_cell", 1923 + "ring", 1924 + "rustls-pki-types", 1925 + "rustls-webpki", 1926 + "subtle", 1927 + "zeroize", 1928 + ] 1929 + 1930 + [[package]] 1931 + name = "rustls-pemfile" 1932 + version = "2.1.3" 1933 + source = "registry+https://github.com/rust-lang/crates.io-index" 1934 + checksum = "196fe16b00e106300d3e45ecfcb764fa292a535d7326a29a5875c579c7417425" 1935 + dependencies = [ 1936 + "base64", 1937 + "rustls-pki-types", 1938 + ] 1939 + 1940 + [[package]] 1941 + name = "rustls-pki-types" 1942 + version = "1.8.0" 1943 + source = "registry+https://github.com/rust-lang/crates.io-index" 1944 + checksum = "fc0a2ce646f8655401bb81e7927b812614bd5d91dbc968696be50603510fcaf0" 1945 + 1946 + [[package]] 1947 + name = "rustls-webpki" 1948 + version = "0.102.8" 1949 + source = "registry+https://github.com/rust-lang/crates.io-index" 1950 + checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" 1951 + dependencies = [ 1952 + "ring", 1953 + "rustls-pki-types", 1954 + "untrusted", 1955 + ] 1956 + 1957 + [[package]] 1958 + name = "rustversion" 1959 + version = "1.0.17" 1960 + source = "registry+https://github.com/rust-lang/crates.io-index" 1961 + checksum = "955d28af4278de8121b7ebeb796b6a45735dc01436d898801014aced2773a3d6" 1962 + 1963 + [[package]] 1964 + name = "ryu" 1965 + version = "1.0.18" 1966 + source = "registry+https://github.com/rust-lang/crates.io-index" 1967 + checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" 1968 + 1969 + [[package]] 1970 + name = "scopeguard" 1971 + version = "1.2.0" 1972 + source = "registry+https://github.com/rust-lang/crates.io-index" 1973 + checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1974 + 1975 + [[package]] 1976 + name = "semver" 1977 + version = "1.0.23" 1978 + source = "registry+https://github.com/rust-lang/crates.io-index" 1979 + checksum = "61697e0a1c7e512e84a621326239844a24d8207b4669b41bc18b32ea5cbf988b" 1980 + 1981 + [[package]] 1982 + name = "serde" 1983 + version = "1.0.210" 1984 + source = "registry+https://github.com/rust-lang/crates.io-index" 1985 + checksum = "c8e3592472072e6e22e0a54d5904d9febf8508f65fb8552499a1abc7d1078c3a" 1986 + dependencies = [ 1987 + "serde_derive", 1988 + ] 1989 + 1990 + [[package]] 1991 + name = "serde_derive" 1992 + version = "1.0.210" 1993 + source = "registry+https://github.com/rust-lang/crates.io-index" 1994 + checksum = "243902eda00fad750862fc144cea25caca5e20d615af0a81bee94ca738f1df1f" 1995 + dependencies = [ 1996 + "proc-macro2", 1997 + "quote", 1998 + "syn", 1999 + ] 2000 + 2001 + [[package]] 2002 + name = "serde_json" 2003 + version = "1.0.128" 2004 + source = "registry+https://github.com/rust-lang/crates.io-index" 2005 + checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" 2006 + dependencies = [ 2007 + "itoa", 2008 + "memchr", 2009 + "ryu", 2010 + "serde", 2011 + ] 2012 + 2013 + [[package]] 2014 + name = "serde_urlencoded" 2015 + version = "0.7.1" 2016 + source = "registry+https://github.com/rust-lang/crates.io-index" 2017 + checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" 2018 + dependencies = [ 2019 + "form_urlencoded", 2020 + "itoa", 2021 + "ryu", 2022 + "serde", 2023 + ] 2024 + 2025 + [[package]] 2026 + name = "sha1" 2027 + version = "0.10.6" 2028 + source = "registry+https://github.com/rust-lang/crates.io-index" 2029 + checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" 2030 + dependencies = [ 2031 + "cfg-if", 2032 + "cpufeatures", 2033 + "digest", 2034 + ] 2035 + 2036 + [[package]] 2037 + name = "sha2" 2038 + version = "0.10.8" 2039 + source = "registry+https://github.com/rust-lang/crates.io-index" 2040 + checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 2041 + dependencies = [ 2042 + "cfg-if", 2043 + "cpufeatures", 2044 + "digest", 2045 + ] 2046 + 2047 + [[package]] 2048 + name = "shlex" 2049 + version = "1.3.0" 2050 + source = "registry+https://github.com/rust-lang/crates.io-index" 2051 + checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" 2052 + 2053 + [[package]] 2054 + name = "signal-hook-registry" 2055 + version = "1.4.2" 2056 + source = "registry+https://github.com/rust-lang/crates.io-index" 2057 + checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" 2058 + dependencies = [ 2059 + "libc", 2060 + ] 2061 + 2062 + [[package]] 2063 + name = "slab" 2064 + version = "0.4.9" 2065 + source = "registry+https://github.com/rust-lang/crates.io-index" 2066 + checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 2067 + dependencies = [ 2068 + "autocfg", 2069 + ] 2070 + 2071 + [[package]] 2072 + name = "smallvec" 2073 + version = "1.13.2" 2074 + source = "registry+https://github.com/rust-lang/crates.io-index" 2075 + checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 2076 + 2077 + [[package]] 2078 + name = "socket2" 2079 + version = "0.5.7" 2080 + source = "registry+https://github.com/rust-lang/crates.io-index" 2081 + checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 2082 + dependencies = [ 2083 + "libc", 2084 + "windows-sys 0.52.0", 2085 + ] 2086 + 2087 + [[package]] 2088 + name = "spin" 2089 + version = "0.9.8" 2090 + source = "registry+https://github.com/rust-lang/crates.io-index" 2091 + checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 2092 + 2093 + [[package]] 2094 + name = "static_assertions_next" 2095 + version = "1.1.2" 2096 + source = "registry+https://github.com/rust-lang/crates.io-index" 2097 + checksum = "d7beae5182595e9a8b683fa98c4317f956c9a2dec3b9716990d20023cc60c766" 2098 + 2099 + [[package]] 2100 + name = "strsim" 2101 + version = "0.11.1" 2102 + source = "registry+https://github.com/rust-lang/crates.io-index" 2103 + checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" 2104 + 2105 + [[package]] 2106 + name = "strum" 2107 + version = "0.26.3" 2108 + source = "registry+https://github.com/rust-lang/crates.io-index" 2109 + checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" 2110 + dependencies = [ 2111 + "strum_macros", 2112 + ] 2113 + 2114 + [[package]] 2115 + name = "strum_macros" 2116 + version = "0.26.4" 2117 + source = "registry+https://github.com/rust-lang/crates.io-index" 2118 + checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" 2119 + dependencies = [ 2120 + "heck", 2121 + "proc-macro2", 2122 + "quote", 2123 + "rustversion", 2124 + "syn", 2125 + ] 2126 + 2127 + [[package]] 2128 + name = "subtle" 2129 + version = "2.6.1" 2130 + source = "registry+https://github.com/rust-lang/crates.io-index" 2131 + checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" 2132 + 2133 + [[package]] 2134 + name = "syn" 2135 + version = "2.0.77" 2136 + source = "registry+https://github.com/rust-lang/crates.io-index" 2137 + checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" 2138 + dependencies = [ 2139 + "proc-macro2", 2140 + "quote", 2141 + "unicode-ident", 2142 + ] 2143 + 2144 + [[package]] 2145 + name = "sync_wrapper" 2146 + version = "0.1.2" 2147 + source = "registry+https://github.com/rust-lang/crates.io-index" 2148 + checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" 2149 + 2150 + [[package]] 2151 + name = "sync_wrapper" 2152 + version = "1.0.1" 2153 + source = "registry+https://github.com/rust-lang/crates.io-index" 2154 + checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" 2155 + dependencies = [ 2156 + "futures-core", 2157 + ] 2158 + 2159 + [[package]] 2160 + name = "tempfile" 2161 + version = "3.12.0" 2162 + source = "registry+https://github.com/rust-lang/crates.io-index" 2163 + checksum = "04cbcdd0c794ebb0d4cf35e88edd2f7d2c4c3e9a5a6dab322839b321c6a87a64" 2164 + dependencies = [ 2165 + "cfg-if", 2166 + "fastrand", 2167 + "once_cell", 2168 + "rustix", 2169 + "windows-sys 0.59.0", 2170 + ] 2171 + 2172 + [[package]] 2173 + name = "thiserror" 2174 + version = "1.0.63" 2175 + source = "registry+https://github.com/rust-lang/crates.io-index" 2176 + checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" 2177 + dependencies = [ 2178 + "thiserror-impl", 2179 + ] 2180 + 2181 + [[package]] 2182 + name = "thiserror-impl" 2183 + version = "1.0.63" 2184 + source = "registry+https://github.com/rust-lang/crates.io-index" 2185 + checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" 2186 + dependencies = [ 2187 + "proc-macro2", 2188 + "quote", 2189 + "syn", 2190 + ] 2191 + 2192 + [[package]] 2193 + name = "time" 2194 + version = "0.3.36" 2195 + source = "registry+https://github.com/rust-lang/crates.io-index" 2196 + checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" 2197 + dependencies = [ 2198 + "deranged", 2199 + "itoa", 2200 + "num-conv", 2201 + "powerfmt", 2202 + "serde", 2203 + "time-core", 2204 + "time-macros", 2205 + ] 2206 + 2207 + [[package]] 2208 + name = "time-core" 2209 + version = "0.1.2" 2210 + source = "registry+https://github.com/rust-lang/crates.io-index" 2211 + checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 2212 + 2213 + [[package]] 2214 + name = "time-macros" 2215 + version = "0.2.18" 2216 + source = "registry+https://github.com/rust-lang/crates.io-index" 2217 + checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" 2218 + dependencies = [ 2219 + "num-conv", 2220 + "time-core", 2221 + ] 2222 + 2223 + [[package]] 2224 + name = "tinyvec" 2225 + version = "1.8.0" 2226 + source = "registry+https://github.com/rust-lang/crates.io-index" 2227 + checksum = "445e881f4f6d382d5f27c034e25eb92edd7c784ceab92a0937db7f2e9471b938" 2228 + dependencies = [ 2229 + "tinyvec_macros", 2230 + ] 2231 + 2232 + [[package]] 2233 + name = "tinyvec_macros" 2234 + version = "0.1.1" 2235 + source = "registry+https://github.com/rust-lang/crates.io-index" 2236 + checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" 2237 + 2238 + [[package]] 2239 + name = "tokio" 2240 + version = "1.40.0" 2241 + source = "registry+https://github.com/rust-lang/crates.io-index" 2242 + checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" 2243 + dependencies = [ 2244 + "backtrace", 2245 + "bytes", 2246 + "libc", 2247 + "mio", 2248 + "parking_lot", 2249 + "pin-project-lite", 2250 + "signal-hook-registry", 2251 + "socket2", 2252 + "tokio-macros", 2253 + "windows-sys 0.52.0", 2254 + ] 2255 + 2256 + [[package]] 2257 + name = "tokio-macros" 2258 + version = "2.4.0" 2259 + source = "registry+https://github.com/rust-lang/crates.io-index" 2260 + checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752" 2261 + dependencies = [ 2262 + "proc-macro2", 2263 + "quote", 2264 + "syn", 2265 + ] 2266 + 2267 + [[package]] 2268 + name = "tokio-rustls" 2269 + version = "0.26.0" 2270 + source = "registry+https://github.com/rust-lang/crates.io-index" 2271 + checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4" 2272 + dependencies = [ 2273 + "rustls", 2274 + "rustls-pki-types", 2275 + "tokio", 2276 + ] 2277 + 2278 + [[package]] 2279 + name = "tokio-stream" 2280 + version = "0.1.16" 2281 + source = "registry+https://github.com/rust-lang/crates.io-index" 2282 + checksum = "4f4e6ce100d0eb49a2734f8c0812bcd324cf357d21810932c5df6b96ef2b86f1" 2283 + dependencies = [ 2284 + "futures-core", 2285 + "pin-project-lite", 2286 + "tokio", 2287 + ] 2288 + 2289 + [[package]] 2290 + name = "tokio-util" 2291 + version = "0.7.12" 2292 + source = "registry+https://github.com/rust-lang/crates.io-index" 2293 + checksum = "61e7c3654c13bcd040d4a03abee2c75b1d14a37b423cf5a813ceae1cc903ec6a" 2294 + dependencies = [ 2295 + "bytes", 2296 + "futures-core", 2297 + "futures-sink", 2298 + "pin-project-lite", 2299 + "tokio", 2300 + ] 2301 + 2302 + [[package]] 2303 + name = "toml_datetime" 2304 + version = "0.6.8" 2305 + source = "registry+https://github.com/rust-lang/crates.io-index" 2306 + checksum = "0dd7358ecb8fc2f8d014bf86f6f638ce72ba252a2c3a2572f2a795f1d23efb41" 2307 + 2308 + [[package]] 2309 + name = "toml_edit" 2310 + version = "0.22.20" 2311 + source = "registry+https://github.com/rust-lang/crates.io-index" 2312 + checksum = "583c44c02ad26b0c3f3066fe629275e50627026c51ac2e595cca4c230ce1ce1d" 2313 + dependencies = [ 2314 + "indexmap 2.5.0", 2315 + "toml_datetime", 2316 + "winnow", 2317 + ] 2318 + 2319 + [[package]] 2320 + name = "tonic" 2321 + version = "0.12.2" 2322 + source = "registry+https://github.com/rust-lang/crates.io-index" 2323 + checksum = "c6f6ba989e4b2c58ae83d862d3a3e27690b6e3ae630d0deb59f3697f32aa88ad" 2324 + dependencies = [ 2325 + "async-stream", 2326 + "async-trait", 2327 + "axum", 2328 + "base64", 2329 + "bytes", 2330 + "h2 0.4.6", 2331 + "http 1.1.0", 2332 + "http-body", 2333 + "http-body-util", 2334 + "hyper", 2335 + "hyper-timeout", 2336 + "hyper-util", 2337 + "percent-encoding", 2338 + "pin-project", 2339 + "prost", 2340 + "socket2", 2341 + "tokio", 2342 + "tokio-stream", 2343 + "tower", 2344 + "tower-layer", 2345 + "tower-service", 2346 + "tracing", 2347 + ] 2348 + 2349 + [[package]] 2350 + name = "tonic-build" 2351 + version = "0.12.2" 2352 + source = "registry+https://github.com/rust-lang/crates.io-index" 2353 + checksum = "fe4ee8877250136bd7e3d2331632810a4df4ea5e004656990d8d66d2f5ee8a67" 2354 + dependencies = [ 2355 + "prettyplease", 2356 + "proc-macro2", 2357 + "prost-build", 2358 + "quote", 2359 + "syn", 2360 + ] 2361 + 2362 + [[package]] 2363 + name = "tonic-reflection" 2364 + version = "0.12.2" 2365 + source = "registry+https://github.com/rust-lang/crates.io-index" 2366 + checksum = "7b56b874eedb04f89907573b408eab1e87c1c1dce43aac6ad63742f57faa99ff" 2367 + dependencies = [ 2368 + "prost", 2369 + "prost-types", 2370 + "tokio", 2371 + "tokio-stream", 2372 + "tonic", 2373 + ] 2374 + 2375 + [[package]] 2376 + name = "tonic-web" 2377 + version = "0.12.2" 2378 + source = "registry+https://github.com/rust-lang/crates.io-index" 2379 + checksum = "b904b18f914fe88913a9f0d750065b39c9c497e4b2aa05148f2c29a724145541" 2380 + dependencies = [ 2381 + "base64", 2382 + "bytes", 2383 + "http 1.1.0", 2384 + "http-body", 2385 + "http-body-util", 2386 + "pin-project", 2387 + "tokio-stream", 2388 + "tonic", 2389 + "tower-http", 2390 + "tower-layer", 2391 + "tower-service", 2392 + "tracing", 2393 + ] 2394 + 2395 + [[package]] 2396 + name = "tower" 2397 + version = "0.4.13" 2398 + source = "registry+https://github.com/rust-lang/crates.io-index" 2399 + checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 2400 + dependencies = [ 2401 + "futures-core", 2402 + "futures-util", 2403 + "indexmap 1.9.3", 2404 + "pin-project", 2405 + "pin-project-lite", 2406 + "rand", 2407 + "slab", 2408 + "tokio", 2409 + "tokio-util", 2410 + "tower-layer", 2411 + "tower-service", 2412 + "tracing", 2413 + ] 2414 + 2415 + [[package]] 2416 + name = "tower-http" 2417 + version = "0.5.2" 2418 + source = "registry+https://github.com/rust-lang/crates.io-index" 2419 + checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" 2420 + dependencies = [ 2421 + "bitflags", 2422 + "bytes", 2423 + "http 1.1.0", 2424 + "http-body", 2425 + "http-body-util", 2426 + "pin-project-lite", 2427 + "tower-layer", 2428 + "tower-service", 2429 + ] 2430 + 2431 + [[package]] 2432 + name = "tower-layer" 2433 + version = "0.3.3" 2434 + source = "registry+https://github.com/rust-lang/crates.io-index" 2435 + checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" 2436 + 2437 + [[package]] 2438 + name = "tower-service" 2439 + version = "0.3.3" 2440 + source = "registry+https://github.com/rust-lang/crates.io-index" 2441 + checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" 2442 + 2443 + [[package]] 2444 + name = "tracing" 2445 + version = "0.1.40" 2446 + source = "registry+https://github.com/rust-lang/crates.io-index" 2447 + checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 2448 + dependencies = [ 2449 + "log", 2450 + "pin-project-lite", 2451 + "tracing-attributes", 2452 + "tracing-core", 2453 + ] 2454 + 2455 + [[package]] 2456 + name = "tracing-attributes" 2457 + version = "0.1.27" 2458 + source = "registry+https://github.com/rust-lang/crates.io-index" 2459 + checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 2460 + dependencies = [ 2461 + "proc-macro2", 2462 + "quote", 2463 + "syn", 2464 + ] 2465 + 2466 + [[package]] 2467 + name = "tracing-core" 2468 + version = "0.1.32" 2469 + source = "registry+https://github.com/rust-lang/crates.io-index" 2470 + checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 2471 + dependencies = [ 2472 + "once_cell", 2473 + ] 2474 + 2475 + [[package]] 2476 + name = "try-lock" 2477 + version = "0.2.5" 2478 + source = "registry+https://github.com/rust-lang/crates.io-index" 2479 + checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 2480 + 2481 + [[package]] 2482 + name = "typenum" 2483 + version = "1.17.0" 2484 + source = "registry+https://github.com/rust-lang/crates.io-index" 2485 + checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 2486 + 2487 + [[package]] 2488 + name = "ucd-trie" 2489 + version = "0.1.6" 2490 + source = "registry+https://github.com/rust-lang/crates.io-index" 2491 + checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" 2492 + 2493 + [[package]] 2494 + name = "unicode-bidi" 2495 + version = "0.3.15" 2496 + source = "registry+https://github.com/rust-lang/crates.io-index" 2497 + checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" 2498 + 2499 + [[package]] 2500 + name = "unicode-ident" 2501 + version = "1.0.12" 2502 + source = "registry+https://github.com/rust-lang/crates.io-index" 2503 + checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 2504 + 2505 + [[package]] 2506 + name = "unicode-normalization" 2507 + version = "0.1.23" 2508 + source = "registry+https://github.com/rust-lang/crates.io-index" 2509 + checksum = "a56d1686db2308d901306f92a263857ef59ea39678a5458e7cb17f01415101f5" 2510 + dependencies = [ 2511 + "tinyvec", 2512 + ] 2513 + 2514 + [[package]] 2515 + name = "untrusted" 2516 + version = "0.9.0" 2517 + source = "registry+https://github.com/rust-lang/crates.io-index" 2518 + checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 2519 + 2520 + [[package]] 2521 + name = "url" 2522 + version = "2.5.2" 2523 + source = "registry+https://github.com/rust-lang/crates.io-index" 2524 + checksum = "22784dbdf76fdde8af1aeda5622b546b422b6fc585325248a2bf9f5e41e94d6c" 2525 + dependencies = [ 2526 + "form_urlencoded", 2527 + "idna", 2528 + "percent-encoding", 2529 + ] 2530 + 2531 + [[package]] 2532 + name = "version_check" 2533 + version = "0.9.5" 2534 + source = "registry+https://github.com/rust-lang/crates.io-index" 2535 + checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" 2536 + 2537 + [[package]] 2538 + name = "want" 2539 + version = "0.3.1" 2540 + source = "registry+https://github.com/rust-lang/crates.io-index" 2541 + checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2542 + dependencies = [ 2543 + "try-lock", 2544 + ] 2545 + 2546 + [[package]] 2547 + name = "wasi" 2548 + version = "0.11.0+wasi-snapshot-preview1" 2549 + source = "registry+https://github.com/rust-lang/crates.io-index" 2550 + checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2551 + 2552 + [[package]] 2553 + name = "wasm-bindgen" 2554 + version = "0.2.93" 2555 + source = "registry+https://github.com/rust-lang/crates.io-index" 2556 + checksum = "a82edfc16a6c469f5f44dc7b571814045d60404b55a0ee849f9bcfa2e63dd9b5" 2557 + dependencies = [ 2558 + "cfg-if", 2559 + "once_cell", 2560 + "wasm-bindgen-macro", 2561 + ] 2562 + 2563 + [[package]] 2564 + name = "wasm-bindgen-backend" 2565 + version = "0.2.93" 2566 + source = "registry+https://github.com/rust-lang/crates.io-index" 2567 + checksum = "9de396da306523044d3302746f1208fa71d7532227f15e347e2d93e4145dd77b" 2568 + dependencies = [ 2569 + "bumpalo", 2570 + "log", 2571 + "once_cell", 2572 + "proc-macro2", 2573 + "quote", 2574 + "syn", 2575 + "wasm-bindgen-shared", 2576 + ] 2577 + 2578 + [[package]] 2579 + name = "wasm-bindgen-futures" 2580 + version = "0.4.43" 2581 + source = "registry+https://github.com/rust-lang/crates.io-index" 2582 + checksum = "61e9300f63a621e96ed275155c108eb6f843b6a26d053f122ab69724559dc8ed" 2583 + dependencies = [ 2584 + "cfg-if", 2585 + "js-sys", 2586 + "wasm-bindgen", 2587 + "web-sys", 2588 + ] 2589 + 2590 + [[package]] 2591 + name = "wasm-bindgen-macro" 2592 + version = "0.2.93" 2593 + source = "registry+https://github.com/rust-lang/crates.io-index" 2594 + checksum = "585c4c91a46b072c92e908d99cb1dcdf95c5218eeb6f3bf1efa991ee7a68cccf" 2595 + dependencies = [ 2596 + "quote", 2597 + "wasm-bindgen-macro-support", 2598 + ] 2599 + 2600 + [[package]] 2601 + name = "wasm-bindgen-macro-support" 2602 + version = "0.2.93" 2603 + source = "registry+https://github.com/rust-lang/crates.io-index" 2604 + checksum = "afc340c74d9005395cf9dd098506f7f44e38f2b4a21c6aaacf9a105ea5e1e836" 2605 + dependencies = [ 2606 + "proc-macro2", 2607 + "quote", 2608 + "syn", 2609 + "wasm-bindgen-backend", 2610 + "wasm-bindgen-shared", 2611 + ] 2612 + 2613 + [[package]] 2614 + name = "wasm-bindgen-shared" 2615 + version = "0.2.93" 2616 + source = "registry+https://github.com/rust-lang/crates.io-index" 2617 + checksum = "c62a0a307cb4a311d3a07867860911ca130c3494e8c2719593806c08bc5d0484" 2618 + 2619 + [[package]] 2620 + name = "web-sys" 2621 + version = "0.3.70" 2622 + source = "registry+https://github.com/rust-lang/crates.io-index" 2623 + checksum = "26fdeaafd9bd129f65e7c031593c24d62186301e0c72c8978fa1678be7d532c0" 2624 + dependencies = [ 2625 + "js-sys", 2626 + "wasm-bindgen", 2627 + ] 2628 + 2629 + [[package]] 2630 + name = "webpki-roots" 2631 + version = "0.26.3" 2632 + source = "registry+https://github.com/rust-lang/crates.io-index" 2633 + checksum = "bd7c23921eeb1713a4e851530e9b9756e4fb0e89978582942612524cf09f01cd" 2634 + dependencies = [ 2635 + "rustls-pki-types", 2636 + ] 2637 + 2638 + [[package]] 2639 + name = "windows-registry" 2640 + version = "0.2.0" 2641 + source = "registry+https://github.com/rust-lang/crates.io-index" 2642 + checksum = "e400001bb720a623c1c69032f8e3e4cf09984deec740f007dd2b03ec864804b0" 2643 + dependencies = [ 2644 + "windows-result", 2645 + "windows-strings", 2646 + "windows-targets", 2647 + ] 2648 + 2649 + [[package]] 2650 + name = "windows-result" 2651 + version = "0.2.0" 2652 + source = "registry+https://github.com/rust-lang/crates.io-index" 2653 + checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" 2654 + dependencies = [ 2655 + "windows-targets", 2656 + ] 2657 + 2658 + [[package]] 2659 + name = "windows-strings" 2660 + version = "0.1.0" 2661 + source = "registry+https://github.com/rust-lang/crates.io-index" 2662 + checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" 2663 + dependencies = [ 2664 + "windows-result", 2665 + "windows-targets", 2666 + ] 2667 + 2668 + [[package]] 2669 + name = "windows-sys" 2670 + version = "0.52.0" 2671 + source = "registry+https://github.com/rust-lang/crates.io-index" 2672 + checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2673 + dependencies = [ 2674 + "windows-targets", 2675 + ] 2676 + 2677 + [[package]] 2678 + name = "windows-sys" 2679 + version = "0.59.0" 2680 + source = "registry+https://github.com/rust-lang/crates.io-index" 2681 + checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" 2682 + dependencies = [ 2683 + "windows-targets", 2684 + ] 2685 + 2686 + [[package]] 2687 + name = "windows-targets" 2688 + version = "0.52.6" 2689 + source = "registry+https://github.com/rust-lang/crates.io-index" 2690 + checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" 2691 + dependencies = [ 2692 + "windows_aarch64_gnullvm", 2693 + "windows_aarch64_msvc", 2694 + "windows_i686_gnu", 2695 + "windows_i686_gnullvm", 2696 + "windows_i686_msvc", 2697 + "windows_x86_64_gnu", 2698 + "windows_x86_64_gnullvm", 2699 + "windows_x86_64_msvc", 2700 + ] 2701 + 2702 + [[package]] 2703 + name = "windows_aarch64_gnullvm" 2704 + version = "0.52.6" 2705 + source = "registry+https://github.com/rust-lang/crates.io-index" 2706 + checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" 2707 + 2708 + [[package]] 2709 + name = "windows_aarch64_msvc" 2710 + version = "0.52.6" 2711 + source = "registry+https://github.com/rust-lang/crates.io-index" 2712 + checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" 2713 + 2714 + [[package]] 2715 + name = "windows_i686_gnu" 2716 + version = "0.52.6" 2717 + source = "registry+https://github.com/rust-lang/crates.io-index" 2718 + checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" 2719 + 2720 + [[package]] 2721 + name = "windows_i686_gnullvm" 2722 + version = "0.52.6" 2723 + source = "registry+https://github.com/rust-lang/crates.io-index" 2724 + checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" 2725 + 2726 + [[package]] 2727 + name = "windows_i686_msvc" 2728 + version = "0.52.6" 2729 + source = "registry+https://github.com/rust-lang/crates.io-index" 2730 + checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" 2731 + 2732 + [[package]] 2733 + name = "windows_x86_64_gnu" 2734 + version = "0.52.6" 2735 + source = "registry+https://github.com/rust-lang/crates.io-index" 2736 + checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" 2737 + 2738 + [[package]] 2739 + name = "windows_x86_64_gnullvm" 2740 + version = "0.52.6" 2741 + source = "registry+https://github.com/rust-lang/crates.io-index" 2742 + checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" 2743 + 2744 + [[package]] 2745 + name = "windows_x86_64_msvc" 2746 + version = "0.52.6" 2747 + source = "registry+https://github.com/rust-lang/crates.io-index" 2748 + checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" 2749 + 2750 + [[package]] 2751 + name = "winnow" 2752 + version = "0.6.18" 2753 + source = "registry+https://github.com/rust-lang/crates.io-index" 2754 + checksum = "68a9bda4691f099d435ad181000724da8e5899daa10713c2d432552b9ccd3a6f" 2755 + dependencies = [ 2756 + "memchr", 2757 + ] 2758 + 2759 + [[package]] 2760 + name = "zerocopy" 2761 + version = "0.7.35" 2762 + source = "registry+https://github.com/rust-lang/crates.io-index" 2763 + checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" 2764 + dependencies = [ 2765 + "byteorder", 2766 + "zerocopy-derive", 2767 + ] 2768 + 2769 + [[package]] 2770 + name = "zerocopy-derive" 2771 + version = "0.7.35" 2772 + source = "registry+https://github.com/rust-lang/crates.io-index" 2773 + checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" 2774 + dependencies = [ 2775 + "proc-macro2", 2776 + "quote", 2777 + "syn", 2778 + ] 2779 + 2780 + [[package]] 2781 + name = "zeroize" 2782 + version = "1.8.1" 2783 + source = "registry+https://github.com/rust-lang/crates.io-index" 2784 + checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" 2785 + 2786 + [[package]] 2787 + name = "zstd" 2788 + version = "0.13.2" 2789 + source = "registry+https://github.com/rust-lang/crates.io-index" 2790 + checksum = "fcf2b778a664581e31e389454a7072dab1647606d44f7feea22cd5abb9c9f3f9" 2791 + dependencies = [ 2792 + "zstd-safe", 2793 + ] 2794 + 2795 + [[package]] 2796 + name = "zstd-safe" 2797 + version = "7.2.1" 2798 + source = "registry+https://github.com/rust-lang/crates.io-index" 2799 + checksum = "54a3ab4db68cea366acc5c897c7b4d4d1b8994a9cd6e6f841f8964566a419059" 2800 + dependencies = [ 2801 + "zstd-sys", 2802 + ] 2803 + 2804 + [[package]] 2805 + name = "zstd-sys" 2806 + version = "2.0.13+zstd.1.5.6" 2807 + source = "registry+https://github.com/rust-lang/crates.io-index" 2808 + checksum = "38ff0f21cfee8f97d94cef41359e0c89aa6113028ab0291aa8ca0038995a95aa" 2809 + dependencies = [ 2810 + "cc", 2811 + "pkg-config", 2812 + ]
+6
Cargo.toml
··· 1 + [workspace] 2 + default-members = ["crates/*"] 3 + members = ["crates/*"] 4 + resolver = "2" 5 + 6 + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+280
LICENSE
··· 1 + GNU GENERAL PUBLIC LICENSE 2 + Version 2, June 1991 3 + 4 + Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 + 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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
+30 -2
README.md
··· 5 5 6 6 # Rockbox Zig 🎵 ⚡ 7 7 8 - Rockbox Zig is an incremental enhancement of the [Rockbox](https://www.rockbox.org) firmware for portable audio players in the Zig programming language. 8 + Rockbox Zig is an incremental enhancement of the [Rockbox](https://www.rockbox.org) firmware for portable audio players in Zig and Rust. 9 9 10 10 > [!NOTE] 11 11 **🐲 It is a work in progress and is not yet ready for use. 🏗️🚧** 12 + 13 + ![Preview](./docs/preview.png) 12 14 13 15 ## 🚀 Quickstart 14 16 ··· 16 18 17 19 ```sh 18 20 sudo apt-get install libusb-dev libsdl1.2-dev libfreetype6-dev 19 - . ./bin/activate-hermit 20 21 mkdir -p build && cd build 21 22 ../tools/configure --target=sdlapp --type=N --lcdwidth=320 --lcdheight=240 --prefix=$HOME/.local 22 23 make zig 23 24 ``` 25 + 26 + ## ✨ Features 27 + 28 + - [x] Zig Build System 29 + - [x] Rockbox API FFI for Rust 30 + - [x] gRPC API 31 + - [x] GraphQL API 32 + - [ ] Web Client (React) 33 + - [ ] Desktop Client (Electron/Gtk) 34 + - [ ] Terminal Client (TUI) 35 + - [ ] Android Library 36 + - [ ] Mobile version (React Native) 37 + - [ ] Stream from Youtube (audio only) 38 + - [ ] Stream from Spotify 39 + - [ ] Stream from Tidal 40 + - [ ] Stream to Chromecast 41 + - [ ] TuneIn Radio 42 + - [ ] MPD Server 43 + - [ ] MPRIS 44 + - [ ] Upnp Player 45 + - [ ] Airplay 46 + - [ ] TypeScript ([Deno](https://deno.com)) API (for writing plugins) 47 + 48 + ## 🧑‍🔬 Architecture 49 + 50 + ![architecture](./docs/rockbox-server-architecture.jpg) 51 +
+5
apps/main.c
··· 94 94 #include "audio_thread.h" 95 95 #include "playback.h" 96 96 #include "tdspeed.h" 97 + #include "server_thread.h" 97 98 #if defined(HAVE_RECORDING) && !defined(SIMULATOR) 98 99 #include "pcm_record.h" 99 100 #endif ··· 449 450 #ifndef USB_NONE 450 451 usb_init(); 451 452 usb_start_monitoring(); 453 + #endif 454 + 455 + #ifdef ROCKBOX_SERVER 456 + server_init(); 452 457 #endif 453 458 } 454 459
+80
apps/server_thread.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2005-2007 Miika Pekkarinen 11 + * Copyright (C) 2007-2008 Nicolas Pennequin 12 + * Copyright (C) 2011-2013 Michael Sevakis 13 + * 14 + * This program is free software; you can redistribute it and/or 15 + * modify it under the terms of the GNU General Public License 16 + * as published by the Free Software Foundation; either version 2 17 + * of the License, or (at your option) any later version. 18 + * 19 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 + * KIND, either express or implied. 21 + * 22 + ****************************************************************************/ 23 + #include "config.h" 24 + #include "system.h" 25 + #include "kernel.h" 26 + #include "logf.h" 27 + #include "appevents.h" 28 + 29 + bool server_is_initialized = false; 30 + 31 + /* Event queues */ 32 + // struct event_queue server_queue SHAREDBSS_ATTR; 33 + // static struct queue_sender_list server_queue_sender_list SHAREDBSS_ATTR; 34 + 35 + /* Server thread */ 36 + static long server_stack[(DEFAULT_STACK_SIZE + 0x1000)/sizeof(long)]; 37 + static const char server_thread_name[] = "server"; 38 + unsigned int server_thread_id = 0; 39 + 40 + extern void start_server(void); 41 + extern void start_servers(void); 42 + 43 + extern void debugfn(const char *fmt); 44 + 45 + static void server_thread(void) { 46 + start_server(); 47 + } 48 + 49 + /** -- Startup -- **/ 50 + 51 + /* Initialize the server - called from init() in main.c */ 52 + void INIT_ATTR server_init(void) 53 + { 54 + /* Can never do this twice */ 55 + if (server_is_initialized) 56 + { 57 + logf("server: already initialized"); 58 + return; 59 + } 60 + 61 + logf("server: initializing"); 62 + 63 + /* Initialize queues before giving control elsewhere in case it likes 64 + to send messages. Thread creation will be delayed however so nothing 65 + starts running until ready if something yields such as talk_init. */ 66 + // queue_init(&server_queue, true); 67 + 68 + /* This thread does buffer, so match its priority */ 69 + server_thread_id = create_thread(server_thread, server_stack, 70 + sizeof(server_stack), 0, server_thread_name 71 + IF_PRIO(, PRIORITY_USER_INTERFACE) 72 + IF_COP(, CPU)); 73 + 74 + sleep(HZ); 75 + 76 + start_servers(); 77 + 78 + /* Probably safe to say */ 79 + server_is_initialized = true; 80 + }
+32
apps/server_thread.h
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * $Id$ 9 + * 10 + * Copyright (C) 2005-2007 Miika Pekkarinen 11 + * Copyright (C) 2007-2008 Nicolas Pennequin 12 + * Copyright (C) 2011-2013 Michael Sevakis 13 + * 14 + * This program is free software; you can redistribute it and/or 15 + * modify it under the terms of the GNU General Public License 16 + * as published by the Free Software Foundation; either version 2 17 + * of the License, or (at your option) any later version. 18 + * 19 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 20 + * KIND, either express or implied. 21 + * 22 + ****************************************************************************/ 23 + #ifndef SERVER_THREAD_H 24 + #define SERVER_THREAD_H 25 + 26 + 27 + /* (*) If you change these, you must check audio_clear_track_notifications 28 + in playback.c for correctness */ 29 + 30 + void server_init(void); 31 + 32 + #endif /* SERVER_THREAD_H */
+1
bin/.buf-1.40.1.pkg
··· 1 + hermit
+1
bin/.grpcurl-1.9.1.pkg
··· 1 + hermit
+1
bin/.protoc-28.0.pkg
··· 1 + hermit
+1
bin/.rust-1.81.0.pkg
··· 1 + hermit
+1
bin/buf
··· 1 + .buf-1.40.1.pkg
+1
bin/cargo
··· 1 + .rust-1.81.0.pkg
+1
bin/cargo-clippy
··· 1 + .rust-1.81.0.pkg
+1
bin/cargo-fmt
··· 1 + .rust-1.81.0.pkg
+1
bin/clippy-driver
··· 1 + .rust-1.81.0.pkg
+1
bin/grpcurl
··· 1 + .grpcurl-1.9.1.pkg
+1
bin/protoc
··· 1 + .protoc-28.0.pkg
+1
bin/protoc-gen-buf-breaking
··· 1 + .buf-1.40.1.pkg
+1
bin/protoc-gen-buf-lint
··· 1 + .buf-1.40.1.pkg
+1
bin/rls
··· 1 + .rust-1.81.0.pkg
+1
bin/rust-analyzer
··· 1 + .rust-1.81.0.pkg
+1
bin/rust-gdb
··· 1 + .rust-1.81.0.pkg
+1
bin/rust-gdbgui
··· 1 + .rust-1.81.0.pkg
+1
bin/rust-lldb
··· 1 + .rust-1.81.0.pkg
+1
bin/rustc
··· 1 + .rust-1.81.0.pkg
+1
bin/rustdoc
··· 1 + .rust-1.81.0.pkg
+1
bin/rustfmt
··· 1 + .rust-1.81.0.pkg
+13 -1
build.zig
··· 138 138 }); 139 139 140 140 exe.defineCMacro("ZIG_APP", null); 141 + exe.defineCMacro("ROCKBOX_SERVER", null); 141 142 142 143 lib.addCSourceFiles(.{ 143 144 .files = &[_][]const u8{}, ··· 158 159 159 160 defineCMacros(libfirmware); 160 161 addIncludePaths(libfirmware); 162 + 163 + libfirmware.linkSystemLibrary("usb"); 161 164 162 165 const libspeex_voice = b.addStaticLibrary(.{ 163 166 .name = "speex-voice", ··· 2920 2923 defineCMacros(exe); 2921 2924 addIncludePaths(exe); 2922 2925 2926 + exe.addObjectFile(.{ 2927 + .cwd_relative = "./build/apps/recorder/jpeg_load.o", 2928 + }); 2929 + 2930 + exe.addLibraryPath(.{ 2931 + .cwd_relative = "./target/release", 2932 + }); 2933 + exe.linkSystemLibrary("rockbox_server"); 2934 + exe.linkSystemLibrary("libunwind"); 2923 2935 exe.linkLibrary(libfirmware); 2924 2936 exe.linkLibrary(libspeex_voice); 2925 2937 exe.linkLibrary(librbcodec); ··· 4207 4219 "apps/recorder/keyboard.c", 4208 4220 "apps/recorder/peakmeter.c", 4209 4221 "apps/recorder/resize.c", 4210 - "apps/recorder/jpeg_load.c", 4211 4222 "apps/recorder/albumart.c", 4212 4223 "apps/gui/color_picker.c", 4213 4224 "apps/audio_thread.c", ··· 4219 4230 "apps/tagcache.c", 4220 4231 "apps/keymaps/keymap-touchscreen.c", 4221 4232 "apps/keymaps/keymap-sdl.c", 4233 + "apps/server_thread.c", 4222 4234 "build/lang/lang_core.c", 4223 4235 }; 4224 4236
+16
crates/graphql/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "rockbox-graphql" 4 + version = "0.1.0" 5 + 6 + [dependencies] 7 + actix-cors = "0.7.0" 8 + actix-web = "4.9.0" 9 + anyhow = "1.0.87" 10 + async-graphql = "7.0.9" 11 + async-graphql-actix-web = "7.0.9" 12 + owo-colors = "4.1.0" 13 + reqwest = {version = "0.12.7", features = ["rustls-tls", "json"], default-features = false} 14 + rockbox-sys = {path = "../sys"} 15 + serde = "1.0.210" 16 + tokio = {version = "1.40.0", features = ["full"]}
+11
crates/graphql/src/lib.rs
··· 1 + use async_graphql::{EmptySubscription, Schema}; 2 + use schema::{Mutation, Query}; 3 + 4 + pub mod schema; 5 + pub mod server; 6 + pub type RockboxSchema = Schema<Query, Mutation, EmptySubscription>; 7 + 8 + pub fn rockbox_url() -> String { 9 + let port = std::env::var("ROCKBOX_TCP_PORT").unwrap_or_else(|_| "6063".to_string()); 10 + format!("http://127.0.0.1:{}", port) 11 + }
+23
crates/graphql/src/schema/browse.rs
··· 1 + use async_graphql::*; 2 + 3 + #[derive(Default)] 4 + pub struct BrowseQuery; 5 + 6 + #[Object] 7 + impl BrowseQuery { 8 + async fn browse_id3(&self) -> String { 9 + "browse id3".to_string() 10 + } 11 + 12 + async fn tree_get_context(&self) -> String { 13 + "tree get context".to_string() 14 + } 15 + 16 + async fn tree_get_entry_at(&self) -> String { 17 + "tree get entry at".to_string() 18 + } 19 + 20 + async fn rockbox_browse(&self) -> String { 21 + "rockbox browse".to_string() 22 + } 23 + }
+4
crates/graphql/src/schema/metadata.rs
··· 1 + use async_graphql::*; 2 + 3 + #[derive(Default)] 4 + pub struct MetadataQuery;
+30
crates/graphql/src/schema/mod.rs
··· 1 + use async_graphql::MergedObject; 2 + use browse::BrowseQuery; 3 + use playback::{PlaybackMutation, PlaybackQuery}; 4 + use playlist::{PlaylistMutation, PlaylistQuery}; 5 + use settings::SettingsQuery; 6 + use sound::{SoundMutation, SoundQuery}; 7 + use system::SystemQuery; 8 + 9 + pub mod browse; 10 + pub mod metadata; 11 + pub mod objects; 12 + pub mod playback; 13 + pub mod playlist; 14 + pub mod settings; 15 + pub mod sound; 16 + pub mod system; 17 + pub mod tagcache; 18 + 19 + #[derive(MergedObject, Default)] 20 + pub struct Query( 21 + BrowseQuery, 22 + PlaybackQuery, 23 + PlaylistQuery, 24 + SoundQuery, 25 + SettingsQuery, 26 + SystemQuery, 27 + ); 28 + 29 + #[derive(MergedObject, Default)] 30 + pub struct Mutation(PlaybackMutation, PlaylistMutation, SoundMutation);
+39
crates/graphql/src/schema/objects/compressor_settings.rs
··· 1 + use async_graphql::*; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + #[derive(Default, Clone, Serialize, Deserialize)] 5 + pub struct CompressorSettings { 6 + pub threshold: i32, 7 + pub makeup_gain: i32, 8 + pub ratio: i32, 9 + pub knee: i32, 10 + pub release_time: i32, 11 + pub attack_time: i32, 12 + } 13 + 14 + #[Object] 15 + impl CompressorSettings { 16 + async fn threshold(&self) -> i32 { 17 + self.threshold 18 + } 19 + 20 + async fn makeup_gain(&self) -> i32 { 21 + self.makeup_gain 22 + } 23 + 24 + async fn ratio(&self) -> i32 { 25 + self.ratio 26 + } 27 + 28 + async fn knee(&self) -> i32 { 29 + self.knee 30 + } 31 + 32 + async fn release_time(&self) -> i32 { 33 + self.release_time 34 + } 35 + 36 + async fn attack_time(&self) -> i32 { 37 + self.attack_time 38 + } 39 + }
+24
crates/graphql/src/schema/objects/eq_band_setting.rs
··· 1 + use async_graphql::*; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + #[derive(Default, Clone, Serialize, Deserialize)] 5 + pub struct EqBandSetting { 6 + pub cutoff: i32, // Hz 7 + pub q: i32, 8 + pub gain: i32, // +/- dB 9 + } 10 + 11 + #[Object] 12 + impl EqBandSetting { 13 + async fn cutoff(&self) -> i32 { 14 + self.cutoff 15 + } 16 + 17 + async fn q(&self) -> i32 { 18 + self.q 19 + } 20 + 21 + async fn gain(&self) -> i32 { 22 + self.gain 23 + } 24 + }
+7
crates/graphql/src/schema/objects/mod.rs
··· 1 + pub mod compressor_settings; 2 + pub mod eq_band_setting; 3 + pub mod replaygain_settings; 4 + pub mod settings_list; 5 + pub mod system_status; 6 + pub mod track; 7 + pub mod user_settings;
+24
crates/graphql/src/schema/objects/replaygain_settings.rs
··· 1 + use async_graphql::*; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + #[derive(Default, Clone, Serialize, Deserialize)] 5 + pub struct ReplaygainSettings { 6 + pub noclip: bool, // scale to prevent clips 7 + pub r#type: i32, // 0=track gain, 1=album gain, 2=track gain if shuffle is on, album gain otherwise, 4=off 8 + pub preamp: i32, // scale replaygained tracks by this 9 + } 10 + 11 + #[Object] 12 + impl ReplaygainSettings { 13 + async fn noclip(&self) -> bool { 14 + self.noclip 15 + } 16 + 17 + async fn r#type(&self) -> i32 { 18 + self.r#type 19 + } 20 + 21 + async fn preamp(&self) -> i32 { 22 + self.preamp 23 + } 24 + }
+46
crates/graphql/src/schema/objects/settings_list.rs
··· 1 + use async_graphql::*; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + #[derive(Default, Clone, Serialize, Deserialize)] 5 + pub struct SettingsList { 6 + pub flags: u32, 7 + // pub setting: *mut c_void, 8 + pub lang_id: i32, 9 + // pub default_val: StorageType, // union storage_type 10 + pub cfg_name: String, // const char* 11 + pub cfg_vals: String, // const char* 12 + 13 + // union with different possible struct types 14 + // pub setting_type: SettingsTypeUnion, 15 + } 16 + 17 + #[Object] 18 + impl SettingsList { 19 + async fn flags(&self) -> u32 { 20 + self.flags 21 + } 22 + 23 + // async fn setting(&self) -> *mut c_void { 24 + // self.setting 25 + // } 26 + 27 + async fn lang_id(&self) -> i32 { 28 + self.lang_id 29 + } 30 + 31 + // async fn default_val(&self) -> StorageType { 32 + // self.default_val 33 + // } 34 + 35 + async fn cfg_name(&self) -> &str { 36 + &self.cfg_name 37 + } 38 + 39 + async fn cfg_vals(&self) -> &str { 40 + &self.cfg_vals 41 + } 42 + 43 + // async fn setting_type(&self) -> SettingsTypeUnion { 44 + // self.setting_type 45 + // } 46 + }
+59
crates/graphql/src/schema/objects/system_status.rs
··· 1 + use async_graphql::*; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + #[derive(Default, Clone, Serialize, Deserialize)] 5 + pub struct SystemStatus { 6 + pub resume_index: i32, 7 + pub resume_crc32: u32, 8 + pub resume_elapsed: u32, 9 + pub resume_offset: u32, 10 + pub runtime: i32, 11 + pub topruntime: i32, 12 + pub dircache_size: i32, 13 + pub last_screen: i8, 14 + pub viewer_icon_count: i32, 15 + pub last_volume_change: i32, 16 + } 17 + 18 + #[Object] 19 + impl SystemStatus { 20 + async fn resume_index(&self) -> i32 { 21 + self.resume_index 22 + } 23 + 24 + async fn resume_crc32(&self) -> u32 { 25 + self.resume_crc32 26 + } 27 + 28 + async fn resume_elapsed(&self) -> u32 { 29 + self.resume_elapsed 30 + } 31 + 32 + async fn resume_offset(&self) -> u32 { 33 + self.resume_offset 34 + } 35 + 36 + async fn runtime(&self) -> i32 { 37 + self.runtime 38 + } 39 + 40 + async fn topruntime(&self) -> i32 { 41 + self.topruntime 42 + } 43 + 44 + async fn dircache_size(&self) -> i32 { 45 + self.dircache_size 46 + } 47 + 48 + async fn last_screen(&self) -> i8 { 49 + self.last_screen 50 + } 51 + 52 + async fn viewer_icon_count(&self) -> i32 { 53 + self.viewer_icon_count 54 + } 55 + 56 + async fn last_volume_change(&self) -> i32 { 57 + self.last_volume_change 58 + } 59 + }
+158
crates/graphql/src/schema/objects/track.rs
··· 1 + use async_graphql::*; 2 + use rockbox_sys::types::mp3_entry::Mp3Entry; 3 + use serde::Serialize; 4 + 5 + #[derive(Default, Clone, Serialize)] 6 + pub struct Track { 7 + pub title: String, 8 + pub artist: String, 9 + pub album: String, 10 + pub genre: String, 11 + pub disc: String, 12 + pub track_string: String, 13 + pub year_string: String, 14 + pub composer: String, 15 + pub comment: String, 16 + pub album_artist: String, 17 + pub grouping: String, 18 + pub discnum: i32, 19 + pub tracknum: i32, 20 + pub layer: i32, 21 + pub year: i32, 22 + pub bitrate: u32, 23 + pub frequency: u64, 24 + pub filesize: u64, 25 + pub length: u64, 26 + pub elapsed: u64, 27 + } 28 + 29 + #[Object] 30 + impl Track { 31 + async fn title(&self) -> &str { 32 + &self.title 33 + } 34 + 35 + async fn artist(&self) -> &str { 36 + &self.artist 37 + } 38 + 39 + async fn album(&self) -> &str { 40 + &self.album 41 + } 42 + 43 + async fn genre(&self) -> &str { 44 + &self.genre 45 + } 46 + 47 + async fn disc(&self) -> &str { 48 + &self.disc 49 + } 50 + 51 + async fn track_string(&self) -> &str { 52 + &self.track_string 53 + } 54 + 55 + async fn year_string(&self) -> &str { 56 + &self.year_string 57 + } 58 + 59 + async fn composer(&self) -> &str { 60 + &self.composer 61 + } 62 + 63 + async fn comment(&self) -> &str { 64 + &self.comment 65 + } 66 + 67 + async fn album_artist(&self) -> &str { 68 + &self.album_artist 69 + } 70 + 71 + async fn grouping(&self) -> &str { 72 + &self.grouping 73 + } 74 + 75 + async fn discnum(&self) -> i32 { 76 + self.discnum 77 + } 78 + 79 + async fn tracknum(&self) -> i32 { 80 + self.tracknum 81 + } 82 + 83 + async fn layer(&self) -> i32 { 84 + self.layer 85 + } 86 + 87 + async fn year(&self) -> i32 { 88 + self.year 89 + } 90 + 91 + async fn bitrate(&self) -> u32 { 92 + self.bitrate 93 + } 94 + 95 + async fn frequency(&self) -> u64 { 96 + self.frequency 97 + } 98 + 99 + async fn filesize(&self) -> u64 { 100 + self.filesize 101 + } 102 + 103 + async fn length(&self) -> u64 { 104 + self.length 105 + } 106 + 107 + async fn elapsed(&self) -> u64 { 108 + self.elapsed 109 + } 110 + } 111 + 112 + impl From<Mp3Entry> for Track { 113 + fn from(mp3entry: Mp3Entry) -> Self { 114 + let title = mp3entry.title; 115 + let artist = mp3entry.artist; 116 + let album = mp3entry.album; 117 + let genre = mp3entry.genre_string; 118 + let disc = mp3entry.disc_string; 119 + let track_string = mp3entry.track_string; 120 + let year_string = mp3entry.year_string; 121 + let composer = mp3entry.composer; 122 + let comment = mp3entry.comment; 123 + let album_artist = mp3entry.albumartist; 124 + let grouping = mp3entry.grouping; 125 + let discnum = mp3entry.discnum; 126 + let tracknum = mp3entry.tracknum; 127 + let layer = mp3entry.layer; 128 + let year = mp3entry.year; 129 + let bitrate = mp3entry.bitrate; 130 + let frequency = mp3entry.frequency; 131 + let filesize = mp3entry.filesize; 132 + let length = mp3entry.length; 133 + let elapsed = mp3entry.elapsed; 134 + 135 + Track { 136 + title, 137 + artist, 138 + album, 139 + genre, 140 + disc, 141 + track_string, 142 + year_string, 143 + composer, 144 + comment, 145 + album_artist, 146 + grouping, 147 + discnum, 148 + tracknum, 149 + layer, 150 + year, 151 + bitrate, 152 + frequency, 153 + filesize, 154 + length, 155 + elapsed, 156 + } 157 + } 158 + }
+1063
crates/graphql/src/schema/objects/user_settings.rs
··· 1 + use async_graphql::*; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + use super::{ 5 + compressor_settings::CompressorSettings, eq_band_setting::EqBandSetting, 6 + replaygain_settings::ReplaygainSettings, settings_list::SettingsList, 7 + }; 8 + 9 + #[derive(Default, Clone, Serialize, Deserialize)] 10 + pub struct UserSettings { 11 + pub volume: i32, 12 + pub balance: i32, 13 + pub bass: i32, 14 + pub treble: i32, 15 + pub channel_config: i32, 16 + pub stereo_width: i32, 17 + 18 + pub bass_cutoff: i32, 19 + pub treble_cutoff: i32, 20 + 21 + pub crossfade: i32, 22 + pub crossfade_fade_in_delay: i32, 23 + pub crossfade_fade_out_delay: i32, 24 + pub crossfade_fade_in_duration: i32, 25 + pub crossfade_fade_out_duration: i32, 26 + pub crossfade_fade_out_mixmode: i32, 27 + 28 + // Replaygain 29 + pub replaygain_settings: ReplaygainSettings, 30 + 31 + // Crossfeed 32 + pub crossfeed: i32, 33 + pub crossfeed_direct_gain: u32, 34 + pub crossfeed_cross_gain: u32, 35 + pub crossfeed_hf_attenuation: u32, 36 + pub crossfeed_hf_cutoff: u32, 37 + 38 + // EQ 39 + pub eq_enabled: bool, 40 + pub eq_precut: u32, 41 + pub eq_band_settings: Vec<EqBandSetting>, 42 + 43 + // Misc. swcodec 44 + pub beep: i32, 45 + pub keyclick: i32, 46 + pub keyclick_repeats: i32, 47 + pub dithering_enabled: bool, 48 + pub timestretch_enabled: bool, 49 + 50 + // Misc options 51 + pub list_accel_start_delay: i32, 52 + pub list_accel_wait: i32, 53 + 54 + pub touchpad_sensitivity: i32, 55 + pub touchpad_deadzone: i32, 56 + 57 + pub pause_rewind: i32, 58 + pub unplug_mode: i32, 59 + pub unplug_autoresume: bool, 60 + 61 + pub qs_items: Vec<SettingsList>, 62 + 63 + pub timeformat: i32, 64 + pub disk_spindown: i32, 65 + pub buffer_margin: i32, 66 + 67 + pub dirfilter: i32, 68 + pub show_filename_ext: i32, 69 + pub default_codepage: i32, 70 + pub hold_lr_for_scroll_in_list: bool, 71 + pub play_selected: bool, 72 + pub single_mode: i32, 73 + pub party_mode: bool, 74 + pub cuesheet: bool, 75 + pub car_adapter_mode: bool, 76 + pub car_adapter_mode_delay: i32, 77 + pub start_in_screen: i32, 78 + pub ff_rewind_min_step: i32, 79 + pub ff_rewind_accel: i32, 80 + 81 + pub peak_meter_release: i32, 82 + pub peak_meter_hold: i32, 83 + pub peak_meter_clip_hold: i32, 84 + pub peak_meter_dbfs: bool, 85 + pub peak_meter_min: i32, 86 + pub peak_meter_max: i32, 87 + 88 + pub wps_file: String, 89 + pub sbs_file: String, 90 + pub lang_file: String, 91 + pub playlist_catalog_dir: String, 92 + pub skip_length: i32, 93 + pub max_files_in_dir: i32, 94 + pub max_files_in_playlist: i32, 95 + pub volume_type: i32, 96 + pub battery_display: i32, 97 + pub show_icons: bool, 98 + pub statusbar: i32, 99 + 100 + pub scrollbar: i32, 101 + pub scrollbar_width: i32, 102 + 103 + pub list_line_padding: i32, 104 + pub list_separator_height: i32, 105 + pub list_separator_color: i32, 106 + 107 + pub browse_current: bool, 108 + pub scroll_paginated: bool, 109 + pub list_wraparound: bool, 110 + pub list_order: i32, 111 + pub scroll_speed: i32, 112 + pub bidir_limit: i32, 113 + pub scroll_delay: i32, 114 + pub scroll_step: i32, 115 + 116 + pub autoloadbookmark: i32, 117 + pub autocreatebookmark: i32, 118 + pub autoupdatebookmark: bool, 119 + pub usemrb: i32, 120 + 121 + pub dircache: bool, 122 + pub tagcache_ram: i32, 123 + pub tagcache_autoupdate: bool, 124 + pub autoresume_enable: bool, 125 + pub autoresume_automatic: i32, 126 + pub autoresume_paths: String, 127 + pub runtimedb: bool, 128 + pub tagcache_scan_paths: String, 129 + pub tagcache_db_path: String, 130 + pub backdrop_file: String, 131 + 132 + pub bg_color: i32, 133 + pub fg_color: i32, 134 + pub lss_color: i32, 135 + pub lse_color: i32, 136 + pub lst_color: i32, 137 + pub colors_file: String, 138 + 139 + pub browser_default: i32, 140 + 141 + pub repeat_mode: i32, 142 + pub next_folder: i32, 143 + pub constrain_next_folder: bool, 144 + pub recursive_dir_insert: i32, 145 + pub fade_on_stop: bool, 146 + pub playlist_shuffle: bool, 147 + pub warnon_erase_dynplaylist: bool, 148 + pub keep_current_track_on_replace_playlist: bool, 149 + pub show_shuffled_adding_options: bool, 150 + pub show_queue_options: i32, 151 + pub album_art: i32, 152 + pub rewind_across_tracks: bool, 153 + 154 + pub playlist_viewer_icons: bool, 155 + pub playlist_viewer_indices: bool, 156 + pub playlist_viewer_track_display: i32, 157 + 158 + pub talk_menu: bool, 159 + pub talk_dir: i32, 160 + pub talk_dir_clip: bool, 161 + pub talk_file: i32, 162 + pub talk_file_clip: bool, 163 + pub talk_filetype: bool, 164 + pub talk_battery_level: bool, 165 + pub talk_mixer_amp: i32, 166 + 167 + pub sort_case: bool, 168 + pub sort_dir: i32, 169 + pub sort_file: i32, 170 + pub interpret_numbers: i32, 171 + 172 + pub poweroff: i32, 173 + pub battery_capacity: i32, 174 + pub battery_type: i32, 175 + pub spdif_enable: bool, 176 + pub usb_charging: i32, 177 + 178 + pub contrast: i32, 179 + pub invert: bool, 180 + pub flip_display: bool, 181 + pub cursor_style: i32, 182 + pub screen_scroll_step: i32, 183 + pub show_path_in_browser: i32, 184 + pub offset_out_of_view: bool, 185 + pub disable_mainmenu_scrolling: bool, 186 + pub icon_file: String, 187 + pub viewers_icon_file: String, 188 + pub font_file: String, 189 + pub glyphs_to_cache: i32, 190 + pub kbd_file: String, 191 + pub backlight_timeout: i32, 192 + pub caption_backlight: bool, 193 + pub bl_filter_first_keypress: bool, 194 + pub backlight_timeout_plugged: i32, 195 + pub bt_selective_softlock_actions: bool, 196 + pub bt_selective_softlock_actions_mask: i32, 197 + pub bl_selective_actions: bool, 198 + pub bl_selective_actions_mask: i32, 199 + pub backlight_on_button_hold: i32, 200 + pub lcd_sleep_after_backlight_off: i32, 201 + pub brightness: i32, 202 + 203 + pub speaker_mode: i32, 204 + pub prevent_skip: bool, 205 + 206 + pub touch_mode: i32, 207 + 208 + pub pitch_mode_semitone: bool, 209 + pub pitch_mode_timestretch: bool, 210 + 211 + pub usb_hid: bool, 212 + pub usb_keypad_mode: i32, 213 + 214 + pub usb_skip_first_drive: bool, 215 + 216 + pub ui_vp_config: String, 217 + pub player_name: String, 218 + 219 + pub compressor_settings: CompressorSettings, 220 + 221 + pub sleeptimer_duration: i32, 222 + pub sleeptimer_on_startup: bool, 223 + pub keypress_restarts_sleeptimer: bool, 224 + 225 + pub show_shutdown_message: bool, 226 + 227 + pub hotkey_wps: i32, 228 + pub hotkey_tree: i32, 229 + 230 + pub resume_rewind: i32, 231 + 232 + pub depth_3d: i32, 233 + 234 + pub roll_off: i32, 235 + 236 + pub power_mode: i32, 237 + 238 + pub keyclick_hardware: bool, 239 + 240 + pub start_directory: String, 241 + pub root_menu_customized: bool, 242 + pub shortcuts_replaces_qs: bool, 243 + 244 + pub play_frequency: i32, 245 + pub volume_limit: i32, 246 + 247 + pub volume_adjust_mode: i32, 248 + pub volume_adjust_norm_steps: i32, 249 + 250 + pub surround_enabled: i32, 251 + pub surround_balance: i32, 252 + pub surround_fx1: i32, 253 + pub surround_fx2: bool, 254 + pub surround_method2: bool, 255 + pub surround_mix: i32, 256 + 257 + pub pbe: i32, 258 + pub pbe_precut: i32, 259 + 260 + pub afr_enabled: i32, 261 + 262 + pub governor: i32, 263 + pub stereosw_mode: i32, 264 + } 265 + 266 + #[Object] 267 + impl UserSettings { 268 + async fn volume(&self) -> i32 { 269 + self.volume 270 + } 271 + 272 + async fn balance(&self) -> i32 { 273 + self.balance 274 + } 275 + 276 + async fn bass(&self) -> i32 { 277 + self.bass 278 + } 279 + 280 + async fn treble(&self) -> i32 { 281 + self.treble 282 + } 283 + 284 + async fn channel_config(&self) -> i32 { 285 + self.channel_config 286 + } 287 + 288 + async fn stereo_width(&self) -> i32 { 289 + self.stereo_width 290 + } 291 + 292 + async fn bass_cutoff(&self) -> i32 { 293 + self.bass_cutoff 294 + } 295 + 296 + async fn treble_cutoff(&self) -> i32 { 297 + self.treble_cutoff 298 + } 299 + 300 + async fn crossfade(&self) -> i32 { 301 + self.crossfade 302 + } 303 + 304 + async fn crossfade_fade_in_delay(&self) -> i32 { 305 + self.crossfade_fade_in_delay 306 + } 307 + 308 + async fn crossfade_fade_out_delay(&self) -> i32 { 309 + self.crossfade_fade_out_delay 310 + } 311 + 312 + async fn crossfade_fade_in_duration(&self) -> i32 { 313 + self.crossfade_fade_in_duration 314 + } 315 + 316 + async fn crossfade_fade_out_duration(&self) -> i32 { 317 + self.crossfade_fade_out_duration 318 + } 319 + 320 + async fn crossfade_fade_out_mixmode(&self) -> i32 { 321 + self.crossfade_fade_out_mixmode 322 + } 323 + 324 + async fn replaygain_settings(&self) -> ReplaygainSettings { 325 + self.replaygain_settings.clone() 326 + } 327 + 328 + async fn crossfeed(&self) -> i32 { 329 + self.crossfeed 330 + } 331 + 332 + async fn crossfeed_direct_gain(&self) -> u32 { 333 + self.crossfeed_direct_gain 334 + } 335 + 336 + async fn crossfeed_cross_gain(&self) -> u32 { 337 + self.crossfeed_cross_gain 338 + } 339 + 340 + async fn crossfeed_hf_attenuation(&self) -> u32 { 341 + self.crossfeed_hf_attenuation 342 + } 343 + 344 + async fn crossfeed_hf_cutoff(&self) -> u32 { 345 + self.crossfeed_hf_cutoff 346 + } 347 + 348 + async fn eq_enabled(&self) -> bool { 349 + self.eq_enabled 350 + } 351 + 352 + async fn eq_precut(&self) -> u32 { 353 + self.eq_precut 354 + } 355 + 356 + async fn eq_band_settings(&self) -> Vec<EqBandSetting> { 357 + self.eq_band_settings.clone() 358 + } 359 + 360 + async fn beep(&self) -> i32 { 361 + self.beep 362 + } 363 + 364 + async fn keyclick(&self) -> i32 { 365 + self.keyclick 366 + } 367 + 368 + async fn keyclick_repeats(&self) -> i32 { 369 + self.keyclick_repeats 370 + } 371 + 372 + async fn dithering_enabled(&self) -> bool { 373 + self.dithering_enabled 374 + } 375 + 376 + async fn timestretch_enabled(&self) -> bool { 377 + self.timestretch_enabled 378 + } 379 + 380 + async fn list_accel_start_delay(&self) -> i32 { 381 + self.list_accel_start_delay 382 + } 383 + 384 + async fn list_accel_wait(&self) -> i32 { 385 + self.list_accel_wait 386 + } 387 + 388 + async fn touchpad_sensitivity(&self) -> i32 { 389 + self.touchpad_sensitivity 390 + } 391 + 392 + async fn touchpad_deadzone(&self) -> i32 { 393 + self.touchpad_deadzone 394 + } 395 + 396 + async fn pause_rewind(&self) -> i32 { 397 + self.pause_rewind 398 + } 399 + 400 + async fn unplug_mode(&self) -> i32 { 401 + self.unplug_mode 402 + } 403 + 404 + async fn unplug_autoresume(&self) -> bool { 405 + self.unplug_autoresume 406 + } 407 + 408 + async fn qs_items(&self) -> Vec<SettingsList> { 409 + self.qs_items.clone() 410 + } 411 + 412 + async fn timeformat(&self) -> i32 { 413 + self.timeformat 414 + } 415 + 416 + async fn disk_spindown(&self) -> i32 { 417 + self.disk_spindown 418 + } 419 + 420 + async fn buffer_margin(&self) -> i32 { 421 + self.buffer_margin 422 + } 423 + 424 + async fn dirfilter(&self) -> i32 { 425 + self.dirfilter 426 + } 427 + 428 + async fn show_filename_ext(&self) -> i32 { 429 + self.show_filename_ext 430 + } 431 + 432 + async fn default_codepage(&self) -> i32 { 433 + self.default_codepage 434 + } 435 + 436 + async fn hold_lr_for_scroll_in_list(&self) -> bool { 437 + self.hold_lr_for_scroll_in_list 438 + } 439 + 440 + async fn play_selected(&self) -> bool { 441 + self.play_selected 442 + } 443 + 444 + async fn single_mode(&self) -> i32 { 445 + self.single_mode 446 + } 447 + 448 + async fn party_mode(&self) -> bool { 449 + self.party_mode 450 + } 451 + 452 + async fn cuesheet(&self) -> bool { 453 + self.cuesheet 454 + } 455 + 456 + async fn car_adapter_mode(&self) -> bool { 457 + self.car_adapter_mode 458 + } 459 + 460 + async fn car_adapter_mode_delay(&self) -> i32 { 461 + self.car_adapter_mode_delay 462 + } 463 + 464 + async fn start_in_screen(&self) -> i32 { 465 + self.start_in_screen 466 + } 467 + 468 + async fn ff_rewind_min_step(&self) -> i32 { 469 + self.ff_rewind_min_step 470 + } 471 + 472 + async fn ff_rewind_accel(&self) -> i32 { 473 + self.ff_rewind_accel 474 + } 475 + 476 + async fn peak_meter_release(&self) -> i32 { 477 + self.peak_meter_release 478 + } 479 + 480 + async fn peak_meter_hold(&self) -> i32 { 481 + self.peak_meter_hold 482 + } 483 + 484 + async fn peak_meter_clip_hold(&self) -> i32 { 485 + self.peak_meter_clip_hold 486 + } 487 + 488 + async fn peak_meter_dbfs(&self) -> bool { 489 + self.peak_meter_dbfs 490 + } 491 + 492 + async fn peak_meter_min(&self) -> i32 { 493 + self.peak_meter_min 494 + } 495 + 496 + async fn peak_meter_max(&self) -> i32 { 497 + self.peak_meter_max 498 + } 499 + 500 + async fn wps_file(&self) -> &str { 501 + &self.wps_file 502 + } 503 + 504 + async fn sbs_file(&self) -> &str { 505 + &self.sbs_file 506 + } 507 + 508 + async fn lang_file(&self) -> &str { 509 + &self.lang_file 510 + } 511 + 512 + async fn playlist_catalog_dir(&self) -> &str { 513 + &self.playlist_catalog_dir 514 + } 515 + 516 + async fn skip_length(&self) -> i32 { 517 + self.skip_length 518 + } 519 + 520 + async fn max_files_in_dir(&self) -> i32 { 521 + self.max_files_in_dir 522 + } 523 + 524 + async fn max_files_in_playlist(&self) -> i32 { 525 + self.max_files_in_playlist 526 + } 527 + 528 + async fn volume_type(&self) -> i32 { 529 + self.volume_type 530 + } 531 + 532 + async fn battery_display(&self) -> i32 { 533 + self.battery_display 534 + } 535 + 536 + async fn show_icons(&self) -> bool { 537 + self.show_icons 538 + } 539 + 540 + async fn statusbar(&self) -> i32 { 541 + self.statusbar 542 + } 543 + 544 + async fn scrollbar(&self) -> i32 { 545 + self.scrollbar 546 + } 547 + 548 + async fn scrollbar_width(&self) -> i32 { 549 + self.scrollbar_width 550 + } 551 + 552 + async fn list_line_padding(&self) -> i32 { 553 + self.list_line_padding 554 + } 555 + 556 + async fn list_separator_height(&self) -> i32 { 557 + self.list_separator_height 558 + } 559 + 560 + async fn list_separator_color(&self) -> i32 { 561 + self.list_separator_color 562 + } 563 + 564 + async fn browse_current(&self) -> bool { 565 + self.browse_current 566 + } 567 + 568 + async fn scroll_paginated(&self) -> bool { 569 + self.scroll_paginated 570 + } 571 + 572 + async fn list_wraparound(&self) -> bool { 573 + self.list_wraparound 574 + } 575 + 576 + async fn list_order(&self) -> i32 { 577 + self.list_order 578 + } 579 + 580 + async fn scroll_speed(&self) -> i32 { 581 + self.scroll_speed 582 + } 583 + 584 + async fn bidir_limit(&self) -> i32 { 585 + self.bidir_limit 586 + } 587 + 588 + async fn scroll_delay(&self) -> i32 { 589 + self.scroll_delay 590 + } 591 + 592 + async fn scroll_step(&self) -> i32 { 593 + self.scroll_step 594 + } 595 + 596 + async fn autoloadbookmark(&self) -> i32 { 597 + self.autoloadbookmark 598 + } 599 + 600 + async fn autocreatebookmark(&self) -> i32 { 601 + self.autocreatebookmark 602 + } 603 + 604 + async fn autoupdatebookmark(&self) -> bool { 605 + self.autoupdatebookmark 606 + } 607 + 608 + async fn usemrb(&self) -> i32 { 609 + self.usemrb 610 + } 611 + 612 + async fn dircache(&self) -> bool { 613 + self.dircache 614 + } 615 + 616 + async fn tagcache_ram(&self) -> i32 { 617 + self.tagcache_ram 618 + } 619 + 620 + async fn tagcache_autoupdate(&self) -> bool { 621 + self.tagcache_autoupdate 622 + } 623 + 624 + async fn autoresume_enable(&self) -> bool { 625 + self.autoresume_enable 626 + } 627 + 628 + async fn autoresume_automatic(&self) -> i32 { 629 + self.autoresume_automatic 630 + } 631 + 632 + async fn autoresume_paths(&self) -> &str { 633 + &self.autoresume_paths 634 + } 635 + 636 + async fn runtimedb(&self) -> bool { 637 + self.runtimedb 638 + } 639 + 640 + async fn tagcache_scan_paths(&self) -> &str { 641 + &self.tagcache_scan_paths 642 + } 643 + 644 + async fn tagcache_db_path(&self) -> &str { 645 + &self.tagcache_db_path 646 + } 647 + 648 + async fn backdrop_file(&self) -> &str { 649 + &self.backdrop_file 650 + } 651 + 652 + async fn bg_color(&self) -> i32 { 653 + self.bg_color 654 + } 655 + 656 + async fn fg_color(&self) -> i32 { 657 + self.fg_color 658 + } 659 + 660 + async fn lss_color(&self) -> i32 { 661 + self.lss_color 662 + } 663 + 664 + async fn lse_color(&self) -> i32 { 665 + self.lse_color 666 + } 667 + 668 + async fn lst_color(&self) -> i32 { 669 + self.lst_color 670 + } 671 + 672 + async fn colors_file(&self) -> &str { 673 + &self.colors_file 674 + } 675 + 676 + async fn browser_default(&self) -> i32 { 677 + self.browser_default 678 + } 679 + 680 + async fn repeat_mode(&self) -> i32 { 681 + self.repeat_mode 682 + } 683 + 684 + async fn next_folder(&self) -> i32 { 685 + self.next_folder 686 + } 687 + 688 + async fn constrain_next_folder(&self) -> bool { 689 + self.constrain_next_folder 690 + } 691 + 692 + async fn recursive_dir_insert(&self) -> i32 { 693 + self.recursive_dir_insert 694 + } 695 + 696 + async fn fade_on_stop(&self) -> bool { 697 + self.fade_on_stop 698 + } 699 + 700 + async fn playlist_shuffle(&self) -> bool { 701 + self.playlist_shuffle 702 + } 703 + 704 + async fn warnon_erase_dynplaylist(&self) -> bool { 705 + self.warnon_erase_dynplaylist 706 + } 707 + 708 + async fn keep_current_track_on_replace_playlist(&self) -> bool { 709 + self.keep_current_track_on_replace_playlist 710 + } 711 + 712 + async fn show_shuffled_adding_options(&self) -> bool { 713 + self.show_shuffled_adding_options 714 + } 715 + 716 + async fn show_queue_options(&self) -> i32 { 717 + self.show_queue_options 718 + } 719 + 720 + async fn album_art(&self) -> i32 { 721 + self.album_art 722 + } 723 + 724 + async fn rewind_across_tracks(&self) -> bool { 725 + self.rewind_across_tracks 726 + } 727 + 728 + async fn playlist_viewer_icons(&self) -> bool { 729 + self.playlist_viewer_icons 730 + } 731 + 732 + async fn playlist_viewer_indices(&self) -> bool { 733 + self.playlist_viewer_indices 734 + } 735 + 736 + async fn playlist_viewer_track_display(&self) -> i32 { 737 + self.playlist_viewer_track_display 738 + } 739 + 740 + async fn talk_menu(&self) -> bool { 741 + self.talk_menu 742 + } 743 + 744 + async fn talk_dir(&self) -> i32 { 745 + self.talk_dir 746 + } 747 + 748 + async fn talk_dir_clip(&self) -> bool { 749 + self.talk_dir_clip 750 + } 751 + 752 + async fn talk_file(&self) -> i32 { 753 + self.talk_file 754 + } 755 + 756 + async fn talk_file_clip(&self) -> bool { 757 + self.talk_file_clip 758 + } 759 + 760 + async fn talk_filetype(&self) -> bool { 761 + self.talk_filetype 762 + } 763 + 764 + async fn talk_battery_level(&self) -> bool { 765 + self.talk_battery_level 766 + } 767 + 768 + async fn talk_mixer_amp(&self) -> i32 { 769 + self.talk_mixer_amp 770 + } 771 + 772 + async fn sort_case(&self) -> bool { 773 + self.sort_case 774 + } 775 + 776 + async fn sort_dir(&self) -> i32 { 777 + self.sort_dir 778 + } 779 + 780 + async fn sort_file(&self) -> i32 { 781 + self.sort_file 782 + } 783 + 784 + async fn interpret_numbers(&self) -> i32 { 785 + self.interpret_numbers 786 + } 787 + 788 + async fn poweroff(&self) -> i32 { 789 + self.poweroff 790 + } 791 + 792 + async fn battery_capacity(&self) -> i32 { 793 + self.battery_capacity 794 + } 795 + 796 + async fn battery_type(&self) -> i32 { 797 + self.battery_type 798 + } 799 + 800 + async fn spdif_enable(&self) -> bool { 801 + self.spdif_enable 802 + } 803 + 804 + async fn usb_charging(&self) -> i32 { 805 + self.usb_charging 806 + } 807 + 808 + async fn contrast(&self) -> i32 { 809 + self.contrast 810 + } 811 + 812 + async fn invert(&self) -> bool { 813 + self.invert 814 + } 815 + 816 + async fn flip_display(&self) -> bool { 817 + self.flip_display 818 + } 819 + 820 + async fn cursor_style(&self) -> i32 { 821 + self.cursor_style 822 + } 823 + 824 + async fn screen_scroll_step(&self) -> i32 { 825 + self.screen_scroll_step 826 + } 827 + 828 + async fn show_path_in_browser(&self) -> i32 { 829 + self.show_path_in_browser 830 + } 831 + 832 + async fn offset_out_of_view(&self) -> bool { 833 + self.offset_out_of_view 834 + } 835 + 836 + async fn disable_mainmenu_scrolling(&self) -> bool { 837 + self.disable_mainmenu_scrolling 838 + } 839 + 840 + async fn icon_file(&self) -> &str { 841 + &self.icon_file 842 + } 843 + 844 + async fn viewers_icon_file(&self) -> &str { 845 + &self.viewers_icon_file 846 + } 847 + 848 + async fn font_file(&self) -> &str { 849 + &self.font_file 850 + } 851 + 852 + async fn glyphs_to_cache(&self) -> i32 { 853 + self.glyphs_to_cache 854 + } 855 + 856 + async fn kbd_file(&self) -> &str { 857 + &self.kbd_file 858 + } 859 + 860 + async fn backlight_timeout(&self) -> i32 { 861 + self.backlight_timeout 862 + } 863 + 864 + async fn caption_backlight(&self) -> bool { 865 + self.caption_backlight 866 + } 867 + 868 + async fn bl_filter_first_keypress(&self) -> bool { 869 + self.bl_filter_first_keypress 870 + } 871 + 872 + async fn backlight_timeout_plugged(&self) -> i32 { 873 + self.backlight_timeout_plugged 874 + } 875 + 876 + async fn bt_selective_softlock_actions(&self) -> bool { 877 + self.bt_selective_softlock_actions 878 + } 879 + 880 + async fn bt_selective_softlock_actions_mask(&self) -> i32 { 881 + self.bt_selective_softlock_actions_mask 882 + } 883 + 884 + async fn bl_selective_actions(&self) -> bool { 885 + self.bl_selective_actions 886 + } 887 + 888 + async fn bl_selective_actions_mask(&self) -> i32 { 889 + self.bl_selective_actions_mask 890 + } 891 + 892 + async fn backlight_on_button_hold(&self) -> i32 { 893 + self.backlight_on_button_hold 894 + } 895 + 896 + async fn lcd_sleep_after_backlight_off(&self) -> i32 { 897 + self.lcd_sleep_after_backlight_off 898 + } 899 + 900 + async fn brightness(&self) -> i32 { 901 + self.brightness 902 + } 903 + 904 + async fn speaker_mode(&self) -> i32 { 905 + self.speaker_mode 906 + } 907 + 908 + async fn prevent_skip(&self) -> bool { 909 + self.prevent_skip 910 + } 911 + 912 + async fn touch_mode(&self) -> i32 { 913 + self.touch_mode 914 + } 915 + 916 + async fn pitch_mode_semitone(&self) -> bool { 917 + self.pitch_mode_semitone 918 + } 919 + 920 + async fn pitch_mode_timestretch(&self) -> bool { 921 + self.pitch_mode_timestretch 922 + } 923 + 924 + async fn usb_hid(&self) -> bool { 925 + self.usb_hid 926 + } 927 + 928 + async fn usb_keypad_mode(&self) -> i32 { 929 + self.usb_keypad_mode 930 + } 931 + 932 + async fn usb_skip_first_drive(&self) -> bool { 933 + self.usb_skip_first_drive 934 + } 935 + 936 + async fn ui_vp_config(&self) -> &str { 937 + &self.ui_vp_config 938 + } 939 + 940 + async fn player_name(&self) -> &str { 941 + &self.player_name 942 + } 943 + 944 + async fn compressor_settings(&self) -> CompressorSettings { 945 + self.compressor_settings.clone() 946 + } 947 + 948 + async fn sleeptimer_duration(&self) -> i32 { 949 + self.sleeptimer_duration 950 + } 951 + 952 + async fn sleeptimer_on_startup(&self) -> bool { 953 + self.sleeptimer_on_startup 954 + } 955 + 956 + async fn keypress_restarts_sleeptimer(&self) -> bool { 957 + self.keypress_restarts_sleeptimer 958 + } 959 + 960 + async fn show_shutdown_message(&self) -> bool { 961 + self.show_shutdown_message 962 + } 963 + 964 + async fn hotkey_wps(&self) -> i32 { 965 + self.hotkey_wps 966 + } 967 + 968 + async fn hotkey_tree(&self) -> i32 { 969 + self.hotkey_tree 970 + } 971 + 972 + async fn resume_rewind(&self) -> i32 { 973 + self.resume_rewind 974 + } 975 + 976 + async fn depth_3d(&self) -> i32 { 977 + self.depth_3d 978 + } 979 + 980 + async fn roll_off(&self) -> i32 { 981 + self.roll_off 982 + } 983 + 984 + async fn power_mode(&self) -> i32 { 985 + self.power_mode 986 + } 987 + 988 + async fn keyclick_hardware(&self) -> bool { 989 + self.keyclick_hardware 990 + } 991 + 992 + async fn start_directory(&self) -> &str { 993 + &self.start_directory 994 + } 995 + 996 + async fn root_menu_customized(&self) -> bool { 997 + self.root_menu_customized 998 + } 999 + 1000 + async fn shortcuts_replaces_qs(&self) -> bool { 1001 + self.shortcuts_replaces_qs 1002 + } 1003 + 1004 + async fn play_frequency(&self) -> i32 { 1005 + self.play_frequency 1006 + } 1007 + 1008 + async fn volume_limit(&self) -> i32 { 1009 + self.volume_limit 1010 + } 1011 + 1012 + async fn volume_adjust_mode(&self) -> i32 { 1013 + self.volume_adjust_mode 1014 + } 1015 + 1016 + async fn volume_adjust_norm_steps(&self) -> i32 { 1017 + self.volume_adjust_norm_steps 1018 + } 1019 + 1020 + async fn surround_enabled(&self) -> i32 { 1021 + self.surround_enabled 1022 + } 1023 + 1024 + async fn surround_balance(&self) -> i32 { 1025 + self.surround_balance 1026 + } 1027 + 1028 + async fn surround_fx1(&self) -> i32 { 1029 + self.surround_fx1 1030 + } 1031 + 1032 + async fn surround_fx2(&self) -> bool { 1033 + self.surround_fx2 1034 + } 1035 + 1036 + async fn surround_method2(&self) -> bool { 1037 + self.surround_method2 1038 + } 1039 + 1040 + async fn surround_mix(&self) -> i32 { 1041 + self.surround_mix 1042 + } 1043 + 1044 + async fn pbe(&self) -> i32 { 1045 + self.pbe 1046 + } 1047 + 1048 + async fn pbe_precut(&self) -> i32 { 1049 + self.pbe_precut 1050 + } 1051 + 1052 + async fn afr_enabled(&self) -> i32 { 1053 + self.afr_enabled 1054 + } 1055 + 1056 + async fn governor(&self) -> i32 { 1057 + self.governor 1058 + } 1059 + 1060 + async fn stereosw_mode(&self) -> i32 { 1061 + self.stereosw_mode 1062 + } 1063 + }
+103
crates/graphql/src/schema/playback.rs
··· 1 + use std::sync::{mpsc::Sender, Arc, Mutex}; 2 + 3 + use async_graphql::*; 4 + use rockbox_sys::{self as rb, events::RockboxCommand}; 5 + 6 + use crate::schema::objects::track::Track; 7 + 8 + #[derive(Default)] 9 + pub struct PlaybackQuery; 10 + 11 + #[Object] 12 + impl PlaybackQuery { 13 + async fn status(&self) -> String { 14 + rb::playback::status(); 15 + "status".to_string() 16 + } 17 + 18 + async fn current_track(&self) -> Option<Track> { 19 + let mp3entry = rb::playback::current_track(); 20 + Some(mp3entry.into()) 21 + } 22 + 23 + async fn get_file_position(&self) -> i32 { 24 + rb::playback::get_file_pos() 25 + } 26 + } 27 + 28 + #[derive(Default)] 29 + pub struct PlaybackMutation; 30 + 31 + #[Object] 32 + impl PlaybackMutation { 33 + async fn play(&self, ctx: &Context<'_>, elapsed: i64, offset: i64) -> Result<String, Error> { 34 + let cmd = ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>().unwrap(); 35 + cmd.lock() 36 + .unwrap() 37 + .send(RockboxCommand::Play(elapsed, offset))?; 38 + Ok("play".to_string()) 39 + } 40 + 41 + async fn pause(&self, ctx: &Context<'_>) -> Result<String, Error> { 42 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 43 + .unwrap() 44 + .lock() 45 + .unwrap() 46 + .send(RockboxCommand::Pause)?; 47 + Ok("pause".to_string()) 48 + } 49 + 50 + async fn resume(&self, ctx: &Context<'_>) -> Result<String, Error> { 51 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 52 + .unwrap() 53 + .lock() 54 + .unwrap() 55 + .send(RockboxCommand::Resume)?; 56 + Ok("resume".to_string()) 57 + } 58 + 59 + async fn next(&self, ctx: &Context<'_>) -> Result<String, Error> { 60 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 61 + .unwrap() 62 + .lock() 63 + .unwrap() 64 + .send(RockboxCommand::Next)?; 65 + Ok("next".to_string()) 66 + } 67 + 68 + async fn previous(&self, ctx: &Context<'_>) -> Result<String, Error> { 69 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 70 + .unwrap() 71 + .lock() 72 + .unwrap() 73 + .send(RockboxCommand::Prev)?; 74 + Ok("previous".to_string()) 75 + } 76 + 77 + async fn fast_forward_rewind(&self, ctx: &Context<'_>, new_time: i32) -> Result<String, Error> { 78 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 79 + .unwrap() 80 + .lock() 81 + .unwrap() 82 + .send(RockboxCommand::FfRewind(new_time))?; 83 + Ok("fast_forward_rewind".to_string()) 84 + } 85 + 86 + async fn flush_and_reload_tracks(&self, ctx: &Context<'_>) -> Result<String, Error> { 87 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 88 + .unwrap() 89 + .lock() 90 + .unwrap() 91 + .send(RockboxCommand::FlushAndReloadTracks)?; 92 + Ok("flush_and_reload_tracks".to_string()) 93 + } 94 + 95 + async fn hard_stop(&self, ctx: &Context<'_>) -> Result<String, Error> { 96 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 97 + .unwrap() 98 + .lock() 99 + .unwrap() 100 + .send(RockboxCommand::Stop)?; 101 + Ok("hard_stop".to_string()) 102 + } 103 + }
+94
crates/graphql/src/schema/playlist.rs
··· 1 + use std::sync::{mpsc::Sender, Arc, Mutex}; 2 + 3 + use async_graphql::*; 4 + use rockbox_sys::events::RockboxCommand; 5 + 6 + #[derive(Default)] 7 + pub struct PlaylistQuery; 8 + 9 + #[Object] 10 + impl PlaylistQuery { 11 + async fn playlist_get_current(&self) -> String { 12 + "playlist get current".to_string() 13 + } 14 + 15 + async fn get_resume_info(&self) -> String { 16 + "get resume info".to_string() 17 + } 18 + 19 + async fn get_track_info(&self) -> String { 20 + "get track info".to_string() 21 + } 22 + 23 + async fn get_first_index(&self) -> String { 24 + "get first index".to_string() 25 + } 26 + 27 + async fn get_display_index(&self) -> String { 28 + "get display index".to_string() 29 + } 30 + 31 + async fn playlist_amount(&self) -> String { 32 + "playlist amount".to_string() 33 + } 34 + } 35 + 36 + #[derive(Default)] 37 + pub struct PlaylistMutation; 38 + 39 + #[Object] 40 + impl PlaylistMutation { 41 + async fn playlist_resume(&self, ctx: &Context<'_>) -> Result<String, Error> { 42 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 43 + .unwrap() 44 + .lock() 45 + .unwrap() 46 + .send(RockboxCommand::PlaylistResume)?; 47 + Ok("playlist resume".to_string()) 48 + } 49 + 50 + async fn resume_track(&self, ctx: &Context<'_>) -> Result<String, Error> { 51 + ctx.data::<Arc<Mutex<Sender<RockboxCommand>>>>() 52 + .unwrap() 53 + .lock() 54 + .unwrap() 55 + .send(RockboxCommand::PlaylistResumeTrack)?; 56 + Ok("resume track".to_string()) 57 + } 58 + 59 + async fn playlist_set_modified(&self) -> String { 60 + "set modified".to_string() 61 + } 62 + 63 + async fn playlist_start(&self) -> String { 64 + "playlist start".to_string() 65 + } 66 + 67 + async fn playlist_sync(&self) -> String { 68 + "playlist sync".to_string() 69 + } 70 + 71 + async fn playlist_remove_all_tracks(&self) -> String { 72 + "playlist remove all tracks".to_string() 73 + } 74 + 75 + async fn playlist_create(&self) -> String { 76 + "playlist create".to_string() 77 + } 78 + 79 + async fn playlist_insert_track(&self) -> String { 80 + "playlist insert track".to_string() 81 + } 82 + 83 + async fn playlist_insert_directory(&self) -> String { 84 + "playlist insert directory".to_string() 85 + } 86 + 87 + async fn shuffle_playlist(&self) -> String { 88 + "shuffle playlist".to_string() 89 + } 90 + 91 + async fn warn_on_playlist_erase(&self) -> String { 92 + "warn on playlist erase".to_string() 93 + } 94 + }
+19
crates/graphql/src/schema/settings.rs
··· 1 + use async_graphql::*; 2 + 3 + use crate::{rockbox_url, schema::objects::user_settings::UserSettings}; 4 + 5 + #[derive(Default)] 6 + pub struct SettingsQuery; 7 + 8 + #[Object] 9 + impl SettingsQuery { 10 + async fn global_settings(&self, ctx: &Context<'_>) -> Result<UserSettings, Error> { 11 + let client = ctx.data::<reqwest::Client>().unwrap(); 12 + let url = format!("{}/settings", rockbox_url()); 13 + let settings = client.get(url).send().await?.json::<UserSettings>().await?; 14 + Ok(settings) 15 + } 16 + } 17 + 18 + #[derive(Default)] 19 + pub struct SettingsMutation;
+77
crates/graphql/src/schema/sound.rs
··· 1 + use async_graphql::*; 2 + 3 + #[derive(Default)] 4 + pub struct SoundQuery; 5 + 6 + #[Object] 7 + impl SoundQuery { 8 + async fn sound_current(&self) -> String { 9 + "sound".to_string() 10 + } 11 + 12 + async fn sound_default(&self) -> String { 13 + "sound default".to_string() 14 + } 15 + 16 + async fn sound_val_2_phys(&self) -> String { 17 + "sound val 2 phys".to_string() 18 + } 19 + 20 + async fn get_pitch(&self) -> String { 21 + "get pitch".to_string() 22 + } 23 + } 24 + 25 + #[derive(Default)] 26 + pub struct SoundMutation; 27 + 28 + #[Object] 29 + impl SoundMutation { 30 + async fn adjust_volume(&self) -> String { 31 + "adjust volume".to_string() 32 + } 33 + 34 + async fn sound_set(&self) -> String { 35 + "sound set".to_string() 36 + } 37 + 38 + async fn sound_min(&self) -> String { 39 + "sound min".to_string() 40 + } 41 + 42 + async fn sound_max(&self) -> String { 43 + "sound max".to_string() 44 + } 45 + 46 + async fn sound_unit(&self) -> String { 47 + "sound unit".to_string() 48 + } 49 + 50 + async fn set_pitch(&self) -> String { 51 + "set pitch".to_string() 52 + } 53 + 54 + async fn beep_play(&self) -> String { 55 + "beep play".to_string() 56 + } 57 + 58 + async fn pcmbuf_play(&self) -> String { 59 + "pcmbuf play".to_string() 60 + } 61 + 62 + async fn pcmbuf_fade(&self) -> String { 63 + "pcmbuf fade".to_string() 64 + } 65 + 66 + async fn pcmbuf_set_low_latency(&self) -> String { 67 + "pcmbuf set low latency".to_string() 68 + } 69 + 70 + async fn system_sound_play(&self) -> String { 71 + "system sound play".to_string() 72 + } 73 + 74 + async fn keyclick_click(&self) -> String { 75 + "keyclick click".to_string() 76 + } 77 + }
+35
crates/graphql/src/schema/system.rs
··· 1 + use async_graphql::*; 2 + use rockbox_sys::types::RockboxVersion; 3 + 4 + use crate::rockbox_url; 5 + 6 + use super::objects::system_status::SystemStatus; 7 + 8 + #[derive(Default)] 9 + pub struct SystemQuery; 10 + 11 + #[Object] 12 + impl SystemQuery { 13 + async fn rockbox_version(&self, ctx: &Context<'_>) -> Result<String, Error> { 14 + let client = ctx.data::<reqwest::Client>().unwrap(); 15 + let url = format!("{}/version", rockbox_url()); 16 + let version = client 17 + .get(url) 18 + .send() 19 + .await? 20 + .json::<RockboxVersion>() 21 + .await? 22 + .version; 23 + Ok(version) 24 + } 25 + 26 + async fn global_status(&self, ctx: &Context<'_>) -> Result<SystemStatus, Error> { 27 + let client = ctx.data::<reqwest::Client>().unwrap(); 28 + let url = format!("{}/status", rockbox_url()); 29 + let status = client.get(url).send().await?.json::<SystemStatus>().await?; 30 + Ok(status) 31 + } 32 + } 33 + 34 + #[derive(Default)] 35 + pub struct SystemMutation;
+7
crates/graphql/src/schema/tagcache.rs
··· 1 + use async_graphql::*; 2 + 3 + #[derive(Default)] 4 + pub struct TagcacheQuery; 5 + 6 + #[derive(Default)] 7 + pub struct TagcacheMutation;
+79
crates/graphql/src/server.rs
··· 1 + use std::sync::{mpsc::Sender, Arc, Mutex}; 2 + 3 + use actix_cors::Cors; 4 + use actix_web::{ 5 + http::header::HOST, 6 + web::{self, Data}, 7 + App, HttpRequest, HttpResponse, HttpServer, Result, 8 + }; 9 + use async_graphql::{http::GraphiQLSource, EmptySubscription, Schema}; 10 + use async_graphql_actix_web::{GraphQLRequest, GraphQLResponse}; 11 + use owo_colors::OwoColorize; 12 + use rockbox_sys::events::RockboxCommand; 13 + 14 + use crate::{ 15 + schema::{Mutation, Query}, 16 + RockboxSchema, 17 + }; 18 + 19 + #[actix_web::post("/graphql")] 20 + async fn index_graphql(schema: web::Data<RockboxSchema>, req: GraphQLRequest) -> GraphQLResponse { 21 + schema.execute(req.into_inner()).await.into() 22 + } 23 + 24 + #[actix_web::get("/graphiql")] 25 + async fn index_graphiql(req: HttpRequest) -> Result<HttpResponse> { 26 + let host = req 27 + .headers() 28 + .get(HOST) 29 + .unwrap() 30 + .to_str() 31 + .unwrap() 32 + .split(":") 33 + .next() 34 + .unwrap(); 35 + 36 + let http_port = std::env::var("ROCKBOX_GRAPHQL_PORT").unwrap_or("6062".to_string()); 37 + let graphql_endpoint = format!("http://{}:{}/graphql", host, http_port); 38 + let ws_endpoint = format!("ws://{}:{}/graphql", host, http_port); 39 + Ok(HttpResponse::Ok() 40 + .content_type("text/html; charset=utf-8") 41 + .body( 42 + GraphiQLSource::build() 43 + .endpoint(&graphql_endpoint) 44 + .subscription_endpoint(&ws_endpoint) 45 + .finish(), 46 + )) 47 + } 48 + 49 + pub async fn start(cmd_tx: Arc<Mutex<Sender<RockboxCommand>>>) -> std::io::Result<()> { 50 + let client = reqwest::Client::new(); 51 + let schema = Schema::build( 52 + Query::default(), 53 + Mutation::default(), 54 + EmptySubscription::default(), 55 + ) 56 + .data(cmd_tx) 57 + .data(client) 58 + .finish(); 59 + let graphql_port = std::env::var("ROCKBOX_GRAPHQL_PORT").unwrap_or("6062".to_string()); 60 + let addr = format!("{}:{}", "0.0.0.0", graphql_port); 61 + 62 + println!( 63 + "{} server is running on {}", 64 + "Rockbox GraphQL".bright_purple(), 65 + addr.bright_green() 66 + ); 67 + 68 + HttpServer::new(move || { 69 + let cors = Cors::permissive(); 70 + App::new() 71 + .app_data(Data::new(schema.clone())) 72 + .wrap(cors) 73 + .service(index_graphql) 74 + .service(index_graphiql) 75 + }) 76 + .bind(addr)? 77 + .run() 78 + .await 79 + }
+18
crates/rpc/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "rockbox-rpc" 4 + version = "0.1.0" 5 + 6 + [dependencies] 7 + owo-colors = "5.0.0" 8 + prost = "0.13.2" 9 + reqwest = {version = "0.12.7", features = ["rustls-tls", "json"], default-features = false} 10 + rockbox-sys = {path = "../sys"} 11 + serde = "1.0.210" 12 + tokio = {version = "1.40.0", features = ["full"]} 13 + tonic = "0.12.2" 14 + tonic-reflection = "0.12.2" 15 + tonic-web = "0.12.2" 16 + 17 + [build-dependencies] 18 + tonic-build = "0.12.2"
+19
crates/rpc/build.rs
··· 1 + fn main() -> Result<(), Box<dyn std::error::Error>> { 2 + tonic_build::configure() 3 + .out_dir("src/api") 4 + .file_descriptor_set_path("src/api/rockbox_descriptor.bin") 5 + .compile( 6 + &[ 7 + "proto/rockbox/v1alpha1/browse.proto", 8 + "proto/rockbox/v1alpha1/metadata.proto", 9 + "proto/rockbox/v1alpha1/playback.proto", 10 + "proto/rockbox/v1alpha1/playlist.proto", 11 + "proto/rockbox/v1alpha1/settings.proto", 12 + "proto/rockbox/v1alpha1/sound.proto", 13 + "proto/rockbox/v1alpha1/system.proto", 14 + "proto/rockbox/v1alpha1/tagcache.proto", 15 + ], 16 + &["proto"], 17 + )?; 18 + Ok(()) 19 + }
+8
crates/rpc/proto/buf.yaml
··· 1 + # For details on buf.yaml configuration, visit https://buf.build/docs/configuration/v2/buf-yaml 2 + version: v2 3 + lint: 4 + use: 5 + - DEFAULT 6 + breaking: 7 + use: 8 + - FILE
+44
crates/rpc/proto/rockbox/v1alpha1/browse.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + message RockboxBrowseRequest { 6 + } 7 + 8 + message RockboxBrowseResponse { 9 + } 10 + 11 + message TreeGetContextRequest { 12 + } 13 + 14 + message TreeGetContextResponse { 15 + } 16 + 17 + message TreeGetEntriesRequest { 18 + } 19 + 20 + message TreeGetEntriesResponse { 21 + } 22 + 23 + 24 + message TreeGetEntryAtRequest { 25 + } 26 + 27 + message TreeGetEntryAtResponse { 28 + } 29 + 30 + message BrowseId3Request { 31 + 32 + } 33 + 34 + message BrowseId3Response { 35 + 36 + } 37 + 38 + service BrowseService { 39 + rpc RockboxBrowse(RockboxBrowseRequest) returns (RockboxBrowseResponse); 40 + rpc TreeGetContext(TreeGetContextRequest) returns (TreeGetContextResponse); 41 + rpc TreeGetEntries(TreeGetEntriesRequest) returns (TreeGetEntriesResponse); 42 + rpc TreeGetEntryAt(TreeGetEntryAtRequest) returns (TreeGetEntryAtResponse); 43 + rpc BrowseId3(BrowseId3Request) returns (BrowseId3Response); 44 + }
+7
crates/rpc/proto/rockbox/v1alpha1/metadata.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + service MetadataService { 6 + 7 + }
+108
crates/rpc/proto/rockbox/v1alpha1/playback.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + message PlayRequest { 6 + int64 elapsed = 1; 7 + int64 offset = 2; 8 + } 9 + 10 + message PlayResponse { 11 + } 12 + 13 + message PauseRequest { 14 + } 15 + 16 + message PauseResponse { 17 + } 18 + 19 + message ResumeRequest { 20 + } 21 + 22 + message ResumeResponse { 23 + } 24 + 25 + message NextRequest { 26 + } 27 + 28 + message NextResponse { 29 + } 30 + 31 + message PreviousRequest { 32 + } 33 + 34 + message PreviousResponse { 35 + } 36 + 37 + message FastForwardRewindRequest { 38 + int32 new_time = 1; 39 + } 40 + 41 + message FastForwardRewindResponse { 42 + } 43 + 44 + message StatusRequest { 45 + } 46 + 47 + message StatusResponse { 48 + int32 status = 1; 49 + } 50 + 51 + message CurrentTrackRequest { 52 + } 53 + 54 + message CurrentTrackResponse { 55 + string title = 1; 56 + string artist = 2; 57 + string album = 3; 58 + string genre = 4; 59 + string disc = 5; 60 + string track_string = 6; 61 + string year_string = 7; 62 + string composer = 8; 63 + string comment = 9; 64 + string album_artist = 10; 65 + string grouping = 11; 66 + int32 discnum = 12; 67 + int32 tracknum = 13; 68 + int32 layer = 14; 69 + int32 year = 15; 70 + uint32 bitrate = 16; 71 + uint64 frequency = 17; 72 + uint64 filesize = 18; 73 + uint64 length = 19; 74 + uint64 elapsed = 20; 75 + } 76 + 77 + message FlushAndReloadTracksRequest { 78 + } 79 + 80 + message FlushAndReloadTracksResponse { 81 + } 82 + 83 + message GetFilePositionRequest { 84 + } 85 + 86 + message GetFilePositionResponse { 87 + int32 position = 1; 88 + } 89 + 90 + message HardStopRequest { 91 + } 92 + 93 + message HardStopResponse { 94 + } 95 + 96 + service PlaybackService { 97 + rpc Play(PlayRequest) returns (PlayResponse) {} 98 + rpc Pause(PauseRequest) returns (PauseResponse) {} 99 + rpc Resume(ResumeRequest) returns (ResumeResponse) {} 100 + rpc Next(NextRequest) returns (NextResponse) {} 101 + rpc Previous(PreviousRequest) returns (PreviousResponse) {} 102 + rpc FastForwardRewind(FastForwardRewindRequest) returns (FastForwardRewindResponse) {} 103 + rpc Status(StatusRequest) returns (StatusResponse) {} 104 + rpc CurrentTrack(CurrentTrackRequest) returns (CurrentTrackResponse) {} 105 + rpc FlushAndReloadTracks(FlushAndReloadTracksRequest) returns (FlushAndReloadTracksResponse) {} 106 + rpc GetFilePosition(GetFilePositionRequest) returns (GetFilePositionResponse) {} 107 + rpc HardStop(HardStopRequest) returns (HardStopResponse) {} 108 + }
+137
crates/rpc/proto/rockbox/v1alpha1/playlist.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + message GetCurrentRequest { 6 + } 7 + 8 + message GetCurrentResponse { 9 + } 10 + 11 + message GetResumeInfoRequest { 12 + } 13 + 14 + message GetResumeInfoResponse { 15 + } 16 + 17 + message GetTrackInfoRequest { 18 + } 19 + 20 + message GetTrackInfoResponse { 21 + } 22 + 23 + message GetFirstIndexRequest { 24 + } 25 + 26 + message GetFirstIndexResponse { 27 + } 28 + 29 + message GetDisplayIndexRequest { 30 + } 31 + 32 + message GetDisplayIndexResponse { 33 + } 34 + 35 + message AmountRequest { 36 + } 37 + 38 + message AmountResponse { 39 + } 40 + 41 + message PlaylistResumeRequest { 42 + } 43 + 44 + message PlaylistResumeResponse { 45 + } 46 + 47 + message ResumeTrackRequest { 48 + int32 start_index = 1; 49 + uint32 crc = 2; 50 + uint64 elapsed = 3; 51 + uint64 offset = 4; 52 + } 53 + 54 + message ResumeTrackResponse { 55 + } 56 + 57 + message SetModifiedRequest { 58 + } 59 + 60 + message SetModifiedResponse { 61 + } 62 + 63 + message StartRequest { 64 + } 65 + 66 + message StartResponse { 67 + } 68 + 69 + message SyncRequest { 70 + } 71 + 72 + message SyncResponse { 73 + } 74 + 75 + message RemoveAllTracksRequest { 76 + } 77 + 78 + message RemoveAllTracksResponse { 79 + } 80 + 81 + message CreatePlaylistRequest { 82 + } 83 + 84 + message CreatePlaylistResponse { 85 + } 86 + 87 + message InsertTrackRequest { 88 + } 89 + 90 + message InsertTrackResponse { 91 + } 92 + 93 + message InsertDirectoryRequest { 94 + } 95 + 96 + message InsertDirectoryResponse { 97 + } 98 + 99 + message InsertPlaylistRequest { 100 + } 101 + 102 + message InsertPlaylistResponse { 103 + } 104 + 105 + message ShufflePlaylistRequest { 106 + } 107 + 108 + message ShufflePlaylistResponse { 109 + } 110 + 111 + message WarnOnPlaylistEraseRequest { 112 + } 113 + 114 + message WarnOnPlaylistEraseResponse { 115 + } 116 + 117 + 118 + service PlaylistService { 119 + rpc GetCurrent(GetCurrentRequest) returns (GetCurrentResponse) {} 120 + rpc GetResumeInfo(GetResumeInfoRequest) returns (GetResumeInfoResponse) {} 121 + rpc GetTrackInfo(GetTrackInfoRequest) returns (GetTrackInfoResponse) {} 122 + rpc GetFirstIndex(GetFirstIndexRequest) returns (GetFirstIndexResponse) {} 123 + rpc GetDisplayIndex(GetDisplayIndexRequest) returns (GetDisplayIndexResponse) {} 124 + rpc Amount(AmountRequest) returns (AmountResponse) {} 125 + rpc PlaylistResume(PlaylistResumeRequest) returns (PlaylistResumeResponse) {} 126 + rpc ResumeTrack(ResumeTrackRequest) returns (ResumeTrackResponse) {} 127 + rpc SetModified(SetModifiedRequest) returns (SetModifiedResponse) {} 128 + rpc Start(StartRequest) returns (StartResponse) {} 129 + rpc Sync(SyncRequest) returns (SyncResponse) {} 130 + rpc RemoveAllTracks(RemoveAllTracksRequest) returns (RemoveAllTracksResponse) {} 131 + rpc CreatePlaylist(CreatePlaylistRequest) returns (CreatePlaylistResponse) {} 132 + rpc InsertTrack(InsertTrackRequest) returns (InsertTrackResponse) {} 133 + rpc InsertDirectory(InsertDirectoryRequest) returns (InsertDirectoryResponse) {} 134 + rpc InsertPlaylist(InsertPlaylistRequest) returns (InsertPlaylistResponse) {} 135 + rpc ShufflePlaylist(ShufflePlaylistRequest) returns (ShufflePlaylistResponse) {} 136 + rpc WarnOnPlaylistErase(WarnOnPlaylistEraseRequest) returns (WarnOnPlaylistEraseResponse) {} 137 + }
+228
crates/rpc/proto/rockbox/v1alpha1/settings.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + message GetSettingsListRequest { 6 + int32 count = 1; 7 + } 8 + 9 + message GetSettingsListResponse {} 10 + 11 + message GetGlobalSettingsRequest {} 12 + 13 + message ReplaygainSettings { 14 + bool noclip = 1; 15 + int32 type = 2; 16 + int32 preamp = 3; 17 + } 18 + 19 + message EqBandSetting { 20 + int32 cutoff = 1; 21 + int32 q = 2; 22 + int32 gain = 3; 23 + } 24 + 25 + message SettingsList { 26 + uint32 flags = 1; 27 + int32 lang_id = 2; 28 + string cfg_name = 3; 29 + string cfg_vals = 4; 30 + } 31 + 32 + message CompressorSettings { 33 + int32 threshold = 1; 34 + int32 makeup_gain = 2; 35 + int32 ratio = 3; 36 + int32 knee = 4; 37 + int32 release_time = 5; 38 + int32 attack_time = 6; 39 + } 40 + 41 + message GetGlobalSettingsResponse { 42 + int32 volume = 1; 43 + int32 balance = 2; 44 + int32 bass = 3; 45 + int32 treble = 4; 46 + int32 channel_config = 5; 47 + int32 stereo_width = 6; 48 + int32 bass_cutoff = 7; 49 + int32 treble_cutoff = 8; 50 + int32 crossfade = 9; 51 + int32 crossfade_fade_in_delay = 10; 52 + int32 crossfade_fade_out_delay = 11; 53 + int32 crossfade_fade_in_duration = 12; 54 + int32 crossfade_fade_out_duration = 13; 55 + int32 crossfade_fade_out_mixmode = 14; 56 + ReplaygainSettings replaygain_settings = 15; 57 + int32 crossfeed = 16; 58 + uint32 crossfeed_direct_gain = 17; 59 + uint32 crossfeed_cross_gain = 18; 60 + uint32 crossfeed_hf_attenuation = 19; 61 + uint32 crossfeed_hf_cutoff = 20; 62 + bool eq_enabled = 21; 63 + uint32 eq_precut = 22; 64 + repeated EqBandSetting eq_band_settings = 23; 65 + int32 beep = 24; 66 + int32 keyclick = 25; 67 + int32 keyclick_repeats = 26; 68 + bool dithering_enabled = 27; 69 + bool timestretch_enabled = 28; 70 + int32 list_accel_start_delay = 29; 71 + int32 list_accel_wait = 30; 72 + int32 touchpad_sensitivity = 31; 73 + int32 touchpad_deadzone = 32; 74 + int32 pause_rewind = 33; 75 + int32 unplug_mode = 34; 76 + bool unplug_autoresume = 35; 77 + int32 timeformat = 37; 78 + int32 disk_spindown = 38; 79 + int32 buffer_margin = 39; 80 + int32 dirfilter = 40; 81 + int32 show_filename_ext = 41; 82 + int32 default_codepage = 42; 83 + bool hold_lr_for_scroll_in_list = 43; 84 + bool play_selected = 44; 85 + int32 single_mode = 45; 86 + bool party_mode = 46; 87 + bool car_adapter_mode = 48; 88 + int32 car_adapter_mode_delay = 49; 89 + int32 start_in_screen = 50; 90 + int32 ff_rewind_min_step = 51; 91 + int32 ff_rewind_accel = 52; 92 + int32 peak_meter_release = 53; 93 + int32 peak_meter_hold = 54; 94 + int32 peak_meter_clip_hold = 55; 95 + bool peak_meter_dbfs = 56; 96 + int32 peak_meter_min = 57; 97 + int32 peak_meter_max = 58; 98 + string wps_file = 59; 99 + string sbs_file = 60; 100 + string lang_file = 61; 101 + string playlist_catalog_dir = 62; 102 + int32 skip_length = 63; 103 + int32 max_files_in_dir = 64; 104 + int32 max_files_in_playlist = 65; 105 + int32 volume_type = 66; 106 + int32 battery_display = 67; 107 + bool show_icons = 68; 108 + int32 statusbar = 69; 109 + int32 scrollbar = 70; 110 + int32 scrollbar_width = 71; 111 + int32 list_line_padding = 72; 112 + int32 list_separator_color = 73; 113 + bool browse_current = 74; 114 + bool scroll_paginated = 75; 115 + bool list_wraparound = 76; 116 + int32 list_order = 77; 117 + int32 scroll_speed = 78; 118 + int32 bidir_limit = 79; 119 + int32 scroll_delay = 80; 120 + int32 scroll_step = 81; 121 + int32 autoloadbookmark = 82; 122 + int32 autocreatebookmark = 83; 123 + bool autoupdatebookmark = 84; 124 + int32 usemrb = 85; 125 + bool dircache = 86; 126 + int32 tagcache_ram = 87; 127 + bool tagcache_autoupdate = 88; 128 + bool autoresume_enable = 89; 129 + int32 autoresume_automatic = 90; 130 + string autoresume_paths = 91; 131 + bool runtimedb = 92; 132 + string tagcache_scan_paths = 93; 133 + string tagcache_db_path = 94; 134 + string backdrop_file = 95; 135 + int32 bg_color = 96; 136 + int32 fg_color = 97; 137 + int32 lss_color = 98; 138 + int32 lse_color = 99; 139 + int32 lst_color = 100; 140 + string colors_file = 101; 141 + int32 browser_default = 102; 142 + int32 repeat_mode = 103; 143 + int32 next_folder = 104; 144 + bool constrain_next_folder = 105; 145 + int32 recursive_dir_insert = 106; 146 + bool fade_on_stop = 107; 147 + bool playlist_shuffle = 108; 148 + bool warnon_erase_dynplaylist = 109; 149 + bool keep_current_track_on_replace_playlist = 110; 150 + bool show_shuffled_adding_options = 111; 151 + int32 show_queue_options = 112; 152 + int32 album_art = 113; 153 + bool rewind_across_tracks = 114; 154 + bool playlist_viewer_icons = 115; 155 + bool playlist_viewer_indices = 116; 156 + int32 playlist_viewer_track_display = 117; 157 + bool sort_case = 118; 158 + int32 sort_dir = 119; 159 + int32 sort_file = 120; 160 + int32 interpret_numbers = 121; 161 + int32 poweroff = 122; 162 + bool spdif_enable = 123; 163 + int32 contrast = 124; 164 + bool invert = 125; 165 + bool flip_display = 126; 166 + int32 cursor_style = 127; 167 + int32 screen_scroll_step = 128; 168 + int32 show_path_in_browser = 129; 169 + bool offset_out_of_view = 130; 170 + bool disable_mainmenu_scrolling = 131; 171 + string icon_file = 132; 172 + string viewers_icon_file = 133; 173 + string font_file = 134; 174 + int32 glyphs_to_cache = 135; 175 + string kbd_file = 136; 176 + int32 backlight_timeout = 137; 177 + bool caption_backlight = 138; 178 + bool bl_filter_first_keypress = 139; 179 + int32 backlight_timeout_plugged = 140; 180 + bool bt_selective_softlock_actions = 141; 181 + int32 bt_selective_softlock_actions_mask = 142; 182 + bool bl_selective_actions = 143; 183 + int32 bl_selective_actions_mask = 144; 184 + int32 backlight_on_button_hold = 145; 185 + int32 lcd_sleep_after_backlight_off = 146; 186 + int32 brightness = 147; 187 + int32 speaker_mode = 148; 188 + bool prevent_skip = 149; 189 + int32 touch_mode = 150; 190 + bool pitch_mode_semitone = 151; 191 + bool pitch_mode_timestretch = 152; 192 + string player_name = 153; 193 + CompressorSettings compressor_settings = 154; 194 + int32 sleeptimer_duration = 155; 195 + bool sleeptimer_on_startup = 156; 196 + bool keypress_restarts_sleeptimer = 157; 197 + bool show_shutdown_message = 158; 198 + int32 hotkey_wps = 159; 199 + int32 hotkey_tree = 160; 200 + int32 resume_rewind = 161; 201 + int32 depth_3d = 162; 202 + int32 roll_off = 163; 203 + int32 power_mode = 164; 204 + bool keyclick_hardware = 165; 205 + string start_directory = 166; 206 + bool root_menu_customized = 167; 207 + bool shortcuts_replaces_qs = 168; 208 + int32 play_frequency = 169; 209 + int32 volume_limit = 170; 210 + int32 volume_adjust_mode = 171; 211 + int32 volume_adjust_norm_steps = 172; 212 + int32 surround_enabled = 173; 213 + int32 surround_balance = 174; 214 + int32 surround_fx1 = 175; 215 + bool surround_fx2 = 176; 216 + bool surround_method2 = 177; 217 + int32 surround_mix = 178; 218 + int32 pbe = 179; 219 + int32 pbe_precut = 180; 220 + int32 afr_enabled = 181; 221 + int32 governor = 182; 222 + int32 stereosw_mode = 183; 223 + } 224 + 225 + service SettingsService { 226 + rpc GetSettingsList(GetSettingsListRequest) returns (GetSettingsListResponse); 227 + rpc GetGlobalSettings(GetGlobalSettingsRequest) returns (GetGlobalSettingsResponse); 228 + }
+126
crates/rpc/proto/rockbox/v1alpha1/sound.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + message AdjustVolumeRequest { 6 + int32 steps = 1; 7 + } 8 + 9 + message AdjustVolumeResponse { 10 + } 11 + 12 + message SoundSetRequest { 13 + int32 setting = 1; 14 + int32 value = 2; 15 + } 16 + 17 + message SoundSetResponse {} 18 + 19 + message SoundCurrentRequest { 20 + int32 setting = 1; 21 + } 22 + 23 + message SoundCurrentResponse { 24 + int32 value = 1; 25 + } 26 + 27 + message SoundDefaultRequest { 28 + int32 setting = 1; 29 + } 30 + 31 + message SoundDefaultResponse { 32 + int32 value = 1; 33 + } 34 + 35 + message SoundMinRequest { 36 + int32 setting = 1; 37 + } 38 + 39 + message SoundMinResponse { 40 + int32 value = 1; 41 + } 42 + 43 + message SoundMaxRequest { 44 + int32 setting = 1; 45 + } 46 + 47 + message SoundMaxResponse { 48 + int32 value = 1; 49 + } 50 + 51 + message SoundUnitRequest { } 52 + 53 + message SoundUnitResponse { } 54 + 55 + message SoundVal2PhysRequest { 56 + int32 setting = 1; 57 + int32 value = 2; 58 + } 59 + 60 + message SoundVal2PhysResponse { 61 + int32 value = 1; 62 + } 63 + 64 + message GetPitchRequest { } 65 + 66 + message GetPitchResponse { 67 + int32 value = 1; 68 + } 69 + 70 + message SetPitchRequest { 71 + int32 value = 1; 72 + } 73 + 74 + message SetPitchResponse { } 75 + 76 + message BeepPlayRequest { 77 + uint32 frequency = 1; 78 + uint32 duration = 2; 79 + uint32 amplitude = 3; 80 + } 81 + 82 + message BeepPlayResponse { } 83 + 84 + message PcmbufFadeRequest { 85 + int32 fade = 1; 86 + bool in = 2; 87 + } 88 + 89 + message PcmbufFadeResponse { } 90 + 91 + message PcmbufSetLowLatencyRequest { 92 + bool state = 1; 93 + } 94 + 95 + message PcmbufSetLowLatencyResponse { } 96 + 97 + message SystemSoundPlayRequest { 98 + uint32 sound = 1; 99 + } 100 + 101 + message SystemSoundPlayResponse { } 102 + 103 + message KeyclickClickRequest { 104 + bool rawbutton = 1; 105 + int32 action = 2; 106 + } 107 + 108 + message KeyclickClickResponse { } 109 + 110 + service SoundService { 111 + rpc AdjustVolume(AdjustVolumeRequest) returns (AdjustVolumeResponse); 112 + rpc SoundSet(SoundSetRequest) returns (SoundSetResponse); 113 + rpc SoundCurrent(SoundCurrentRequest) returns (SoundCurrentResponse); 114 + rpc SoundDefault(SoundDefaultRequest) returns (SoundDefaultResponse); 115 + rpc SoundMin(SoundMinRequest) returns (SoundMinResponse); 116 + rpc SoundMax(SoundMaxRequest) returns (SoundMaxResponse); 117 + rpc SoundUnit(SoundUnitRequest) returns (SoundUnitResponse); 118 + rpc SoundVal2Phys(SoundVal2PhysRequest) returns (SoundVal2PhysResponse); 119 + rpc GetPitch(GetPitchRequest) returns (GetPitchResponse); 120 + rpc SetPitch(SetPitchRequest) returns (SetPitchResponse); 121 + rpc BeepPlay(BeepPlayRequest) returns (BeepPlayResponse); 122 + rpc PcmbufFade(PcmbufFadeRequest) returns (PcmbufFadeResponse); 123 + rpc PcmbufSetLowLatency(PcmbufSetLowLatencyRequest) returns (PcmbufSetLowLatencyResponse); 124 + rpc SystemSoundPlay(SystemSoundPlayRequest) returns (SystemSoundPlayResponse); 125 + rpc KeyclickClick(KeyclickClickRequest) returns (KeyclickClickResponse); 126 + }
+31
crates/rpc/proto/rockbox/v1alpha1/system.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + message GetRockboxVersionRequest { 6 + } 7 + 8 + message GetRockboxVersionResponse { 9 + string version = 1; 10 + } 11 + 12 + message GetGlobalStatusRequest { 13 + } 14 + 15 + message GetGlobalStatusResponse { 16 + int32 resume_index = 1; 17 + uint32 resume_crc32 = 2; 18 + uint32 resume_elapsed = 3; 19 + uint32 resume_offset = 4; 20 + int32 runtime = 5; 21 + int32 topruntime = 6; 22 + int32 dircache_size = 7; 23 + int32 last_screen = 8; 24 + int32 viewer_icon_count = 9; 25 + int32 last_volume_change = 10; 26 + } 27 + 28 + service SystemService { 29 + rpc GetRockboxVersion(GetRockboxVersionRequest) returns (GetRockboxVersionResponse); 30 + rpc GetGlobalStatus(GetGlobalStatusRequest) returns (GetGlobalStatusResponse); 31 + }
+5
crates/rpc/proto/rockbox/v1alpha1/tagcache.proto
··· 1 + syntax = "proto3"; 2 + 3 + package rockbox.v1alpha1; 4 + 5 + service TagcacheService {}
+6595
crates/rpc/src/api/rockbox.v1alpha1.rs
··· 1 + // This file is @generated by prost-build. 2 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3 + pub struct RockboxBrowseRequest {} 4 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 5 + pub struct RockboxBrowseResponse {} 6 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 7 + pub struct TreeGetContextRequest {} 8 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 9 + pub struct TreeGetContextResponse {} 10 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 11 + pub struct TreeGetEntriesRequest {} 12 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 13 + pub struct TreeGetEntriesResponse {} 14 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 15 + pub struct TreeGetEntryAtRequest {} 16 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 17 + pub struct TreeGetEntryAtResponse {} 18 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 19 + pub struct BrowseId3Request {} 20 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 21 + pub struct BrowseId3Response {} 22 + /// Generated client implementations. 23 + pub mod browse_service_client { 24 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 25 + use tonic::codegen::*; 26 + use tonic::codegen::http::Uri; 27 + #[derive(Debug, Clone)] 28 + pub struct BrowseServiceClient<T> { 29 + inner: tonic::client::Grpc<T>, 30 + } 31 + impl BrowseServiceClient<tonic::transport::Channel> { 32 + /// Attempt to create a new client by connecting to a given endpoint. 33 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 34 + where 35 + D: TryInto<tonic::transport::Endpoint>, 36 + D::Error: Into<StdError>, 37 + { 38 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 39 + Ok(Self::new(conn)) 40 + } 41 + } 42 + impl<T> BrowseServiceClient<T> 43 + where 44 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 45 + T::Error: Into<StdError>, 46 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 47 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 48 + { 49 + pub fn new(inner: T) -> Self { 50 + let inner = tonic::client::Grpc::new(inner); 51 + Self { inner } 52 + } 53 + pub fn with_origin(inner: T, origin: Uri) -> Self { 54 + let inner = tonic::client::Grpc::with_origin(inner, origin); 55 + Self { inner } 56 + } 57 + pub fn with_interceptor<F>( 58 + inner: T, 59 + interceptor: F, 60 + ) -> BrowseServiceClient<InterceptedService<T, F>> 61 + where 62 + F: tonic::service::Interceptor, 63 + T::ResponseBody: Default, 64 + T: tonic::codegen::Service< 65 + http::Request<tonic::body::BoxBody>, 66 + Response = http::Response< 67 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 68 + >, 69 + >, 70 + <T as tonic::codegen::Service< 71 + http::Request<tonic::body::BoxBody>, 72 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 73 + { 74 + BrowseServiceClient::new(InterceptedService::new(inner, interceptor)) 75 + } 76 + /// Compress requests with the given encoding. 77 + /// 78 + /// This requires the server to support it otherwise it might respond with an 79 + /// error. 80 + #[must_use] 81 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 82 + self.inner = self.inner.send_compressed(encoding); 83 + self 84 + } 85 + /// Enable decompressing responses. 86 + #[must_use] 87 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 88 + self.inner = self.inner.accept_compressed(encoding); 89 + self 90 + } 91 + /// Limits the maximum size of a decoded message. 92 + /// 93 + /// Default: `4MB` 94 + #[must_use] 95 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 96 + self.inner = self.inner.max_decoding_message_size(limit); 97 + self 98 + } 99 + /// Limits the maximum size of an encoded message. 100 + /// 101 + /// Default: `usize::MAX` 102 + #[must_use] 103 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 104 + self.inner = self.inner.max_encoding_message_size(limit); 105 + self 106 + } 107 + pub async fn rockbox_browse( 108 + &mut self, 109 + request: impl tonic::IntoRequest<super::RockboxBrowseRequest>, 110 + ) -> std::result::Result< 111 + tonic::Response<super::RockboxBrowseResponse>, 112 + tonic::Status, 113 + > { 114 + self.inner 115 + .ready() 116 + .await 117 + .map_err(|e| { 118 + tonic::Status::new( 119 + tonic::Code::Unknown, 120 + format!("Service was not ready: {}", e.into()), 121 + ) 122 + })?; 123 + let codec = tonic::codec::ProstCodec::default(); 124 + let path = http::uri::PathAndQuery::from_static( 125 + "/rockbox.v1alpha1.BrowseService/RockboxBrowse", 126 + ); 127 + let mut req = request.into_request(); 128 + req.extensions_mut() 129 + .insert( 130 + GrpcMethod::new("rockbox.v1alpha1.BrowseService", "RockboxBrowse"), 131 + ); 132 + self.inner.unary(req, path, codec).await 133 + } 134 + pub async fn tree_get_context( 135 + &mut self, 136 + request: impl tonic::IntoRequest<super::TreeGetContextRequest>, 137 + ) -> std::result::Result< 138 + tonic::Response<super::TreeGetContextResponse>, 139 + tonic::Status, 140 + > { 141 + self.inner 142 + .ready() 143 + .await 144 + .map_err(|e| { 145 + tonic::Status::new( 146 + tonic::Code::Unknown, 147 + format!("Service was not ready: {}", e.into()), 148 + ) 149 + })?; 150 + let codec = tonic::codec::ProstCodec::default(); 151 + let path = http::uri::PathAndQuery::from_static( 152 + "/rockbox.v1alpha1.BrowseService/TreeGetContext", 153 + ); 154 + let mut req = request.into_request(); 155 + req.extensions_mut() 156 + .insert( 157 + GrpcMethod::new("rockbox.v1alpha1.BrowseService", "TreeGetContext"), 158 + ); 159 + self.inner.unary(req, path, codec).await 160 + } 161 + pub async fn tree_get_entries( 162 + &mut self, 163 + request: impl tonic::IntoRequest<super::TreeGetEntriesRequest>, 164 + ) -> std::result::Result< 165 + tonic::Response<super::TreeGetEntriesResponse>, 166 + tonic::Status, 167 + > { 168 + self.inner 169 + .ready() 170 + .await 171 + .map_err(|e| { 172 + tonic::Status::new( 173 + tonic::Code::Unknown, 174 + format!("Service was not ready: {}", e.into()), 175 + ) 176 + })?; 177 + let codec = tonic::codec::ProstCodec::default(); 178 + let path = http::uri::PathAndQuery::from_static( 179 + "/rockbox.v1alpha1.BrowseService/TreeGetEntries", 180 + ); 181 + let mut req = request.into_request(); 182 + req.extensions_mut() 183 + .insert( 184 + GrpcMethod::new("rockbox.v1alpha1.BrowseService", "TreeGetEntries"), 185 + ); 186 + self.inner.unary(req, path, codec).await 187 + } 188 + pub async fn tree_get_entry_at( 189 + &mut self, 190 + request: impl tonic::IntoRequest<super::TreeGetEntryAtRequest>, 191 + ) -> std::result::Result< 192 + tonic::Response<super::TreeGetEntryAtResponse>, 193 + tonic::Status, 194 + > { 195 + self.inner 196 + .ready() 197 + .await 198 + .map_err(|e| { 199 + tonic::Status::new( 200 + tonic::Code::Unknown, 201 + format!("Service was not ready: {}", e.into()), 202 + ) 203 + })?; 204 + let codec = tonic::codec::ProstCodec::default(); 205 + let path = http::uri::PathAndQuery::from_static( 206 + "/rockbox.v1alpha1.BrowseService/TreeGetEntryAt", 207 + ); 208 + let mut req = request.into_request(); 209 + req.extensions_mut() 210 + .insert( 211 + GrpcMethod::new("rockbox.v1alpha1.BrowseService", "TreeGetEntryAt"), 212 + ); 213 + self.inner.unary(req, path, codec).await 214 + } 215 + pub async fn browse_id3( 216 + &mut self, 217 + request: impl tonic::IntoRequest<super::BrowseId3Request>, 218 + ) -> std::result::Result< 219 + tonic::Response<super::BrowseId3Response>, 220 + tonic::Status, 221 + > { 222 + self.inner 223 + .ready() 224 + .await 225 + .map_err(|e| { 226 + tonic::Status::new( 227 + tonic::Code::Unknown, 228 + format!("Service was not ready: {}", e.into()), 229 + ) 230 + })?; 231 + let codec = tonic::codec::ProstCodec::default(); 232 + let path = http::uri::PathAndQuery::from_static( 233 + "/rockbox.v1alpha1.BrowseService/BrowseId3", 234 + ); 235 + let mut req = request.into_request(); 236 + req.extensions_mut() 237 + .insert(GrpcMethod::new("rockbox.v1alpha1.BrowseService", "BrowseId3")); 238 + self.inner.unary(req, path, codec).await 239 + } 240 + } 241 + } 242 + /// Generated server implementations. 243 + pub mod browse_service_server { 244 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 245 + use tonic::codegen::*; 246 + /// Generated trait containing gRPC methods that should be implemented for use with BrowseServiceServer. 247 + #[async_trait] 248 + pub trait BrowseService: std::marker::Send + std::marker::Sync + 'static { 249 + async fn rockbox_browse( 250 + &self, 251 + request: tonic::Request<super::RockboxBrowseRequest>, 252 + ) -> std::result::Result< 253 + tonic::Response<super::RockboxBrowseResponse>, 254 + tonic::Status, 255 + >; 256 + async fn tree_get_context( 257 + &self, 258 + request: tonic::Request<super::TreeGetContextRequest>, 259 + ) -> std::result::Result< 260 + tonic::Response<super::TreeGetContextResponse>, 261 + tonic::Status, 262 + >; 263 + async fn tree_get_entries( 264 + &self, 265 + request: tonic::Request<super::TreeGetEntriesRequest>, 266 + ) -> std::result::Result< 267 + tonic::Response<super::TreeGetEntriesResponse>, 268 + tonic::Status, 269 + >; 270 + async fn tree_get_entry_at( 271 + &self, 272 + request: tonic::Request<super::TreeGetEntryAtRequest>, 273 + ) -> std::result::Result< 274 + tonic::Response<super::TreeGetEntryAtResponse>, 275 + tonic::Status, 276 + >; 277 + async fn browse_id3( 278 + &self, 279 + request: tonic::Request<super::BrowseId3Request>, 280 + ) -> std::result::Result< 281 + tonic::Response<super::BrowseId3Response>, 282 + tonic::Status, 283 + >; 284 + } 285 + #[derive(Debug)] 286 + pub struct BrowseServiceServer<T> { 287 + inner: Arc<T>, 288 + accept_compression_encodings: EnabledCompressionEncodings, 289 + send_compression_encodings: EnabledCompressionEncodings, 290 + max_decoding_message_size: Option<usize>, 291 + max_encoding_message_size: Option<usize>, 292 + } 293 + impl<T> BrowseServiceServer<T> { 294 + pub fn new(inner: T) -> Self { 295 + Self::from_arc(Arc::new(inner)) 296 + } 297 + pub fn from_arc(inner: Arc<T>) -> Self { 298 + Self { 299 + inner, 300 + accept_compression_encodings: Default::default(), 301 + send_compression_encodings: Default::default(), 302 + max_decoding_message_size: None, 303 + max_encoding_message_size: None, 304 + } 305 + } 306 + pub fn with_interceptor<F>( 307 + inner: T, 308 + interceptor: F, 309 + ) -> InterceptedService<Self, F> 310 + where 311 + F: tonic::service::Interceptor, 312 + { 313 + InterceptedService::new(Self::new(inner), interceptor) 314 + } 315 + /// Enable decompressing requests with the given encoding. 316 + #[must_use] 317 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 318 + self.accept_compression_encodings.enable(encoding); 319 + self 320 + } 321 + /// Compress responses with the given encoding, if the client supports it. 322 + #[must_use] 323 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 324 + self.send_compression_encodings.enable(encoding); 325 + self 326 + } 327 + /// Limits the maximum size of a decoded message. 328 + /// 329 + /// Default: `4MB` 330 + #[must_use] 331 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 332 + self.max_decoding_message_size = Some(limit); 333 + self 334 + } 335 + /// Limits the maximum size of an encoded message. 336 + /// 337 + /// Default: `usize::MAX` 338 + #[must_use] 339 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 340 + self.max_encoding_message_size = Some(limit); 341 + self 342 + } 343 + } 344 + impl<T, B> tonic::codegen::Service<http::Request<B>> for BrowseServiceServer<T> 345 + where 346 + T: BrowseService, 347 + B: Body + std::marker::Send + 'static, 348 + B::Error: Into<StdError> + std::marker::Send + 'static, 349 + { 350 + type Response = http::Response<tonic::body::BoxBody>; 351 + type Error = std::convert::Infallible; 352 + type Future = BoxFuture<Self::Response, Self::Error>; 353 + fn poll_ready( 354 + &mut self, 355 + _cx: &mut Context<'_>, 356 + ) -> Poll<std::result::Result<(), Self::Error>> { 357 + Poll::Ready(Ok(())) 358 + } 359 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 360 + match req.uri().path() { 361 + "/rockbox.v1alpha1.BrowseService/RockboxBrowse" => { 362 + #[allow(non_camel_case_types)] 363 + struct RockboxBrowseSvc<T: BrowseService>(pub Arc<T>); 364 + impl< 365 + T: BrowseService, 366 + > tonic::server::UnaryService<super::RockboxBrowseRequest> 367 + for RockboxBrowseSvc<T> { 368 + type Response = super::RockboxBrowseResponse; 369 + type Future = BoxFuture< 370 + tonic::Response<Self::Response>, 371 + tonic::Status, 372 + >; 373 + fn call( 374 + &mut self, 375 + request: tonic::Request<super::RockboxBrowseRequest>, 376 + ) -> Self::Future { 377 + let inner = Arc::clone(&self.0); 378 + let fut = async move { 379 + <T as BrowseService>::rockbox_browse(&inner, request).await 380 + }; 381 + Box::pin(fut) 382 + } 383 + } 384 + let accept_compression_encodings = self.accept_compression_encodings; 385 + let send_compression_encodings = self.send_compression_encodings; 386 + let max_decoding_message_size = self.max_decoding_message_size; 387 + let max_encoding_message_size = self.max_encoding_message_size; 388 + let inner = self.inner.clone(); 389 + let fut = async move { 390 + let method = RockboxBrowseSvc(inner); 391 + let codec = tonic::codec::ProstCodec::default(); 392 + let mut grpc = tonic::server::Grpc::new(codec) 393 + .apply_compression_config( 394 + accept_compression_encodings, 395 + send_compression_encodings, 396 + ) 397 + .apply_max_message_size_config( 398 + max_decoding_message_size, 399 + max_encoding_message_size, 400 + ); 401 + let res = grpc.unary(method, req).await; 402 + Ok(res) 403 + }; 404 + Box::pin(fut) 405 + } 406 + "/rockbox.v1alpha1.BrowseService/TreeGetContext" => { 407 + #[allow(non_camel_case_types)] 408 + struct TreeGetContextSvc<T: BrowseService>(pub Arc<T>); 409 + impl< 410 + T: BrowseService, 411 + > tonic::server::UnaryService<super::TreeGetContextRequest> 412 + for TreeGetContextSvc<T> { 413 + type Response = super::TreeGetContextResponse; 414 + type Future = BoxFuture< 415 + tonic::Response<Self::Response>, 416 + tonic::Status, 417 + >; 418 + fn call( 419 + &mut self, 420 + request: tonic::Request<super::TreeGetContextRequest>, 421 + ) -> Self::Future { 422 + let inner = Arc::clone(&self.0); 423 + let fut = async move { 424 + <T as BrowseService>::tree_get_context(&inner, request) 425 + .await 426 + }; 427 + Box::pin(fut) 428 + } 429 + } 430 + let accept_compression_encodings = self.accept_compression_encodings; 431 + let send_compression_encodings = self.send_compression_encodings; 432 + let max_decoding_message_size = self.max_decoding_message_size; 433 + let max_encoding_message_size = self.max_encoding_message_size; 434 + let inner = self.inner.clone(); 435 + let fut = async move { 436 + let method = TreeGetContextSvc(inner); 437 + let codec = tonic::codec::ProstCodec::default(); 438 + let mut grpc = tonic::server::Grpc::new(codec) 439 + .apply_compression_config( 440 + accept_compression_encodings, 441 + send_compression_encodings, 442 + ) 443 + .apply_max_message_size_config( 444 + max_decoding_message_size, 445 + max_encoding_message_size, 446 + ); 447 + let res = grpc.unary(method, req).await; 448 + Ok(res) 449 + }; 450 + Box::pin(fut) 451 + } 452 + "/rockbox.v1alpha1.BrowseService/TreeGetEntries" => { 453 + #[allow(non_camel_case_types)] 454 + struct TreeGetEntriesSvc<T: BrowseService>(pub Arc<T>); 455 + impl< 456 + T: BrowseService, 457 + > tonic::server::UnaryService<super::TreeGetEntriesRequest> 458 + for TreeGetEntriesSvc<T> { 459 + type Response = super::TreeGetEntriesResponse; 460 + type Future = BoxFuture< 461 + tonic::Response<Self::Response>, 462 + tonic::Status, 463 + >; 464 + fn call( 465 + &mut self, 466 + request: tonic::Request<super::TreeGetEntriesRequest>, 467 + ) -> Self::Future { 468 + let inner = Arc::clone(&self.0); 469 + let fut = async move { 470 + <T as BrowseService>::tree_get_entries(&inner, request) 471 + .await 472 + }; 473 + Box::pin(fut) 474 + } 475 + } 476 + let accept_compression_encodings = self.accept_compression_encodings; 477 + let send_compression_encodings = self.send_compression_encodings; 478 + let max_decoding_message_size = self.max_decoding_message_size; 479 + let max_encoding_message_size = self.max_encoding_message_size; 480 + let inner = self.inner.clone(); 481 + let fut = async move { 482 + let method = TreeGetEntriesSvc(inner); 483 + let codec = tonic::codec::ProstCodec::default(); 484 + let mut grpc = tonic::server::Grpc::new(codec) 485 + .apply_compression_config( 486 + accept_compression_encodings, 487 + send_compression_encodings, 488 + ) 489 + .apply_max_message_size_config( 490 + max_decoding_message_size, 491 + max_encoding_message_size, 492 + ); 493 + let res = grpc.unary(method, req).await; 494 + Ok(res) 495 + }; 496 + Box::pin(fut) 497 + } 498 + "/rockbox.v1alpha1.BrowseService/TreeGetEntryAt" => { 499 + #[allow(non_camel_case_types)] 500 + struct TreeGetEntryAtSvc<T: BrowseService>(pub Arc<T>); 501 + impl< 502 + T: BrowseService, 503 + > tonic::server::UnaryService<super::TreeGetEntryAtRequest> 504 + for TreeGetEntryAtSvc<T> { 505 + type Response = super::TreeGetEntryAtResponse; 506 + type Future = BoxFuture< 507 + tonic::Response<Self::Response>, 508 + tonic::Status, 509 + >; 510 + fn call( 511 + &mut self, 512 + request: tonic::Request<super::TreeGetEntryAtRequest>, 513 + ) -> Self::Future { 514 + let inner = Arc::clone(&self.0); 515 + let fut = async move { 516 + <T as BrowseService>::tree_get_entry_at(&inner, request) 517 + .await 518 + }; 519 + Box::pin(fut) 520 + } 521 + } 522 + let accept_compression_encodings = self.accept_compression_encodings; 523 + let send_compression_encodings = self.send_compression_encodings; 524 + let max_decoding_message_size = self.max_decoding_message_size; 525 + let max_encoding_message_size = self.max_encoding_message_size; 526 + let inner = self.inner.clone(); 527 + let fut = async move { 528 + let method = TreeGetEntryAtSvc(inner); 529 + let codec = tonic::codec::ProstCodec::default(); 530 + let mut grpc = tonic::server::Grpc::new(codec) 531 + .apply_compression_config( 532 + accept_compression_encodings, 533 + send_compression_encodings, 534 + ) 535 + .apply_max_message_size_config( 536 + max_decoding_message_size, 537 + max_encoding_message_size, 538 + ); 539 + let res = grpc.unary(method, req).await; 540 + Ok(res) 541 + }; 542 + Box::pin(fut) 543 + } 544 + "/rockbox.v1alpha1.BrowseService/BrowseId3" => { 545 + #[allow(non_camel_case_types)] 546 + struct BrowseId3Svc<T: BrowseService>(pub Arc<T>); 547 + impl< 548 + T: BrowseService, 549 + > tonic::server::UnaryService<super::BrowseId3Request> 550 + for BrowseId3Svc<T> { 551 + type Response = super::BrowseId3Response; 552 + type Future = BoxFuture< 553 + tonic::Response<Self::Response>, 554 + tonic::Status, 555 + >; 556 + fn call( 557 + &mut self, 558 + request: tonic::Request<super::BrowseId3Request>, 559 + ) -> Self::Future { 560 + let inner = Arc::clone(&self.0); 561 + let fut = async move { 562 + <T as BrowseService>::browse_id3(&inner, request).await 563 + }; 564 + Box::pin(fut) 565 + } 566 + } 567 + let accept_compression_encodings = self.accept_compression_encodings; 568 + let send_compression_encodings = self.send_compression_encodings; 569 + let max_decoding_message_size = self.max_decoding_message_size; 570 + let max_encoding_message_size = self.max_encoding_message_size; 571 + let inner = self.inner.clone(); 572 + let fut = async move { 573 + let method = BrowseId3Svc(inner); 574 + let codec = tonic::codec::ProstCodec::default(); 575 + let mut grpc = tonic::server::Grpc::new(codec) 576 + .apply_compression_config( 577 + accept_compression_encodings, 578 + send_compression_encodings, 579 + ) 580 + .apply_max_message_size_config( 581 + max_decoding_message_size, 582 + max_encoding_message_size, 583 + ); 584 + let res = grpc.unary(method, req).await; 585 + Ok(res) 586 + }; 587 + Box::pin(fut) 588 + } 589 + _ => { 590 + Box::pin(async move { 591 + Ok( 592 + http::Response::builder() 593 + .status(200) 594 + .header("grpc-status", tonic::Code::Unimplemented as i32) 595 + .header( 596 + http::header::CONTENT_TYPE, 597 + tonic::metadata::GRPC_CONTENT_TYPE, 598 + ) 599 + .body(empty_body()) 600 + .unwrap(), 601 + ) 602 + }) 603 + } 604 + } 605 + } 606 + } 607 + impl<T> Clone for BrowseServiceServer<T> { 608 + fn clone(&self) -> Self { 609 + let inner = self.inner.clone(); 610 + Self { 611 + inner, 612 + accept_compression_encodings: self.accept_compression_encodings, 613 + send_compression_encodings: self.send_compression_encodings, 614 + max_decoding_message_size: self.max_decoding_message_size, 615 + max_encoding_message_size: self.max_encoding_message_size, 616 + } 617 + } 618 + } 619 + /// Generated gRPC service name 620 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.BrowseService"; 621 + impl<T> tonic::server::NamedService for BrowseServiceServer<T> { 622 + const NAME: &'static str = SERVICE_NAME; 623 + } 624 + } 625 + /// Generated client implementations. 626 + pub mod metadata_service_client { 627 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 628 + use tonic::codegen::*; 629 + use tonic::codegen::http::Uri; 630 + #[derive(Debug, Clone)] 631 + pub struct MetadataServiceClient<T> { 632 + inner: tonic::client::Grpc<T>, 633 + } 634 + impl MetadataServiceClient<tonic::transport::Channel> { 635 + /// Attempt to create a new client by connecting to a given endpoint. 636 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 637 + where 638 + D: TryInto<tonic::transport::Endpoint>, 639 + D::Error: Into<StdError>, 640 + { 641 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 642 + Ok(Self::new(conn)) 643 + } 644 + } 645 + impl<T> MetadataServiceClient<T> 646 + where 647 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 648 + T::Error: Into<StdError>, 649 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 650 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 651 + { 652 + pub fn new(inner: T) -> Self { 653 + let inner = tonic::client::Grpc::new(inner); 654 + Self { inner } 655 + } 656 + pub fn with_origin(inner: T, origin: Uri) -> Self { 657 + let inner = tonic::client::Grpc::with_origin(inner, origin); 658 + Self { inner } 659 + } 660 + pub fn with_interceptor<F>( 661 + inner: T, 662 + interceptor: F, 663 + ) -> MetadataServiceClient<InterceptedService<T, F>> 664 + where 665 + F: tonic::service::Interceptor, 666 + T::ResponseBody: Default, 667 + T: tonic::codegen::Service< 668 + http::Request<tonic::body::BoxBody>, 669 + Response = http::Response< 670 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 671 + >, 672 + >, 673 + <T as tonic::codegen::Service< 674 + http::Request<tonic::body::BoxBody>, 675 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 676 + { 677 + MetadataServiceClient::new(InterceptedService::new(inner, interceptor)) 678 + } 679 + /// Compress requests with the given encoding. 680 + /// 681 + /// This requires the server to support it otherwise it might respond with an 682 + /// error. 683 + #[must_use] 684 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 685 + self.inner = self.inner.send_compressed(encoding); 686 + self 687 + } 688 + /// Enable decompressing responses. 689 + #[must_use] 690 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 691 + self.inner = self.inner.accept_compressed(encoding); 692 + self 693 + } 694 + /// Limits the maximum size of a decoded message. 695 + /// 696 + /// Default: `4MB` 697 + #[must_use] 698 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 699 + self.inner = self.inner.max_decoding_message_size(limit); 700 + self 701 + } 702 + /// Limits the maximum size of an encoded message. 703 + /// 704 + /// Default: `usize::MAX` 705 + #[must_use] 706 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 707 + self.inner = self.inner.max_encoding_message_size(limit); 708 + self 709 + } 710 + } 711 + } 712 + /// Generated server implementations. 713 + pub mod metadata_service_server { 714 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 715 + use tonic::codegen::*; 716 + /// Generated trait containing gRPC methods that should be implemented for use with MetadataServiceServer. 717 + #[async_trait] 718 + pub trait MetadataService: std::marker::Send + std::marker::Sync + 'static {} 719 + #[derive(Debug)] 720 + pub struct MetadataServiceServer<T> { 721 + inner: Arc<T>, 722 + accept_compression_encodings: EnabledCompressionEncodings, 723 + send_compression_encodings: EnabledCompressionEncodings, 724 + max_decoding_message_size: Option<usize>, 725 + max_encoding_message_size: Option<usize>, 726 + } 727 + impl<T> MetadataServiceServer<T> { 728 + pub fn new(inner: T) -> Self { 729 + Self::from_arc(Arc::new(inner)) 730 + } 731 + pub fn from_arc(inner: Arc<T>) -> Self { 732 + Self { 733 + inner, 734 + accept_compression_encodings: Default::default(), 735 + send_compression_encodings: Default::default(), 736 + max_decoding_message_size: None, 737 + max_encoding_message_size: None, 738 + } 739 + } 740 + pub fn with_interceptor<F>( 741 + inner: T, 742 + interceptor: F, 743 + ) -> InterceptedService<Self, F> 744 + where 745 + F: tonic::service::Interceptor, 746 + { 747 + InterceptedService::new(Self::new(inner), interceptor) 748 + } 749 + /// Enable decompressing requests with the given encoding. 750 + #[must_use] 751 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 752 + self.accept_compression_encodings.enable(encoding); 753 + self 754 + } 755 + /// Compress responses with the given encoding, if the client supports it. 756 + #[must_use] 757 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 758 + self.send_compression_encodings.enable(encoding); 759 + self 760 + } 761 + /// Limits the maximum size of a decoded message. 762 + /// 763 + /// Default: `4MB` 764 + #[must_use] 765 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 766 + self.max_decoding_message_size = Some(limit); 767 + self 768 + } 769 + /// Limits the maximum size of an encoded message. 770 + /// 771 + /// Default: `usize::MAX` 772 + #[must_use] 773 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 774 + self.max_encoding_message_size = Some(limit); 775 + self 776 + } 777 + } 778 + impl<T, B> tonic::codegen::Service<http::Request<B>> for MetadataServiceServer<T> 779 + where 780 + T: MetadataService, 781 + B: Body + std::marker::Send + 'static, 782 + B::Error: Into<StdError> + std::marker::Send + 'static, 783 + { 784 + type Response = http::Response<tonic::body::BoxBody>; 785 + type Error = std::convert::Infallible; 786 + type Future = BoxFuture<Self::Response, Self::Error>; 787 + fn poll_ready( 788 + &mut self, 789 + _cx: &mut Context<'_>, 790 + ) -> Poll<std::result::Result<(), Self::Error>> { 791 + Poll::Ready(Ok(())) 792 + } 793 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 794 + match req.uri().path() { 795 + _ => { 796 + Box::pin(async move { 797 + Ok( 798 + http::Response::builder() 799 + .status(200) 800 + .header("grpc-status", tonic::Code::Unimplemented as i32) 801 + .header( 802 + http::header::CONTENT_TYPE, 803 + tonic::metadata::GRPC_CONTENT_TYPE, 804 + ) 805 + .body(empty_body()) 806 + .unwrap(), 807 + ) 808 + }) 809 + } 810 + } 811 + } 812 + } 813 + impl<T> Clone for MetadataServiceServer<T> { 814 + fn clone(&self) -> Self { 815 + let inner = self.inner.clone(); 816 + Self { 817 + inner, 818 + accept_compression_encodings: self.accept_compression_encodings, 819 + send_compression_encodings: self.send_compression_encodings, 820 + max_decoding_message_size: self.max_decoding_message_size, 821 + max_encoding_message_size: self.max_encoding_message_size, 822 + } 823 + } 824 + } 825 + /// Generated gRPC service name 826 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.MetadataService"; 827 + impl<T> tonic::server::NamedService for MetadataServiceServer<T> { 828 + const NAME: &'static str = SERVICE_NAME; 829 + } 830 + } 831 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 832 + pub struct PlayRequest { 833 + #[prost(int64, tag = "1")] 834 + pub elapsed: i64, 835 + #[prost(int64, tag = "2")] 836 + pub offset: i64, 837 + } 838 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 839 + pub struct PlayResponse {} 840 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 841 + pub struct PauseRequest {} 842 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 843 + pub struct PauseResponse {} 844 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 845 + pub struct ResumeRequest {} 846 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 847 + pub struct ResumeResponse {} 848 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 849 + pub struct NextRequest {} 850 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 851 + pub struct NextResponse {} 852 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 853 + pub struct PreviousRequest {} 854 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 855 + pub struct PreviousResponse {} 856 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 857 + pub struct FastForwardRewindRequest { 858 + #[prost(int32, tag = "1")] 859 + pub new_time: i32, 860 + } 861 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 862 + pub struct FastForwardRewindResponse {} 863 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 864 + pub struct StatusRequest {} 865 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 866 + pub struct StatusResponse { 867 + #[prost(int32, tag = "1")] 868 + pub status: i32, 869 + } 870 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 871 + pub struct CurrentTrackRequest {} 872 + #[derive(Clone, PartialEq, ::prost::Message)] 873 + pub struct CurrentTrackResponse { 874 + #[prost(string, tag = "1")] 875 + pub title: ::prost::alloc::string::String, 876 + #[prost(string, tag = "2")] 877 + pub artist: ::prost::alloc::string::String, 878 + #[prost(string, tag = "3")] 879 + pub album: ::prost::alloc::string::String, 880 + #[prost(string, tag = "4")] 881 + pub genre: ::prost::alloc::string::String, 882 + #[prost(string, tag = "5")] 883 + pub disc: ::prost::alloc::string::String, 884 + #[prost(string, tag = "6")] 885 + pub track_string: ::prost::alloc::string::String, 886 + #[prost(string, tag = "7")] 887 + pub year_string: ::prost::alloc::string::String, 888 + #[prost(string, tag = "8")] 889 + pub composer: ::prost::alloc::string::String, 890 + #[prost(string, tag = "9")] 891 + pub comment: ::prost::alloc::string::String, 892 + #[prost(string, tag = "10")] 893 + pub album_artist: ::prost::alloc::string::String, 894 + #[prost(string, tag = "11")] 895 + pub grouping: ::prost::alloc::string::String, 896 + #[prost(int32, tag = "12")] 897 + pub discnum: i32, 898 + #[prost(int32, tag = "13")] 899 + pub tracknum: i32, 900 + #[prost(int32, tag = "14")] 901 + pub layer: i32, 902 + #[prost(int32, tag = "15")] 903 + pub year: i32, 904 + #[prost(uint32, tag = "16")] 905 + pub bitrate: u32, 906 + #[prost(uint64, tag = "17")] 907 + pub frequency: u64, 908 + #[prost(uint64, tag = "18")] 909 + pub filesize: u64, 910 + #[prost(uint64, tag = "19")] 911 + pub length: u64, 912 + #[prost(uint64, tag = "20")] 913 + pub elapsed: u64, 914 + } 915 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 916 + pub struct FlushAndReloadTracksRequest {} 917 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 918 + pub struct FlushAndReloadTracksResponse {} 919 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 920 + pub struct GetFilePositionRequest {} 921 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 922 + pub struct GetFilePositionResponse { 923 + #[prost(int32, tag = "1")] 924 + pub position: i32, 925 + } 926 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 927 + pub struct HardStopRequest {} 928 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 929 + pub struct HardStopResponse {} 930 + /// Generated client implementations. 931 + pub mod playback_service_client { 932 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 933 + use tonic::codegen::*; 934 + use tonic::codegen::http::Uri; 935 + #[derive(Debug, Clone)] 936 + pub struct PlaybackServiceClient<T> { 937 + inner: tonic::client::Grpc<T>, 938 + } 939 + impl PlaybackServiceClient<tonic::transport::Channel> { 940 + /// Attempt to create a new client by connecting to a given endpoint. 941 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 942 + where 943 + D: TryInto<tonic::transport::Endpoint>, 944 + D::Error: Into<StdError>, 945 + { 946 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 947 + Ok(Self::new(conn)) 948 + } 949 + } 950 + impl<T> PlaybackServiceClient<T> 951 + where 952 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 953 + T::Error: Into<StdError>, 954 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 955 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 956 + { 957 + pub fn new(inner: T) -> Self { 958 + let inner = tonic::client::Grpc::new(inner); 959 + Self { inner } 960 + } 961 + pub fn with_origin(inner: T, origin: Uri) -> Self { 962 + let inner = tonic::client::Grpc::with_origin(inner, origin); 963 + Self { inner } 964 + } 965 + pub fn with_interceptor<F>( 966 + inner: T, 967 + interceptor: F, 968 + ) -> PlaybackServiceClient<InterceptedService<T, F>> 969 + where 970 + F: tonic::service::Interceptor, 971 + T::ResponseBody: Default, 972 + T: tonic::codegen::Service< 973 + http::Request<tonic::body::BoxBody>, 974 + Response = http::Response< 975 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 976 + >, 977 + >, 978 + <T as tonic::codegen::Service< 979 + http::Request<tonic::body::BoxBody>, 980 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 981 + { 982 + PlaybackServiceClient::new(InterceptedService::new(inner, interceptor)) 983 + } 984 + /// Compress requests with the given encoding. 985 + /// 986 + /// This requires the server to support it otherwise it might respond with an 987 + /// error. 988 + #[must_use] 989 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 990 + self.inner = self.inner.send_compressed(encoding); 991 + self 992 + } 993 + /// Enable decompressing responses. 994 + #[must_use] 995 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 996 + self.inner = self.inner.accept_compressed(encoding); 997 + self 998 + } 999 + /// Limits the maximum size of a decoded message. 1000 + /// 1001 + /// Default: `4MB` 1002 + #[must_use] 1003 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 1004 + self.inner = self.inner.max_decoding_message_size(limit); 1005 + self 1006 + } 1007 + /// Limits the maximum size of an encoded message. 1008 + /// 1009 + /// Default: `usize::MAX` 1010 + #[must_use] 1011 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 1012 + self.inner = self.inner.max_encoding_message_size(limit); 1013 + self 1014 + } 1015 + pub async fn play( 1016 + &mut self, 1017 + request: impl tonic::IntoRequest<super::PlayRequest>, 1018 + ) -> std::result::Result<tonic::Response<super::PlayResponse>, tonic::Status> { 1019 + self.inner 1020 + .ready() 1021 + .await 1022 + .map_err(|e| { 1023 + tonic::Status::new( 1024 + tonic::Code::Unknown, 1025 + format!("Service was not ready: {}", e.into()), 1026 + ) 1027 + })?; 1028 + let codec = tonic::codec::ProstCodec::default(); 1029 + let path = http::uri::PathAndQuery::from_static( 1030 + "/rockbox.v1alpha1.PlaybackService/Play", 1031 + ); 1032 + let mut req = request.into_request(); 1033 + req.extensions_mut() 1034 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Play")); 1035 + self.inner.unary(req, path, codec).await 1036 + } 1037 + pub async fn pause( 1038 + &mut self, 1039 + request: impl tonic::IntoRequest<super::PauseRequest>, 1040 + ) -> std::result::Result<tonic::Response<super::PauseResponse>, tonic::Status> { 1041 + self.inner 1042 + .ready() 1043 + .await 1044 + .map_err(|e| { 1045 + tonic::Status::new( 1046 + tonic::Code::Unknown, 1047 + format!("Service was not ready: {}", e.into()), 1048 + ) 1049 + })?; 1050 + let codec = tonic::codec::ProstCodec::default(); 1051 + let path = http::uri::PathAndQuery::from_static( 1052 + "/rockbox.v1alpha1.PlaybackService/Pause", 1053 + ); 1054 + let mut req = request.into_request(); 1055 + req.extensions_mut() 1056 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Pause")); 1057 + self.inner.unary(req, path, codec).await 1058 + } 1059 + pub async fn resume( 1060 + &mut self, 1061 + request: impl tonic::IntoRequest<super::ResumeRequest>, 1062 + ) -> std::result::Result<tonic::Response<super::ResumeResponse>, tonic::Status> { 1063 + self.inner 1064 + .ready() 1065 + .await 1066 + .map_err(|e| { 1067 + tonic::Status::new( 1068 + tonic::Code::Unknown, 1069 + format!("Service was not ready: {}", e.into()), 1070 + ) 1071 + })?; 1072 + let codec = tonic::codec::ProstCodec::default(); 1073 + let path = http::uri::PathAndQuery::from_static( 1074 + "/rockbox.v1alpha1.PlaybackService/Resume", 1075 + ); 1076 + let mut req = request.into_request(); 1077 + req.extensions_mut() 1078 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Resume")); 1079 + self.inner.unary(req, path, codec).await 1080 + } 1081 + pub async fn next( 1082 + &mut self, 1083 + request: impl tonic::IntoRequest<super::NextRequest>, 1084 + ) -> std::result::Result<tonic::Response<super::NextResponse>, tonic::Status> { 1085 + self.inner 1086 + .ready() 1087 + .await 1088 + .map_err(|e| { 1089 + tonic::Status::new( 1090 + tonic::Code::Unknown, 1091 + format!("Service was not ready: {}", e.into()), 1092 + ) 1093 + })?; 1094 + let codec = tonic::codec::ProstCodec::default(); 1095 + let path = http::uri::PathAndQuery::from_static( 1096 + "/rockbox.v1alpha1.PlaybackService/Next", 1097 + ); 1098 + let mut req = request.into_request(); 1099 + req.extensions_mut() 1100 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Next")); 1101 + self.inner.unary(req, path, codec).await 1102 + } 1103 + pub async fn previous( 1104 + &mut self, 1105 + request: impl tonic::IntoRequest<super::PreviousRequest>, 1106 + ) -> std::result::Result< 1107 + tonic::Response<super::PreviousResponse>, 1108 + tonic::Status, 1109 + > { 1110 + self.inner 1111 + .ready() 1112 + .await 1113 + .map_err(|e| { 1114 + tonic::Status::new( 1115 + tonic::Code::Unknown, 1116 + format!("Service was not ready: {}", e.into()), 1117 + ) 1118 + })?; 1119 + let codec = tonic::codec::ProstCodec::default(); 1120 + let path = http::uri::PathAndQuery::from_static( 1121 + "/rockbox.v1alpha1.PlaybackService/Previous", 1122 + ); 1123 + let mut req = request.into_request(); 1124 + req.extensions_mut() 1125 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Previous")); 1126 + self.inner.unary(req, path, codec).await 1127 + } 1128 + pub async fn fast_forward_rewind( 1129 + &mut self, 1130 + request: impl tonic::IntoRequest<super::FastForwardRewindRequest>, 1131 + ) -> std::result::Result< 1132 + tonic::Response<super::FastForwardRewindResponse>, 1133 + tonic::Status, 1134 + > { 1135 + self.inner 1136 + .ready() 1137 + .await 1138 + .map_err(|e| { 1139 + tonic::Status::new( 1140 + tonic::Code::Unknown, 1141 + format!("Service was not ready: {}", e.into()), 1142 + ) 1143 + })?; 1144 + let codec = tonic::codec::ProstCodec::default(); 1145 + let path = http::uri::PathAndQuery::from_static( 1146 + "/rockbox.v1alpha1.PlaybackService/FastForwardRewind", 1147 + ); 1148 + let mut req = request.into_request(); 1149 + req.extensions_mut() 1150 + .insert( 1151 + GrpcMethod::new( 1152 + "rockbox.v1alpha1.PlaybackService", 1153 + "FastForwardRewind", 1154 + ), 1155 + ); 1156 + self.inner.unary(req, path, codec).await 1157 + } 1158 + pub async fn status( 1159 + &mut self, 1160 + request: impl tonic::IntoRequest<super::StatusRequest>, 1161 + ) -> std::result::Result<tonic::Response<super::StatusResponse>, tonic::Status> { 1162 + self.inner 1163 + .ready() 1164 + .await 1165 + .map_err(|e| { 1166 + tonic::Status::new( 1167 + tonic::Code::Unknown, 1168 + format!("Service was not ready: {}", e.into()), 1169 + ) 1170 + })?; 1171 + let codec = tonic::codec::ProstCodec::default(); 1172 + let path = http::uri::PathAndQuery::from_static( 1173 + "/rockbox.v1alpha1.PlaybackService/Status", 1174 + ); 1175 + let mut req = request.into_request(); 1176 + req.extensions_mut() 1177 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Status")); 1178 + self.inner.unary(req, path, codec).await 1179 + } 1180 + pub async fn current_track( 1181 + &mut self, 1182 + request: impl tonic::IntoRequest<super::CurrentTrackRequest>, 1183 + ) -> std::result::Result< 1184 + tonic::Response<super::CurrentTrackResponse>, 1185 + tonic::Status, 1186 + > { 1187 + self.inner 1188 + .ready() 1189 + .await 1190 + .map_err(|e| { 1191 + tonic::Status::new( 1192 + tonic::Code::Unknown, 1193 + format!("Service was not ready: {}", e.into()), 1194 + ) 1195 + })?; 1196 + let codec = tonic::codec::ProstCodec::default(); 1197 + let path = http::uri::PathAndQuery::from_static( 1198 + "/rockbox.v1alpha1.PlaybackService/CurrentTrack", 1199 + ); 1200 + let mut req = request.into_request(); 1201 + req.extensions_mut() 1202 + .insert( 1203 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "CurrentTrack"), 1204 + ); 1205 + self.inner.unary(req, path, codec).await 1206 + } 1207 + pub async fn flush_and_reload_tracks( 1208 + &mut self, 1209 + request: impl tonic::IntoRequest<super::FlushAndReloadTracksRequest>, 1210 + ) -> std::result::Result< 1211 + tonic::Response<super::FlushAndReloadTracksResponse>, 1212 + tonic::Status, 1213 + > { 1214 + self.inner 1215 + .ready() 1216 + .await 1217 + .map_err(|e| { 1218 + tonic::Status::new( 1219 + tonic::Code::Unknown, 1220 + format!("Service was not ready: {}", e.into()), 1221 + ) 1222 + })?; 1223 + let codec = tonic::codec::ProstCodec::default(); 1224 + let path = http::uri::PathAndQuery::from_static( 1225 + "/rockbox.v1alpha1.PlaybackService/FlushAndReloadTracks", 1226 + ); 1227 + let mut req = request.into_request(); 1228 + req.extensions_mut() 1229 + .insert( 1230 + GrpcMethod::new( 1231 + "rockbox.v1alpha1.PlaybackService", 1232 + "FlushAndReloadTracks", 1233 + ), 1234 + ); 1235 + self.inner.unary(req, path, codec).await 1236 + } 1237 + pub async fn get_file_position( 1238 + &mut self, 1239 + request: impl tonic::IntoRequest<super::GetFilePositionRequest>, 1240 + ) -> std::result::Result< 1241 + tonic::Response<super::GetFilePositionResponse>, 1242 + tonic::Status, 1243 + > { 1244 + self.inner 1245 + .ready() 1246 + .await 1247 + .map_err(|e| { 1248 + tonic::Status::new( 1249 + tonic::Code::Unknown, 1250 + format!("Service was not ready: {}", e.into()), 1251 + ) 1252 + })?; 1253 + let codec = tonic::codec::ProstCodec::default(); 1254 + let path = http::uri::PathAndQuery::from_static( 1255 + "/rockbox.v1alpha1.PlaybackService/GetFilePosition", 1256 + ); 1257 + let mut req = request.into_request(); 1258 + req.extensions_mut() 1259 + .insert( 1260 + GrpcMethod::new( 1261 + "rockbox.v1alpha1.PlaybackService", 1262 + "GetFilePosition", 1263 + ), 1264 + ); 1265 + self.inner.unary(req, path, codec).await 1266 + } 1267 + pub async fn hard_stop( 1268 + &mut self, 1269 + request: impl tonic::IntoRequest<super::HardStopRequest>, 1270 + ) -> std::result::Result< 1271 + tonic::Response<super::HardStopResponse>, 1272 + tonic::Status, 1273 + > { 1274 + self.inner 1275 + .ready() 1276 + .await 1277 + .map_err(|e| { 1278 + tonic::Status::new( 1279 + tonic::Code::Unknown, 1280 + format!("Service was not ready: {}", e.into()), 1281 + ) 1282 + })?; 1283 + let codec = tonic::codec::ProstCodec::default(); 1284 + let path = http::uri::PathAndQuery::from_static( 1285 + "/rockbox.v1alpha1.PlaybackService/HardStop", 1286 + ); 1287 + let mut req = request.into_request(); 1288 + req.extensions_mut() 1289 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "HardStop")); 1290 + self.inner.unary(req, path, codec).await 1291 + } 1292 + } 1293 + } 1294 + /// Generated server implementations. 1295 + pub mod playback_service_server { 1296 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 1297 + use tonic::codegen::*; 1298 + /// Generated trait containing gRPC methods that should be implemented for use with PlaybackServiceServer. 1299 + #[async_trait] 1300 + pub trait PlaybackService: std::marker::Send + std::marker::Sync + 'static { 1301 + async fn play( 1302 + &self, 1303 + request: tonic::Request<super::PlayRequest>, 1304 + ) -> std::result::Result<tonic::Response<super::PlayResponse>, tonic::Status>; 1305 + async fn pause( 1306 + &self, 1307 + request: tonic::Request<super::PauseRequest>, 1308 + ) -> std::result::Result<tonic::Response<super::PauseResponse>, tonic::Status>; 1309 + async fn resume( 1310 + &self, 1311 + request: tonic::Request<super::ResumeRequest>, 1312 + ) -> std::result::Result<tonic::Response<super::ResumeResponse>, tonic::Status>; 1313 + async fn next( 1314 + &self, 1315 + request: tonic::Request<super::NextRequest>, 1316 + ) -> std::result::Result<tonic::Response<super::NextResponse>, tonic::Status>; 1317 + async fn previous( 1318 + &self, 1319 + request: tonic::Request<super::PreviousRequest>, 1320 + ) -> std::result::Result< 1321 + tonic::Response<super::PreviousResponse>, 1322 + tonic::Status, 1323 + >; 1324 + async fn fast_forward_rewind( 1325 + &self, 1326 + request: tonic::Request<super::FastForwardRewindRequest>, 1327 + ) -> std::result::Result< 1328 + tonic::Response<super::FastForwardRewindResponse>, 1329 + tonic::Status, 1330 + >; 1331 + async fn status( 1332 + &self, 1333 + request: tonic::Request<super::StatusRequest>, 1334 + ) -> std::result::Result<tonic::Response<super::StatusResponse>, tonic::Status>; 1335 + async fn current_track( 1336 + &self, 1337 + request: tonic::Request<super::CurrentTrackRequest>, 1338 + ) -> std::result::Result< 1339 + tonic::Response<super::CurrentTrackResponse>, 1340 + tonic::Status, 1341 + >; 1342 + async fn flush_and_reload_tracks( 1343 + &self, 1344 + request: tonic::Request<super::FlushAndReloadTracksRequest>, 1345 + ) -> std::result::Result< 1346 + tonic::Response<super::FlushAndReloadTracksResponse>, 1347 + tonic::Status, 1348 + >; 1349 + async fn get_file_position( 1350 + &self, 1351 + request: tonic::Request<super::GetFilePositionRequest>, 1352 + ) -> std::result::Result< 1353 + tonic::Response<super::GetFilePositionResponse>, 1354 + tonic::Status, 1355 + >; 1356 + async fn hard_stop( 1357 + &self, 1358 + request: tonic::Request<super::HardStopRequest>, 1359 + ) -> std::result::Result< 1360 + tonic::Response<super::HardStopResponse>, 1361 + tonic::Status, 1362 + >; 1363 + } 1364 + #[derive(Debug)] 1365 + pub struct PlaybackServiceServer<T> { 1366 + inner: Arc<T>, 1367 + accept_compression_encodings: EnabledCompressionEncodings, 1368 + send_compression_encodings: EnabledCompressionEncodings, 1369 + max_decoding_message_size: Option<usize>, 1370 + max_encoding_message_size: Option<usize>, 1371 + } 1372 + impl<T> PlaybackServiceServer<T> { 1373 + pub fn new(inner: T) -> Self { 1374 + Self::from_arc(Arc::new(inner)) 1375 + } 1376 + pub fn from_arc(inner: Arc<T>) -> Self { 1377 + Self { 1378 + inner, 1379 + accept_compression_encodings: Default::default(), 1380 + send_compression_encodings: Default::default(), 1381 + max_decoding_message_size: None, 1382 + max_encoding_message_size: None, 1383 + } 1384 + } 1385 + pub fn with_interceptor<F>( 1386 + inner: T, 1387 + interceptor: F, 1388 + ) -> InterceptedService<Self, F> 1389 + where 1390 + F: tonic::service::Interceptor, 1391 + { 1392 + InterceptedService::new(Self::new(inner), interceptor) 1393 + } 1394 + /// Enable decompressing requests with the given encoding. 1395 + #[must_use] 1396 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 1397 + self.accept_compression_encodings.enable(encoding); 1398 + self 1399 + } 1400 + /// Compress responses with the given encoding, if the client supports it. 1401 + #[must_use] 1402 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 1403 + self.send_compression_encodings.enable(encoding); 1404 + self 1405 + } 1406 + /// Limits the maximum size of a decoded message. 1407 + /// 1408 + /// Default: `4MB` 1409 + #[must_use] 1410 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 1411 + self.max_decoding_message_size = Some(limit); 1412 + self 1413 + } 1414 + /// Limits the maximum size of an encoded message. 1415 + /// 1416 + /// Default: `usize::MAX` 1417 + #[must_use] 1418 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 1419 + self.max_encoding_message_size = Some(limit); 1420 + self 1421 + } 1422 + } 1423 + impl<T, B> tonic::codegen::Service<http::Request<B>> for PlaybackServiceServer<T> 1424 + where 1425 + T: PlaybackService, 1426 + B: Body + std::marker::Send + 'static, 1427 + B::Error: Into<StdError> + std::marker::Send + 'static, 1428 + { 1429 + type Response = http::Response<tonic::body::BoxBody>; 1430 + type Error = std::convert::Infallible; 1431 + type Future = BoxFuture<Self::Response, Self::Error>; 1432 + fn poll_ready( 1433 + &mut self, 1434 + _cx: &mut Context<'_>, 1435 + ) -> Poll<std::result::Result<(), Self::Error>> { 1436 + Poll::Ready(Ok(())) 1437 + } 1438 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 1439 + match req.uri().path() { 1440 + "/rockbox.v1alpha1.PlaybackService/Play" => { 1441 + #[allow(non_camel_case_types)] 1442 + struct PlaySvc<T: PlaybackService>(pub Arc<T>); 1443 + impl< 1444 + T: PlaybackService, 1445 + > tonic::server::UnaryService<super::PlayRequest> for PlaySvc<T> { 1446 + type Response = super::PlayResponse; 1447 + type Future = BoxFuture< 1448 + tonic::Response<Self::Response>, 1449 + tonic::Status, 1450 + >; 1451 + fn call( 1452 + &mut self, 1453 + request: tonic::Request<super::PlayRequest>, 1454 + ) -> Self::Future { 1455 + let inner = Arc::clone(&self.0); 1456 + let fut = async move { 1457 + <T as PlaybackService>::play(&inner, request).await 1458 + }; 1459 + Box::pin(fut) 1460 + } 1461 + } 1462 + let accept_compression_encodings = self.accept_compression_encodings; 1463 + let send_compression_encodings = self.send_compression_encodings; 1464 + let max_decoding_message_size = self.max_decoding_message_size; 1465 + let max_encoding_message_size = self.max_encoding_message_size; 1466 + let inner = self.inner.clone(); 1467 + let fut = async move { 1468 + let method = PlaySvc(inner); 1469 + let codec = tonic::codec::ProstCodec::default(); 1470 + let mut grpc = tonic::server::Grpc::new(codec) 1471 + .apply_compression_config( 1472 + accept_compression_encodings, 1473 + send_compression_encodings, 1474 + ) 1475 + .apply_max_message_size_config( 1476 + max_decoding_message_size, 1477 + max_encoding_message_size, 1478 + ); 1479 + let res = grpc.unary(method, req).await; 1480 + Ok(res) 1481 + }; 1482 + Box::pin(fut) 1483 + } 1484 + "/rockbox.v1alpha1.PlaybackService/Pause" => { 1485 + #[allow(non_camel_case_types)] 1486 + struct PauseSvc<T: PlaybackService>(pub Arc<T>); 1487 + impl< 1488 + T: PlaybackService, 1489 + > tonic::server::UnaryService<super::PauseRequest> for PauseSvc<T> { 1490 + type Response = super::PauseResponse; 1491 + type Future = BoxFuture< 1492 + tonic::Response<Self::Response>, 1493 + tonic::Status, 1494 + >; 1495 + fn call( 1496 + &mut self, 1497 + request: tonic::Request<super::PauseRequest>, 1498 + ) -> Self::Future { 1499 + let inner = Arc::clone(&self.0); 1500 + let fut = async move { 1501 + <T as PlaybackService>::pause(&inner, request).await 1502 + }; 1503 + Box::pin(fut) 1504 + } 1505 + } 1506 + let accept_compression_encodings = self.accept_compression_encodings; 1507 + let send_compression_encodings = self.send_compression_encodings; 1508 + let max_decoding_message_size = self.max_decoding_message_size; 1509 + let max_encoding_message_size = self.max_encoding_message_size; 1510 + let inner = self.inner.clone(); 1511 + let fut = async move { 1512 + let method = PauseSvc(inner); 1513 + let codec = tonic::codec::ProstCodec::default(); 1514 + let mut grpc = tonic::server::Grpc::new(codec) 1515 + .apply_compression_config( 1516 + accept_compression_encodings, 1517 + send_compression_encodings, 1518 + ) 1519 + .apply_max_message_size_config( 1520 + max_decoding_message_size, 1521 + max_encoding_message_size, 1522 + ); 1523 + let res = grpc.unary(method, req).await; 1524 + Ok(res) 1525 + }; 1526 + Box::pin(fut) 1527 + } 1528 + "/rockbox.v1alpha1.PlaybackService/Resume" => { 1529 + #[allow(non_camel_case_types)] 1530 + struct ResumeSvc<T: PlaybackService>(pub Arc<T>); 1531 + impl< 1532 + T: PlaybackService, 1533 + > tonic::server::UnaryService<super::ResumeRequest> 1534 + for ResumeSvc<T> { 1535 + type Response = super::ResumeResponse; 1536 + type Future = BoxFuture< 1537 + tonic::Response<Self::Response>, 1538 + tonic::Status, 1539 + >; 1540 + fn call( 1541 + &mut self, 1542 + request: tonic::Request<super::ResumeRequest>, 1543 + ) -> Self::Future { 1544 + let inner = Arc::clone(&self.0); 1545 + let fut = async move { 1546 + <T as PlaybackService>::resume(&inner, request).await 1547 + }; 1548 + Box::pin(fut) 1549 + } 1550 + } 1551 + let accept_compression_encodings = self.accept_compression_encodings; 1552 + let send_compression_encodings = self.send_compression_encodings; 1553 + let max_decoding_message_size = self.max_decoding_message_size; 1554 + let max_encoding_message_size = self.max_encoding_message_size; 1555 + let inner = self.inner.clone(); 1556 + let fut = async move { 1557 + let method = ResumeSvc(inner); 1558 + let codec = tonic::codec::ProstCodec::default(); 1559 + let mut grpc = tonic::server::Grpc::new(codec) 1560 + .apply_compression_config( 1561 + accept_compression_encodings, 1562 + send_compression_encodings, 1563 + ) 1564 + .apply_max_message_size_config( 1565 + max_decoding_message_size, 1566 + max_encoding_message_size, 1567 + ); 1568 + let res = grpc.unary(method, req).await; 1569 + Ok(res) 1570 + }; 1571 + Box::pin(fut) 1572 + } 1573 + "/rockbox.v1alpha1.PlaybackService/Next" => { 1574 + #[allow(non_camel_case_types)] 1575 + struct NextSvc<T: PlaybackService>(pub Arc<T>); 1576 + impl< 1577 + T: PlaybackService, 1578 + > tonic::server::UnaryService<super::NextRequest> for NextSvc<T> { 1579 + type Response = super::NextResponse; 1580 + type Future = BoxFuture< 1581 + tonic::Response<Self::Response>, 1582 + tonic::Status, 1583 + >; 1584 + fn call( 1585 + &mut self, 1586 + request: tonic::Request<super::NextRequest>, 1587 + ) -> Self::Future { 1588 + let inner = Arc::clone(&self.0); 1589 + let fut = async move { 1590 + <T as PlaybackService>::next(&inner, request).await 1591 + }; 1592 + Box::pin(fut) 1593 + } 1594 + } 1595 + let accept_compression_encodings = self.accept_compression_encodings; 1596 + let send_compression_encodings = self.send_compression_encodings; 1597 + let max_decoding_message_size = self.max_decoding_message_size; 1598 + let max_encoding_message_size = self.max_encoding_message_size; 1599 + let inner = self.inner.clone(); 1600 + let fut = async move { 1601 + let method = NextSvc(inner); 1602 + let codec = tonic::codec::ProstCodec::default(); 1603 + let mut grpc = tonic::server::Grpc::new(codec) 1604 + .apply_compression_config( 1605 + accept_compression_encodings, 1606 + send_compression_encodings, 1607 + ) 1608 + .apply_max_message_size_config( 1609 + max_decoding_message_size, 1610 + max_encoding_message_size, 1611 + ); 1612 + let res = grpc.unary(method, req).await; 1613 + Ok(res) 1614 + }; 1615 + Box::pin(fut) 1616 + } 1617 + "/rockbox.v1alpha1.PlaybackService/Previous" => { 1618 + #[allow(non_camel_case_types)] 1619 + struct PreviousSvc<T: PlaybackService>(pub Arc<T>); 1620 + impl< 1621 + T: PlaybackService, 1622 + > tonic::server::UnaryService<super::PreviousRequest> 1623 + for PreviousSvc<T> { 1624 + type Response = super::PreviousResponse; 1625 + type Future = BoxFuture< 1626 + tonic::Response<Self::Response>, 1627 + tonic::Status, 1628 + >; 1629 + fn call( 1630 + &mut self, 1631 + request: tonic::Request<super::PreviousRequest>, 1632 + ) -> Self::Future { 1633 + let inner = Arc::clone(&self.0); 1634 + let fut = async move { 1635 + <T as PlaybackService>::previous(&inner, request).await 1636 + }; 1637 + Box::pin(fut) 1638 + } 1639 + } 1640 + let accept_compression_encodings = self.accept_compression_encodings; 1641 + let send_compression_encodings = self.send_compression_encodings; 1642 + let max_decoding_message_size = self.max_decoding_message_size; 1643 + let max_encoding_message_size = self.max_encoding_message_size; 1644 + let inner = self.inner.clone(); 1645 + let fut = async move { 1646 + let method = PreviousSvc(inner); 1647 + let codec = tonic::codec::ProstCodec::default(); 1648 + let mut grpc = tonic::server::Grpc::new(codec) 1649 + .apply_compression_config( 1650 + accept_compression_encodings, 1651 + send_compression_encodings, 1652 + ) 1653 + .apply_max_message_size_config( 1654 + max_decoding_message_size, 1655 + max_encoding_message_size, 1656 + ); 1657 + let res = grpc.unary(method, req).await; 1658 + Ok(res) 1659 + }; 1660 + Box::pin(fut) 1661 + } 1662 + "/rockbox.v1alpha1.PlaybackService/FastForwardRewind" => { 1663 + #[allow(non_camel_case_types)] 1664 + struct FastForwardRewindSvc<T: PlaybackService>(pub Arc<T>); 1665 + impl< 1666 + T: PlaybackService, 1667 + > tonic::server::UnaryService<super::FastForwardRewindRequest> 1668 + for FastForwardRewindSvc<T> { 1669 + type Response = super::FastForwardRewindResponse; 1670 + type Future = BoxFuture< 1671 + tonic::Response<Self::Response>, 1672 + tonic::Status, 1673 + >; 1674 + fn call( 1675 + &mut self, 1676 + request: tonic::Request<super::FastForwardRewindRequest>, 1677 + ) -> Self::Future { 1678 + let inner = Arc::clone(&self.0); 1679 + let fut = async move { 1680 + <T as PlaybackService>::fast_forward_rewind(&inner, request) 1681 + .await 1682 + }; 1683 + Box::pin(fut) 1684 + } 1685 + } 1686 + let accept_compression_encodings = self.accept_compression_encodings; 1687 + let send_compression_encodings = self.send_compression_encodings; 1688 + let max_decoding_message_size = self.max_decoding_message_size; 1689 + let max_encoding_message_size = self.max_encoding_message_size; 1690 + let inner = self.inner.clone(); 1691 + let fut = async move { 1692 + let method = FastForwardRewindSvc(inner); 1693 + let codec = tonic::codec::ProstCodec::default(); 1694 + let mut grpc = tonic::server::Grpc::new(codec) 1695 + .apply_compression_config( 1696 + accept_compression_encodings, 1697 + send_compression_encodings, 1698 + ) 1699 + .apply_max_message_size_config( 1700 + max_decoding_message_size, 1701 + max_encoding_message_size, 1702 + ); 1703 + let res = grpc.unary(method, req).await; 1704 + Ok(res) 1705 + }; 1706 + Box::pin(fut) 1707 + } 1708 + "/rockbox.v1alpha1.PlaybackService/Status" => { 1709 + #[allow(non_camel_case_types)] 1710 + struct StatusSvc<T: PlaybackService>(pub Arc<T>); 1711 + impl< 1712 + T: PlaybackService, 1713 + > tonic::server::UnaryService<super::StatusRequest> 1714 + for StatusSvc<T> { 1715 + type Response = super::StatusResponse; 1716 + type Future = BoxFuture< 1717 + tonic::Response<Self::Response>, 1718 + tonic::Status, 1719 + >; 1720 + fn call( 1721 + &mut self, 1722 + request: tonic::Request<super::StatusRequest>, 1723 + ) -> Self::Future { 1724 + let inner = Arc::clone(&self.0); 1725 + let fut = async move { 1726 + <T as PlaybackService>::status(&inner, request).await 1727 + }; 1728 + Box::pin(fut) 1729 + } 1730 + } 1731 + let accept_compression_encodings = self.accept_compression_encodings; 1732 + let send_compression_encodings = self.send_compression_encodings; 1733 + let max_decoding_message_size = self.max_decoding_message_size; 1734 + let max_encoding_message_size = self.max_encoding_message_size; 1735 + let inner = self.inner.clone(); 1736 + let fut = async move { 1737 + let method = StatusSvc(inner); 1738 + let codec = tonic::codec::ProstCodec::default(); 1739 + let mut grpc = tonic::server::Grpc::new(codec) 1740 + .apply_compression_config( 1741 + accept_compression_encodings, 1742 + send_compression_encodings, 1743 + ) 1744 + .apply_max_message_size_config( 1745 + max_decoding_message_size, 1746 + max_encoding_message_size, 1747 + ); 1748 + let res = grpc.unary(method, req).await; 1749 + Ok(res) 1750 + }; 1751 + Box::pin(fut) 1752 + } 1753 + "/rockbox.v1alpha1.PlaybackService/CurrentTrack" => { 1754 + #[allow(non_camel_case_types)] 1755 + struct CurrentTrackSvc<T: PlaybackService>(pub Arc<T>); 1756 + impl< 1757 + T: PlaybackService, 1758 + > tonic::server::UnaryService<super::CurrentTrackRequest> 1759 + for CurrentTrackSvc<T> { 1760 + type Response = super::CurrentTrackResponse; 1761 + type Future = BoxFuture< 1762 + tonic::Response<Self::Response>, 1763 + tonic::Status, 1764 + >; 1765 + fn call( 1766 + &mut self, 1767 + request: tonic::Request<super::CurrentTrackRequest>, 1768 + ) -> Self::Future { 1769 + let inner = Arc::clone(&self.0); 1770 + let fut = async move { 1771 + <T as PlaybackService>::current_track(&inner, request).await 1772 + }; 1773 + Box::pin(fut) 1774 + } 1775 + } 1776 + let accept_compression_encodings = self.accept_compression_encodings; 1777 + let send_compression_encodings = self.send_compression_encodings; 1778 + let max_decoding_message_size = self.max_decoding_message_size; 1779 + let max_encoding_message_size = self.max_encoding_message_size; 1780 + let inner = self.inner.clone(); 1781 + let fut = async move { 1782 + let method = CurrentTrackSvc(inner); 1783 + let codec = tonic::codec::ProstCodec::default(); 1784 + let mut grpc = tonic::server::Grpc::new(codec) 1785 + .apply_compression_config( 1786 + accept_compression_encodings, 1787 + send_compression_encodings, 1788 + ) 1789 + .apply_max_message_size_config( 1790 + max_decoding_message_size, 1791 + max_encoding_message_size, 1792 + ); 1793 + let res = grpc.unary(method, req).await; 1794 + Ok(res) 1795 + }; 1796 + Box::pin(fut) 1797 + } 1798 + "/rockbox.v1alpha1.PlaybackService/FlushAndReloadTracks" => { 1799 + #[allow(non_camel_case_types)] 1800 + struct FlushAndReloadTracksSvc<T: PlaybackService>(pub Arc<T>); 1801 + impl< 1802 + T: PlaybackService, 1803 + > tonic::server::UnaryService<super::FlushAndReloadTracksRequest> 1804 + for FlushAndReloadTracksSvc<T> { 1805 + type Response = super::FlushAndReloadTracksResponse; 1806 + type Future = BoxFuture< 1807 + tonic::Response<Self::Response>, 1808 + tonic::Status, 1809 + >; 1810 + fn call( 1811 + &mut self, 1812 + request: tonic::Request<super::FlushAndReloadTracksRequest>, 1813 + ) -> Self::Future { 1814 + let inner = Arc::clone(&self.0); 1815 + let fut = async move { 1816 + <T as PlaybackService>::flush_and_reload_tracks( 1817 + &inner, 1818 + request, 1819 + ) 1820 + .await 1821 + }; 1822 + Box::pin(fut) 1823 + } 1824 + } 1825 + let accept_compression_encodings = self.accept_compression_encodings; 1826 + let send_compression_encodings = self.send_compression_encodings; 1827 + let max_decoding_message_size = self.max_decoding_message_size; 1828 + let max_encoding_message_size = self.max_encoding_message_size; 1829 + let inner = self.inner.clone(); 1830 + let fut = async move { 1831 + let method = FlushAndReloadTracksSvc(inner); 1832 + let codec = tonic::codec::ProstCodec::default(); 1833 + let mut grpc = tonic::server::Grpc::new(codec) 1834 + .apply_compression_config( 1835 + accept_compression_encodings, 1836 + send_compression_encodings, 1837 + ) 1838 + .apply_max_message_size_config( 1839 + max_decoding_message_size, 1840 + max_encoding_message_size, 1841 + ); 1842 + let res = grpc.unary(method, req).await; 1843 + Ok(res) 1844 + }; 1845 + Box::pin(fut) 1846 + } 1847 + "/rockbox.v1alpha1.PlaybackService/GetFilePosition" => { 1848 + #[allow(non_camel_case_types)] 1849 + struct GetFilePositionSvc<T: PlaybackService>(pub Arc<T>); 1850 + impl< 1851 + T: PlaybackService, 1852 + > tonic::server::UnaryService<super::GetFilePositionRequest> 1853 + for GetFilePositionSvc<T> { 1854 + type Response = super::GetFilePositionResponse; 1855 + type Future = BoxFuture< 1856 + tonic::Response<Self::Response>, 1857 + tonic::Status, 1858 + >; 1859 + fn call( 1860 + &mut self, 1861 + request: tonic::Request<super::GetFilePositionRequest>, 1862 + ) -> Self::Future { 1863 + let inner = Arc::clone(&self.0); 1864 + let fut = async move { 1865 + <T as PlaybackService>::get_file_position(&inner, request) 1866 + .await 1867 + }; 1868 + Box::pin(fut) 1869 + } 1870 + } 1871 + let accept_compression_encodings = self.accept_compression_encodings; 1872 + let send_compression_encodings = self.send_compression_encodings; 1873 + let max_decoding_message_size = self.max_decoding_message_size; 1874 + let max_encoding_message_size = self.max_encoding_message_size; 1875 + let inner = self.inner.clone(); 1876 + let fut = async move { 1877 + let method = GetFilePositionSvc(inner); 1878 + let codec = tonic::codec::ProstCodec::default(); 1879 + let mut grpc = tonic::server::Grpc::new(codec) 1880 + .apply_compression_config( 1881 + accept_compression_encodings, 1882 + send_compression_encodings, 1883 + ) 1884 + .apply_max_message_size_config( 1885 + max_decoding_message_size, 1886 + max_encoding_message_size, 1887 + ); 1888 + let res = grpc.unary(method, req).await; 1889 + Ok(res) 1890 + }; 1891 + Box::pin(fut) 1892 + } 1893 + "/rockbox.v1alpha1.PlaybackService/HardStop" => { 1894 + #[allow(non_camel_case_types)] 1895 + struct HardStopSvc<T: PlaybackService>(pub Arc<T>); 1896 + impl< 1897 + T: PlaybackService, 1898 + > tonic::server::UnaryService<super::HardStopRequest> 1899 + for HardStopSvc<T> { 1900 + type Response = super::HardStopResponse; 1901 + type Future = BoxFuture< 1902 + tonic::Response<Self::Response>, 1903 + tonic::Status, 1904 + >; 1905 + fn call( 1906 + &mut self, 1907 + request: tonic::Request<super::HardStopRequest>, 1908 + ) -> Self::Future { 1909 + let inner = Arc::clone(&self.0); 1910 + let fut = async move { 1911 + <T as PlaybackService>::hard_stop(&inner, request).await 1912 + }; 1913 + Box::pin(fut) 1914 + } 1915 + } 1916 + let accept_compression_encodings = self.accept_compression_encodings; 1917 + let send_compression_encodings = self.send_compression_encodings; 1918 + let max_decoding_message_size = self.max_decoding_message_size; 1919 + let max_encoding_message_size = self.max_encoding_message_size; 1920 + let inner = self.inner.clone(); 1921 + let fut = async move { 1922 + let method = HardStopSvc(inner); 1923 + let codec = tonic::codec::ProstCodec::default(); 1924 + let mut grpc = tonic::server::Grpc::new(codec) 1925 + .apply_compression_config( 1926 + accept_compression_encodings, 1927 + send_compression_encodings, 1928 + ) 1929 + .apply_max_message_size_config( 1930 + max_decoding_message_size, 1931 + max_encoding_message_size, 1932 + ); 1933 + let res = grpc.unary(method, req).await; 1934 + Ok(res) 1935 + }; 1936 + Box::pin(fut) 1937 + } 1938 + _ => { 1939 + Box::pin(async move { 1940 + Ok( 1941 + http::Response::builder() 1942 + .status(200) 1943 + .header("grpc-status", tonic::Code::Unimplemented as i32) 1944 + .header( 1945 + http::header::CONTENT_TYPE, 1946 + tonic::metadata::GRPC_CONTENT_TYPE, 1947 + ) 1948 + .body(empty_body()) 1949 + .unwrap(), 1950 + ) 1951 + }) 1952 + } 1953 + } 1954 + } 1955 + } 1956 + impl<T> Clone for PlaybackServiceServer<T> { 1957 + fn clone(&self) -> Self { 1958 + let inner = self.inner.clone(); 1959 + Self { 1960 + inner, 1961 + accept_compression_encodings: self.accept_compression_encodings, 1962 + send_compression_encodings: self.send_compression_encodings, 1963 + max_decoding_message_size: self.max_decoding_message_size, 1964 + max_encoding_message_size: self.max_encoding_message_size, 1965 + } 1966 + } 1967 + } 1968 + /// Generated gRPC service name 1969 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.PlaybackService"; 1970 + impl<T> tonic::server::NamedService for PlaybackServiceServer<T> { 1971 + const NAME: &'static str = SERVICE_NAME; 1972 + } 1973 + } 1974 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1975 + pub struct GetCurrentRequest {} 1976 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1977 + pub struct GetCurrentResponse {} 1978 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1979 + pub struct GetResumeInfoRequest {} 1980 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1981 + pub struct GetResumeInfoResponse {} 1982 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1983 + pub struct GetTrackInfoRequest {} 1984 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1985 + pub struct GetTrackInfoResponse {} 1986 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1987 + pub struct GetFirstIndexRequest {} 1988 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1989 + pub struct GetFirstIndexResponse {} 1990 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1991 + pub struct GetDisplayIndexRequest {} 1992 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1993 + pub struct GetDisplayIndexResponse {} 1994 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1995 + pub struct AmountRequest {} 1996 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1997 + pub struct AmountResponse {} 1998 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 1999 + pub struct PlaylistResumeRequest {} 2000 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2001 + pub struct PlaylistResumeResponse {} 2002 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2003 + pub struct ResumeTrackRequest { 2004 + #[prost(int32, tag = "1")] 2005 + pub start_index: i32, 2006 + #[prost(uint32, tag = "2")] 2007 + pub crc: u32, 2008 + #[prost(uint64, tag = "3")] 2009 + pub elapsed: u64, 2010 + #[prost(uint64, tag = "4")] 2011 + pub offset: u64, 2012 + } 2013 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2014 + pub struct ResumeTrackResponse {} 2015 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2016 + pub struct SetModifiedRequest {} 2017 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2018 + pub struct SetModifiedResponse {} 2019 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2020 + pub struct StartRequest {} 2021 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2022 + pub struct StartResponse {} 2023 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2024 + pub struct SyncRequest {} 2025 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2026 + pub struct SyncResponse {} 2027 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2028 + pub struct RemoveAllTracksRequest {} 2029 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2030 + pub struct RemoveAllTracksResponse {} 2031 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2032 + pub struct CreatePlaylistRequest {} 2033 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2034 + pub struct CreatePlaylistResponse {} 2035 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2036 + pub struct InsertTrackRequest {} 2037 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2038 + pub struct InsertTrackResponse {} 2039 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2040 + pub struct InsertDirectoryRequest {} 2041 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2042 + pub struct InsertDirectoryResponse {} 2043 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2044 + pub struct InsertPlaylistRequest {} 2045 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2046 + pub struct InsertPlaylistResponse {} 2047 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2048 + pub struct ShufflePlaylistRequest {} 2049 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2050 + pub struct ShufflePlaylistResponse {} 2051 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2052 + pub struct WarnOnPlaylistEraseRequest {} 2053 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 2054 + pub struct WarnOnPlaylistEraseResponse {} 2055 + /// Generated client implementations. 2056 + pub mod playlist_service_client { 2057 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 2058 + use tonic::codegen::*; 2059 + use tonic::codegen::http::Uri; 2060 + #[derive(Debug, Clone)] 2061 + pub struct PlaylistServiceClient<T> { 2062 + inner: tonic::client::Grpc<T>, 2063 + } 2064 + impl PlaylistServiceClient<tonic::transport::Channel> { 2065 + /// Attempt to create a new client by connecting to a given endpoint. 2066 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 2067 + where 2068 + D: TryInto<tonic::transport::Endpoint>, 2069 + D::Error: Into<StdError>, 2070 + { 2071 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 2072 + Ok(Self::new(conn)) 2073 + } 2074 + } 2075 + impl<T> PlaylistServiceClient<T> 2076 + where 2077 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 2078 + T::Error: Into<StdError>, 2079 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 2080 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 2081 + { 2082 + pub fn new(inner: T) -> Self { 2083 + let inner = tonic::client::Grpc::new(inner); 2084 + Self { inner } 2085 + } 2086 + pub fn with_origin(inner: T, origin: Uri) -> Self { 2087 + let inner = tonic::client::Grpc::with_origin(inner, origin); 2088 + Self { inner } 2089 + } 2090 + pub fn with_interceptor<F>( 2091 + inner: T, 2092 + interceptor: F, 2093 + ) -> PlaylistServiceClient<InterceptedService<T, F>> 2094 + where 2095 + F: tonic::service::Interceptor, 2096 + T::ResponseBody: Default, 2097 + T: tonic::codegen::Service< 2098 + http::Request<tonic::body::BoxBody>, 2099 + Response = http::Response< 2100 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 2101 + >, 2102 + >, 2103 + <T as tonic::codegen::Service< 2104 + http::Request<tonic::body::BoxBody>, 2105 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 2106 + { 2107 + PlaylistServiceClient::new(InterceptedService::new(inner, interceptor)) 2108 + } 2109 + /// Compress requests with the given encoding. 2110 + /// 2111 + /// This requires the server to support it otherwise it might respond with an 2112 + /// error. 2113 + #[must_use] 2114 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 2115 + self.inner = self.inner.send_compressed(encoding); 2116 + self 2117 + } 2118 + /// Enable decompressing responses. 2119 + #[must_use] 2120 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 2121 + self.inner = self.inner.accept_compressed(encoding); 2122 + self 2123 + } 2124 + /// Limits the maximum size of a decoded message. 2125 + /// 2126 + /// Default: `4MB` 2127 + #[must_use] 2128 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 2129 + self.inner = self.inner.max_decoding_message_size(limit); 2130 + self 2131 + } 2132 + /// Limits the maximum size of an encoded message. 2133 + /// 2134 + /// Default: `usize::MAX` 2135 + #[must_use] 2136 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 2137 + self.inner = self.inner.max_encoding_message_size(limit); 2138 + self 2139 + } 2140 + pub async fn get_current( 2141 + &mut self, 2142 + request: impl tonic::IntoRequest<super::GetCurrentRequest>, 2143 + ) -> std::result::Result< 2144 + tonic::Response<super::GetCurrentResponse>, 2145 + tonic::Status, 2146 + > { 2147 + self.inner 2148 + .ready() 2149 + .await 2150 + .map_err(|e| { 2151 + tonic::Status::new( 2152 + tonic::Code::Unknown, 2153 + format!("Service was not ready: {}", e.into()), 2154 + ) 2155 + })?; 2156 + let codec = tonic::codec::ProstCodec::default(); 2157 + let path = http::uri::PathAndQuery::from_static( 2158 + "/rockbox.v1alpha1.PlaylistService/GetCurrent", 2159 + ); 2160 + let mut req = request.into_request(); 2161 + req.extensions_mut() 2162 + .insert( 2163 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetCurrent"), 2164 + ); 2165 + self.inner.unary(req, path, codec).await 2166 + } 2167 + pub async fn get_resume_info( 2168 + &mut self, 2169 + request: impl tonic::IntoRequest<super::GetResumeInfoRequest>, 2170 + ) -> std::result::Result< 2171 + tonic::Response<super::GetResumeInfoResponse>, 2172 + tonic::Status, 2173 + > { 2174 + self.inner 2175 + .ready() 2176 + .await 2177 + .map_err(|e| { 2178 + tonic::Status::new( 2179 + tonic::Code::Unknown, 2180 + format!("Service was not ready: {}", e.into()), 2181 + ) 2182 + })?; 2183 + let codec = tonic::codec::ProstCodec::default(); 2184 + let path = http::uri::PathAndQuery::from_static( 2185 + "/rockbox.v1alpha1.PlaylistService/GetResumeInfo", 2186 + ); 2187 + let mut req = request.into_request(); 2188 + req.extensions_mut() 2189 + .insert( 2190 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetResumeInfo"), 2191 + ); 2192 + self.inner.unary(req, path, codec).await 2193 + } 2194 + pub async fn get_track_info( 2195 + &mut self, 2196 + request: impl tonic::IntoRequest<super::GetTrackInfoRequest>, 2197 + ) -> std::result::Result< 2198 + tonic::Response<super::GetTrackInfoResponse>, 2199 + tonic::Status, 2200 + > { 2201 + self.inner 2202 + .ready() 2203 + .await 2204 + .map_err(|e| { 2205 + tonic::Status::new( 2206 + tonic::Code::Unknown, 2207 + format!("Service was not ready: {}", e.into()), 2208 + ) 2209 + })?; 2210 + let codec = tonic::codec::ProstCodec::default(); 2211 + let path = http::uri::PathAndQuery::from_static( 2212 + "/rockbox.v1alpha1.PlaylistService/GetTrackInfo", 2213 + ); 2214 + let mut req = request.into_request(); 2215 + req.extensions_mut() 2216 + .insert( 2217 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetTrackInfo"), 2218 + ); 2219 + self.inner.unary(req, path, codec).await 2220 + } 2221 + pub async fn get_first_index( 2222 + &mut self, 2223 + request: impl tonic::IntoRequest<super::GetFirstIndexRequest>, 2224 + ) -> std::result::Result< 2225 + tonic::Response<super::GetFirstIndexResponse>, 2226 + tonic::Status, 2227 + > { 2228 + self.inner 2229 + .ready() 2230 + .await 2231 + .map_err(|e| { 2232 + tonic::Status::new( 2233 + tonic::Code::Unknown, 2234 + format!("Service was not ready: {}", e.into()), 2235 + ) 2236 + })?; 2237 + let codec = tonic::codec::ProstCodec::default(); 2238 + let path = http::uri::PathAndQuery::from_static( 2239 + "/rockbox.v1alpha1.PlaylistService/GetFirstIndex", 2240 + ); 2241 + let mut req = request.into_request(); 2242 + req.extensions_mut() 2243 + .insert( 2244 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetFirstIndex"), 2245 + ); 2246 + self.inner.unary(req, path, codec).await 2247 + } 2248 + pub async fn get_display_index( 2249 + &mut self, 2250 + request: impl tonic::IntoRequest<super::GetDisplayIndexRequest>, 2251 + ) -> std::result::Result< 2252 + tonic::Response<super::GetDisplayIndexResponse>, 2253 + tonic::Status, 2254 + > { 2255 + self.inner 2256 + .ready() 2257 + .await 2258 + .map_err(|e| { 2259 + tonic::Status::new( 2260 + tonic::Code::Unknown, 2261 + format!("Service was not ready: {}", e.into()), 2262 + ) 2263 + })?; 2264 + let codec = tonic::codec::ProstCodec::default(); 2265 + let path = http::uri::PathAndQuery::from_static( 2266 + "/rockbox.v1alpha1.PlaylistService/GetDisplayIndex", 2267 + ); 2268 + let mut req = request.into_request(); 2269 + req.extensions_mut() 2270 + .insert( 2271 + GrpcMethod::new( 2272 + "rockbox.v1alpha1.PlaylistService", 2273 + "GetDisplayIndex", 2274 + ), 2275 + ); 2276 + self.inner.unary(req, path, codec).await 2277 + } 2278 + pub async fn amount( 2279 + &mut self, 2280 + request: impl tonic::IntoRequest<super::AmountRequest>, 2281 + ) -> std::result::Result<tonic::Response<super::AmountResponse>, tonic::Status> { 2282 + self.inner 2283 + .ready() 2284 + .await 2285 + .map_err(|e| { 2286 + tonic::Status::new( 2287 + tonic::Code::Unknown, 2288 + format!("Service was not ready: {}", e.into()), 2289 + ) 2290 + })?; 2291 + let codec = tonic::codec::ProstCodec::default(); 2292 + let path = http::uri::PathAndQuery::from_static( 2293 + "/rockbox.v1alpha1.PlaylistService/Amount", 2294 + ); 2295 + let mut req = request.into_request(); 2296 + req.extensions_mut() 2297 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "Amount")); 2298 + self.inner.unary(req, path, codec).await 2299 + } 2300 + pub async fn playlist_resume( 2301 + &mut self, 2302 + request: impl tonic::IntoRequest<super::PlaylistResumeRequest>, 2303 + ) -> std::result::Result< 2304 + tonic::Response<super::PlaylistResumeResponse>, 2305 + tonic::Status, 2306 + > { 2307 + self.inner 2308 + .ready() 2309 + .await 2310 + .map_err(|e| { 2311 + tonic::Status::new( 2312 + tonic::Code::Unknown, 2313 + format!("Service was not ready: {}", e.into()), 2314 + ) 2315 + })?; 2316 + let codec = tonic::codec::ProstCodec::default(); 2317 + let path = http::uri::PathAndQuery::from_static( 2318 + "/rockbox.v1alpha1.PlaylistService/PlaylistResume", 2319 + ); 2320 + let mut req = request.into_request(); 2321 + req.extensions_mut() 2322 + .insert( 2323 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "PlaylistResume"), 2324 + ); 2325 + self.inner.unary(req, path, codec).await 2326 + } 2327 + pub async fn resume_track( 2328 + &mut self, 2329 + request: impl tonic::IntoRequest<super::ResumeTrackRequest>, 2330 + ) -> std::result::Result< 2331 + tonic::Response<super::ResumeTrackResponse>, 2332 + tonic::Status, 2333 + > { 2334 + self.inner 2335 + .ready() 2336 + .await 2337 + .map_err(|e| { 2338 + tonic::Status::new( 2339 + tonic::Code::Unknown, 2340 + format!("Service was not ready: {}", e.into()), 2341 + ) 2342 + })?; 2343 + let codec = tonic::codec::ProstCodec::default(); 2344 + let path = http::uri::PathAndQuery::from_static( 2345 + "/rockbox.v1alpha1.PlaylistService/ResumeTrack", 2346 + ); 2347 + let mut req = request.into_request(); 2348 + req.extensions_mut() 2349 + .insert( 2350 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "ResumeTrack"), 2351 + ); 2352 + self.inner.unary(req, path, codec).await 2353 + } 2354 + pub async fn set_modified( 2355 + &mut self, 2356 + request: impl tonic::IntoRequest<super::SetModifiedRequest>, 2357 + ) -> std::result::Result< 2358 + tonic::Response<super::SetModifiedResponse>, 2359 + tonic::Status, 2360 + > { 2361 + self.inner 2362 + .ready() 2363 + .await 2364 + .map_err(|e| { 2365 + tonic::Status::new( 2366 + tonic::Code::Unknown, 2367 + format!("Service was not ready: {}", e.into()), 2368 + ) 2369 + })?; 2370 + let codec = tonic::codec::ProstCodec::default(); 2371 + let path = http::uri::PathAndQuery::from_static( 2372 + "/rockbox.v1alpha1.PlaylistService/SetModified", 2373 + ); 2374 + let mut req = request.into_request(); 2375 + req.extensions_mut() 2376 + .insert( 2377 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "SetModified"), 2378 + ); 2379 + self.inner.unary(req, path, codec).await 2380 + } 2381 + pub async fn start( 2382 + &mut self, 2383 + request: impl tonic::IntoRequest<super::StartRequest>, 2384 + ) -> std::result::Result<tonic::Response<super::StartResponse>, tonic::Status> { 2385 + self.inner 2386 + .ready() 2387 + .await 2388 + .map_err(|e| { 2389 + tonic::Status::new( 2390 + tonic::Code::Unknown, 2391 + format!("Service was not ready: {}", e.into()), 2392 + ) 2393 + })?; 2394 + let codec = tonic::codec::ProstCodec::default(); 2395 + let path = http::uri::PathAndQuery::from_static( 2396 + "/rockbox.v1alpha1.PlaylistService/Start", 2397 + ); 2398 + let mut req = request.into_request(); 2399 + req.extensions_mut() 2400 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "Start")); 2401 + self.inner.unary(req, path, codec).await 2402 + } 2403 + pub async fn sync( 2404 + &mut self, 2405 + request: impl tonic::IntoRequest<super::SyncRequest>, 2406 + ) -> std::result::Result<tonic::Response<super::SyncResponse>, tonic::Status> { 2407 + self.inner 2408 + .ready() 2409 + .await 2410 + .map_err(|e| { 2411 + tonic::Status::new( 2412 + tonic::Code::Unknown, 2413 + format!("Service was not ready: {}", e.into()), 2414 + ) 2415 + })?; 2416 + let codec = tonic::codec::ProstCodec::default(); 2417 + let path = http::uri::PathAndQuery::from_static( 2418 + "/rockbox.v1alpha1.PlaylistService/Sync", 2419 + ); 2420 + let mut req = request.into_request(); 2421 + req.extensions_mut() 2422 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "Sync")); 2423 + self.inner.unary(req, path, codec).await 2424 + } 2425 + pub async fn remove_all_tracks( 2426 + &mut self, 2427 + request: impl tonic::IntoRequest<super::RemoveAllTracksRequest>, 2428 + ) -> std::result::Result< 2429 + tonic::Response<super::RemoveAllTracksResponse>, 2430 + tonic::Status, 2431 + > { 2432 + self.inner 2433 + .ready() 2434 + .await 2435 + .map_err(|e| { 2436 + tonic::Status::new( 2437 + tonic::Code::Unknown, 2438 + format!("Service was not ready: {}", e.into()), 2439 + ) 2440 + })?; 2441 + let codec = tonic::codec::ProstCodec::default(); 2442 + let path = http::uri::PathAndQuery::from_static( 2443 + "/rockbox.v1alpha1.PlaylistService/RemoveAllTracks", 2444 + ); 2445 + let mut req = request.into_request(); 2446 + req.extensions_mut() 2447 + .insert( 2448 + GrpcMethod::new( 2449 + "rockbox.v1alpha1.PlaylistService", 2450 + "RemoveAllTracks", 2451 + ), 2452 + ); 2453 + self.inner.unary(req, path, codec).await 2454 + } 2455 + pub async fn create_playlist( 2456 + &mut self, 2457 + request: impl tonic::IntoRequest<super::CreatePlaylistRequest>, 2458 + ) -> std::result::Result< 2459 + tonic::Response<super::CreatePlaylistResponse>, 2460 + tonic::Status, 2461 + > { 2462 + self.inner 2463 + .ready() 2464 + .await 2465 + .map_err(|e| { 2466 + tonic::Status::new( 2467 + tonic::Code::Unknown, 2468 + format!("Service was not ready: {}", e.into()), 2469 + ) 2470 + })?; 2471 + let codec = tonic::codec::ProstCodec::default(); 2472 + let path = http::uri::PathAndQuery::from_static( 2473 + "/rockbox.v1alpha1.PlaylistService/CreatePlaylist", 2474 + ); 2475 + let mut req = request.into_request(); 2476 + req.extensions_mut() 2477 + .insert( 2478 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "CreatePlaylist"), 2479 + ); 2480 + self.inner.unary(req, path, codec).await 2481 + } 2482 + pub async fn insert_track( 2483 + &mut self, 2484 + request: impl tonic::IntoRequest<super::InsertTrackRequest>, 2485 + ) -> std::result::Result< 2486 + tonic::Response<super::InsertTrackResponse>, 2487 + tonic::Status, 2488 + > { 2489 + self.inner 2490 + .ready() 2491 + .await 2492 + .map_err(|e| { 2493 + tonic::Status::new( 2494 + tonic::Code::Unknown, 2495 + format!("Service was not ready: {}", e.into()), 2496 + ) 2497 + })?; 2498 + let codec = tonic::codec::ProstCodec::default(); 2499 + let path = http::uri::PathAndQuery::from_static( 2500 + "/rockbox.v1alpha1.PlaylistService/InsertTrack", 2501 + ); 2502 + let mut req = request.into_request(); 2503 + req.extensions_mut() 2504 + .insert( 2505 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "InsertTrack"), 2506 + ); 2507 + self.inner.unary(req, path, codec).await 2508 + } 2509 + pub async fn insert_directory( 2510 + &mut self, 2511 + request: impl tonic::IntoRequest<super::InsertDirectoryRequest>, 2512 + ) -> std::result::Result< 2513 + tonic::Response<super::InsertDirectoryResponse>, 2514 + tonic::Status, 2515 + > { 2516 + self.inner 2517 + .ready() 2518 + .await 2519 + .map_err(|e| { 2520 + tonic::Status::new( 2521 + tonic::Code::Unknown, 2522 + format!("Service was not ready: {}", e.into()), 2523 + ) 2524 + })?; 2525 + let codec = tonic::codec::ProstCodec::default(); 2526 + let path = http::uri::PathAndQuery::from_static( 2527 + "/rockbox.v1alpha1.PlaylistService/InsertDirectory", 2528 + ); 2529 + let mut req = request.into_request(); 2530 + req.extensions_mut() 2531 + .insert( 2532 + GrpcMethod::new( 2533 + "rockbox.v1alpha1.PlaylistService", 2534 + "InsertDirectory", 2535 + ), 2536 + ); 2537 + self.inner.unary(req, path, codec).await 2538 + } 2539 + pub async fn insert_playlist( 2540 + &mut self, 2541 + request: impl tonic::IntoRequest<super::InsertPlaylistRequest>, 2542 + ) -> std::result::Result< 2543 + tonic::Response<super::InsertPlaylistResponse>, 2544 + tonic::Status, 2545 + > { 2546 + self.inner 2547 + .ready() 2548 + .await 2549 + .map_err(|e| { 2550 + tonic::Status::new( 2551 + tonic::Code::Unknown, 2552 + format!("Service was not ready: {}", e.into()), 2553 + ) 2554 + })?; 2555 + let codec = tonic::codec::ProstCodec::default(); 2556 + let path = http::uri::PathAndQuery::from_static( 2557 + "/rockbox.v1alpha1.PlaylistService/InsertPlaylist", 2558 + ); 2559 + let mut req = request.into_request(); 2560 + req.extensions_mut() 2561 + .insert( 2562 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "InsertPlaylist"), 2563 + ); 2564 + self.inner.unary(req, path, codec).await 2565 + } 2566 + pub async fn shuffle_playlist( 2567 + &mut self, 2568 + request: impl tonic::IntoRequest<super::ShufflePlaylistRequest>, 2569 + ) -> std::result::Result< 2570 + tonic::Response<super::ShufflePlaylistResponse>, 2571 + tonic::Status, 2572 + > { 2573 + self.inner 2574 + .ready() 2575 + .await 2576 + .map_err(|e| { 2577 + tonic::Status::new( 2578 + tonic::Code::Unknown, 2579 + format!("Service was not ready: {}", e.into()), 2580 + ) 2581 + })?; 2582 + let codec = tonic::codec::ProstCodec::default(); 2583 + let path = http::uri::PathAndQuery::from_static( 2584 + "/rockbox.v1alpha1.PlaylistService/ShufflePlaylist", 2585 + ); 2586 + let mut req = request.into_request(); 2587 + req.extensions_mut() 2588 + .insert( 2589 + GrpcMethod::new( 2590 + "rockbox.v1alpha1.PlaylistService", 2591 + "ShufflePlaylist", 2592 + ), 2593 + ); 2594 + self.inner.unary(req, path, codec).await 2595 + } 2596 + pub async fn warn_on_playlist_erase( 2597 + &mut self, 2598 + request: impl tonic::IntoRequest<super::WarnOnPlaylistEraseRequest>, 2599 + ) -> std::result::Result< 2600 + tonic::Response<super::WarnOnPlaylistEraseResponse>, 2601 + tonic::Status, 2602 + > { 2603 + self.inner 2604 + .ready() 2605 + .await 2606 + .map_err(|e| { 2607 + tonic::Status::new( 2608 + tonic::Code::Unknown, 2609 + format!("Service was not ready: {}", e.into()), 2610 + ) 2611 + })?; 2612 + let codec = tonic::codec::ProstCodec::default(); 2613 + let path = http::uri::PathAndQuery::from_static( 2614 + "/rockbox.v1alpha1.PlaylistService/WarnOnPlaylistErase", 2615 + ); 2616 + let mut req = request.into_request(); 2617 + req.extensions_mut() 2618 + .insert( 2619 + GrpcMethod::new( 2620 + "rockbox.v1alpha1.PlaylistService", 2621 + "WarnOnPlaylistErase", 2622 + ), 2623 + ); 2624 + self.inner.unary(req, path, codec).await 2625 + } 2626 + } 2627 + } 2628 + /// Generated server implementations. 2629 + pub mod playlist_service_server { 2630 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 2631 + use tonic::codegen::*; 2632 + /// Generated trait containing gRPC methods that should be implemented for use with PlaylistServiceServer. 2633 + #[async_trait] 2634 + pub trait PlaylistService: std::marker::Send + std::marker::Sync + 'static { 2635 + async fn get_current( 2636 + &self, 2637 + request: tonic::Request<super::GetCurrentRequest>, 2638 + ) -> std::result::Result< 2639 + tonic::Response<super::GetCurrentResponse>, 2640 + tonic::Status, 2641 + >; 2642 + async fn get_resume_info( 2643 + &self, 2644 + request: tonic::Request<super::GetResumeInfoRequest>, 2645 + ) -> std::result::Result< 2646 + tonic::Response<super::GetResumeInfoResponse>, 2647 + tonic::Status, 2648 + >; 2649 + async fn get_track_info( 2650 + &self, 2651 + request: tonic::Request<super::GetTrackInfoRequest>, 2652 + ) -> std::result::Result< 2653 + tonic::Response<super::GetTrackInfoResponse>, 2654 + tonic::Status, 2655 + >; 2656 + async fn get_first_index( 2657 + &self, 2658 + request: tonic::Request<super::GetFirstIndexRequest>, 2659 + ) -> std::result::Result< 2660 + tonic::Response<super::GetFirstIndexResponse>, 2661 + tonic::Status, 2662 + >; 2663 + async fn get_display_index( 2664 + &self, 2665 + request: tonic::Request<super::GetDisplayIndexRequest>, 2666 + ) -> std::result::Result< 2667 + tonic::Response<super::GetDisplayIndexResponse>, 2668 + tonic::Status, 2669 + >; 2670 + async fn amount( 2671 + &self, 2672 + request: tonic::Request<super::AmountRequest>, 2673 + ) -> std::result::Result<tonic::Response<super::AmountResponse>, tonic::Status>; 2674 + async fn playlist_resume( 2675 + &self, 2676 + request: tonic::Request<super::PlaylistResumeRequest>, 2677 + ) -> std::result::Result< 2678 + tonic::Response<super::PlaylistResumeResponse>, 2679 + tonic::Status, 2680 + >; 2681 + async fn resume_track( 2682 + &self, 2683 + request: tonic::Request<super::ResumeTrackRequest>, 2684 + ) -> std::result::Result< 2685 + tonic::Response<super::ResumeTrackResponse>, 2686 + tonic::Status, 2687 + >; 2688 + async fn set_modified( 2689 + &self, 2690 + request: tonic::Request<super::SetModifiedRequest>, 2691 + ) -> std::result::Result< 2692 + tonic::Response<super::SetModifiedResponse>, 2693 + tonic::Status, 2694 + >; 2695 + async fn start( 2696 + &self, 2697 + request: tonic::Request<super::StartRequest>, 2698 + ) -> std::result::Result<tonic::Response<super::StartResponse>, tonic::Status>; 2699 + async fn sync( 2700 + &self, 2701 + request: tonic::Request<super::SyncRequest>, 2702 + ) -> std::result::Result<tonic::Response<super::SyncResponse>, tonic::Status>; 2703 + async fn remove_all_tracks( 2704 + &self, 2705 + request: tonic::Request<super::RemoveAllTracksRequest>, 2706 + ) -> std::result::Result< 2707 + tonic::Response<super::RemoveAllTracksResponse>, 2708 + tonic::Status, 2709 + >; 2710 + async fn create_playlist( 2711 + &self, 2712 + request: tonic::Request<super::CreatePlaylistRequest>, 2713 + ) -> std::result::Result< 2714 + tonic::Response<super::CreatePlaylistResponse>, 2715 + tonic::Status, 2716 + >; 2717 + async fn insert_track( 2718 + &self, 2719 + request: tonic::Request<super::InsertTrackRequest>, 2720 + ) -> std::result::Result< 2721 + tonic::Response<super::InsertTrackResponse>, 2722 + tonic::Status, 2723 + >; 2724 + async fn insert_directory( 2725 + &self, 2726 + request: tonic::Request<super::InsertDirectoryRequest>, 2727 + ) -> std::result::Result< 2728 + tonic::Response<super::InsertDirectoryResponse>, 2729 + tonic::Status, 2730 + >; 2731 + async fn insert_playlist( 2732 + &self, 2733 + request: tonic::Request<super::InsertPlaylistRequest>, 2734 + ) -> std::result::Result< 2735 + tonic::Response<super::InsertPlaylistResponse>, 2736 + tonic::Status, 2737 + >; 2738 + async fn shuffle_playlist( 2739 + &self, 2740 + request: tonic::Request<super::ShufflePlaylistRequest>, 2741 + ) -> std::result::Result< 2742 + tonic::Response<super::ShufflePlaylistResponse>, 2743 + tonic::Status, 2744 + >; 2745 + async fn warn_on_playlist_erase( 2746 + &self, 2747 + request: tonic::Request<super::WarnOnPlaylistEraseRequest>, 2748 + ) -> std::result::Result< 2749 + tonic::Response<super::WarnOnPlaylistEraseResponse>, 2750 + tonic::Status, 2751 + >; 2752 + } 2753 + #[derive(Debug)] 2754 + pub struct PlaylistServiceServer<T> { 2755 + inner: Arc<T>, 2756 + accept_compression_encodings: EnabledCompressionEncodings, 2757 + send_compression_encodings: EnabledCompressionEncodings, 2758 + max_decoding_message_size: Option<usize>, 2759 + max_encoding_message_size: Option<usize>, 2760 + } 2761 + impl<T> PlaylistServiceServer<T> { 2762 + pub fn new(inner: T) -> Self { 2763 + Self::from_arc(Arc::new(inner)) 2764 + } 2765 + pub fn from_arc(inner: Arc<T>) -> Self { 2766 + Self { 2767 + inner, 2768 + accept_compression_encodings: Default::default(), 2769 + send_compression_encodings: Default::default(), 2770 + max_decoding_message_size: None, 2771 + max_encoding_message_size: None, 2772 + } 2773 + } 2774 + pub fn with_interceptor<F>( 2775 + inner: T, 2776 + interceptor: F, 2777 + ) -> InterceptedService<Self, F> 2778 + where 2779 + F: tonic::service::Interceptor, 2780 + { 2781 + InterceptedService::new(Self::new(inner), interceptor) 2782 + } 2783 + /// Enable decompressing requests with the given encoding. 2784 + #[must_use] 2785 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 2786 + self.accept_compression_encodings.enable(encoding); 2787 + self 2788 + } 2789 + /// Compress responses with the given encoding, if the client supports it. 2790 + #[must_use] 2791 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 2792 + self.send_compression_encodings.enable(encoding); 2793 + self 2794 + } 2795 + /// Limits the maximum size of a decoded message. 2796 + /// 2797 + /// Default: `4MB` 2798 + #[must_use] 2799 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 2800 + self.max_decoding_message_size = Some(limit); 2801 + self 2802 + } 2803 + /// Limits the maximum size of an encoded message. 2804 + /// 2805 + /// Default: `usize::MAX` 2806 + #[must_use] 2807 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 2808 + self.max_encoding_message_size = Some(limit); 2809 + self 2810 + } 2811 + } 2812 + impl<T, B> tonic::codegen::Service<http::Request<B>> for PlaylistServiceServer<T> 2813 + where 2814 + T: PlaylistService, 2815 + B: Body + std::marker::Send + 'static, 2816 + B::Error: Into<StdError> + std::marker::Send + 'static, 2817 + { 2818 + type Response = http::Response<tonic::body::BoxBody>; 2819 + type Error = std::convert::Infallible; 2820 + type Future = BoxFuture<Self::Response, Self::Error>; 2821 + fn poll_ready( 2822 + &mut self, 2823 + _cx: &mut Context<'_>, 2824 + ) -> Poll<std::result::Result<(), Self::Error>> { 2825 + Poll::Ready(Ok(())) 2826 + } 2827 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 2828 + match req.uri().path() { 2829 + "/rockbox.v1alpha1.PlaylistService/GetCurrent" => { 2830 + #[allow(non_camel_case_types)] 2831 + struct GetCurrentSvc<T: PlaylistService>(pub Arc<T>); 2832 + impl< 2833 + T: PlaylistService, 2834 + > tonic::server::UnaryService<super::GetCurrentRequest> 2835 + for GetCurrentSvc<T> { 2836 + type Response = super::GetCurrentResponse; 2837 + type Future = BoxFuture< 2838 + tonic::Response<Self::Response>, 2839 + tonic::Status, 2840 + >; 2841 + fn call( 2842 + &mut self, 2843 + request: tonic::Request<super::GetCurrentRequest>, 2844 + ) -> Self::Future { 2845 + let inner = Arc::clone(&self.0); 2846 + let fut = async move { 2847 + <T as PlaylistService>::get_current(&inner, request).await 2848 + }; 2849 + Box::pin(fut) 2850 + } 2851 + } 2852 + let accept_compression_encodings = self.accept_compression_encodings; 2853 + let send_compression_encodings = self.send_compression_encodings; 2854 + let max_decoding_message_size = self.max_decoding_message_size; 2855 + let max_encoding_message_size = self.max_encoding_message_size; 2856 + let inner = self.inner.clone(); 2857 + let fut = async move { 2858 + let method = GetCurrentSvc(inner); 2859 + let codec = tonic::codec::ProstCodec::default(); 2860 + let mut grpc = tonic::server::Grpc::new(codec) 2861 + .apply_compression_config( 2862 + accept_compression_encodings, 2863 + send_compression_encodings, 2864 + ) 2865 + .apply_max_message_size_config( 2866 + max_decoding_message_size, 2867 + max_encoding_message_size, 2868 + ); 2869 + let res = grpc.unary(method, req).await; 2870 + Ok(res) 2871 + }; 2872 + Box::pin(fut) 2873 + } 2874 + "/rockbox.v1alpha1.PlaylistService/GetResumeInfo" => { 2875 + #[allow(non_camel_case_types)] 2876 + struct GetResumeInfoSvc<T: PlaylistService>(pub Arc<T>); 2877 + impl< 2878 + T: PlaylistService, 2879 + > tonic::server::UnaryService<super::GetResumeInfoRequest> 2880 + for GetResumeInfoSvc<T> { 2881 + type Response = super::GetResumeInfoResponse; 2882 + type Future = BoxFuture< 2883 + tonic::Response<Self::Response>, 2884 + tonic::Status, 2885 + >; 2886 + fn call( 2887 + &mut self, 2888 + request: tonic::Request<super::GetResumeInfoRequest>, 2889 + ) -> Self::Future { 2890 + let inner = Arc::clone(&self.0); 2891 + let fut = async move { 2892 + <T as PlaylistService>::get_resume_info(&inner, request) 2893 + .await 2894 + }; 2895 + Box::pin(fut) 2896 + } 2897 + } 2898 + let accept_compression_encodings = self.accept_compression_encodings; 2899 + let send_compression_encodings = self.send_compression_encodings; 2900 + let max_decoding_message_size = self.max_decoding_message_size; 2901 + let max_encoding_message_size = self.max_encoding_message_size; 2902 + let inner = self.inner.clone(); 2903 + let fut = async move { 2904 + let method = GetResumeInfoSvc(inner); 2905 + let codec = tonic::codec::ProstCodec::default(); 2906 + let mut grpc = tonic::server::Grpc::new(codec) 2907 + .apply_compression_config( 2908 + accept_compression_encodings, 2909 + send_compression_encodings, 2910 + ) 2911 + .apply_max_message_size_config( 2912 + max_decoding_message_size, 2913 + max_encoding_message_size, 2914 + ); 2915 + let res = grpc.unary(method, req).await; 2916 + Ok(res) 2917 + }; 2918 + Box::pin(fut) 2919 + } 2920 + "/rockbox.v1alpha1.PlaylistService/GetTrackInfo" => { 2921 + #[allow(non_camel_case_types)] 2922 + struct GetTrackInfoSvc<T: PlaylistService>(pub Arc<T>); 2923 + impl< 2924 + T: PlaylistService, 2925 + > tonic::server::UnaryService<super::GetTrackInfoRequest> 2926 + for GetTrackInfoSvc<T> { 2927 + type Response = super::GetTrackInfoResponse; 2928 + type Future = BoxFuture< 2929 + tonic::Response<Self::Response>, 2930 + tonic::Status, 2931 + >; 2932 + fn call( 2933 + &mut self, 2934 + request: tonic::Request<super::GetTrackInfoRequest>, 2935 + ) -> Self::Future { 2936 + let inner = Arc::clone(&self.0); 2937 + let fut = async move { 2938 + <T as PlaylistService>::get_track_info(&inner, request) 2939 + .await 2940 + }; 2941 + Box::pin(fut) 2942 + } 2943 + } 2944 + let accept_compression_encodings = self.accept_compression_encodings; 2945 + let send_compression_encodings = self.send_compression_encodings; 2946 + let max_decoding_message_size = self.max_decoding_message_size; 2947 + let max_encoding_message_size = self.max_encoding_message_size; 2948 + let inner = self.inner.clone(); 2949 + let fut = async move { 2950 + let method = GetTrackInfoSvc(inner); 2951 + let codec = tonic::codec::ProstCodec::default(); 2952 + let mut grpc = tonic::server::Grpc::new(codec) 2953 + .apply_compression_config( 2954 + accept_compression_encodings, 2955 + send_compression_encodings, 2956 + ) 2957 + .apply_max_message_size_config( 2958 + max_decoding_message_size, 2959 + max_encoding_message_size, 2960 + ); 2961 + let res = grpc.unary(method, req).await; 2962 + Ok(res) 2963 + }; 2964 + Box::pin(fut) 2965 + } 2966 + "/rockbox.v1alpha1.PlaylistService/GetFirstIndex" => { 2967 + #[allow(non_camel_case_types)] 2968 + struct GetFirstIndexSvc<T: PlaylistService>(pub Arc<T>); 2969 + impl< 2970 + T: PlaylistService, 2971 + > tonic::server::UnaryService<super::GetFirstIndexRequest> 2972 + for GetFirstIndexSvc<T> { 2973 + type Response = super::GetFirstIndexResponse; 2974 + type Future = BoxFuture< 2975 + tonic::Response<Self::Response>, 2976 + tonic::Status, 2977 + >; 2978 + fn call( 2979 + &mut self, 2980 + request: tonic::Request<super::GetFirstIndexRequest>, 2981 + ) -> Self::Future { 2982 + let inner = Arc::clone(&self.0); 2983 + let fut = async move { 2984 + <T as PlaylistService>::get_first_index(&inner, request) 2985 + .await 2986 + }; 2987 + Box::pin(fut) 2988 + } 2989 + } 2990 + let accept_compression_encodings = self.accept_compression_encodings; 2991 + let send_compression_encodings = self.send_compression_encodings; 2992 + let max_decoding_message_size = self.max_decoding_message_size; 2993 + let max_encoding_message_size = self.max_encoding_message_size; 2994 + let inner = self.inner.clone(); 2995 + let fut = async move { 2996 + let method = GetFirstIndexSvc(inner); 2997 + let codec = tonic::codec::ProstCodec::default(); 2998 + let mut grpc = tonic::server::Grpc::new(codec) 2999 + .apply_compression_config( 3000 + accept_compression_encodings, 3001 + send_compression_encodings, 3002 + ) 3003 + .apply_max_message_size_config( 3004 + max_decoding_message_size, 3005 + max_encoding_message_size, 3006 + ); 3007 + let res = grpc.unary(method, req).await; 3008 + Ok(res) 3009 + }; 3010 + Box::pin(fut) 3011 + } 3012 + "/rockbox.v1alpha1.PlaylistService/GetDisplayIndex" => { 3013 + #[allow(non_camel_case_types)] 3014 + struct GetDisplayIndexSvc<T: PlaylistService>(pub Arc<T>); 3015 + impl< 3016 + T: PlaylistService, 3017 + > tonic::server::UnaryService<super::GetDisplayIndexRequest> 3018 + for GetDisplayIndexSvc<T> { 3019 + type Response = super::GetDisplayIndexResponse; 3020 + type Future = BoxFuture< 3021 + tonic::Response<Self::Response>, 3022 + tonic::Status, 3023 + >; 3024 + fn call( 3025 + &mut self, 3026 + request: tonic::Request<super::GetDisplayIndexRequest>, 3027 + ) -> Self::Future { 3028 + let inner = Arc::clone(&self.0); 3029 + let fut = async move { 3030 + <T as PlaylistService>::get_display_index(&inner, request) 3031 + .await 3032 + }; 3033 + Box::pin(fut) 3034 + } 3035 + } 3036 + let accept_compression_encodings = self.accept_compression_encodings; 3037 + let send_compression_encodings = self.send_compression_encodings; 3038 + let max_decoding_message_size = self.max_decoding_message_size; 3039 + let max_encoding_message_size = self.max_encoding_message_size; 3040 + let inner = self.inner.clone(); 3041 + let fut = async move { 3042 + let method = GetDisplayIndexSvc(inner); 3043 + let codec = tonic::codec::ProstCodec::default(); 3044 + let mut grpc = tonic::server::Grpc::new(codec) 3045 + .apply_compression_config( 3046 + accept_compression_encodings, 3047 + send_compression_encodings, 3048 + ) 3049 + .apply_max_message_size_config( 3050 + max_decoding_message_size, 3051 + max_encoding_message_size, 3052 + ); 3053 + let res = grpc.unary(method, req).await; 3054 + Ok(res) 3055 + }; 3056 + Box::pin(fut) 3057 + } 3058 + "/rockbox.v1alpha1.PlaylistService/Amount" => { 3059 + #[allow(non_camel_case_types)] 3060 + struct AmountSvc<T: PlaylistService>(pub Arc<T>); 3061 + impl< 3062 + T: PlaylistService, 3063 + > tonic::server::UnaryService<super::AmountRequest> 3064 + for AmountSvc<T> { 3065 + type Response = super::AmountResponse; 3066 + type Future = BoxFuture< 3067 + tonic::Response<Self::Response>, 3068 + tonic::Status, 3069 + >; 3070 + fn call( 3071 + &mut self, 3072 + request: tonic::Request<super::AmountRequest>, 3073 + ) -> Self::Future { 3074 + let inner = Arc::clone(&self.0); 3075 + let fut = async move { 3076 + <T as PlaylistService>::amount(&inner, request).await 3077 + }; 3078 + Box::pin(fut) 3079 + } 3080 + } 3081 + let accept_compression_encodings = self.accept_compression_encodings; 3082 + let send_compression_encodings = self.send_compression_encodings; 3083 + let max_decoding_message_size = self.max_decoding_message_size; 3084 + let max_encoding_message_size = self.max_encoding_message_size; 3085 + let inner = self.inner.clone(); 3086 + let fut = async move { 3087 + let method = AmountSvc(inner); 3088 + let codec = tonic::codec::ProstCodec::default(); 3089 + let mut grpc = tonic::server::Grpc::new(codec) 3090 + .apply_compression_config( 3091 + accept_compression_encodings, 3092 + send_compression_encodings, 3093 + ) 3094 + .apply_max_message_size_config( 3095 + max_decoding_message_size, 3096 + max_encoding_message_size, 3097 + ); 3098 + let res = grpc.unary(method, req).await; 3099 + Ok(res) 3100 + }; 3101 + Box::pin(fut) 3102 + } 3103 + "/rockbox.v1alpha1.PlaylistService/PlaylistResume" => { 3104 + #[allow(non_camel_case_types)] 3105 + struct PlaylistResumeSvc<T: PlaylistService>(pub Arc<T>); 3106 + impl< 3107 + T: PlaylistService, 3108 + > tonic::server::UnaryService<super::PlaylistResumeRequest> 3109 + for PlaylistResumeSvc<T> { 3110 + type Response = super::PlaylistResumeResponse; 3111 + type Future = BoxFuture< 3112 + tonic::Response<Self::Response>, 3113 + tonic::Status, 3114 + >; 3115 + fn call( 3116 + &mut self, 3117 + request: tonic::Request<super::PlaylistResumeRequest>, 3118 + ) -> Self::Future { 3119 + let inner = Arc::clone(&self.0); 3120 + let fut = async move { 3121 + <T as PlaylistService>::playlist_resume(&inner, request) 3122 + .await 3123 + }; 3124 + Box::pin(fut) 3125 + } 3126 + } 3127 + let accept_compression_encodings = self.accept_compression_encodings; 3128 + let send_compression_encodings = self.send_compression_encodings; 3129 + let max_decoding_message_size = self.max_decoding_message_size; 3130 + let max_encoding_message_size = self.max_encoding_message_size; 3131 + let inner = self.inner.clone(); 3132 + let fut = async move { 3133 + let method = PlaylistResumeSvc(inner); 3134 + let codec = tonic::codec::ProstCodec::default(); 3135 + let mut grpc = tonic::server::Grpc::new(codec) 3136 + .apply_compression_config( 3137 + accept_compression_encodings, 3138 + send_compression_encodings, 3139 + ) 3140 + .apply_max_message_size_config( 3141 + max_decoding_message_size, 3142 + max_encoding_message_size, 3143 + ); 3144 + let res = grpc.unary(method, req).await; 3145 + Ok(res) 3146 + }; 3147 + Box::pin(fut) 3148 + } 3149 + "/rockbox.v1alpha1.PlaylistService/ResumeTrack" => { 3150 + #[allow(non_camel_case_types)] 3151 + struct ResumeTrackSvc<T: PlaylistService>(pub Arc<T>); 3152 + impl< 3153 + T: PlaylistService, 3154 + > tonic::server::UnaryService<super::ResumeTrackRequest> 3155 + for ResumeTrackSvc<T> { 3156 + type Response = super::ResumeTrackResponse; 3157 + type Future = BoxFuture< 3158 + tonic::Response<Self::Response>, 3159 + tonic::Status, 3160 + >; 3161 + fn call( 3162 + &mut self, 3163 + request: tonic::Request<super::ResumeTrackRequest>, 3164 + ) -> Self::Future { 3165 + let inner = Arc::clone(&self.0); 3166 + let fut = async move { 3167 + <T as PlaylistService>::resume_track(&inner, request).await 3168 + }; 3169 + Box::pin(fut) 3170 + } 3171 + } 3172 + let accept_compression_encodings = self.accept_compression_encodings; 3173 + let send_compression_encodings = self.send_compression_encodings; 3174 + let max_decoding_message_size = self.max_decoding_message_size; 3175 + let max_encoding_message_size = self.max_encoding_message_size; 3176 + let inner = self.inner.clone(); 3177 + let fut = async move { 3178 + let method = ResumeTrackSvc(inner); 3179 + let codec = tonic::codec::ProstCodec::default(); 3180 + let mut grpc = tonic::server::Grpc::new(codec) 3181 + .apply_compression_config( 3182 + accept_compression_encodings, 3183 + send_compression_encodings, 3184 + ) 3185 + .apply_max_message_size_config( 3186 + max_decoding_message_size, 3187 + max_encoding_message_size, 3188 + ); 3189 + let res = grpc.unary(method, req).await; 3190 + Ok(res) 3191 + }; 3192 + Box::pin(fut) 3193 + } 3194 + "/rockbox.v1alpha1.PlaylistService/SetModified" => { 3195 + #[allow(non_camel_case_types)] 3196 + struct SetModifiedSvc<T: PlaylistService>(pub Arc<T>); 3197 + impl< 3198 + T: PlaylistService, 3199 + > tonic::server::UnaryService<super::SetModifiedRequest> 3200 + for SetModifiedSvc<T> { 3201 + type Response = super::SetModifiedResponse; 3202 + type Future = BoxFuture< 3203 + tonic::Response<Self::Response>, 3204 + tonic::Status, 3205 + >; 3206 + fn call( 3207 + &mut self, 3208 + request: tonic::Request<super::SetModifiedRequest>, 3209 + ) -> Self::Future { 3210 + let inner = Arc::clone(&self.0); 3211 + let fut = async move { 3212 + <T as PlaylistService>::set_modified(&inner, request).await 3213 + }; 3214 + Box::pin(fut) 3215 + } 3216 + } 3217 + let accept_compression_encodings = self.accept_compression_encodings; 3218 + let send_compression_encodings = self.send_compression_encodings; 3219 + let max_decoding_message_size = self.max_decoding_message_size; 3220 + let max_encoding_message_size = self.max_encoding_message_size; 3221 + let inner = self.inner.clone(); 3222 + let fut = async move { 3223 + let method = SetModifiedSvc(inner); 3224 + let codec = tonic::codec::ProstCodec::default(); 3225 + let mut grpc = tonic::server::Grpc::new(codec) 3226 + .apply_compression_config( 3227 + accept_compression_encodings, 3228 + send_compression_encodings, 3229 + ) 3230 + .apply_max_message_size_config( 3231 + max_decoding_message_size, 3232 + max_encoding_message_size, 3233 + ); 3234 + let res = grpc.unary(method, req).await; 3235 + Ok(res) 3236 + }; 3237 + Box::pin(fut) 3238 + } 3239 + "/rockbox.v1alpha1.PlaylistService/Start" => { 3240 + #[allow(non_camel_case_types)] 3241 + struct StartSvc<T: PlaylistService>(pub Arc<T>); 3242 + impl< 3243 + T: PlaylistService, 3244 + > tonic::server::UnaryService<super::StartRequest> for StartSvc<T> { 3245 + type Response = super::StartResponse; 3246 + type Future = BoxFuture< 3247 + tonic::Response<Self::Response>, 3248 + tonic::Status, 3249 + >; 3250 + fn call( 3251 + &mut self, 3252 + request: tonic::Request<super::StartRequest>, 3253 + ) -> Self::Future { 3254 + let inner = Arc::clone(&self.0); 3255 + let fut = async move { 3256 + <T as PlaylistService>::start(&inner, request).await 3257 + }; 3258 + Box::pin(fut) 3259 + } 3260 + } 3261 + let accept_compression_encodings = self.accept_compression_encodings; 3262 + let send_compression_encodings = self.send_compression_encodings; 3263 + let max_decoding_message_size = self.max_decoding_message_size; 3264 + let max_encoding_message_size = self.max_encoding_message_size; 3265 + let inner = self.inner.clone(); 3266 + let fut = async move { 3267 + let method = StartSvc(inner); 3268 + let codec = tonic::codec::ProstCodec::default(); 3269 + let mut grpc = tonic::server::Grpc::new(codec) 3270 + .apply_compression_config( 3271 + accept_compression_encodings, 3272 + send_compression_encodings, 3273 + ) 3274 + .apply_max_message_size_config( 3275 + max_decoding_message_size, 3276 + max_encoding_message_size, 3277 + ); 3278 + let res = grpc.unary(method, req).await; 3279 + Ok(res) 3280 + }; 3281 + Box::pin(fut) 3282 + } 3283 + "/rockbox.v1alpha1.PlaylistService/Sync" => { 3284 + #[allow(non_camel_case_types)] 3285 + struct SyncSvc<T: PlaylistService>(pub Arc<T>); 3286 + impl< 3287 + T: PlaylistService, 3288 + > tonic::server::UnaryService<super::SyncRequest> for SyncSvc<T> { 3289 + type Response = super::SyncResponse; 3290 + type Future = BoxFuture< 3291 + tonic::Response<Self::Response>, 3292 + tonic::Status, 3293 + >; 3294 + fn call( 3295 + &mut self, 3296 + request: tonic::Request<super::SyncRequest>, 3297 + ) -> Self::Future { 3298 + let inner = Arc::clone(&self.0); 3299 + let fut = async move { 3300 + <T as PlaylistService>::sync(&inner, request).await 3301 + }; 3302 + Box::pin(fut) 3303 + } 3304 + } 3305 + let accept_compression_encodings = self.accept_compression_encodings; 3306 + let send_compression_encodings = self.send_compression_encodings; 3307 + let max_decoding_message_size = self.max_decoding_message_size; 3308 + let max_encoding_message_size = self.max_encoding_message_size; 3309 + let inner = self.inner.clone(); 3310 + let fut = async move { 3311 + let method = SyncSvc(inner); 3312 + let codec = tonic::codec::ProstCodec::default(); 3313 + let mut grpc = tonic::server::Grpc::new(codec) 3314 + .apply_compression_config( 3315 + accept_compression_encodings, 3316 + send_compression_encodings, 3317 + ) 3318 + .apply_max_message_size_config( 3319 + max_decoding_message_size, 3320 + max_encoding_message_size, 3321 + ); 3322 + let res = grpc.unary(method, req).await; 3323 + Ok(res) 3324 + }; 3325 + Box::pin(fut) 3326 + } 3327 + "/rockbox.v1alpha1.PlaylistService/RemoveAllTracks" => { 3328 + #[allow(non_camel_case_types)] 3329 + struct RemoveAllTracksSvc<T: PlaylistService>(pub Arc<T>); 3330 + impl< 3331 + T: PlaylistService, 3332 + > tonic::server::UnaryService<super::RemoveAllTracksRequest> 3333 + for RemoveAllTracksSvc<T> { 3334 + type Response = super::RemoveAllTracksResponse; 3335 + type Future = BoxFuture< 3336 + tonic::Response<Self::Response>, 3337 + tonic::Status, 3338 + >; 3339 + fn call( 3340 + &mut self, 3341 + request: tonic::Request<super::RemoveAllTracksRequest>, 3342 + ) -> Self::Future { 3343 + let inner = Arc::clone(&self.0); 3344 + let fut = async move { 3345 + <T as PlaylistService>::remove_all_tracks(&inner, request) 3346 + .await 3347 + }; 3348 + Box::pin(fut) 3349 + } 3350 + } 3351 + let accept_compression_encodings = self.accept_compression_encodings; 3352 + let send_compression_encodings = self.send_compression_encodings; 3353 + let max_decoding_message_size = self.max_decoding_message_size; 3354 + let max_encoding_message_size = self.max_encoding_message_size; 3355 + let inner = self.inner.clone(); 3356 + let fut = async move { 3357 + let method = RemoveAllTracksSvc(inner); 3358 + let codec = tonic::codec::ProstCodec::default(); 3359 + let mut grpc = tonic::server::Grpc::new(codec) 3360 + .apply_compression_config( 3361 + accept_compression_encodings, 3362 + send_compression_encodings, 3363 + ) 3364 + .apply_max_message_size_config( 3365 + max_decoding_message_size, 3366 + max_encoding_message_size, 3367 + ); 3368 + let res = grpc.unary(method, req).await; 3369 + Ok(res) 3370 + }; 3371 + Box::pin(fut) 3372 + } 3373 + "/rockbox.v1alpha1.PlaylistService/CreatePlaylist" => { 3374 + #[allow(non_camel_case_types)] 3375 + struct CreatePlaylistSvc<T: PlaylistService>(pub Arc<T>); 3376 + impl< 3377 + T: PlaylistService, 3378 + > tonic::server::UnaryService<super::CreatePlaylistRequest> 3379 + for CreatePlaylistSvc<T> { 3380 + type Response = super::CreatePlaylistResponse; 3381 + type Future = BoxFuture< 3382 + tonic::Response<Self::Response>, 3383 + tonic::Status, 3384 + >; 3385 + fn call( 3386 + &mut self, 3387 + request: tonic::Request<super::CreatePlaylistRequest>, 3388 + ) -> Self::Future { 3389 + let inner = Arc::clone(&self.0); 3390 + let fut = async move { 3391 + <T as PlaylistService>::create_playlist(&inner, request) 3392 + .await 3393 + }; 3394 + Box::pin(fut) 3395 + } 3396 + } 3397 + let accept_compression_encodings = self.accept_compression_encodings; 3398 + let send_compression_encodings = self.send_compression_encodings; 3399 + let max_decoding_message_size = self.max_decoding_message_size; 3400 + let max_encoding_message_size = self.max_encoding_message_size; 3401 + let inner = self.inner.clone(); 3402 + let fut = async move { 3403 + let method = CreatePlaylistSvc(inner); 3404 + let codec = tonic::codec::ProstCodec::default(); 3405 + let mut grpc = tonic::server::Grpc::new(codec) 3406 + .apply_compression_config( 3407 + accept_compression_encodings, 3408 + send_compression_encodings, 3409 + ) 3410 + .apply_max_message_size_config( 3411 + max_decoding_message_size, 3412 + max_encoding_message_size, 3413 + ); 3414 + let res = grpc.unary(method, req).await; 3415 + Ok(res) 3416 + }; 3417 + Box::pin(fut) 3418 + } 3419 + "/rockbox.v1alpha1.PlaylistService/InsertTrack" => { 3420 + #[allow(non_camel_case_types)] 3421 + struct InsertTrackSvc<T: PlaylistService>(pub Arc<T>); 3422 + impl< 3423 + T: PlaylistService, 3424 + > tonic::server::UnaryService<super::InsertTrackRequest> 3425 + for InsertTrackSvc<T> { 3426 + type Response = super::InsertTrackResponse; 3427 + type Future = BoxFuture< 3428 + tonic::Response<Self::Response>, 3429 + tonic::Status, 3430 + >; 3431 + fn call( 3432 + &mut self, 3433 + request: tonic::Request<super::InsertTrackRequest>, 3434 + ) -> Self::Future { 3435 + let inner = Arc::clone(&self.0); 3436 + let fut = async move { 3437 + <T as PlaylistService>::insert_track(&inner, request).await 3438 + }; 3439 + Box::pin(fut) 3440 + } 3441 + } 3442 + let accept_compression_encodings = self.accept_compression_encodings; 3443 + let send_compression_encodings = self.send_compression_encodings; 3444 + let max_decoding_message_size = self.max_decoding_message_size; 3445 + let max_encoding_message_size = self.max_encoding_message_size; 3446 + let inner = self.inner.clone(); 3447 + let fut = async move { 3448 + let method = InsertTrackSvc(inner); 3449 + let codec = tonic::codec::ProstCodec::default(); 3450 + let mut grpc = tonic::server::Grpc::new(codec) 3451 + .apply_compression_config( 3452 + accept_compression_encodings, 3453 + send_compression_encodings, 3454 + ) 3455 + .apply_max_message_size_config( 3456 + max_decoding_message_size, 3457 + max_encoding_message_size, 3458 + ); 3459 + let res = grpc.unary(method, req).await; 3460 + Ok(res) 3461 + }; 3462 + Box::pin(fut) 3463 + } 3464 + "/rockbox.v1alpha1.PlaylistService/InsertDirectory" => { 3465 + #[allow(non_camel_case_types)] 3466 + struct InsertDirectorySvc<T: PlaylistService>(pub Arc<T>); 3467 + impl< 3468 + T: PlaylistService, 3469 + > tonic::server::UnaryService<super::InsertDirectoryRequest> 3470 + for InsertDirectorySvc<T> { 3471 + type Response = super::InsertDirectoryResponse; 3472 + type Future = BoxFuture< 3473 + tonic::Response<Self::Response>, 3474 + tonic::Status, 3475 + >; 3476 + fn call( 3477 + &mut self, 3478 + request: tonic::Request<super::InsertDirectoryRequest>, 3479 + ) -> Self::Future { 3480 + let inner = Arc::clone(&self.0); 3481 + let fut = async move { 3482 + <T as PlaylistService>::insert_directory(&inner, request) 3483 + .await 3484 + }; 3485 + Box::pin(fut) 3486 + } 3487 + } 3488 + let accept_compression_encodings = self.accept_compression_encodings; 3489 + let send_compression_encodings = self.send_compression_encodings; 3490 + let max_decoding_message_size = self.max_decoding_message_size; 3491 + let max_encoding_message_size = self.max_encoding_message_size; 3492 + let inner = self.inner.clone(); 3493 + let fut = async move { 3494 + let method = InsertDirectorySvc(inner); 3495 + let codec = tonic::codec::ProstCodec::default(); 3496 + let mut grpc = tonic::server::Grpc::new(codec) 3497 + .apply_compression_config( 3498 + accept_compression_encodings, 3499 + send_compression_encodings, 3500 + ) 3501 + .apply_max_message_size_config( 3502 + max_decoding_message_size, 3503 + max_encoding_message_size, 3504 + ); 3505 + let res = grpc.unary(method, req).await; 3506 + Ok(res) 3507 + }; 3508 + Box::pin(fut) 3509 + } 3510 + "/rockbox.v1alpha1.PlaylistService/InsertPlaylist" => { 3511 + #[allow(non_camel_case_types)] 3512 + struct InsertPlaylistSvc<T: PlaylistService>(pub Arc<T>); 3513 + impl< 3514 + T: PlaylistService, 3515 + > tonic::server::UnaryService<super::InsertPlaylistRequest> 3516 + for InsertPlaylistSvc<T> { 3517 + type Response = super::InsertPlaylistResponse; 3518 + type Future = BoxFuture< 3519 + tonic::Response<Self::Response>, 3520 + tonic::Status, 3521 + >; 3522 + fn call( 3523 + &mut self, 3524 + request: tonic::Request<super::InsertPlaylistRequest>, 3525 + ) -> Self::Future { 3526 + let inner = Arc::clone(&self.0); 3527 + let fut = async move { 3528 + <T as PlaylistService>::insert_playlist(&inner, request) 3529 + .await 3530 + }; 3531 + Box::pin(fut) 3532 + } 3533 + } 3534 + let accept_compression_encodings = self.accept_compression_encodings; 3535 + let send_compression_encodings = self.send_compression_encodings; 3536 + let max_decoding_message_size = self.max_decoding_message_size; 3537 + let max_encoding_message_size = self.max_encoding_message_size; 3538 + let inner = self.inner.clone(); 3539 + let fut = async move { 3540 + let method = InsertPlaylistSvc(inner); 3541 + let codec = tonic::codec::ProstCodec::default(); 3542 + let mut grpc = tonic::server::Grpc::new(codec) 3543 + .apply_compression_config( 3544 + accept_compression_encodings, 3545 + send_compression_encodings, 3546 + ) 3547 + .apply_max_message_size_config( 3548 + max_decoding_message_size, 3549 + max_encoding_message_size, 3550 + ); 3551 + let res = grpc.unary(method, req).await; 3552 + Ok(res) 3553 + }; 3554 + Box::pin(fut) 3555 + } 3556 + "/rockbox.v1alpha1.PlaylistService/ShufflePlaylist" => { 3557 + #[allow(non_camel_case_types)] 3558 + struct ShufflePlaylistSvc<T: PlaylistService>(pub Arc<T>); 3559 + impl< 3560 + T: PlaylistService, 3561 + > tonic::server::UnaryService<super::ShufflePlaylistRequest> 3562 + for ShufflePlaylistSvc<T> { 3563 + type Response = super::ShufflePlaylistResponse; 3564 + type Future = BoxFuture< 3565 + tonic::Response<Self::Response>, 3566 + tonic::Status, 3567 + >; 3568 + fn call( 3569 + &mut self, 3570 + request: tonic::Request<super::ShufflePlaylistRequest>, 3571 + ) -> Self::Future { 3572 + let inner = Arc::clone(&self.0); 3573 + let fut = async move { 3574 + <T as PlaylistService>::shuffle_playlist(&inner, request) 3575 + .await 3576 + }; 3577 + Box::pin(fut) 3578 + } 3579 + } 3580 + let accept_compression_encodings = self.accept_compression_encodings; 3581 + let send_compression_encodings = self.send_compression_encodings; 3582 + let max_decoding_message_size = self.max_decoding_message_size; 3583 + let max_encoding_message_size = self.max_encoding_message_size; 3584 + let inner = self.inner.clone(); 3585 + let fut = async move { 3586 + let method = ShufflePlaylistSvc(inner); 3587 + let codec = tonic::codec::ProstCodec::default(); 3588 + let mut grpc = tonic::server::Grpc::new(codec) 3589 + .apply_compression_config( 3590 + accept_compression_encodings, 3591 + send_compression_encodings, 3592 + ) 3593 + .apply_max_message_size_config( 3594 + max_decoding_message_size, 3595 + max_encoding_message_size, 3596 + ); 3597 + let res = grpc.unary(method, req).await; 3598 + Ok(res) 3599 + }; 3600 + Box::pin(fut) 3601 + } 3602 + "/rockbox.v1alpha1.PlaylistService/WarnOnPlaylistErase" => { 3603 + #[allow(non_camel_case_types)] 3604 + struct WarnOnPlaylistEraseSvc<T: PlaylistService>(pub Arc<T>); 3605 + impl< 3606 + T: PlaylistService, 3607 + > tonic::server::UnaryService<super::WarnOnPlaylistEraseRequest> 3608 + for WarnOnPlaylistEraseSvc<T> { 3609 + type Response = super::WarnOnPlaylistEraseResponse; 3610 + type Future = BoxFuture< 3611 + tonic::Response<Self::Response>, 3612 + tonic::Status, 3613 + >; 3614 + fn call( 3615 + &mut self, 3616 + request: tonic::Request<super::WarnOnPlaylistEraseRequest>, 3617 + ) -> Self::Future { 3618 + let inner = Arc::clone(&self.0); 3619 + let fut = async move { 3620 + <T as PlaylistService>::warn_on_playlist_erase( 3621 + &inner, 3622 + request, 3623 + ) 3624 + .await 3625 + }; 3626 + Box::pin(fut) 3627 + } 3628 + } 3629 + let accept_compression_encodings = self.accept_compression_encodings; 3630 + let send_compression_encodings = self.send_compression_encodings; 3631 + let max_decoding_message_size = self.max_decoding_message_size; 3632 + let max_encoding_message_size = self.max_encoding_message_size; 3633 + let inner = self.inner.clone(); 3634 + let fut = async move { 3635 + let method = WarnOnPlaylistEraseSvc(inner); 3636 + let codec = tonic::codec::ProstCodec::default(); 3637 + let mut grpc = tonic::server::Grpc::new(codec) 3638 + .apply_compression_config( 3639 + accept_compression_encodings, 3640 + send_compression_encodings, 3641 + ) 3642 + .apply_max_message_size_config( 3643 + max_decoding_message_size, 3644 + max_encoding_message_size, 3645 + ); 3646 + let res = grpc.unary(method, req).await; 3647 + Ok(res) 3648 + }; 3649 + Box::pin(fut) 3650 + } 3651 + _ => { 3652 + Box::pin(async move { 3653 + Ok( 3654 + http::Response::builder() 3655 + .status(200) 3656 + .header("grpc-status", tonic::Code::Unimplemented as i32) 3657 + .header( 3658 + http::header::CONTENT_TYPE, 3659 + tonic::metadata::GRPC_CONTENT_TYPE, 3660 + ) 3661 + .body(empty_body()) 3662 + .unwrap(), 3663 + ) 3664 + }) 3665 + } 3666 + } 3667 + } 3668 + } 3669 + impl<T> Clone for PlaylistServiceServer<T> { 3670 + fn clone(&self) -> Self { 3671 + let inner = self.inner.clone(); 3672 + Self { 3673 + inner, 3674 + accept_compression_encodings: self.accept_compression_encodings, 3675 + send_compression_encodings: self.send_compression_encodings, 3676 + max_decoding_message_size: self.max_decoding_message_size, 3677 + max_encoding_message_size: self.max_encoding_message_size, 3678 + } 3679 + } 3680 + } 3681 + /// Generated gRPC service name 3682 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.PlaylistService"; 3683 + impl<T> tonic::server::NamedService for PlaylistServiceServer<T> { 3684 + const NAME: &'static str = SERVICE_NAME; 3685 + } 3686 + } 3687 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3688 + pub struct GetSettingsListRequest { 3689 + #[prost(int32, tag = "1")] 3690 + pub count: i32, 3691 + } 3692 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3693 + pub struct GetSettingsListResponse {} 3694 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3695 + pub struct GetGlobalSettingsRequest {} 3696 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3697 + pub struct ReplaygainSettings { 3698 + #[prost(bool, tag = "1")] 3699 + pub noclip: bool, 3700 + #[prost(int32, tag = "2")] 3701 + pub r#type: i32, 3702 + #[prost(int32, tag = "3")] 3703 + pub preamp: i32, 3704 + } 3705 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3706 + pub struct EqBandSetting { 3707 + #[prost(int32, tag = "1")] 3708 + pub cutoff: i32, 3709 + #[prost(int32, tag = "2")] 3710 + pub q: i32, 3711 + #[prost(int32, tag = "3")] 3712 + pub gain: i32, 3713 + } 3714 + #[derive(Clone, PartialEq, ::prost::Message)] 3715 + pub struct SettingsList { 3716 + #[prost(uint32, tag = "1")] 3717 + pub flags: u32, 3718 + #[prost(int32, tag = "2")] 3719 + pub lang_id: i32, 3720 + #[prost(string, tag = "3")] 3721 + pub cfg_name: ::prost::alloc::string::String, 3722 + #[prost(string, tag = "4")] 3723 + pub cfg_vals: ::prost::alloc::string::String, 3724 + } 3725 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 3726 + pub struct CompressorSettings { 3727 + #[prost(int32, tag = "1")] 3728 + pub threshold: i32, 3729 + #[prost(int32, tag = "2")] 3730 + pub makeup_gain: i32, 3731 + #[prost(int32, tag = "3")] 3732 + pub ratio: i32, 3733 + #[prost(int32, tag = "4")] 3734 + pub knee: i32, 3735 + #[prost(int32, tag = "5")] 3736 + pub release_time: i32, 3737 + #[prost(int32, tag = "6")] 3738 + pub attack_time: i32, 3739 + } 3740 + #[derive(Clone, PartialEq, ::prost::Message)] 3741 + pub struct GetGlobalSettingsResponse { 3742 + #[prost(int32, tag = "1")] 3743 + pub volume: i32, 3744 + #[prost(int32, tag = "2")] 3745 + pub balance: i32, 3746 + #[prost(int32, tag = "3")] 3747 + pub bass: i32, 3748 + #[prost(int32, tag = "4")] 3749 + pub treble: i32, 3750 + #[prost(int32, tag = "5")] 3751 + pub channel_config: i32, 3752 + #[prost(int32, tag = "6")] 3753 + pub stereo_width: i32, 3754 + #[prost(int32, tag = "7")] 3755 + pub bass_cutoff: i32, 3756 + #[prost(int32, tag = "8")] 3757 + pub treble_cutoff: i32, 3758 + #[prost(int32, tag = "9")] 3759 + pub crossfade: i32, 3760 + #[prost(int32, tag = "10")] 3761 + pub crossfade_fade_in_delay: i32, 3762 + #[prost(int32, tag = "11")] 3763 + pub crossfade_fade_out_delay: i32, 3764 + #[prost(int32, tag = "12")] 3765 + pub crossfade_fade_in_duration: i32, 3766 + #[prost(int32, tag = "13")] 3767 + pub crossfade_fade_out_duration: i32, 3768 + #[prost(int32, tag = "14")] 3769 + pub crossfade_fade_out_mixmode: i32, 3770 + #[prost(message, optional, tag = "15")] 3771 + pub replaygain_settings: ::core::option::Option<ReplaygainSettings>, 3772 + #[prost(int32, tag = "16")] 3773 + pub crossfeed: i32, 3774 + #[prost(uint32, tag = "17")] 3775 + pub crossfeed_direct_gain: u32, 3776 + #[prost(uint32, tag = "18")] 3777 + pub crossfeed_cross_gain: u32, 3778 + #[prost(uint32, tag = "19")] 3779 + pub crossfeed_hf_attenuation: u32, 3780 + #[prost(uint32, tag = "20")] 3781 + pub crossfeed_hf_cutoff: u32, 3782 + #[prost(bool, tag = "21")] 3783 + pub eq_enabled: bool, 3784 + #[prost(uint32, tag = "22")] 3785 + pub eq_precut: u32, 3786 + #[prost(message, repeated, tag = "23")] 3787 + pub eq_band_settings: ::prost::alloc::vec::Vec<EqBandSetting>, 3788 + #[prost(int32, tag = "24")] 3789 + pub beep: i32, 3790 + #[prost(int32, tag = "25")] 3791 + pub keyclick: i32, 3792 + #[prost(int32, tag = "26")] 3793 + pub keyclick_repeats: i32, 3794 + #[prost(bool, tag = "27")] 3795 + pub dithering_enabled: bool, 3796 + #[prost(bool, tag = "28")] 3797 + pub timestretch_enabled: bool, 3798 + #[prost(int32, tag = "29")] 3799 + pub list_accel_start_delay: i32, 3800 + #[prost(int32, tag = "30")] 3801 + pub list_accel_wait: i32, 3802 + #[prost(int32, tag = "31")] 3803 + pub touchpad_sensitivity: i32, 3804 + #[prost(int32, tag = "32")] 3805 + pub touchpad_deadzone: i32, 3806 + #[prost(int32, tag = "33")] 3807 + pub pause_rewind: i32, 3808 + #[prost(int32, tag = "34")] 3809 + pub unplug_mode: i32, 3810 + #[prost(bool, tag = "35")] 3811 + pub unplug_autoresume: bool, 3812 + #[prost(int32, tag = "37")] 3813 + pub timeformat: i32, 3814 + #[prost(int32, tag = "38")] 3815 + pub disk_spindown: i32, 3816 + #[prost(int32, tag = "39")] 3817 + pub buffer_margin: i32, 3818 + #[prost(int32, tag = "40")] 3819 + pub dirfilter: i32, 3820 + #[prost(int32, tag = "41")] 3821 + pub show_filename_ext: i32, 3822 + #[prost(int32, tag = "42")] 3823 + pub default_codepage: i32, 3824 + #[prost(bool, tag = "43")] 3825 + pub hold_lr_for_scroll_in_list: bool, 3826 + #[prost(bool, tag = "44")] 3827 + pub play_selected: bool, 3828 + #[prost(int32, tag = "45")] 3829 + pub single_mode: i32, 3830 + #[prost(bool, tag = "46")] 3831 + pub party_mode: bool, 3832 + #[prost(bool, tag = "48")] 3833 + pub car_adapter_mode: bool, 3834 + #[prost(int32, tag = "49")] 3835 + pub car_adapter_mode_delay: i32, 3836 + #[prost(int32, tag = "50")] 3837 + pub start_in_screen: i32, 3838 + #[prost(int32, tag = "51")] 3839 + pub ff_rewind_min_step: i32, 3840 + #[prost(int32, tag = "52")] 3841 + pub ff_rewind_accel: i32, 3842 + #[prost(int32, tag = "53")] 3843 + pub peak_meter_release: i32, 3844 + #[prost(int32, tag = "54")] 3845 + pub peak_meter_hold: i32, 3846 + #[prost(int32, tag = "55")] 3847 + pub peak_meter_clip_hold: i32, 3848 + #[prost(bool, tag = "56")] 3849 + pub peak_meter_dbfs: bool, 3850 + #[prost(int32, tag = "57")] 3851 + pub peak_meter_min: i32, 3852 + #[prost(int32, tag = "58")] 3853 + pub peak_meter_max: i32, 3854 + #[prost(string, tag = "59")] 3855 + pub wps_file: ::prost::alloc::string::String, 3856 + #[prost(string, tag = "60")] 3857 + pub sbs_file: ::prost::alloc::string::String, 3858 + #[prost(string, tag = "61")] 3859 + pub lang_file: ::prost::alloc::string::String, 3860 + #[prost(string, tag = "62")] 3861 + pub playlist_catalog_dir: ::prost::alloc::string::String, 3862 + #[prost(int32, tag = "63")] 3863 + pub skip_length: i32, 3864 + #[prost(int32, tag = "64")] 3865 + pub max_files_in_dir: i32, 3866 + #[prost(int32, tag = "65")] 3867 + pub max_files_in_playlist: i32, 3868 + #[prost(int32, tag = "66")] 3869 + pub volume_type: i32, 3870 + #[prost(int32, tag = "67")] 3871 + pub battery_display: i32, 3872 + #[prost(bool, tag = "68")] 3873 + pub show_icons: bool, 3874 + #[prost(int32, tag = "69")] 3875 + pub statusbar: i32, 3876 + #[prost(int32, tag = "70")] 3877 + pub scrollbar: i32, 3878 + #[prost(int32, tag = "71")] 3879 + pub scrollbar_width: i32, 3880 + #[prost(int32, tag = "72")] 3881 + pub list_line_padding: i32, 3882 + #[prost(int32, tag = "73")] 3883 + pub list_separator_color: i32, 3884 + #[prost(bool, tag = "74")] 3885 + pub browse_current: bool, 3886 + #[prost(bool, tag = "75")] 3887 + pub scroll_paginated: bool, 3888 + #[prost(bool, tag = "76")] 3889 + pub list_wraparound: bool, 3890 + #[prost(int32, tag = "77")] 3891 + pub list_order: i32, 3892 + #[prost(int32, tag = "78")] 3893 + pub scroll_speed: i32, 3894 + #[prost(int32, tag = "79")] 3895 + pub bidir_limit: i32, 3896 + #[prost(int32, tag = "80")] 3897 + pub scroll_delay: i32, 3898 + #[prost(int32, tag = "81")] 3899 + pub scroll_step: i32, 3900 + #[prost(int32, tag = "82")] 3901 + pub autoloadbookmark: i32, 3902 + #[prost(int32, tag = "83")] 3903 + pub autocreatebookmark: i32, 3904 + #[prost(bool, tag = "84")] 3905 + pub autoupdatebookmark: bool, 3906 + #[prost(int32, tag = "85")] 3907 + pub usemrb: i32, 3908 + #[prost(bool, tag = "86")] 3909 + pub dircache: bool, 3910 + #[prost(int32, tag = "87")] 3911 + pub tagcache_ram: i32, 3912 + #[prost(bool, tag = "88")] 3913 + pub tagcache_autoupdate: bool, 3914 + #[prost(bool, tag = "89")] 3915 + pub autoresume_enable: bool, 3916 + #[prost(int32, tag = "90")] 3917 + pub autoresume_automatic: i32, 3918 + #[prost(string, tag = "91")] 3919 + pub autoresume_paths: ::prost::alloc::string::String, 3920 + #[prost(bool, tag = "92")] 3921 + pub runtimedb: bool, 3922 + #[prost(string, tag = "93")] 3923 + pub tagcache_scan_paths: ::prost::alloc::string::String, 3924 + #[prost(string, tag = "94")] 3925 + pub tagcache_db_path: ::prost::alloc::string::String, 3926 + #[prost(string, tag = "95")] 3927 + pub backdrop_file: ::prost::alloc::string::String, 3928 + #[prost(int32, tag = "96")] 3929 + pub bg_color: i32, 3930 + #[prost(int32, tag = "97")] 3931 + pub fg_color: i32, 3932 + #[prost(int32, tag = "98")] 3933 + pub lss_color: i32, 3934 + #[prost(int32, tag = "99")] 3935 + pub lse_color: i32, 3936 + #[prost(int32, tag = "100")] 3937 + pub lst_color: i32, 3938 + #[prost(string, tag = "101")] 3939 + pub colors_file: ::prost::alloc::string::String, 3940 + #[prost(int32, tag = "102")] 3941 + pub browser_default: i32, 3942 + #[prost(int32, tag = "103")] 3943 + pub repeat_mode: i32, 3944 + #[prost(int32, tag = "104")] 3945 + pub next_folder: i32, 3946 + #[prost(bool, tag = "105")] 3947 + pub constrain_next_folder: bool, 3948 + #[prost(int32, tag = "106")] 3949 + pub recursive_dir_insert: i32, 3950 + #[prost(bool, tag = "107")] 3951 + pub fade_on_stop: bool, 3952 + #[prost(bool, tag = "108")] 3953 + pub playlist_shuffle: bool, 3954 + #[prost(bool, tag = "109")] 3955 + pub warnon_erase_dynplaylist: bool, 3956 + #[prost(bool, tag = "110")] 3957 + pub keep_current_track_on_replace_playlist: bool, 3958 + #[prost(bool, tag = "111")] 3959 + pub show_shuffled_adding_options: bool, 3960 + #[prost(int32, tag = "112")] 3961 + pub show_queue_options: i32, 3962 + #[prost(int32, tag = "113")] 3963 + pub album_art: i32, 3964 + #[prost(bool, tag = "114")] 3965 + pub rewind_across_tracks: bool, 3966 + #[prost(bool, tag = "115")] 3967 + pub playlist_viewer_icons: bool, 3968 + #[prost(bool, tag = "116")] 3969 + pub playlist_viewer_indices: bool, 3970 + #[prost(int32, tag = "117")] 3971 + pub playlist_viewer_track_display: i32, 3972 + #[prost(bool, tag = "118")] 3973 + pub sort_case: bool, 3974 + #[prost(int32, tag = "119")] 3975 + pub sort_dir: i32, 3976 + #[prost(int32, tag = "120")] 3977 + pub sort_file: i32, 3978 + #[prost(int32, tag = "121")] 3979 + pub interpret_numbers: i32, 3980 + #[prost(int32, tag = "122")] 3981 + pub poweroff: i32, 3982 + #[prost(bool, tag = "123")] 3983 + pub spdif_enable: bool, 3984 + #[prost(int32, tag = "124")] 3985 + pub contrast: i32, 3986 + #[prost(bool, tag = "125")] 3987 + pub invert: bool, 3988 + #[prost(bool, tag = "126")] 3989 + pub flip_display: bool, 3990 + #[prost(int32, tag = "127")] 3991 + pub cursor_style: i32, 3992 + #[prost(int32, tag = "128")] 3993 + pub screen_scroll_step: i32, 3994 + #[prost(int32, tag = "129")] 3995 + pub show_path_in_browser: i32, 3996 + #[prost(bool, tag = "130")] 3997 + pub offset_out_of_view: bool, 3998 + #[prost(bool, tag = "131")] 3999 + pub disable_mainmenu_scrolling: bool, 4000 + #[prost(string, tag = "132")] 4001 + pub icon_file: ::prost::alloc::string::String, 4002 + #[prost(string, tag = "133")] 4003 + pub viewers_icon_file: ::prost::alloc::string::String, 4004 + #[prost(string, tag = "134")] 4005 + pub font_file: ::prost::alloc::string::String, 4006 + #[prost(int32, tag = "135")] 4007 + pub glyphs_to_cache: i32, 4008 + #[prost(string, tag = "136")] 4009 + pub kbd_file: ::prost::alloc::string::String, 4010 + #[prost(int32, tag = "137")] 4011 + pub backlight_timeout: i32, 4012 + #[prost(bool, tag = "138")] 4013 + pub caption_backlight: bool, 4014 + #[prost(bool, tag = "139")] 4015 + pub bl_filter_first_keypress: bool, 4016 + #[prost(int32, tag = "140")] 4017 + pub backlight_timeout_plugged: i32, 4018 + #[prost(bool, tag = "141")] 4019 + pub bt_selective_softlock_actions: bool, 4020 + #[prost(int32, tag = "142")] 4021 + pub bt_selective_softlock_actions_mask: i32, 4022 + #[prost(bool, tag = "143")] 4023 + pub bl_selective_actions: bool, 4024 + #[prost(int32, tag = "144")] 4025 + pub bl_selective_actions_mask: i32, 4026 + #[prost(int32, tag = "145")] 4027 + pub backlight_on_button_hold: i32, 4028 + #[prost(int32, tag = "146")] 4029 + pub lcd_sleep_after_backlight_off: i32, 4030 + #[prost(int32, tag = "147")] 4031 + pub brightness: i32, 4032 + #[prost(int32, tag = "148")] 4033 + pub speaker_mode: i32, 4034 + #[prost(bool, tag = "149")] 4035 + pub prevent_skip: bool, 4036 + #[prost(int32, tag = "150")] 4037 + pub touch_mode: i32, 4038 + #[prost(bool, tag = "151")] 4039 + pub pitch_mode_semitone: bool, 4040 + #[prost(bool, tag = "152")] 4041 + pub pitch_mode_timestretch: bool, 4042 + #[prost(string, tag = "153")] 4043 + pub player_name: ::prost::alloc::string::String, 4044 + #[prost(message, optional, tag = "154")] 4045 + pub compressor_settings: ::core::option::Option<CompressorSettings>, 4046 + #[prost(int32, tag = "155")] 4047 + pub sleeptimer_duration: i32, 4048 + #[prost(bool, tag = "156")] 4049 + pub sleeptimer_on_startup: bool, 4050 + #[prost(bool, tag = "157")] 4051 + pub keypress_restarts_sleeptimer: bool, 4052 + #[prost(bool, tag = "158")] 4053 + pub show_shutdown_message: bool, 4054 + #[prost(int32, tag = "159")] 4055 + pub hotkey_wps: i32, 4056 + #[prost(int32, tag = "160")] 4057 + pub hotkey_tree: i32, 4058 + #[prost(int32, tag = "161")] 4059 + pub resume_rewind: i32, 4060 + #[prost(int32, tag = "162")] 4061 + pub depth_3d: i32, 4062 + #[prost(int32, tag = "163")] 4063 + pub roll_off: i32, 4064 + #[prost(int32, tag = "164")] 4065 + pub power_mode: i32, 4066 + #[prost(bool, tag = "165")] 4067 + pub keyclick_hardware: bool, 4068 + #[prost(string, tag = "166")] 4069 + pub start_directory: ::prost::alloc::string::String, 4070 + #[prost(bool, tag = "167")] 4071 + pub root_menu_customized: bool, 4072 + #[prost(bool, tag = "168")] 4073 + pub shortcuts_replaces_qs: bool, 4074 + #[prost(int32, tag = "169")] 4075 + pub play_frequency: i32, 4076 + #[prost(int32, tag = "170")] 4077 + pub volume_limit: i32, 4078 + #[prost(int32, tag = "171")] 4079 + pub volume_adjust_mode: i32, 4080 + #[prost(int32, tag = "172")] 4081 + pub volume_adjust_norm_steps: i32, 4082 + #[prost(int32, tag = "173")] 4083 + pub surround_enabled: i32, 4084 + #[prost(int32, tag = "174")] 4085 + pub surround_balance: i32, 4086 + #[prost(int32, tag = "175")] 4087 + pub surround_fx1: i32, 4088 + #[prost(bool, tag = "176")] 4089 + pub surround_fx2: bool, 4090 + #[prost(bool, tag = "177")] 4091 + pub surround_method2: bool, 4092 + #[prost(int32, tag = "178")] 4093 + pub surround_mix: i32, 4094 + #[prost(int32, tag = "179")] 4095 + pub pbe: i32, 4096 + #[prost(int32, tag = "180")] 4097 + pub pbe_precut: i32, 4098 + #[prost(int32, tag = "181")] 4099 + pub afr_enabled: i32, 4100 + #[prost(int32, tag = "182")] 4101 + pub governor: i32, 4102 + #[prost(int32, tag = "183")] 4103 + pub stereosw_mode: i32, 4104 + } 4105 + /// Generated client implementations. 4106 + pub mod settings_service_client { 4107 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 4108 + use tonic::codegen::*; 4109 + use tonic::codegen::http::Uri; 4110 + #[derive(Debug, Clone)] 4111 + pub struct SettingsServiceClient<T> { 4112 + inner: tonic::client::Grpc<T>, 4113 + } 4114 + impl SettingsServiceClient<tonic::transport::Channel> { 4115 + /// Attempt to create a new client by connecting to a given endpoint. 4116 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 4117 + where 4118 + D: TryInto<tonic::transport::Endpoint>, 4119 + D::Error: Into<StdError>, 4120 + { 4121 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 4122 + Ok(Self::new(conn)) 4123 + } 4124 + } 4125 + impl<T> SettingsServiceClient<T> 4126 + where 4127 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 4128 + T::Error: Into<StdError>, 4129 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 4130 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 4131 + { 4132 + pub fn new(inner: T) -> Self { 4133 + let inner = tonic::client::Grpc::new(inner); 4134 + Self { inner } 4135 + } 4136 + pub fn with_origin(inner: T, origin: Uri) -> Self { 4137 + let inner = tonic::client::Grpc::with_origin(inner, origin); 4138 + Self { inner } 4139 + } 4140 + pub fn with_interceptor<F>( 4141 + inner: T, 4142 + interceptor: F, 4143 + ) -> SettingsServiceClient<InterceptedService<T, F>> 4144 + where 4145 + F: tonic::service::Interceptor, 4146 + T::ResponseBody: Default, 4147 + T: tonic::codegen::Service< 4148 + http::Request<tonic::body::BoxBody>, 4149 + Response = http::Response< 4150 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 4151 + >, 4152 + >, 4153 + <T as tonic::codegen::Service< 4154 + http::Request<tonic::body::BoxBody>, 4155 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 4156 + { 4157 + SettingsServiceClient::new(InterceptedService::new(inner, interceptor)) 4158 + } 4159 + /// Compress requests with the given encoding. 4160 + /// 4161 + /// This requires the server to support it otherwise it might respond with an 4162 + /// error. 4163 + #[must_use] 4164 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 4165 + self.inner = self.inner.send_compressed(encoding); 4166 + self 4167 + } 4168 + /// Enable decompressing responses. 4169 + #[must_use] 4170 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 4171 + self.inner = self.inner.accept_compressed(encoding); 4172 + self 4173 + } 4174 + /// Limits the maximum size of a decoded message. 4175 + /// 4176 + /// Default: `4MB` 4177 + #[must_use] 4178 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 4179 + self.inner = self.inner.max_decoding_message_size(limit); 4180 + self 4181 + } 4182 + /// Limits the maximum size of an encoded message. 4183 + /// 4184 + /// Default: `usize::MAX` 4185 + #[must_use] 4186 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 4187 + self.inner = self.inner.max_encoding_message_size(limit); 4188 + self 4189 + } 4190 + pub async fn get_settings_list( 4191 + &mut self, 4192 + request: impl tonic::IntoRequest<super::GetSettingsListRequest>, 4193 + ) -> std::result::Result< 4194 + tonic::Response<super::GetSettingsListResponse>, 4195 + tonic::Status, 4196 + > { 4197 + self.inner 4198 + .ready() 4199 + .await 4200 + .map_err(|e| { 4201 + tonic::Status::new( 4202 + tonic::Code::Unknown, 4203 + format!("Service was not ready: {}", e.into()), 4204 + ) 4205 + })?; 4206 + let codec = tonic::codec::ProstCodec::default(); 4207 + let path = http::uri::PathAndQuery::from_static( 4208 + "/rockbox.v1alpha1.SettingsService/GetSettingsList", 4209 + ); 4210 + let mut req = request.into_request(); 4211 + req.extensions_mut() 4212 + .insert( 4213 + GrpcMethod::new( 4214 + "rockbox.v1alpha1.SettingsService", 4215 + "GetSettingsList", 4216 + ), 4217 + ); 4218 + self.inner.unary(req, path, codec).await 4219 + } 4220 + pub async fn get_global_settings( 4221 + &mut self, 4222 + request: impl tonic::IntoRequest<super::GetGlobalSettingsRequest>, 4223 + ) -> std::result::Result< 4224 + tonic::Response<super::GetGlobalSettingsResponse>, 4225 + tonic::Status, 4226 + > { 4227 + self.inner 4228 + .ready() 4229 + .await 4230 + .map_err(|e| { 4231 + tonic::Status::new( 4232 + tonic::Code::Unknown, 4233 + format!("Service was not ready: {}", e.into()), 4234 + ) 4235 + })?; 4236 + let codec = tonic::codec::ProstCodec::default(); 4237 + let path = http::uri::PathAndQuery::from_static( 4238 + "/rockbox.v1alpha1.SettingsService/GetGlobalSettings", 4239 + ); 4240 + let mut req = request.into_request(); 4241 + req.extensions_mut() 4242 + .insert( 4243 + GrpcMethod::new( 4244 + "rockbox.v1alpha1.SettingsService", 4245 + "GetGlobalSettings", 4246 + ), 4247 + ); 4248 + self.inner.unary(req, path, codec).await 4249 + } 4250 + } 4251 + } 4252 + /// Generated server implementations. 4253 + pub mod settings_service_server { 4254 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 4255 + use tonic::codegen::*; 4256 + /// Generated trait containing gRPC methods that should be implemented for use with SettingsServiceServer. 4257 + #[async_trait] 4258 + pub trait SettingsService: std::marker::Send + std::marker::Sync + 'static { 4259 + async fn get_settings_list( 4260 + &self, 4261 + request: tonic::Request<super::GetSettingsListRequest>, 4262 + ) -> std::result::Result< 4263 + tonic::Response<super::GetSettingsListResponse>, 4264 + tonic::Status, 4265 + >; 4266 + async fn get_global_settings( 4267 + &self, 4268 + request: tonic::Request<super::GetGlobalSettingsRequest>, 4269 + ) -> std::result::Result< 4270 + tonic::Response<super::GetGlobalSettingsResponse>, 4271 + tonic::Status, 4272 + >; 4273 + } 4274 + #[derive(Debug)] 4275 + pub struct SettingsServiceServer<T> { 4276 + inner: Arc<T>, 4277 + accept_compression_encodings: EnabledCompressionEncodings, 4278 + send_compression_encodings: EnabledCompressionEncodings, 4279 + max_decoding_message_size: Option<usize>, 4280 + max_encoding_message_size: Option<usize>, 4281 + } 4282 + impl<T> SettingsServiceServer<T> { 4283 + pub fn new(inner: T) -> Self { 4284 + Self::from_arc(Arc::new(inner)) 4285 + } 4286 + pub fn from_arc(inner: Arc<T>) -> Self { 4287 + Self { 4288 + inner, 4289 + accept_compression_encodings: Default::default(), 4290 + send_compression_encodings: Default::default(), 4291 + max_decoding_message_size: None, 4292 + max_encoding_message_size: None, 4293 + } 4294 + } 4295 + pub fn with_interceptor<F>( 4296 + inner: T, 4297 + interceptor: F, 4298 + ) -> InterceptedService<Self, F> 4299 + where 4300 + F: tonic::service::Interceptor, 4301 + { 4302 + InterceptedService::new(Self::new(inner), interceptor) 4303 + } 4304 + /// Enable decompressing requests with the given encoding. 4305 + #[must_use] 4306 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 4307 + self.accept_compression_encodings.enable(encoding); 4308 + self 4309 + } 4310 + /// Compress responses with the given encoding, if the client supports it. 4311 + #[must_use] 4312 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 4313 + self.send_compression_encodings.enable(encoding); 4314 + self 4315 + } 4316 + /// Limits the maximum size of a decoded message. 4317 + /// 4318 + /// Default: `4MB` 4319 + #[must_use] 4320 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 4321 + self.max_decoding_message_size = Some(limit); 4322 + self 4323 + } 4324 + /// Limits the maximum size of an encoded message. 4325 + /// 4326 + /// Default: `usize::MAX` 4327 + #[must_use] 4328 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 4329 + self.max_encoding_message_size = Some(limit); 4330 + self 4331 + } 4332 + } 4333 + impl<T, B> tonic::codegen::Service<http::Request<B>> for SettingsServiceServer<T> 4334 + where 4335 + T: SettingsService, 4336 + B: Body + std::marker::Send + 'static, 4337 + B::Error: Into<StdError> + std::marker::Send + 'static, 4338 + { 4339 + type Response = http::Response<tonic::body::BoxBody>; 4340 + type Error = std::convert::Infallible; 4341 + type Future = BoxFuture<Self::Response, Self::Error>; 4342 + fn poll_ready( 4343 + &mut self, 4344 + _cx: &mut Context<'_>, 4345 + ) -> Poll<std::result::Result<(), Self::Error>> { 4346 + Poll::Ready(Ok(())) 4347 + } 4348 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 4349 + match req.uri().path() { 4350 + "/rockbox.v1alpha1.SettingsService/GetSettingsList" => { 4351 + #[allow(non_camel_case_types)] 4352 + struct GetSettingsListSvc<T: SettingsService>(pub Arc<T>); 4353 + impl< 4354 + T: SettingsService, 4355 + > tonic::server::UnaryService<super::GetSettingsListRequest> 4356 + for GetSettingsListSvc<T> { 4357 + type Response = super::GetSettingsListResponse; 4358 + type Future = BoxFuture< 4359 + tonic::Response<Self::Response>, 4360 + tonic::Status, 4361 + >; 4362 + fn call( 4363 + &mut self, 4364 + request: tonic::Request<super::GetSettingsListRequest>, 4365 + ) -> Self::Future { 4366 + let inner = Arc::clone(&self.0); 4367 + let fut = async move { 4368 + <T as SettingsService>::get_settings_list(&inner, request) 4369 + .await 4370 + }; 4371 + Box::pin(fut) 4372 + } 4373 + } 4374 + let accept_compression_encodings = self.accept_compression_encodings; 4375 + let send_compression_encodings = self.send_compression_encodings; 4376 + let max_decoding_message_size = self.max_decoding_message_size; 4377 + let max_encoding_message_size = self.max_encoding_message_size; 4378 + let inner = self.inner.clone(); 4379 + let fut = async move { 4380 + let method = GetSettingsListSvc(inner); 4381 + let codec = tonic::codec::ProstCodec::default(); 4382 + let mut grpc = tonic::server::Grpc::new(codec) 4383 + .apply_compression_config( 4384 + accept_compression_encodings, 4385 + send_compression_encodings, 4386 + ) 4387 + .apply_max_message_size_config( 4388 + max_decoding_message_size, 4389 + max_encoding_message_size, 4390 + ); 4391 + let res = grpc.unary(method, req).await; 4392 + Ok(res) 4393 + }; 4394 + Box::pin(fut) 4395 + } 4396 + "/rockbox.v1alpha1.SettingsService/GetGlobalSettings" => { 4397 + #[allow(non_camel_case_types)] 4398 + struct GetGlobalSettingsSvc<T: SettingsService>(pub Arc<T>); 4399 + impl< 4400 + T: SettingsService, 4401 + > tonic::server::UnaryService<super::GetGlobalSettingsRequest> 4402 + for GetGlobalSettingsSvc<T> { 4403 + type Response = super::GetGlobalSettingsResponse; 4404 + type Future = BoxFuture< 4405 + tonic::Response<Self::Response>, 4406 + tonic::Status, 4407 + >; 4408 + fn call( 4409 + &mut self, 4410 + request: tonic::Request<super::GetGlobalSettingsRequest>, 4411 + ) -> Self::Future { 4412 + let inner = Arc::clone(&self.0); 4413 + let fut = async move { 4414 + <T as SettingsService>::get_global_settings(&inner, request) 4415 + .await 4416 + }; 4417 + Box::pin(fut) 4418 + } 4419 + } 4420 + let accept_compression_encodings = self.accept_compression_encodings; 4421 + let send_compression_encodings = self.send_compression_encodings; 4422 + let max_decoding_message_size = self.max_decoding_message_size; 4423 + let max_encoding_message_size = self.max_encoding_message_size; 4424 + let inner = self.inner.clone(); 4425 + let fut = async move { 4426 + let method = GetGlobalSettingsSvc(inner); 4427 + let codec = tonic::codec::ProstCodec::default(); 4428 + let mut grpc = tonic::server::Grpc::new(codec) 4429 + .apply_compression_config( 4430 + accept_compression_encodings, 4431 + send_compression_encodings, 4432 + ) 4433 + .apply_max_message_size_config( 4434 + max_decoding_message_size, 4435 + max_encoding_message_size, 4436 + ); 4437 + let res = grpc.unary(method, req).await; 4438 + Ok(res) 4439 + }; 4440 + Box::pin(fut) 4441 + } 4442 + _ => { 4443 + Box::pin(async move { 4444 + Ok( 4445 + http::Response::builder() 4446 + .status(200) 4447 + .header("grpc-status", tonic::Code::Unimplemented as i32) 4448 + .header( 4449 + http::header::CONTENT_TYPE, 4450 + tonic::metadata::GRPC_CONTENT_TYPE, 4451 + ) 4452 + .body(empty_body()) 4453 + .unwrap(), 4454 + ) 4455 + }) 4456 + } 4457 + } 4458 + } 4459 + } 4460 + impl<T> Clone for SettingsServiceServer<T> { 4461 + fn clone(&self) -> Self { 4462 + let inner = self.inner.clone(); 4463 + Self { 4464 + inner, 4465 + accept_compression_encodings: self.accept_compression_encodings, 4466 + send_compression_encodings: self.send_compression_encodings, 4467 + max_decoding_message_size: self.max_decoding_message_size, 4468 + max_encoding_message_size: self.max_encoding_message_size, 4469 + } 4470 + } 4471 + } 4472 + /// Generated gRPC service name 4473 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.SettingsService"; 4474 + impl<T> tonic::server::NamedService for SettingsServiceServer<T> { 4475 + const NAME: &'static str = SERVICE_NAME; 4476 + } 4477 + } 4478 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4479 + pub struct AdjustVolumeRequest { 4480 + #[prost(int32, tag = "1")] 4481 + pub steps: i32, 4482 + } 4483 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4484 + pub struct AdjustVolumeResponse {} 4485 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4486 + pub struct SoundSetRequest { 4487 + #[prost(int32, tag = "1")] 4488 + pub setting: i32, 4489 + #[prost(int32, tag = "2")] 4490 + pub value: i32, 4491 + } 4492 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4493 + pub struct SoundSetResponse {} 4494 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4495 + pub struct SoundCurrentRequest { 4496 + #[prost(int32, tag = "1")] 4497 + pub setting: i32, 4498 + } 4499 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4500 + pub struct SoundCurrentResponse { 4501 + #[prost(int32, tag = "1")] 4502 + pub value: i32, 4503 + } 4504 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4505 + pub struct SoundDefaultRequest { 4506 + #[prost(int32, tag = "1")] 4507 + pub setting: i32, 4508 + } 4509 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4510 + pub struct SoundDefaultResponse { 4511 + #[prost(int32, tag = "1")] 4512 + pub value: i32, 4513 + } 4514 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4515 + pub struct SoundMinRequest { 4516 + #[prost(int32, tag = "1")] 4517 + pub setting: i32, 4518 + } 4519 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4520 + pub struct SoundMinResponse { 4521 + #[prost(int32, tag = "1")] 4522 + pub value: i32, 4523 + } 4524 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4525 + pub struct SoundMaxRequest { 4526 + #[prost(int32, tag = "1")] 4527 + pub setting: i32, 4528 + } 4529 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4530 + pub struct SoundMaxResponse { 4531 + #[prost(int32, tag = "1")] 4532 + pub value: i32, 4533 + } 4534 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4535 + pub struct SoundUnitRequest {} 4536 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4537 + pub struct SoundUnitResponse {} 4538 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4539 + pub struct SoundVal2PhysRequest { 4540 + #[prost(int32, tag = "1")] 4541 + pub setting: i32, 4542 + #[prost(int32, tag = "2")] 4543 + pub value: i32, 4544 + } 4545 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4546 + pub struct SoundVal2PhysResponse { 4547 + #[prost(int32, tag = "1")] 4548 + pub value: i32, 4549 + } 4550 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4551 + pub struct GetPitchRequest {} 4552 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4553 + pub struct GetPitchResponse { 4554 + #[prost(int32, tag = "1")] 4555 + pub value: i32, 4556 + } 4557 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4558 + pub struct SetPitchRequest { 4559 + #[prost(int32, tag = "1")] 4560 + pub value: i32, 4561 + } 4562 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4563 + pub struct SetPitchResponse {} 4564 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4565 + pub struct BeepPlayRequest { 4566 + #[prost(uint32, tag = "1")] 4567 + pub frequency: u32, 4568 + #[prost(uint32, tag = "2")] 4569 + pub duration: u32, 4570 + #[prost(uint32, tag = "3")] 4571 + pub amplitude: u32, 4572 + } 4573 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4574 + pub struct BeepPlayResponse {} 4575 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4576 + pub struct PcmbufFadeRequest { 4577 + #[prost(int32, tag = "1")] 4578 + pub fade: i32, 4579 + #[prost(bool, tag = "2")] 4580 + pub r#in: bool, 4581 + } 4582 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4583 + pub struct PcmbufFadeResponse {} 4584 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4585 + pub struct PcmbufSetLowLatencyRequest { 4586 + #[prost(bool, tag = "1")] 4587 + pub state: bool, 4588 + } 4589 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4590 + pub struct PcmbufSetLowLatencyResponse {} 4591 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4592 + pub struct SystemSoundPlayRequest { 4593 + #[prost(uint32, tag = "1")] 4594 + pub sound: u32, 4595 + } 4596 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4597 + pub struct SystemSoundPlayResponse {} 4598 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4599 + pub struct KeyclickClickRequest { 4600 + #[prost(bool, tag = "1")] 4601 + pub rawbutton: bool, 4602 + #[prost(int32, tag = "2")] 4603 + pub action: i32, 4604 + } 4605 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 4606 + pub struct KeyclickClickResponse {} 4607 + /// Generated client implementations. 4608 + pub mod sound_service_client { 4609 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 4610 + use tonic::codegen::*; 4611 + use tonic::codegen::http::Uri; 4612 + #[derive(Debug, Clone)] 4613 + pub struct SoundServiceClient<T> { 4614 + inner: tonic::client::Grpc<T>, 4615 + } 4616 + impl SoundServiceClient<tonic::transport::Channel> { 4617 + /// Attempt to create a new client by connecting to a given endpoint. 4618 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 4619 + where 4620 + D: TryInto<tonic::transport::Endpoint>, 4621 + D::Error: Into<StdError>, 4622 + { 4623 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 4624 + Ok(Self::new(conn)) 4625 + } 4626 + } 4627 + impl<T> SoundServiceClient<T> 4628 + where 4629 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 4630 + T::Error: Into<StdError>, 4631 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 4632 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 4633 + { 4634 + pub fn new(inner: T) -> Self { 4635 + let inner = tonic::client::Grpc::new(inner); 4636 + Self { inner } 4637 + } 4638 + pub fn with_origin(inner: T, origin: Uri) -> Self { 4639 + let inner = tonic::client::Grpc::with_origin(inner, origin); 4640 + Self { inner } 4641 + } 4642 + pub fn with_interceptor<F>( 4643 + inner: T, 4644 + interceptor: F, 4645 + ) -> SoundServiceClient<InterceptedService<T, F>> 4646 + where 4647 + F: tonic::service::Interceptor, 4648 + T::ResponseBody: Default, 4649 + T: tonic::codegen::Service< 4650 + http::Request<tonic::body::BoxBody>, 4651 + Response = http::Response< 4652 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 4653 + >, 4654 + >, 4655 + <T as tonic::codegen::Service< 4656 + http::Request<tonic::body::BoxBody>, 4657 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 4658 + { 4659 + SoundServiceClient::new(InterceptedService::new(inner, interceptor)) 4660 + } 4661 + /// Compress requests with the given encoding. 4662 + /// 4663 + /// This requires the server to support it otherwise it might respond with an 4664 + /// error. 4665 + #[must_use] 4666 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 4667 + self.inner = self.inner.send_compressed(encoding); 4668 + self 4669 + } 4670 + /// Enable decompressing responses. 4671 + #[must_use] 4672 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 4673 + self.inner = self.inner.accept_compressed(encoding); 4674 + self 4675 + } 4676 + /// Limits the maximum size of a decoded message. 4677 + /// 4678 + /// Default: `4MB` 4679 + #[must_use] 4680 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 4681 + self.inner = self.inner.max_decoding_message_size(limit); 4682 + self 4683 + } 4684 + /// Limits the maximum size of an encoded message. 4685 + /// 4686 + /// Default: `usize::MAX` 4687 + #[must_use] 4688 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 4689 + self.inner = self.inner.max_encoding_message_size(limit); 4690 + self 4691 + } 4692 + pub async fn adjust_volume( 4693 + &mut self, 4694 + request: impl tonic::IntoRequest<super::AdjustVolumeRequest>, 4695 + ) -> std::result::Result< 4696 + tonic::Response<super::AdjustVolumeResponse>, 4697 + tonic::Status, 4698 + > { 4699 + self.inner 4700 + .ready() 4701 + .await 4702 + .map_err(|e| { 4703 + tonic::Status::new( 4704 + tonic::Code::Unknown, 4705 + format!("Service was not ready: {}", e.into()), 4706 + ) 4707 + })?; 4708 + let codec = tonic::codec::ProstCodec::default(); 4709 + let path = http::uri::PathAndQuery::from_static( 4710 + "/rockbox.v1alpha1.SoundService/AdjustVolume", 4711 + ); 4712 + let mut req = request.into_request(); 4713 + req.extensions_mut() 4714 + .insert( 4715 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "AdjustVolume"), 4716 + ); 4717 + self.inner.unary(req, path, codec).await 4718 + } 4719 + pub async fn sound_set( 4720 + &mut self, 4721 + request: impl tonic::IntoRequest<super::SoundSetRequest>, 4722 + ) -> std::result::Result< 4723 + tonic::Response<super::SoundSetResponse>, 4724 + tonic::Status, 4725 + > { 4726 + self.inner 4727 + .ready() 4728 + .await 4729 + .map_err(|e| { 4730 + tonic::Status::new( 4731 + tonic::Code::Unknown, 4732 + format!("Service was not ready: {}", e.into()), 4733 + ) 4734 + })?; 4735 + let codec = tonic::codec::ProstCodec::default(); 4736 + let path = http::uri::PathAndQuery::from_static( 4737 + "/rockbox.v1alpha1.SoundService/SoundSet", 4738 + ); 4739 + let mut req = request.into_request(); 4740 + req.extensions_mut() 4741 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundSet")); 4742 + self.inner.unary(req, path, codec).await 4743 + } 4744 + pub async fn sound_current( 4745 + &mut self, 4746 + request: impl tonic::IntoRequest<super::SoundCurrentRequest>, 4747 + ) -> std::result::Result< 4748 + tonic::Response<super::SoundCurrentResponse>, 4749 + tonic::Status, 4750 + > { 4751 + self.inner 4752 + .ready() 4753 + .await 4754 + .map_err(|e| { 4755 + tonic::Status::new( 4756 + tonic::Code::Unknown, 4757 + format!("Service was not ready: {}", e.into()), 4758 + ) 4759 + })?; 4760 + let codec = tonic::codec::ProstCodec::default(); 4761 + let path = http::uri::PathAndQuery::from_static( 4762 + "/rockbox.v1alpha1.SoundService/SoundCurrent", 4763 + ); 4764 + let mut req = request.into_request(); 4765 + req.extensions_mut() 4766 + .insert( 4767 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundCurrent"), 4768 + ); 4769 + self.inner.unary(req, path, codec).await 4770 + } 4771 + pub async fn sound_default( 4772 + &mut self, 4773 + request: impl tonic::IntoRequest<super::SoundDefaultRequest>, 4774 + ) -> std::result::Result< 4775 + tonic::Response<super::SoundDefaultResponse>, 4776 + tonic::Status, 4777 + > { 4778 + self.inner 4779 + .ready() 4780 + .await 4781 + .map_err(|e| { 4782 + tonic::Status::new( 4783 + tonic::Code::Unknown, 4784 + format!("Service was not ready: {}", e.into()), 4785 + ) 4786 + })?; 4787 + let codec = tonic::codec::ProstCodec::default(); 4788 + let path = http::uri::PathAndQuery::from_static( 4789 + "/rockbox.v1alpha1.SoundService/SoundDefault", 4790 + ); 4791 + let mut req = request.into_request(); 4792 + req.extensions_mut() 4793 + .insert( 4794 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundDefault"), 4795 + ); 4796 + self.inner.unary(req, path, codec).await 4797 + } 4798 + pub async fn sound_min( 4799 + &mut self, 4800 + request: impl tonic::IntoRequest<super::SoundMinRequest>, 4801 + ) -> std::result::Result< 4802 + tonic::Response<super::SoundMinResponse>, 4803 + tonic::Status, 4804 + > { 4805 + self.inner 4806 + .ready() 4807 + .await 4808 + .map_err(|e| { 4809 + tonic::Status::new( 4810 + tonic::Code::Unknown, 4811 + format!("Service was not ready: {}", e.into()), 4812 + ) 4813 + })?; 4814 + let codec = tonic::codec::ProstCodec::default(); 4815 + let path = http::uri::PathAndQuery::from_static( 4816 + "/rockbox.v1alpha1.SoundService/SoundMin", 4817 + ); 4818 + let mut req = request.into_request(); 4819 + req.extensions_mut() 4820 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundMin")); 4821 + self.inner.unary(req, path, codec).await 4822 + } 4823 + pub async fn sound_max( 4824 + &mut self, 4825 + request: impl tonic::IntoRequest<super::SoundMaxRequest>, 4826 + ) -> std::result::Result< 4827 + tonic::Response<super::SoundMaxResponse>, 4828 + tonic::Status, 4829 + > { 4830 + self.inner 4831 + .ready() 4832 + .await 4833 + .map_err(|e| { 4834 + tonic::Status::new( 4835 + tonic::Code::Unknown, 4836 + format!("Service was not ready: {}", e.into()), 4837 + ) 4838 + })?; 4839 + let codec = tonic::codec::ProstCodec::default(); 4840 + let path = http::uri::PathAndQuery::from_static( 4841 + "/rockbox.v1alpha1.SoundService/SoundMax", 4842 + ); 4843 + let mut req = request.into_request(); 4844 + req.extensions_mut() 4845 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundMax")); 4846 + self.inner.unary(req, path, codec).await 4847 + } 4848 + pub async fn sound_unit( 4849 + &mut self, 4850 + request: impl tonic::IntoRequest<super::SoundUnitRequest>, 4851 + ) -> std::result::Result< 4852 + tonic::Response<super::SoundUnitResponse>, 4853 + tonic::Status, 4854 + > { 4855 + self.inner 4856 + .ready() 4857 + .await 4858 + .map_err(|e| { 4859 + tonic::Status::new( 4860 + tonic::Code::Unknown, 4861 + format!("Service was not ready: {}", e.into()), 4862 + ) 4863 + })?; 4864 + let codec = tonic::codec::ProstCodec::default(); 4865 + let path = http::uri::PathAndQuery::from_static( 4866 + "/rockbox.v1alpha1.SoundService/SoundUnit", 4867 + ); 4868 + let mut req = request.into_request(); 4869 + req.extensions_mut() 4870 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundUnit")); 4871 + self.inner.unary(req, path, codec).await 4872 + } 4873 + pub async fn sound_val2_phys( 4874 + &mut self, 4875 + request: impl tonic::IntoRequest<super::SoundVal2PhysRequest>, 4876 + ) -> std::result::Result< 4877 + tonic::Response<super::SoundVal2PhysResponse>, 4878 + tonic::Status, 4879 + > { 4880 + self.inner 4881 + .ready() 4882 + .await 4883 + .map_err(|e| { 4884 + tonic::Status::new( 4885 + tonic::Code::Unknown, 4886 + format!("Service was not ready: {}", e.into()), 4887 + ) 4888 + })?; 4889 + let codec = tonic::codec::ProstCodec::default(); 4890 + let path = http::uri::PathAndQuery::from_static( 4891 + "/rockbox.v1alpha1.SoundService/SoundVal2Phys", 4892 + ); 4893 + let mut req = request.into_request(); 4894 + req.extensions_mut() 4895 + .insert( 4896 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundVal2Phys"), 4897 + ); 4898 + self.inner.unary(req, path, codec).await 4899 + } 4900 + pub async fn get_pitch( 4901 + &mut self, 4902 + request: impl tonic::IntoRequest<super::GetPitchRequest>, 4903 + ) -> std::result::Result< 4904 + tonic::Response<super::GetPitchResponse>, 4905 + tonic::Status, 4906 + > { 4907 + self.inner 4908 + .ready() 4909 + .await 4910 + .map_err(|e| { 4911 + tonic::Status::new( 4912 + tonic::Code::Unknown, 4913 + format!("Service was not ready: {}", e.into()), 4914 + ) 4915 + })?; 4916 + let codec = tonic::codec::ProstCodec::default(); 4917 + let path = http::uri::PathAndQuery::from_static( 4918 + "/rockbox.v1alpha1.SoundService/GetPitch", 4919 + ); 4920 + let mut req = request.into_request(); 4921 + req.extensions_mut() 4922 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "GetPitch")); 4923 + self.inner.unary(req, path, codec).await 4924 + } 4925 + pub async fn set_pitch( 4926 + &mut self, 4927 + request: impl tonic::IntoRequest<super::SetPitchRequest>, 4928 + ) -> std::result::Result< 4929 + tonic::Response<super::SetPitchResponse>, 4930 + tonic::Status, 4931 + > { 4932 + self.inner 4933 + .ready() 4934 + .await 4935 + .map_err(|e| { 4936 + tonic::Status::new( 4937 + tonic::Code::Unknown, 4938 + format!("Service was not ready: {}", e.into()), 4939 + ) 4940 + })?; 4941 + let codec = tonic::codec::ProstCodec::default(); 4942 + let path = http::uri::PathAndQuery::from_static( 4943 + "/rockbox.v1alpha1.SoundService/SetPitch", 4944 + ); 4945 + let mut req = request.into_request(); 4946 + req.extensions_mut() 4947 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SetPitch")); 4948 + self.inner.unary(req, path, codec).await 4949 + } 4950 + pub async fn beep_play( 4951 + &mut self, 4952 + request: impl tonic::IntoRequest<super::BeepPlayRequest>, 4953 + ) -> std::result::Result< 4954 + tonic::Response<super::BeepPlayResponse>, 4955 + tonic::Status, 4956 + > { 4957 + self.inner 4958 + .ready() 4959 + .await 4960 + .map_err(|e| { 4961 + tonic::Status::new( 4962 + tonic::Code::Unknown, 4963 + format!("Service was not ready: {}", e.into()), 4964 + ) 4965 + })?; 4966 + let codec = tonic::codec::ProstCodec::default(); 4967 + let path = http::uri::PathAndQuery::from_static( 4968 + "/rockbox.v1alpha1.SoundService/BeepPlay", 4969 + ); 4970 + let mut req = request.into_request(); 4971 + req.extensions_mut() 4972 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "BeepPlay")); 4973 + self.inner.unary(req, path, codec).await 4974 + } 4975 + pub async fn pcmbuf_fade( 4976 + &mut self, 4977 + request: impl tonic::IntoRequest<super::PcmbufFadeRequest>, 4978 + ) -> std::result::Result< 4979 + tonic::Response<super::PcmbufFadeResponse>, 4980 + tonic::Status, 4981 + > { 4982 + self.inner 4983 + .ready() 4984 + .await 4985 + .map_err(|e| { 4986 + tonic::Status::new( 4987 + tonic::Code::Unknown, 4988 + format!("Service was not ready: {}", e.into()), 4989 + ) 4990 + })?; 4991 + let codec = tonic::codec::ProstCodec::default(); 4992 + let path = http::uri::PathAndQuery::from_static( 4993 + "/rockbox.v1alpha1.SoundService/PcmbufFade", 4994 + ); 4995 + let mut req = request.into_request(); 4996 + req.extensions_mut() 4997 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "PcmbufFade")); 4998 + self.inner.unary(req, path, codec).await 4999 + } 5000 + pub async fn pcmbuf_set_low_latency( 5001 + &mut self, 5002 + request: impl tonic::IntoRequest<super::PcmbufSetLowLatencyRequest>, 5003 + ) -> std::result::Result< 5004 + tonic::Response<super::PcmbufSetLowLatencyResponse>, 5005 + tonic::Status, 5006 + > { 5007 + self.inner 5008 + .ready() 5009 + .await 5010 + .map_err(|e| { 5011 + tonic::Status::new( 5012 + tonic::Code::Unknown, 5013 + format!("Service was not ready: {}", e.into()), 5014 + ) 5015 + })?; 5016 + let codec = tonic::codec::ProstCodec::default(); 5017 + let path = http::uri::PathAndQuery::from_static( 5018 + "/rockbox.v1alpha1.SoundService/PcmbufSetLowLatency", 5019 + ); 5020 + let mut req = request.into_request(); 5021 + req.extensions_mut() 5022 + .insert( 5023 + GrpcMethod::new( 5024 + "rockbox.v1alpha1.SoundService", 5025 + "PcmbufSetLowLatency", 5026 + ), 5027 + ); 5028 + self.inner.unary(req, path, codec).await 5029 + } 5030 + pub async fn system_sound_play( 5031 + &mut self, 5032 + request: impl tonic::IntoRequest<super::SystemSoundPlayRequest>, 5033 + ) -> std::result::Result< 5034 + tonic::Response<super::SystemSoundPlayResponse>, 5035 + tonic::Status, 5036 + > { 5037 + self.inner 5038 + .ready() 5039 + .await 5040 + .map_err(|e| { 5041 + tonic::Status::new( 5042 + tonic::Code::Unknown, 5043 + format!("Service was not ready: {}", e.into()), 5044 + ) 5045 + })?; 5046 + let codec = tonic::codec::ProstCodec::default(); 5047 + let path = http::uri::PathAndQuery::from_static( 5048 + "/rockbox.v1alpha1.SoundService/SystemSoundPlay", 5049 + ); 5050 + let mut req = request.into_request(); 5051 + req.extensions_mut() 5052 + .insert( 5053 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SystemSoundPlay"), 5054 + ); 5055 + self.inner.unary(req, path, codec).await 5056 + } 5057 + pub async fn keyclick_click( 5058 + &mut self, 5059 + request: impl tonic::IntoRequest<super::KeyclickClickRequest>, 5060 + ) -> std::result::Result< 5061 + tonic::Response<super::KeyclickClickResponse>, 5062 + tonic::Status, 5063 + > { 5064 + self.inner 5065 + .ready() 5066 + .await 5067 + .map_err(|e| { 5068 + tonic::Status::new( 5069 + tonic::Code::Unknown, 5070 + format!("Service was not ready: {}", e.into()), 5071 + ) 5072 + })?; 5073 + let codec = tonic::codec::ProstCodec::default(); 5074 + let path = http::uri::PathAndQuery::from_static( 5075 + "/rockbox.v1alpha1.SoundService/KeyclickClick", 5076 + ); 5077 + let mut req = request.into_request(); 5078 + req.extensions_mut() 5079 + .insert( 5080 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "KeyclickClick"), 5081 + ); 5082 + self.inner.unary(req, path, codec).await 5083 + } 5084 + } 5085 + } 5086 + /// Generated server implementations. 5087 + pub mod sound_service_server { 5088 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 5089 + use tonic::codegen::*; 5090 + /// Generated trait containing gRPC methods that should be implemented for use with SoundServiceServer. 5091 + #[async_trait] 5092 + pub trait SoundService: std::marker::Send + std::marker::Sync + 'static { 5093 + async fn adjust_volume( 5094 + &self, 5095 + request: tonic::Request<super::AdjustVolumeRequest>, 5096 + ) -> std::result::Result< 5097 + tonic::Response<super::AdjustVolumeResponse>, 5098 + tonic::Status, 5099 + >; 5100 + async fn sound_set( 5101 + &self, 5102 + request: tonic::Request<super::SoundSetRequest>, 5103 + ) -> std::result::Result< 5104 + tonic::Response<super::SoundSetResponse>, 5105 + tonic::Status, 5106 + >; 5107 + async fn sound_current( 5108 + &self, 5109 + request: tonic::Request<super::SoundCurrentRequest>, 5110 + ) -> std::result::Result< 5111 + tonic::Response<super::SoundCurrentResponse>, 5112 + tonic::Status, 5113 + >; 5114 + async fn sound_default( 5115 + &self, 5116 + request: tonic::Request<super::SoundDefaultRequest>, 5117 + ) -> std::result::Result< 5118 + tonic::Response<super::SoundDefaultResponse>, 5119 + tonic::Status, 5120 + >; 5121 + async fn sound_min( 5122 + &self, 5123 + request: tonic::Request<super::SoundMinRequest>, 5124 + ) -> std::result::Result< 5125 + tonic::Response<super::SoundMinResponse>, 5126 + tonic::Status, 5127 + >; 5128 + async fn sound_max( 5129 + &self, 5130 + request: tonic::Request<super::SoundMaxRequest>, 5131 + ) -> std::result::Result< 5132 + tonic::Response<super::SoundMaxResponse>, 5133 + tonic::Status, 5134 + >; 5135 + async fn sound_unit( 5136 + &self, 5137 + request: tonic::Request<super::SoundUnitRequest>, 5138 + ) -> std::result::Result< 5139 + tonic::Response<super::SoundUnitResponse>, 5140 + tonic::Status, 5141 + >; 5142 + async fn sound_val2_phys( 5143 + &self, 5144 + request: tonic::Request<super::SoundVal2PhysRequest>, 5145 + ) -> std::result::Result< 5146 + tonic::Response<super::SoundVal2PhysResponse>, 5147 + tonic::Status, 5148 + >; 5149 + async fn get_pitch( 5150 + &self, 5151 + request: tonic::Request<super::GetPitchRequest>, 5152 + ) -> std::result::Result< 5153 + tonic::Response<super::GetPitchResponse>, 5154 + tonic::Status, 5155 + >; 5156 + async fn set_pitch( 5157 + &self, 5158 + request: tonic::Request<super::SetPitchRequest>, 5159 + ) -> std::result::Result< 5160 + tonic::Response<super::SetPitchResponse>, 5161 + tonic::Status, 5162 + >; 5163 + async fn beep_play( 5164 + &self, 5165 + request: tonic::Request<super::BeepPlayRequest>, 5166 + ) -> std::result::Result< 5167 + tonic::Response<super::BeepPlayResponse>, 5168 + tonic::Status, 5169 + >; 5170 + async fn pcmbuf_fade( 5171 + &self, 5172 + request: tonic::Request<super::PcmbufFadeRequest>, 5173 + ) -> std::result::Result< 5174 + tonic::Response<super::PcmbufFadeResponse>, 5175 + tonic::Status, 5176 + >; 5177 + async fn pcmbuf_set_low_latency( 5178 + &self, 5179 + request: tonic::Request<super::PcmbufSetLowLatencyRequest>, 5180 + ) -> std::result::Result< 5181 + tonic::Response<super::PcmbufSetLowLatencyResponse>, 5182 + tonic::Status, 5183 + >; 5184 + async fn system_sound_play( 5185 + &self, 5186 + request: tonic::Request<super::SystemSoundPlayRequest>, 5187 + ) -> std::result::Result< 5188 + tonic::Response<super::SystemSoundPlayResponse>, 5189 + tonic::Status, 5190 + >; 5191 + async fn keyclick_click( 5192 + &self, 5193 + request: tonic::Request<super::KeyclickClickRequest>, 5194 + ) -> std::result::Result< 5195 + tonic::Response<super::KeyclickClickResponse>, 5196 + tonic::Status, 5197 + >; 5198 + } 5199 + #[derive(Debug)] 5200 + pub struct SoundServiceServer<T> { 5201 + inner: Arc<T>, 5202 + accept_compression_encodings: EnabledCompressionEncodings, 5203 + send_compression_encodings: EnabledCompressionEncodings, 5204 + max_decoding_message_size: Option<usize>, 5205 + max_encoding_message_size: Option<usize>, 5206 + } 5207 + impl<T> SoundServiceServer<T> { 5208 + pub fn new(inner: T) -> Self { 5209 + Self::from_arc(Arc::new(inner)) 5210 + } 5211 + pub fn from_arc(inner: Arc<T>) -> Self { 5212 + Self { 5213 + inner, 5214 + accept_compression_encodings: Default::default(), 5215 + send_compression_encodings: Default::default(), 5216 + max_decoding_message_size: None, 5217 + max_encoding_message_size: None, 5218 + } 5219 + } 5220 + pub fn with_interceptor<F>( 5221 + inner: T, 5222 + interceptor: F, 5223 + ) -> InterceptedService<Self, F> 5224 + where 5225 + F: tonic::service::Interceptor, 5226 + { 5227 + InterceptedService::new(Self::new(inner), interceptor) 5228 + } 5229 + /// Enable decompressing requests with the given encoding. 5230 + #[must_use] 5231 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 5232 + self.accept_compression_encodings.enable(encoding); 5233 + self 5234 + } 5235 + /// Compress responses with the given encoding, if the client supports it. 5236 + #[must_use] 5237 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 5238 + self.send_compression_encodings.enable(encoding); 5239 + self 5240 + } 5241 + /// Limits the maximum size of a decoded message. 5242 + /// 5243 + /// Default: `4MB` 5244 + #[must_use] 5245 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 5246 + self.max_decoding_message_size = Some(limit); 5247 + self 5248 + } 5249 + /// Limits the maximum size of an encoded message. 5250 + /// 5251 + /// Default: `usize::MAX` 5252 + #[must_use] 5253 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 5254 + self.max_encoding_message_size = Some(limit); 5255 + self 5256 + } 5257 + } 5258 + impl<T, B> tonic::codegen::Service<http::Request<B>> for SoundServiceServer<T> 5259 + where 5260 + T: SoundService, 5261 + B: Body + std::marker::Send + 'static, 5262 + B::Error: Into<StdError> + std::marker::Send + 'static, 5263 + { 5264 + type Response = http::Response<tonic::body::BoxBody>; 5265 + type Error = std::convert::Infallible; 5266 + type Future = BoxFuture<Self::Response, Self::Error>; 5267 + fn poll_ready( 5268 + &mut self, 5269 + _cx: &mut Context<'_>, 5270 + ) -> Poll<std::result::Result<(), Self::Error>> { 5271 + Poll::Ready(Ok(())) 5272 + } 5273 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 5274 + match req.uri().path() { 5275 + "/rockbox.v1alpha1.SoundService/AdjustVolume" => { 5276 + #[allow(non_camel_case_types)] 5277 + struct AdjustVolumeSvc<T: SoundService>(pub Arc<T>); 5278 + impl< 5279 + T: SoundService, 5280 + > tonic::server::UnaryService<super::AdjustVolumeRequest> 5281 + for AdjustVolumeSvc<T> { 5282 + type Response = super::AdjustVolumeResponse; 5283 + type Future = BoxFuture< 5284 + tonic::Response<Self::Response>, 5285 + tonic::Status, 5286 + >; 5287 + fn call( 5288 + &mut self, 5289 + request: tonic::Request<super::AdjustVolumeRequest>, 5290 + ) -> Self::Future { 5291 + let inner = Arc::clone(&self.0); 5292 + let fut = async move { 5293 + <T as SoundService>::adjust_volume(&inner, request).await 5294 + }; 5295 + Box::pin(fut) 5296 + } 5297 + } 5298 + let accept_compression_encodings = self.accept_compression_encodings; 5299 + let send_compression_encodings = self.send_compression_encodings; 5300 + let max_decoding_message_size = self.max_decoding_message_size; 5301 + let max_encoding_message_size = self.max_encoding_message_size; 5302 + let inner = self.inner.clone(); 5303 + let fut = async move { 5304 + let method = AdjustVolumeSvc(inner); 5305 + let codec = tonic::codec::ProstCodec::default(); 5306 + let mut grpc = tonic::server::Grpc::new(codec) 5307 + .apply_compression_config( 5308 + accept_compression_encodings, 5309 + send_compression_encodings, 5310 + ) 5311 + .apply_max_message_size_config( 5312 + max_decoding_message_size, 5313 + max_encoding_message_size, 5314 + ); 5315 + let res = grpc.unary(method, req).await; 5316 + Ok(res) 5317 + }; 5318 + Box::pin(fut) 5319 + } 5320 + "/rockbox.v1alpha1.SoundService/SoundSet" => { 5321 + #[allow(non_camel_case_types)] 5322 + struct SoundSetSvc<T: SoundService>(pub Arc<T>); 5323 + impl< 5324 + T: SoundService, 5325 + > tonic::server::UnaryService<super::SoundSetRequest> 5326 + for SoundSetSvc<T> { 5327 + type Response = super::SoundSetResponse; 5328 + type Future = BoxFuture< 5329 + tonic::Response<Self::Response>, 5330 + tonic::Status, 5331 + >; 5332 + fn call( 5333 + &mut self, 5334 + request: tonic::Request<super::SoundSetRequest>, 5335 + ) -> Self::Future { 5336 + let inner = Arc::clone(&self.0); 5337 + let fut = async move { 5338 + <T as SoundService>::sound_set(&inner, request).await 5339 + }; 5340 + Box::pin(fut) 5341 + } 5342 + } 5343 + let accept_compression_encodings = self.accept_compression_encodings; 5344 + let send_compression_encodings = self.send_compression_encodings; 5345 + let max_decoding_message_size = self.max_decoding_message_size; 5346 + let max_encoding_message_size = self.max_encoding_message_size; 5347 + let inner = self.inner.clone(); 5348 + let fut = async move { 5349 + let method = SoundSetSvc(inner); 5350 + let codec = tonic::codec::ProstCodec::default(); 5351 + let mut grpc = tonic::server::Grpc::new(codec) 5352 + .apply_compression_config( 5353 + accept_compression_encodings, 5354 + send_compression_encodings, 5355 + ) 5356 + .apply_max_message_size_config( 5357 + max_decoding_message_size, 5358 + max_encoding_message_size, 5359 + ); 5360 + let res = grpc.unary(method, req).await; 5361 + Ok(res) 5362 + }; 5363 + Box::pin(fut) 5364 + } 5365 + "/rockbox.v1alpha1.SoundService/SoundCurrent" => { 5366 + #[allow(non_camel_case_types)] 5367 + struct SoundCurrentSvc<T: SoundService>(pub Arc<T>); 5368 + impl< 5369 + T: SoundService, 5370 + > tonic::server::UnaryService<super::SoundCurrentRequest> 5371 + for SoundCurrentSvc<T> { 5372 + type Response = super::SoundCurrentResponse; 5373 + type Future = BoxFuture< 5374 + tonic::Response<Self::Response>, 5375 + tonic::Status, 5376 + >; 5377 + fn call( 5378 + &mut self, 5379 + request: tonic::Request<super::SoundCurrentRequest>, 5380 + ) -> Self::Future { 5381 + let inner = Arc::clone(&self.0); 5382 + let fut = async move { 5383 + <T as SoundService>::sound_current(&inner, request).await 5384 + }; 5385 + Box::pin(fut) 5386 + } 5387 + } 5388 + let accept_compression_encodings = self.accept_compression_encodings; 5389 + let send_compression_encodings = self.send_compression_encodings; 5390 + let max_decoding_message_size = self.max_decoding_message_size; 5391 + let max_encoding_message_size = self.max_encoding_message_size; 5392 + let inner = self.inner.clone(); 5393 + let fut = async move { 5394 + let method = SoundCurrentSvc(inner); 5395 + let codec = tonic::codec::ProstCodec::default(); 5396 + let mut grpc = tonic::server::Grpc::new(codec) 5397 + .apply_compression_config( 5398 + accept_compression_encodings, 5399 + send_compression_encodings, 5400 + ) 5401 + .apply_max_message_size_config( 5402 + max_decoding_message_size, 5403 + max_encoding_message_size, 5404 + ); 5405 + let res = grpc.unary(method, req).await; 5406 + Ok(res) 5407 + }; 5408 + Box::pin(fut) 5409 + } 5410 + "/rockbox.v1alpha1.SoundService/SoundDefault" => { 5411 + #[allow(non_camel_case_types)] 5412 + struct SoundDefaultSvc<T: SoundService>(pub Arc<T>); 5413 + impl< 5414 + T: SoundService, 5415 + > tonic::server::UnaryService<super::SoundDefaultRequest> 5416 + for SoundDefaultSvc<T> { 5417 + type Response = super::SoundDefaultResponse; 5418 + type Future = BoxFuture< 5419 + tonic::Response<Self::Response>, 5420 + tonic::Status, 5421 + >; 5422 + fn call( 5423 + &mut self, 5424 + request: tonic::Request<super::SoundDefaultRequest>, 5425 + ) -> Self::Future { 5426 + let inner = Arc::clone(&self.0); 5427 + let fut = async move { 5428 + <T as SoundService>::sound_default(&inner, request).await 5429 + }; 5430 + Box::pin(fut) 5431 + } 5432 + } 5433 + let accept_compression_encodings = self.accept_compression_encodings; 5434 + let send_compression_encodings = self.send_compression_encodings; 5435 + let max_decoding_message_size = self.max_decoding_message_size; 5436 + let max_encoding_message_size = self.max_encoding_message_size; 5437 + let inner = self.inner.clone(); 5438 + let fut = async move { 5439 + let method = SoundDefaultSvc(inner); 5440 + let codec = tonic::codec::ProstCodec::default(); 5441 + let mut grpc = tonic::server::Grpc::new(codec) 5442 + .apply_compression_config( 5443 + accept_compression_encodings, 5444 + send_compression_encodings, 5445 + ) 5446 + .apply_max_message_size_config( 5447 + max_decoding_message_size, 5448 + max_encoding_message_size, 5449 + ); 5450 + let res = grpc.unary(method, req).await; 5451 + Ok(res) 5452 + }; 5453 + Box::pin(fut) 5454 + } 5455 + "/rockbox.v1alpha1.SoundService/SoundMin" => { 5456 + #[allow(non_camel_case_types)] 5457 + struct SoundMinSvc<T: SoundService>(pub Arc<T>); 5458 + impl< 5459 + T: SoundService, 5460 + > tonic::server::UnaryService<super::SoundMinRequest> 5461 + for SoundMinSvc<T> { 5462 + type Response = super::SoundMinResponse; 5463 + type Future = BoxFuture< 5464 + tonic::Response<Self::Response>, 5465 + tonic::Status, 5466 + >; 5467 + fn call( 5468 + &mut self, 5469 + request: tonic::Request<super::SoundMinRequest>, 5470 + ) -> Self::Future { 5471 + let inner = Arc::clone(&self.0); 5472 + let fut = async move { 5473 + <T as SoundService>::sound_min(&inner, request).await 5474 + }; 5475 + Box::pin(fut) 5476 + } 5477 + } 5478 + let accept_compression_encodings = self.accept_compression_encodings; 5479 + let send_compression_encodings = self.send_compression_encodings; 5480 + let max_decoding_message_size = self.max_decoding_message_size; 5481 + let max_encoding_message_size = self.max_encoding_message_size; 5482 + let inner = self.inner.clone(); 5483 + let fut = async move { 5484 + let method = SoundMinSvc(inner); 5485 + let codec = tonic::codec::ProstCodec::default(); 5486 + let mut grpc = tonic::server::Grpc::new(codec) 5487 + .apply_compression_config( 5488 + accept_compression_encodings, 5489 + send_compression_encodings, 5490 + ) 5491 + .apply_max_message_size_config( 5492 + max_decoding_message_size, 5493 + max_encoding_message_size, 5494 + ); 5495 + let res = grpc.unary(method, req).await; 5496 + Ok(res) 5497 + }; 5498 + Box::pin(fut) 5499 + } 5500 + "/rockbox.v1alpha1.SoundService/SoundMax" => { 5501 + #[allow(non_camel_case_types)] 5502 + struct SoundMaxSvc<T: SoundService>(pub Arc<T>); 5503 + impl< 5504 + T: SoundService, 5505 + > tonic::server::UnaryService<super::SoundMaxRequest> 5506 + for SoundMaxSvc<T> { 5507 + type Response = super::SoundMaxResponse; 5508 + type Future = BoxFuture< 5509 + tonic::Response<Self::Response>, 5510 + tonic::Status, 5511 + >; 5512 + fn call( 5513 + &mut self, 5514 + request: tonic::Request<super::SoundMaxRequest>, 5515 + ) -> Self::Future { 5516 + let inner = Arc::clone(&self.0); 5517 + let fut = async move { 5518 + <T as SoundService>::sound_max(&inner, request).await 5519 + }; 5520 + Box::pin(fut) 5521 + } 5522 + } 5523 + let accept_compression_encodings = self.accept_compression_encodings; 5524 + let send_compression_encodings = self.send_compression_encodings; 5525 + let max_decoding_message_size = self.max_decoding_message_size; 5526 + let max_encoding_message_size = self.max_encoding_message_size; 5527 + let inner = self.inner.clone(); 5528 + let fut = async move { 5529 + let method = SoundMaxSvc(inner); 5530 + let codec = tonic::codec::ProstCodec::default(); 5531 + let mut grpc = tonic::server::Grpc::new(codec) 5532 + .apply_compression_config( 5533 + accept_compression_encodings, 5534 + send_compression_encodings, 5535 + ) 5536 + .apply_max_message_size_config( 5537 + max_decoding_message_size, 5538 + max_encoding_message_size, 5539 + ); 5540 + let res = grpc.unary(method, req).await; 5541 + Ok(res) 5542 + }; 5543 + Box::pin(fut) 5544 + } 5545 + "/rockbox.v1alpha1.SoundService/SoundUnit" => { 5546 + #[allow(non_camel_case_types)] 5547 + struct SoundUnitSvc<T: SoundService>(pub Arc<T>); 5548 + impl< 5549 + T: SoundService, 5550 + > tonic::server::UnaryService<super::SoundUnitRequest> 5551 + for SoundUnitSvc<T> { 5552 + type Response = super::SoundUnitResponse; 5553 + type Future = BoxFuture< 5554 + tonic::Response<Self::Response>, 5555 + tonic::Status, 5556 + >; 5557 + fn call( 5558 + &mut self, 5559 + request: tonic::Request<super::SoundUnitRequest>, 5560 + ) -> Self::Future { 5561 + let inner = Arc::clone(&self.0); 5562 + let fut = async move { 5563 + <T as SoundService>::sound_unit(&inner, request).await 5564 + }; 5565 + Box::pin(fut) 5566 + } 5567 + } 5568 + let accept_compression_encodings = self.accept_compression_encodings; 5569 + let send_compression_encodings = self.send_compression_encodings; 5570 + let max_decoding_message_size = self.max_decoding_message_size; 5571 + let max_encoding_message_size = self.max_encoding_message_size; 5572 + let inner = self.inner.clone(); 5573 + let fut = async move { 5574 + let method = SoundUnitSvc(inner); 5575 + let codec = tonic::codec::ProstCodec::default(); 5576 + let mut grpc = tonic::server::Grpc::new(codec) 5577 + .apply_compression_config( 5578 + accept_compression_encodings, 5579 + send_compression_encodings, 5580 + ) 5581 + .apply_max_message_size_config( 5582 + max_decoding_message_size, 5583 + max_encoding_message_size, 5584 + ); 5585 + let res = grpc.unary(method, req).await; 5586 + Ok(res) 5587 + }; 5588 + Box::pin(fut) 5589 + } 5590 + "/rockbox.v1alpha1.SoundService/SoundVal2Phys" => { 5591 + #[allow(non_camel_case_types)] 5592 + struct SoundVal2PhysSvc<T: SoundService>(pub Arc<T>); 5593 + impl< 5594 + T: SoundService, 5595 + > tonic::server::UnaryService<super::SoundVal2PhysRequest> 5596 + for SoundVal2PhysSvc<T> { 5597 + type Response = super::SoundVal2PhysResponse; 5598 + type Future = BoxFuture< 5599 + tonic::Response<Self::Response>, 5600 + tonic::Status, 5601 + >; 5602 + fn call( 5603 + &mut self, 5604 + request: tonic::Request<super::SoundVal2PhysRequest>, 5605 + ) -> Self::Future { 5606 + let inner = Arc::clone(&self.0); 5607 + let fut = async move { 5608 + <T as SoundService>::sound_val2_phys(&inner, request).await 5609 + }; 5610 + Box::pin(fut) 5611 + } 5612 + } 5613 + let accept_compression_encodings = self.accept_compression_encodings; 5614 + let send_compression_encodings = self.send_compression_encodings; 5615 + let max_decoding_message_size = self.max_decoding_message_size; 5616 + let max_encoding_message_size = self.max_encoding_message_size; 5617 + let inner = self.inner.clone(); 5618 + let fut = async move { 5619 + let method = SoundVal2PhysSvc(inner); 5620 + let codec = tonic::codec::ProstCodec::default(); 5621 + let mut grpc = tonic::server::Grpc::new(codec) 5622 + .apply_compression_config( 5623 + accept_compression_encodings, 5624 + send_compression_encodings, 5625 + ) 5626 + .apply_max_message_size_config( 5627 + max_decoding_message_size, 5628 + max_encoding_message_size, 5629 + ); 5630 + let res = grpc.unary(method, req).await; 5631 + Ok(res) 5632 + }; 5633 + Box::pin(fut) 5634 + } 5635 + "/rockbox.v1alpha1.SoundService/GetPitch" => { 5636 + #[allow(non_camel_case_types)] 5637 + struct GetPitchSvc<T: SoundService>(pub Arc<T>); 5638 + impl< 5639 + T: SoundService, 5640 + > tonic::server::UnaryService<super::GetPitchRequest> 5641 + for GetPitchSvc<T> { 5642 + type Response = super::GetPitchResponse; 5643 + type Future = BoxFuture< 5644 + tonic::Response<Self::Response>, 5645 + tonic::Status, 5646 + >; 5647 + fn call( 5648 + &mut self, 5649 + request: tonic::Request<super::GetPitchRequest>, 5650 + ) -> Self::Future { 5651 + let inner = Arc::clone(&self.0); 5652 + let fut = async move { 5653 + <T as SoundService>::get_pitch(&inner, request).await 5654 + }; 5655 + Box::pin(fut) 5656 + } 5657 + } 5658 + let accept_compression_encodings = self.accept_compression_encodings; 5659 + let send_compression_encodings = self.send_compression_encodings; 5660 + let max_decoding_message_size = self.max_decoding_message_size; 5661 + let max_encoding_message_size = self.max_encoding_message_size; 5662 + let inner = self.inner.clone(); 5663 + let fut = async move { 5664 + let method = GetPitchSvc(inner); 5665 + let codec = tonic::codec::ProstCodec::default(); 5666 + let mut grpc = tonic::server::Grpc::new(codec) 5667 + .apply_compression_config( 5668 + accept_compression_encodings, 5669 + send_compression_encodings, 5670 + ) 5671 + .apply_max_message_size_config( 5672 + max_decoding_message_size, 5673 + max_encoding_message_size, 5674 + ); 5675 + let res = grpc.unary(method, req).await; 5676 + Ok(res) 5677 + }; 5678 + Box::pin(fut) 5679 + } 5680 + "/rockbox.v1alpha1.SoundService/SetPitch" => { 5681 + #[allow(non_camel_case_types)] 5682 + struct SetPitchSvc<T: SoundService>(pub Arc<T>); 5683 + impl< 5684 + T: SoundService, 5685 + > tonic::server::UnaryService<super::SetPitchRequest> 5686 + for SetPitchSvc<T> { 5687 + type Response = super::SetPitchResponse; 5688 + type Future = BoxFuture< 5689 + tonic::Response<Self::Response>, 5690 + tonic::Status, 5691 + >; 5692 + fn call( 5693 + &mut self, 5694 + request: tonic::Request<super::SetPitchRequest>, 5695 + ) -> Self::Future { 5696 + let inner = Arc::clone(&self.0); 5697 + let fut = async move { 5698 + <T as SoundService>::set_pitch(&inner, request).await 5699 + }; 5700 + Box::pin(fut) 5701 + } 5702 + } 5703 + let accept_compression_encodings = self.accept_compression_encodings; 5704 + let send_compression_encodings = self.send_compression_encodings; 5705 + let max_decoding_message_size = self.max_decoding_message_size; 5706 + let max_encoding_message_size = self.max_encoding_message_size; 5707 + let inner = self.inner.clone(); 5708 + let fut = async move { 5709 + let method = SetPitchSvc(inner); 5710 + let codec = tonic::codec::ProstCodec::default(); 5711 + let mut grpc = tonic::server::Grpc::new(codec) 5712 + .apply_compression_config( 5713 + accept_compression_encodings, 5714 + send_compression_encodings, 5715 + ) 5716 + .apply_max_message_size_config( 5717 + max_decoding_message_size, 5718 + max_encoding_message_size, 5719 + ); 5720 + let res = grpc.unary(method, req).await; 5721 + Ok(res) 5722 + }; 5723 + Box::pin(fut) 5724 + } 5725 + "/rockbox.v1alpha1.SoundService/BeepPlay" => { 5726 + #[allow(non_camel_case_types)] 5727 + struct BeepPlaySvc<T: SoundService>(pub Arc<T>); 5728 + impl< 5729 + T: SoundService, 5730 + > tonic::server::UnaryService<super::BeepPlayRequest> 5731 + for BeepPlaySvc<T> { 5732 + type Response = super::BeepPlayResponse; 5733 + type Future = BoxFuture< 5734 + tonic::Response<Self::Response>, 5735 + tonic::Status, 5736 + >; 5737 + fn call( 5738 + &mut self, 5739 + request: tonic::Request<super::BeepPlayRequest>, 5740 + ) -> Self::Future { 5741 + let inner = Arc::clone(&self.0); 5742 + let fut = async move { 5743 + <T as SoundService>::beep_play(&inner, request).await 5744 + }; 5745 + Box::pin(fut) 5746 + } 5747 + } 5748 + let accept_compression_encodings = self.accept_compression_encodings; 5749 + let send_compression_encodings = self.send_compression_encodings; 5750 + let max_decoding_message_size = self.max_decoding_message_size; 5751 + let max_encoding_message_size = self.max_encoding_message_size; 5752 + let inner = self.inner.clone(); 5753 + let fut = async move { 5754 + let method = BeepPlaySvc(inner); 5755 + let codec = tonic::codec::ProstCodec::default(); 5756 + let mut grpc = tonic::server::Grpc::new(codec) 5757 + .apply_compression_config( 5758 + accept_compression_encodings, 5759 + send_compression_encodings, 5760 + ) 5761 + .apply_max_message_size_config( 5762 + max_decoding_message_size, 5763 + max_encoding_message_size, 5764 + ); 5765 + let res = grpc.unary(method, req).await; 5766 + Ok(res) 5767 + }; 5768 + Box::pin(fut) 5769 + } 5770 + "/rockbox.v1alpha1.SoundService/PcmbufFade" => { 5771 + #[allow(non_camel_case_types)] 5772 + struct PcmbufFadeSvc<T: SoundService>(pub Arc<T>); 5773 + impl< 5774 + T: SoundService, 5775 + > tonic::server::UnaryService<super::PcmbufFadeRequest> 5776 + for PcmbufFadeSvc<T> { 5777 + type Response = super::PcmbufFadeResponse; 5778 + type Future = BoxFuture< 5779 + tonic::Response<Self::Response>, 5780 + tonic::Status, 5781 + >; 5782 + fn call( 5783 + &mut self, 5784 + request: tonic::Request<super::PcmbufFadeRequest>, 5785 + ) -> Self::Future { 5786 + let inner = Arc::clone(&self.0); 5787 + let fut = async move { 5788 + <T as SoundService>::pcmbuf_fade(&inner, request).await 5789 + }; 5790 + Box::pin(fut) 5791 + } 5792 + } 5793 + let accept_compression_encodings = self.accept_compression_encodings; 5794 + let send_compression_encodings = self.send_compression_encodings; 5795 + let max_decoding_message_size = self.max_decoding_message_size; 5796 + let max_encoding_message_size = self.max_encoding_message_size; 5797 + let inner = self.inner.clone(); 5798 + let fut = async move { 5799 + let method = PcmbufFadeSvc(inner); 5800 + let codec = tonic::codec::ProstCodec::default(); 5801 + let mut grpc = tonic::server::Grpc::new(codec) 5802 + .apply_compression_config( 5803 + accept_compression_encodings, 5804 + send_compression_encodings, 5805 + ) 5806 + .apply_max_message_size_config( 5807 + max_decoding_message_size, 5808 + max_encoding_message_size, 5809 + ); 5810 + let res = grpc.unary(method, req).await; 5811 + Ok(res) 5812 + }; 5813 + Box::pin(fut) 5814 + } 5815 + "/rockbox.v1alpha1.SoundService/PcmbufSetLowLatency" => { 5816 + #[allow(non_camel_case_types)] 5817 + struct PcmbufSetLowLatencySvc<T: SoundService>(pub Arc<T>); 5818 + impl< 5819 + T: SoundService, 5820 + > tonic::server::UnaryService<super::PcmbufSetLowLatencyRequest> 5821 + for PcmbufSetLowLatencySvc<T> { 5822 + type Response = super::PcmbufSetLowLatencyResponse; 5823 + type Future = BoxFuture< 5824 + tonic::Response<Self::Response>, 5825 + tonic::Status, 5826 + >; 5827 + fn call( 5828 + &mut self, 5829 + request: tonic::Request<super::PcmbufSetLowLatencyRequest>, 5830 + ) -> Self::Future { 5831 + let inner = Arc::clone(&self.0); 5832 + let fut = async move { 5833 + <T as SoundService>::pcmbuf_set_low_latency(&inner, request) 5834 + .await 5835 + }; 5836 + Box::pin(fut) 5837 + } 5838 + } 5839 + let accept_compression_encodings = self.accept_compression_encodings; 5840 + let send_compression_encodings = self.send_compression_encodings; 5841 + let max_decoding_message_size = self.max_decoding_message_size; 5842 + let max_encoding_message_size = self.max_encoding_message_size; 5843 + let inner = self.inner.clone(); 5844 + let fut = async move { 5845 + let method = PcmbufSetLowLatencySvc(inner); 5846 + let codec = tonic::codec::ProstCodec::default(); 5847 + let mut grpc = tonic::server::Grpc::new(codec) 5848 + .apply_compression_config( 5849 + accept_compression_encodings, 5850 + send_compression_encodings, 5851 + ) 5852 + .apply_max_message_size_config( 5853 + max_decoding_message_size, 5854 + max_encoding_message_size, 5855 + ); 5856 + let res = grpc.unary(method, req).await; 5857 + Ok(res) 5858 + }; 5859 + Box::pin(fut) 5860 + } 5861 + "/rockbox.v1alpha1.SoundService/SystemSoundPlay" => { 5862 + #[allow(non_camel_case_types)] 5863 + struct SystemSoundPlaySvc<T: SoundService>(pub Arc<T>); 5864 + impl< 5865 + T: SoundService, 5866 + > tonic::server::UnaryService<super::SystemSoundPlayRequest> 5867 + for SystemSoundPlaySvc<T> { 5868 + type Response = super::SystemSoundPlayResponse; 5869 + type Future = BoxFuture< 5870 + tonic::Response<Self::Response>, 5871 + tonic::Status, 5872 + >; 5873 + fn call( 5874 + &mut self, 5875 + request: tonic::Request<super::SystemSoundPlayRequest>, 5876 + ) -> Self::Future { 5877 + let inner = Arc::clone(&self.0); 5878 + let fut = async move { 5879 + <T as SoundService>::system_sound_play(&inner, request) 5880 + .await 5881 + }; 5882 + Box::pin(fut) 5883 + } 5884 + } 5885 + let accept_compression_encodings = self.accept_compression_encodings; 5886 + let send_compression_encodings = self.send_compression_encodings; 5887 + let max_decoding_message_size = self.max_decoding_message_size; 5888 + let max_encoding_message_size = self.max_encoding_message_size; 5889 + let inner = self.inner.clone(); 5890 + let fut = async move { 5891 + let method = SystemSoundPlaySvc(inner); 5892 + let codec = tonic::codec::ProstCodec::default(); 5893 + let mut grpc = tonic::server::Grpc::new(codec) 5894 + .apply_compression_config( 5895 + accept_compression_encodings, 5896 + send_compression_encodings, 5897 + ) 5898 + .apply_max_message_size_config( 5899 + max_decoding_message_size, 5900 + max_encoding_message_size, 5901 + ); 5902 + let res = grpc.unary(method, req).await; 5903 + Ok(res) 5904 + }; 5905 + Box::pin(fut) 5906 + } 5907 + "/rockbox.v1alpha1.SoundService/KeyclickClick" => { 5908 + #[allow(non_camel_case_types)] 5909 + struct KeyclickClickSvc<T: SoundService>(pub Arc<T>); 5910 + impl< 5911 + T: SoundService, 5912 + > tonic::server::UnaryService<super::KeyclickClickRequest> 5913 + for KeyclickClickSvc<T> { 5914 + type Response = super::KeyclickClickResponse; 5915 + type Future = BoxFuture< 5916 + tonic::Response<Self::Response>, 5917 + tonic::Status, 5918 + >; 5919 + fn call( 5920 + &mut self, 5921 + request: tonic::Request<super::KeyclickClickRequest>, 5922 + ) -> Self::Future { 5923 + let inner = Arc::clone(&self.0); 5924 + let fut = async move { 5925 + <T as SoundService>::keyclick_click(&inner, request).await 5926 + }; 5927 + Box::pin(fut) 5928 + } 5929 + } 5930 + let accept_compression_encodings = self.accept_compression_encodings; 5931 + let send_compression_encodings = self.send_compression_encodings; 5932 + let max_decoding_message_size = self.max_decoding_message_size; 5933 + let max_encoding_message_size = self.max_encoding_message_size; 5934 + let inner = self.inner.clone(); 5935 + let fut = async move { 5936 + let method = KeyclickClickSvc(inner); 5937 + let codec = tonic::codec::ProstCodec::default(); 5938 + let mut grpc = tonic::server::Grpc::new(codec) 5939 + .apply_compression_config( 5940 + accept_compression_encodings, 5941 + send_compression_encodings, 5942 + ) 5943 + .apply_max_message_size_config( 5944 + max_decoding_message_size, 5945 + max_encoding_message_size, 5946 + ); 5947 + let res = grpc.unary(method, req).await; 5948 + Ok(res) 5949 + }; 5950 + Box::pin(fut) 5951 + } 5952 + _ => { 5953 + Box::pin(async move { 5954 + Ok( 5955 + http::Response::builder() 5956 + .status(200) 5957 + .header("grpc-status", tonic::Code::Unimplemented as i32) 5958 + .header( 5959 + http::header::CONTENT_TYPE, 5960 + tonic::metadata::GRPC_CONTENT_TYPE, 5961 + ) 5962 + .body(empty_body()) 5963 + .unwrap(), 5964 + ) 5965 + }) 5966 + } 5967 + } 5968 + } 5969 + } 5970 + impl<T> Clone for SoundServiceServer<T> { 5971 + fn clone(&self) -> Self { 5972 + let inner = self.inner.clone(); 5973 + Self { 5974 + inner, 5975 + accept_compression_encodings: self.accept_compression_encodings, 5976 + send_compression_encodings: self.send_compression_encodings, 5977 + max_decoding_message_size: self.max_decoding_message_size, 5978 + max_encoding_message_size: self.max_encoding_message_size, 5979 + } 5980 + } 5981 + } 5982 + /// Generated gRPC service name 5983 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.SoundService"; 5984 + impl<T> tonic::server::NamedService for SoundServiceServer<T> { 5985 + const NAME: &'static str = SERVICE_NAME; 5986 + } 5987 + } 5988 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 5989 + pub struct GetRockboxVersionRequest {} 5990 + #[derive(Clone, PartialEq, ::prost::Message)] 5991 + pub struct GetRockboxVersionResponse { 5992 + #[prost(string, tag = "1")] 5993 + pub version: ::prost::alloc::string::String, 5994 + } 5995 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 5996 + pub struct GetGlobalStatusRequest {} 5997 + #[derive(Clone, Copy, PartialEq, ::prost::Message)] 5998 + pub struct GetGlobalStatusResponse { 5999 + #[prost(int32, tag = "1")] 6000 + pub resume_index: i32, 6001 + #[prost(uint32, tag = "2")] 6002 + pub resume_crc32: u32, 6003 + #[prost(uint32, tag = "3")] 6004 + pub resume_elapsed: u32, 6005 + #[prost(uint32, tag = "4")] 6006 + pub resume_offset: u32, 6007 + #[prost(int32, tag = "5")] 6008 + pub runtime: i32, 6009 + #[prost(int32, tag = "6")] 6010 + pub topruntime: i32, 6011 + #[prost(int32, tag = "7")] 6012 + pub dircache_size: i32, 6013 + #[prost(int32, tag = "8")] 6014 + pub last_screen: i32, 6015 + #[prost(int32, tag = "9")] 6016 + pub viewer_icon_count: i32, 6017 + #[prost(int32, tag = "10")] 6018 + pub last_volume_change: i32, 6019 + } 6020 + /// Generated client implementations. 6021 + pub mod system_service_client { 6022 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 6023 + use tonic::codegen::*; 6024 + use tonic::codegen::http::Uri; 6025 + #[derive(Debug, Clone)] 6026 + pub struct SystemServiceClient<T> { 6027 + inner: tonic::client::Grpc<T>, 6028 + } 6029 + impl SystemServiceClient<tonic::transport::Channel> { 6030 + /// Attempt to create a new client by connecting to a given endpoint. 6031 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 6032 + where 6033 + D: TryInto<tonic::transport::Endpoint>, 6034 + D::Error: Into<StdError>, 6035 + { 6036 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 6037 + Ok(Self::new(conn)) 6038 + } 6039 + } 6040 + impl<T> SystemServiceClient<T> 6041 + where 6042 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 6043 + T::Error: Into<StdError>, 6044 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 6045 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 6046 + { 6047 + pub fn new(inner: T) -> Self { 6048 + let inner = tonic::client::Grpc::new(inner); 6049 + Self { inner } 6050 + } 6051 + pub fn with_origin(inner: T, origin: Uri) -> Self { 6052 + let inner = tonic::client::Grpc::with_origin(inner, origin); 6053 + Self { inner } 6054 + } 6055 + pub fn with_interceptor<F>( 6056 + inner: T, 6057 + interceptor: F, 6058 + ) -> SystemServiceClient<InterceptedService<T, F>> 6059 + where 6060 + F: tonic::service::Interceptor, 6061 + T::ResponseBody: Default, 6062 + T: tonic::codegen::Service< 6063 + http::Request<tonic::body::BoxBody>, 6064 + Response = http::Response< 6065 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 6066 + >, 6067 + >, 6068 + <T as tonic::codegen::Service< 6069 + http::Request<tonic::body::BoxBody>, 6070 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 6071 + { 6072 + SystemServiceClient::new(InterceptedService::new(inner, interceptor)) 6073 + } 6074 + /// Compress requests with the given encoding. 6075 + /// 6076 + /// This requires the server to support it otherwise it might respond with an 6077 + /// error. 6078 + #[must_use] 6079 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 6080 + self.inner = self.inner.send_compressed(encoding); 6081 + self 6082 + } 6083 + /// Enable decompressing responses. 6084 + #[must_use] 6085 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 6086 + self.inner = self.inner.accept_compressed(encoding); 6087 + self 6088 + } 6089 + /// Limits the maximum size of a decoded message. 6090 + /// 6091 + /// Default: `4MB` 6092 + #[must_use] 6093 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 6094 + self.inner = self.inner.max_decoding_message_size(limit); 6095 + self 6096 + } 6097 + /// Limits the maximum size of an encoded message. 6098 + /// 6099 + /// Default: `usize::MAX` 6100 + #[must_use] 6101 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 6102 + self.inner = self.inner.max_encoding_message_size(limit); 6103 + self 6104 + } 6105 + pub async fn get_rockbox_version( 6106 + &mut self, 6107 + request: impl tonic::IntoRequest<super::GetRockboxVersionRequest>, 6108 + ) -> std::result::Result< 6109 + tonic::Response<super::GetRockboxVersionResponse>, 6110 + tonic::Status, 6111 + > { 6112 + self.inner 6113 + .ready() 6114 + .await 6115 + .map_err(|e| { 6116 + tonic::Status::new( 6117 + tonic::Code::Unknown, 6118 + format!("Service was not ready: {}", e.into()), 6119 + ) 6120 + })?; 6121 + let codec = tonic::codec::ProstCodec::default(); 6122 + let path = http::uri::PathAndQuery::from_static( 6123 + "/rockbox.v1alpha1.SystemService/GetRockboxVersion", 6124 + ); 6125 + let mut req = request.into_request(); 6126 + req.extensions_mut() 6127 + .insert( 6128 + GrpcMethod::new( 6129 + "rockbox.v1alpha1.SystemService", 6130 + "GetRockboxVersion", 6131 + ), 6132 + ); 6133 + self.inner.unary(req, path, codec).await 6134 + } 6135 + pub async fn get_global_status( 6136 + &mut self, 6137 + request: impl tonic::IntoRequest<super::GetGlobalStatusRequest>, 6138 + ) -> std::result::Result< 6139 + tonic::Response<super::GetGlobalStatusResponse>, 6140 + tonic::Status, 6141 + > { 6142 + self.inner 6143 + .ready() 6144 + .await 6145 + .map_err(|e| { 6146 + tonic::Status::new( 6147 + tonic::Code::Unknown, 6148 + format!("Service was not ready: {}", e.into()), 6149 + ) 6150 + })?; 6151 + let codec = tonic::codec::ProstCodec::default(); 6152 + let path = http::uri::PathAndQuery::from_static( 6153 + "/rockbox.v1alpha1.SystemService/GetGlobalStatus", 6154 + ); 6155 + let mut req = request.into_request(); 6156 + req.extensions_mut() 6157 + .insert( 6158 + GrpcMethod::new("rockbox.v1alpha1.SystemService", "GetGlobalStatus"), 6159 + ); 6160 + self.inner.unary(req, path, codec).await 6161 + } 6162 + } 6163 + } 6164 + /// Generated server implementations. 6165 + pub mod system_service_server { 6166 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 6167 + use tonic::codegen::*; 6168 + /// Generated trait containing gRPC methods that should be implemented for use with SystemServiceServer. 6169 + #[async_trait] 6170 + pub trait SystemService: std::marker::Send + std::marker::Sync + 'static { 6171 + async fn get_rockbox_version( 6172 + &self, 6173 + request: tonic::Request<super::GetRockboxVersionRequest>, 6174 + ) -> std::result::Result< 6175 + tonic::Response<super::GetRockboxVersionResponse>, 6176 + tonic::Status, 6177 + >; 6178 + async fn get_global_status( 6179 + &self, 6180 + request: tonic::Request<super::GetGlobalStatusRequest>, 6181 + ) -> std::result::Result< 6182 + tonic::Response<super::GetGlobalStatusResponse>, 6183 + tonic::Status, 6184 + >; 6185 + } 6186 + #[derive(Debug)] 6187 + pub struct SystemServiceServer<T> { 6188 + inner: Arc<T>, 6189 + accept_compression_encodings: EnabledCompressionEncodings, 6190 + send_compression_encodings: EnabledCompressionEncodings, 6191 + max_decoding_message_size: Option<usize>, 6192 + max_encoding_message_size: Option<usize>, 6193 + } 6194 + impl<T> SystemServiceServer<T> { 6195 + pub fn new(inner: T) -> Self { 6196 + Self::from_arc(Arc::new(inner)) 6197 + } 6198 + pub fn from_arc(inner: Arc<T>) -> Self { 6199 + Self { 6200 + inner, 6201 + accept_compression_encodings: Default::default(), 6202 + send_compression_encodings: Default::default(), 6203 + max_decoding_message_size: None, 6204 + max_encoding_message_size: None, 6205 + } 6206 + } 6207 + pub fn with_interceptor<F>( 6208 + inner: T, 6209 + interceptor: F, 6210 + ) -> InterceptedService<Self, F> 6211 + where 6212 + F: tonic::service::Interceptor, 6213 + { 6214 + InterceptedService::new(Self::new(inner), interceptor) 6215 + } 6216 + /// Enable decompressing requests with the given encoding. 6217 + #[must_use] 6218 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 6219 + self.accept_compression_encodings.enable(encoding); 6220 + self 6221 + } 6222 + /// Compress responses with the given encoding, if the client supports it. 6223 + #[must_use] 6224 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 6225 + self.send_compression_encodings.enable(encoding); 6226 + self 6227 + } 6228 + /// Limits the maximum size of a decoded message. 6229 + /// 6230 + /// Default: `4MB` 6231 + #[must_use] 6232 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 6233 + self.max_decoding_message_size = Some(limit); 6234 + self 6235 + } 6236 + /// Limits the maximum size of an encoded message. 6237 + /// 6238 + /// Default: `usize::MAX` 6239 + #[must_use] 6240 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 6241 + self.max_encoding_message_size = Some(limit); 6242 + self 6243 + } 6244 + } 6245 + impl<T, B> tonic::codegen::Service<http::Request<B>> for SystemServiceServer<T> 6246 + where 6247 + T: SystemService, 6248 + B: Body + std::marker::Send + 'static, 6249 + B::Error: Into<StdError> + std::marker::Send + 'static, 6250 + { 6251 + type Response = http::Response<tonic::body::BoxBody>; 6252 + type Error = std::convert::Infallible; 6253 + type Future = BoxFuture<Self::Response, Self::Error>; 6254 + fn poll_ready( 6255 + &mut self, 6256 + _cx: &mut Context<'_>, 6257 + ) -> Poll<std::result::Result<(), Self::Error>> { 6258 + Poll::Ready(Ok(())) 6259 + } 6260 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 6261 + match req.uri().path() { 6262 + "/rockbox.v1alpha1.SystemService/GetRockboxVersion" => { 6263 + #[allow(non_camel_case_types)] 6264 + struct GetRockboxVersionSvc<T: SystemService>(pub Arc<T>); 6265 + impl< 6266 + T: SystemService, 6267 + > tonic::server::UnaryService<super::GetRockboxVersionRequest> 6268 + for GetRockboxVersionSvc<T> { 6269 + type Response = super::GetRockboxVersionResponse; 6270 + type Future = BoxFuture< 6271 + tonic::Response<Self::Response>, 6272 + tonic::Status, 6273 + >; 6274 + fn call( 6275 + &mut self, 6276 + request: tonic::Request<super::GetRockboxVersionRequest>, 6277 + ) -> Self::Future { 6278 + let inner = Arc::clone(&self.0); 6279 + let fut = async move { 6280 + <T as SystemService>::get_rockbox_version(&inner, request) 6281 + .await 6282 + }; 6283 + Box::pin(fut) 6284 + } 6285 + } 6286 + let accept_compression_encodings = self.accept_compression_encodings; 6287 + let send_compression_encodings = self.send_compression_encodings; 6288 + let max_decoding_message_size = self.max_decoding_message_size; 6289 + let max_encoding_message_size = self.max_encoding_message_size; 6290 + let inner = self.inner.clone(); 6291 + let fut = async move { 6292 + let method = GetRockboxVersionSvc(inner); 6293 + let codec = tonic::codec::ProstCodec::default(); 6294 + let mut grpc = tonic::server::Grpc::new(codec) 6295 + .apply_compression_config( 6296 + accept_compression_encodings, 6297 + send_compression_encodings, 6298 + ) 6299 + .apply_max_message_size_config( 6300 + max_decoding_message_size, 6301 + max_encoding_message_size, 6302 + ); 6303 + let res = grpc.unary(method, req).await; 6304 + Ok(res) 6305 + }; 6306 + Box::pin(fut) 6307 + } 6308 + "/rockbox.v1alpha1.SystemService/GetGlobalStatus" => { 6309 + #[allow(non_camel_case_types)] 6310 + struct GetGlobalStatusSvc<T: SystemService>(pub Arc<T>); 6311 + impl< 6312 + T: SystemService, 6313 + > tonic::server::UnaryService<super::GetGlobalStatusRequest> 6314 + for GetGlobalStatusSvc<T> { 6315 + type Response = super::GetGlobalStatusResponse; 6316 + type Future = BoxFuture< 6317 + tonic::Response<Self::Response>, 6318 + tonic::Status, 6319 + >; 6320 + fn call( 6321 + &mut self, 6322 + request: tonic::Request<super::GetGlobalStatusRequest>, 6323 + ) -> Self::Future { 6324 + let inner = Arc::clone(&self.0); 6325 + let fut = async move { 6326 + <T as SystemService>::get_global_status(&inner, request) 6327 + .await 6328 + }; 6329 + Box::pin(fut) 6330 + } 6331 + } 6332 + let accept_compression_encodings = self.accept_compression_encodings; 6333 + let send_compression_encodings = self.send_compression_encodings; 6334 + let max_decoding_message_size = self.max_decoding_message_size; 6335 + let max_encoding_message_size = self.max_encoding_message_size; 6336 + let inner = self.inner.clone(); 6337 + let fut = async move { 6338 + let method = GetGlobalStatusSvc(inner); 6339 + let codec = tonic::codec::ProstCodec::default(); 6340 + let mut grpc = tonic::server::Grpc::new(codec) 6341 + .apply_compression_config( 6342 + accept_compression_encodings, 6343 + send_compression_encodings, 6344 + ) 6345 + .apply_max_message_size_config( 6346 + max_decoding_message_size, 6347 + max_encoding_message_size, 6348 + ); 6349 + let res = grpc.unary(method, req).await; 6350 + Ok(res) 6351 + }; 6352 + Box::pin(fut) 6353 + } 6354 + _ => { 6355 + Box::pin(async move { 6356 + Ok( 6357 + http::Response::builder() 6358 + .status(200) 6359 + .header("grpc-status", tonic::Code::Unimplemented as i32) 6360 + .header( 6361 + http::header::CONTENT_TYPE, 6362 + tonic::metadata::GRPC_CONTENT_TYPE, 6363 + ) 6364 + .body(empty_body()) 6365 + .unwrap(), 6366 + ) 6367 + }) 6368 + } 6369 + } 6370 + } 6371 + } 6372 + impl<T> Clone for SystemServiceServer<T> { 6373 + fn clone(&self) -> Self { 6374 + let inner = self.inner.clone(); 6375 + Self { 6376 + inner, 6377 + accept_compression_encodings: self.accept_compression_encodings, 6378 + send_compression_encodings: self.send_compression_encodings, 6379 + max_decoding_message_size: self.max_decoding_message_size, 6380 + max_encoding_message_size: self.max_encoding_message_size, 6381 + } 6382 + } 6383 + } 6384 + /// Generated gRPC service name 6385 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.SystemService"; 6386 + impl<T> tonic::server::NamedService for SystemServiceServer<T> { 6387 + const NAME: &'static str = SERVICE_NAME; 6388 + } 6389 + } 6390 + /// Generated client implementations. 6391 + pub mod tagcache_service_client { 6392 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 6393 + use tonic::codegen::*; 6394 + use tonic::codegen::http::Uri; 6395 + #[derive(Debug, Clone)] 6396 + pub struct TagcacheServiceClient<T> { 6397 + inner: tonic::client::Grpc<T>, 6398 + } 6399 + impl TagcacheServiceClient<tonic::transport::Channel> { 6400 + /// Attempt to create a new client by connecting to a given endpoint. 6401 + pub async fn connect<D>(dst: D) -> Result<Self, tonic::transport::Error> 6402 + where 6403 + D: TryInto<tonic::transport::Endpoint>, 6404 + D::Error: Into<StdError>, 6405 + { 6406 + let conn = tonic::transport::Endpoint::new(dst)?.connect().await?; 6407 + Ok(Self::new(conn)) 6408 + } 6409 + } 6410 + impl<T> TagcacheServiceClient<T> 6411 + where 6412 + T: tonic::client::GrpcService<tonic::body::BoxBody>, 6413 + T::Error: Into<StdError>, 6414 + T::ResponseBody: Body<Data = Bytes> + std::marker::Send + 'static, 6415 + <T::ResponseBody as Body>::Error: Into<StdError> + std::marker::Send, 6416 + { 6417 + pub fn new(inner: T) -> Self { 6418 + let inner = tonic::client::Grpc::new(inner); 6419 + Self { inner } 6420 + } 6421 + pub fn with_origin(inner: T, origin: Uri) -> Self { 6422 + let inner = tonic::client::Grpc::with_origin(inner, origin); 6423 + Self { inner } 6424 + } 6425 + pub fn with_interceptor<F>( 6426 + inner: T, 6427 + interceptor: F, 6428 + ) -> TagcacheServiceClient<InterceptedService<T, F>> 6429 + where 6430 + F: tonic::service::Interceptor, 6431 + T::ResponseBody: Default, 6432 + T: tonic::codegen::Service< 6433 + http::Request<tonic::body::BoxBody>, 6434 + Response = http::Response< 6435 + <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 6436 + >, 6437 + >, 6438 + <T as tonic::codegen::Service< 6439 + http::Request<tonic::body::BoxBody>, 6440 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 6441 + { 6442 + TagcacheServiceClient::new(InterceptedService::new(inner, interceptor)) 6443 + } 6444 + /// Compress requests with the given encoding. 6445 + /// 6446 + /// This requires the server to support it otherwise it might respond with an 6447 + /// error. 6448 + #[must_use] 6449 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 6450 + self.inner = self.inner.send_compressed(encoding); 6451 + self 6452 + } 6453 + /// Enable decompressing responses. 6454 + #[must_use] 6455 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 6456 + self.inner = self.inner.accept_compressed(encoding); 6457 + self 6458 + } 6459 + /// Limits the maximum size of a decoded message. 6460 + /// 6461 + /// Default: `4MB` 6462 + #[must_use] 6463 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 6464 + self.inner = self.inner.max_decoding_message_size(limit); 6465 + self 6466 + } 6467 + /// Limits the maximum size of an encoded message. 6468 + /// 6469 + /// Default: `usize::MAX` 6470 + #[must_use] 6471 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 6472 + self.inner = self.inner.max_encoding_message_size(limit); 6473 + self 6474 + } 6475 + } 6476 + } 6477 + /// Generated server implementations. 6478 + pub mod tagcache_service_server { 6479 + #![allow(unused_variables, dead_code, missing_docs, clippy::let_unit_value)] 6480 + use tonic::codegen::*; 6481 + /// Generated trait containing gRPC methods that should be implemented for use with TagcacheServiceServer. 6482 + #[async_trait] 6483 + pub trait TagcacheService: std::marker::Send + std::marker::Sync + 'static {} 6484 + #[derive(Debug)] 6485 + pub struct TagcacheServiceServer<T> { 6486 + inner: Arc<T>, 6487 + accept_compression_encodings: EnabledCompressionEncodings, 6488 + send_compression_encodings: EnabledCompressionEncodings, 6489 + max_decoding_message_size: Option<usize>, 6490 + max_encoding_message_size: Option<usize>, 6491 + } 6492 + impl<T> TagcacheServiceServer<T> { 6493 + pub fn new(inner: T) -> Self { 6494 + Self::from_arc(Arc::new(inner)) 6495 + } 6496 + pub fn from_arc(inner: Arc<T>) -> Self { 6497 + Self { 6498 + inner, 6499 + accept_compression_encodings: Default::default(), 6500 + send_compression_encodings: Default::default(), 6501 + max_decoding_message_size: None, 6502 + max_encoding_message_size: None, 6503 + } 6504 + } 6505 + pub fn with_interceptor<F>( 6506 + inner: T, 6507 + interceptor: F, 6508 + ) -> InterceptedService<Self, F> 6509 + where 6510 + F: tonic::service::Interceptor, 6511 + { 6512 + InterceptedService::new(Self::new(inner), interceptor) 6513 + } 6514 + /// Enable decompressing requests with the given encoding. 6515 + #[must_use] 6516 + pub fn accept_compressed(mut self, encoding: CompressionEncoding) -> Self { 6517 + self.accept_compression_encodings.enable(encoding); 6518 + self 6519 + } 6520 + /// Compress responses with the given encoding, if the client supports it. 6521 + #[must_use] 6522 + pub fn send_compressed(mut self, encoding: CompressionEncoding) -> Self { 6523 + self.send_compression_encodings.enable(encoding); 6524 + self 6525 + } 6526 + /// Limits the maximum size of a decoded message. 6527 + /// 6528 + /// Default: `4MB` 6529 + #[must_use] 6530 + pub fn max_decoding_message_size(mut self, limit: usize) -> Self { 6531 + self.max_decoding_message_size = Some(limit); 6532 + self 6533 + } 6534 + /// Limits the maximum size of an encoded message. 6535 + /// 6536 + /// Default: `usize::MAX` 6537 + #[must_use] 6538 + pub fn max_encoding_message_size(mut self, limit: usize) -> Self { 6539 + self.max_encoding_message_size = Some(limit); 6540 + self 6541 + } 6542 + } 6543 + impl<T, B> tonic::codegen::Service<http::Request<B>> for TagcacheServiceServer<T> 6544 + where 6545 + T: TagcacheService, 6546 + B: Body + std::marker::Send + 'static, 6547 + B::Error: Into<StdError> + std::marker::Send + 'static, 6548 + { 6549 + type Response = http::Response<tonic::body::BoxBody>; 6550 + type Error = std::convert::Infallible; 6551 + type Future = BoxFuture<Self::Response, Self::Error>; 6552 + fn poll_ready( 6553 + &mut self, 6554 + _cx: &mut Context<'_>, 6555 + ) -> Poll<std::result::Result<(), Self::Error>> { 6556 + Poll::Ready(Ok(())) 6557 + } 6558 + fn call(&mut self, req: http::Request<B>) -> Self::Future { 6559 + match req.uri().path() { 6560 + _ => { 6561 + Box::pin(async move { 6562 + Ok( 6563 + http::Response::builder() 6564 + .status(200) 6565 + .header("grpc-status", tonic::Code::Unimplemented as i32) 6566 + .header( 6567 + http::header::CONTENT_TYPE, 6568 + tonic::metadata::GRPC_CONTENT_TYPE, 6569 + ) 6570 + .body(empty_body()) 6571 + .unwrap(), 6572 + ) 6573 + }) 6574 + } 6575 + } 6576 + } 6577 + } 6578 + impl<T> Clone for TagcacheServiceServer<T> { 6579 + fn clone(&self) -> Self { 6580 + let inner = self.inner.clone(); 6581 + Self { 6582 + inner, 6583 + accept_compression_encodings: self.accept_compression_encodings, 6584 + send_compression_encodings: self.send_compression_encodings, 6585 + max_decoding_message_size: self.max_decoding_message_size, 6586 + max_encoding_message_size: self.max_encoding_message_size, 6587 + } 6588 + } 6589 + } 6590 + /// Generated gRPC service name 6591 + pub const SERVICE_NAME: &str = "rockbox.v1alpha1.TagcacheService"; 6592 + impl<T> tonic::server::NamedService for TagcacheServiceServer<T> { 6593 + const NAME: &'static str = SERVICE_NAME; 6594 + } 6595 + }
crates/rpc/src/api/rockbox_descriptor.bin

This is a binary file and will not be displayed.

+42
crates/rpc/src/browse.rs
··· 1 + use crate::api::rockbox::v1alpha1::{browse_service_server::BrowseService, *}; 2 + 3 + #[derive(Default)] 4 + pub struct Browse; 5 + 6 + #[tonic::async_trait] 7 + impl BrowseService for Browse { 8 + async fn rockbox_browse( 9 + &self, 10 + request: tonic::Request<RockboxBrowseRequest>, 11 + ) -> Result<tonic::Response<RockboxBrowseResponse>, tonic::Status> { 12 + Ok(tonic::Response::new(RockboxBrowseResponse::default())) 13 + } 14 + 15 + async fn tree_get_context( 16 + &self, 17 + request: tonic::Request<TreeGetContextRequest>, 18 + ) -> Result<tonic::Response<TreeGetContextResponse>, tonic::Status> { 19 + Ok(tonic::Response::new(TreeGetContextResponse::default())) 20 + } 21 + 22 + async fn tree_get_entries( 23 + &self, 24 + request: tonic::Request<TreeGetEntriesRequest>, 25 + ) -> Result<tonic::Response<TreeGetEntriesResponse>, tonic::Status> { 26 + Ok(tonic::Response::new(TreeGetEntriesResponse::default())) 27 + } 28 + 29 + async fn tree_get_entry_at( 30 + &self, 31 + request: tonic::Request<TreeGetEntryAtRequest>, 32 + ) -> Result<tonic::Response<TreeGetEntryAtResponse>, tonic::Status> { 33 + Ok(tonic::Response::new(TreeGetEntryAtResponse::default())) 34 + } 35 + 36 + async fn browse_id3( 37 + &self, 38 + request: tonic::Request<BrowseId3Request>, 39 + ) -> Result<tonic::Response<BrowseId3Response>, tonic::Status> { 40 + Ok(tonic::Response::new(BrowseId3Response::default())) 41 + } 42 + }
+529
crates/rpc/src/lib.rs
··· 1 + pub mod browse; 2 + pub mod metadata; 3 + pub mod playback; 4 + pub mod playlist; 5 + pub mod server; 6 + pub mod settings; 7 + pub mod sound; 8 + pub mod system; 9 + pub mod tagcache; 10 + 11 + pub mod api { 12 + #[path = ""] 13 + pub mod rockbox { 14 + use rockbox_sys::types::{ 15 + mp3_entry::Mp3Entry, 16 + system_status::SystemStatus, 17 + user_settings::{CompressorSettings, EqBandSetting, ReplaygainSettings, UserSettings}, 18 + }; 19 + use v1alpha1::{CurrentTrackResponse, GetGlobalSettingsResponse, GetGlobalStatusResponse}; 20 + 21 + #[path = "rockbox.v1alpha1.rs"] 22 + pub mod v1alpha1; 23 + 24 + pub(crate) const FILE_DESCRIPTOR_SET: &[u8] = include_bytes!("api/rockbox_descriptor.bin"); 25 + 26 + impl From<Mp3Entry> for CurrentTrackResponse { 27 + fn from(mp3entry: Mp3Entry) -> Self { 28 + let title = mp3entry.title; 29 + let artist = mp3entry.artist; 30 + let album = mp3entry.album; 31 + let genre = mp3entry.genre_string; 32 + let disc = mp3entry.disc_string; 33 + let track_string = mp3entry.track_string; 34 + let year_string = mp3entry.year_string; 35 + let composer = mp3entry.composer; 36 + let album_artist = mp3entry.albumartist; 37 + let comment = mp3entry.comment; 38 + let grouping = mp3entry.grouping; 39 + let discnum = mp3entry.discnum; 40 + let tracknum = mp3entry.tracknum; 41 + let layer = mp3entry.layer; 42 + let year = mp3entry.year; 43 + let bitrate = mp3entry.bitrate; 44 + let frequency = mp3entry.frequency; 45 + let filesize = mp3entry.filesize; 46 + let length = mp3entry.length; 47 + let elapsed = mp3entry.elapsed; 48 + 49 + CurrentTrackResponse { 50 + title, 51 + artist, 52 + album, 53 + genre, 54 + disc, 55 + track_string, 56 + year_string, 57 + composer, 58 + album_artist, 59 + comment, 60 + grouping, 61 + discnum, 62 + tracknum, 63 + layer, 64 + year, 65 + bitrate, 66 + frequency, 67 + filesize, 68 + length, 69 + elapsed, 70 + } 71 + } 72 + } 73 + 74 + impl From<ReplaygainSettings> for v1alpha1::ReplaygainSettings { 75 + fn from(settings: ReplaygainSettings) -> Self { 76 + let noclip = settings.noclip; 77 + let r#type = settings.r#type; 78 + let preamp = settings.preamp; 79 + 80 + v1alpha1::ReplaygainSettings { 81 + noclip, 82 + r#type, 83 + preamp, 84 + } 85 + } 86 + } 87 + 88 + impl From<EqBandSetting> for v1alpha1::EqBandSetting { 89 + fn from(band: EqBandSetting) -> Self { 90 + let cutoff = band.cutoff; 91 + let q = band.q; 92 + let gain = band.gain; 93 + 94 + v1alpha1::EqBandSetting { cutoff, q, gain } 95 + } 96 + } 97 + 98 + impl From<CompressorSettings> for v1alpha1::CompressorSettings { 99 + fn from(settings: CompressorSettings) -> Self { 100 + let threshold = settings.threshold; 101 + let makeup_gain = settings.makeup_gain; 102 + let ratio = settings.ratio; 103 + let knee = settings.knee; 104 + let release_time = settings.release_time; 105 + let attack_time = settings.attack_time; 106 + 107 + v1alpha1::CompressorSettings { 108 + threshold, 109 + makeup_gain, 110 + ratio, 111 + knee, 112 + release_time, 113 + attack_time, 114 + } 115 + } 116 + } 117 + 118 + impl From<UserSettings> for GetGlobalSettingsResponse { 119 + fn from(settings: UserSettings) -> Self { 120 + let volume = settings.volume; 121 + let balance = settings.balance; 122 + let bass = settings.bass; 123 + let treble = settings.treble; 124 + let channel_config = settings.channel_config; 125 + let stereo_width = settings.stereo_width; 126 + let bass_cutoff = settings.bass_cutoff; 127 + let treble_cutoff = settings.treble_cutoff; 128 + let crossfade = settings.crossfade; 129 + let crossfade_fade_in_delay = settings.crossfade_fade_in_delay; 130 + let crossfade_fade_out_delay = settings.crossfade_fade_out_delay; 131 + let crossfade_fade_in_duration = settings.crossfade_fade_in_duration; 132 + let crossfade_fade_out_duration = settings.crossfade_fade_out_duration; 133 + let crossfade_fade_out_mixmode = settings.crossfade_fade_out_mixmode; 134 + let replaygain_settings = 135 + v1alpha1::ReplaygainSettings::from(settings.replaygain_settings); 136 + let crossfeed = settings.crossfeed; 137 + let crossfeed_direct_gain = settings.crossfeed_direct_gain; 138 + let crossfeed_cross_gain = settings.crossfeed_cross_gain; 139 + let crossfeed_hf_attenuation = settings.crossfeed_hf_attenuation; 140 + let crossfeed_hf_cutoff = settings.crossfeed_hf_cutoff; 141 + let eq_enabled = settings.eq_enabled; 142 + let eq_precut = settings.eq_precut; 143 + let eq_band_settings = settings 144 + .eq_band_settings 145 + .into_iter() 146 + .map(|band| band.into()) 147 + .collect(); 148 + let beep = settings.beep; 149 + let keyclick = settings.keyclick; 150 + let keyclick_repeats = settings.keyclick_repeats; 151 + let dithering_enabled = settings.dithering_enabled; 152 + let timestretch_enabled = settings.timestretch_enabled; 153 + let list_accel_start_delay = settings.list_accel_start_delay; 154 + let list_accel_wait = settings.list_accel_wait; 155 + let touchpad_sensitivity = settings.touchpad_sensitivity; 156 + let touchpad_deadzone = settings.touchpad_deadzone; 157 + let pause_rewind = settings.pause_rewind; 158 + let unplug_mode = settings.unplug_mode; 159 + let unplug_autoresume = settings.unplug_autoresume; 160 + let timeformat = settings.timeformat; 161 + let disk_spindown = settings.disk_spindown; 162 + let buffer_margin = settings.buffer_margin; 163 + let dirfilter = settings.dirfilter; 164 + let show_filename_ext = settings.show_filename_ext; 165 + let default_codepage = settings.default_codepage; 166 + let hold_lr_for_scroll_in_list = settings.hold_lr_for_scroll_in_list; 167 + let play_selected = settings.play_selected; 168 + let single_mode = settings.single_mode; 169 + let party_mode = settings.party_mode; 170 + let car_adapter_mode = settings.car_adapter_mode; 171 + let car_adapter_mode_delay = settings.car_adapter_mode_delay; 172 + let start_in_screen = settings.start_in_screen; 173 + let ff_rewind_min_step = settings.ff_rewind_min_step; 174 + let ff_rewind_accel = settings.ff_rewind_accel; 175 + let peak_meter_release = settings.peak_meter_release; 176 + let peak_meter_hold = settings.peak_meter_hold; 177 + let peak_meter_clip_hold = settings.peak_meter_clip_hold; 178 + let peak_meter_dbfs = settings.peak_meter_dbfs; 179 + let peak_meter_min = settings.peak_meter_min; 180 + let peak_meter_max = settings.peak_meter_max; 181 + let wps_file = settings.wps_file; 182 + let sbs_file = settings.sbs_file; 183 + let lang_file = settings.lang_file; 184 + let playlist_catalog_dir = settings.playlist_catalog_dir; 185 + let skip_length = settings.skip_length; 186 + let max_files_in_dir = settings.max_files_in_dir; 187 + let max_files_in_playlist = settings.max_files_in_playlist; 188 + let volume_type = settings.volume_type; 189 + let battery_display = settings.battery_display; 190 + let show_icons = settings.show_icons; 191 + let statusbar = settings.statusbar; 192 + let scrollbar = settings.scrollbar; 193 + let scrollbar_width = settings.scrollbar_width; 194 + let list_line_padding = settings.list_line_padding; 195 + let list_separator_color = settings.list_separator_color; 196 + let browse_current = settings.browse_current; 197 + let scroll_paginated = settings.scroll_paginated; 198 + let list_wraparound = settings.list_wraparound; 199 + let list_order = settings.list_order; 200 + let scroll_speed = settings.scroll_speed; 201 + let bidir_limit = settings.bidir_limit; 202 + let scroll_delay = settings.scroll_delay; 203 + let scroll_step = settings.scroll_step; 204 + let autoloadbookmark = settings.autoloadbookmark; 205 + let autocreatebookmark = settings.autocreatebookmark; 206 + let autoupdatebookmark = settings.autoupdatebookmark; 207 + let usemrb = settings.usemrb; 208 + let dircache = settings.dircache; 209 + let tagcache_ram = settings.tagcache_ram; 210 + let tagcache_autoupdate = settings.tagcache_autoupdate; 211 + let autoresume_enable = settings.autoresume_enable; 212 + let autoresume_automatic = settings.autoresume_automatic; 213 + let autoresume_paths = settings.autoresume_paths; 214 + let runtimedb = settings.runtimedb; 215 + let tagcache_scan_paths = settings.tagcache_scan_paths; 216 + let tagcache_db_path = settings.tagcache_db_path; 217 + let backdrop_file = settings.backdrop_file; 218 + let bg_color = settings.bg_color; 219 + let fg_color = settings.fg_color; 220 + let lss_color = settings.lss_color; 221 + let lse_color = settings.lse_color; 222 + let lst_color = settings.lst_color; 223 + let colors_file = settings.colors_file; 224 + let browser_default = settings.browser_default; 225 + let repeat_mode = settings.repeat_mode; 226 + let next_folder = settings.next_folder; 227 + let constrain_next_folder = settings.constrain_next_folder; 228 + let recursive_dir_insert = settings.recursive_dir_insert; 229 + let fade_on_stop = settings.fade_on_stop; 230 + let playlist_shuffle = settings.playlist_shuffle; 231 + let warnon_erase_dynplaylist = settings.warnon_erase_dynplaylist; 232 + let keep_current_track_on_replace_playlist = 233 + settings.keep_current_track_on_replace_playlist; 234 + let show_shuffled_adding_options = settings.show_shuffled_adding_options; 235 + let show_queue_options = settings.show_queue_options; 236 + let album_art = settings.album_art; 237 + let rewind_across_tracks = settings.rewind_across_tracks; 238 + let playlist_viewer_icons = settings.playlist_viewer_icons; 239 + let playlist_viewer_indices = settings.playlist_viewer_indices; 240 + let playlist_viewer_track_display = settings.playlist_viewer_track_display; 241 + let sort_case = settings.sort_case; 242 + let sort_dir = settings.sort_dir; 243 + let sort_file = settings.sort_file; 244 + let interpret_numbers = settings.interpret_numbers; 245 + let poweroff = settings.poweroff; 246 + let spdif_enable = settings.spdif_enable; 247 + let contrast = settings.contrast; 248 + let invert = settings.invert; 249 + let flip_display = settings.flip_display; 250 + let cursor_style = settings.cursor_style; 251 + let screen_scroll_step = settings.screen_scroll_step; 252 + let show_path_in_browser = settings.show_path_in_browser; 253 + let offset_out_of_view = settings.offset_out_of_view; 254 + let disable_mainmenu_scrolling = settings.disable_mainmenu_scrolling; 255 + let icon_file = settings.icon_file; 256 + let viewers_icon_file = settings.viewers_icon_file; 257 + let font_file = settings.font_file; 258 + let glyphs_to_cache = settings.glyphs_to_cache; 259 + let kbd_file = settings.kbd_file; 260 + let backlight_timeout = settings.backlight_timeout; 261 + let caption_backlight = settings.caption_backlight; 262 + let bl_filter_first_keypress = settings.bl_filter_first_keypress; 263 + let backlight_timeout_plugged = settings.backlight_timeout_plugged; 264 + let bt_selective_softlock_actions = settings.bt_selective_softlock_actions; 265 + let bt_selective_softlock_actions_mask = 266 + settings.bt_selective_softlock_actions_mask; 267 + let bl_selective_actions = settings.bl_selective_actions; 268 + let bl_selective_actions_mask = settings.bl_selective_actions_mask; 269 + let backlight_on_button_hold = settings.backlight_on_button_hold; 270 + let lcd_sleep_after_backlight_off = settings.lcd_sleep_after_backlight_off; 271 + let brightness = settings.brightness; 272 + let speaker_mode = settings.speaker_mode; 273 + let prevent_skip = settings.prevent_skip; 274 + let touch_mode = settings.touch_mode; 275 + let pitch_mode_semitone = settings.pitch_mode_semitone; 276 + let pitch_mode_timestretch = settings.pitch_mode_timestretch; 277 + let player_name = settings.player_name; 278 + let compressor_settings = 279 + v1alpha1::CompressorSettings::from(settings.compressor_settings); 280 + let sleeptimer_duration = settings.sleeptimer_duration; 281 + let sleeptimer_on_startup = settings.sleeptimer_on_startup; 282 + let keypress_restarts_sleeptimer = settings.keypress_restarts_sleeptimer; 283 + let show_shutdown_message = settings.show_shutdown_message; 284 + let hotkey_wps = settings.hotkey_wps; 285 + let hotkey_tree = settings.hotkey_tree; 286 + let resume_rewind = settings.resume_rewind; 287 + let depth_3d = settings.depth_3d; 288 + let roll_off = settings.roll_off; 289 + let power_mode = settings.power_mode; 290 + let keyclick_hardware = settings.keyclick_hardware; 291 + let start_directory = settings.start_directory; 292 + let root_menu_customized = settings.root_menu_customized; 293 + let shortcuts_replaces_qs = settings.shortcuts_replaces_qs; 294 + let play_frequency = settings.play_frequency; 295 + let volume_limit = settings.volume_limit; 296 + let volume_adjust_mode = settings.volume_adjust_mode; 297 + let volume_adjust_norm_steps = settings.volume_adjust_norm_steps; 298 + let surround_enabled = settings.surround_enabled; 299 + let surround_balance = settings.surround_balance; 300 + let surround_fx1 = settings.surround_fx1; 301 + let surround_fx2 = settings.surround_fx2; 302 + let surround_method2 = settings.surround_method2; 303 + let surround_mix = settings.surround_mix; 304 + let pbe = settings.pbe; 305 + let pbe_precut = settings.pbe_precut; 306 + let afr_enabled = settings.afr_enabled; 307 + let governor = settings.governor; 308 + let stereosw_mode = settings.stereosw_mode; 309 + 310 + GetGlobalSettingsResponse { 311 + volume, 312 + balance, 313 + bass, 314 + treble, 315 + channel_config, 316 + stereo_width, 317 + bass_cutoff, 318 + treble_cutoff, 319 + crossfade, 320 + crossfade_fade_in_delay, 321 + crossfade_fade_out_delay, 322 + crossfade_fade_in_duration, 323 + crossfade_fade_out_duration, 324 + crossfade_fade_out_mixmode, 325 + replaygain_settings: Some(replaygain_settings), 326 + crossfeed, 327 + crossfeed_direct_gain, 328 + crossfeed_cross_gain, 329 + crossfeed_hf_attenuation, 330 + crossfeed_hf_cutoff, 331 + eq_enabled, 332 + eq_precut, 333 + eq_band_settings, 334 + beep, 335 + keyclick, 336 + keyclick_repeats, 337 + dithering_enabled, 338 + timestretch_enabled, 339 + list_accel_start_delay, 340 + list_accel_wait, 341 + touchpad_sensitivity, 342 + touchpad_deadzone, 343 + pause_rewind, 344 + unplug_mode, 345 + unplug_autoresume, 346 + timeformat, 347 + disk_spindown, 348 + buffer_margin, 349 + dirfilter, 350 + show_filename_ext, 351 + default_codepage, 352 + hold_lr_for_scroll_in_list, 353 + play_selected, 354 + single_mode, 355 + party_mode, 356 + car_adapter_mode, 357 + car_adapter_mode_delay, 358 + start_in_screen, 359 + ff_rewind_min_step, 360 + ff_rewind_accel, 361 + peak_meter_release, 362 + peak_meter_hold, 363 + peak_meter_clip_hold, 364 + peak_meter_dbfs, 365 + peak_meter_min, 366 + peak_meter_max, 367 + wps_file, 368 + sbs_file, 369 + lang_file, 370 + playlist_catalog_dir, 371 + skip_length, 372 + max_files_in_dir, 373 + max_files_in_playlist, 374 + volume_type, 375 + battery_display, 376 + show_icons, 377 + statusbar, 378 + scrollbar, 379 + scrollbar_width, 380 + list_line_padding, 381 + list_separator_color, 382 + browse_current, 383 + scroll_paginated, 384 + list_wraparound, 385 + list_order, 386 + scroll_speed, 387 + bidir_limit, 388 + scroll_delay, 389 + scroll_step, 390 + autoloadbookmark, 391 + autocreatebookmark, 392 + autoupdatebookmark, 393 + usemrb, 394 + dircache, 395 + tagcache_ram, 396 + tagcache_autoupdate, 397 + autoresume_enable, 398 + autoresume_automatic, 399 + autoresume_paths, 400 + runtimedb, 401 + tagcache_scan_paths, 402 + tagcache_db_path, 403 + backdrop_file, 404 + bg_color, 405 + fg_color, 406 + lss_color, 407 + lse_color, 408 + lst_color, 409 + colors_file, 410 + browser_default, 411 + repeat_mode, 412 + next_folder, 413 + constrain_next_folder, 414 + recursive_dir_insert, 415 + fade_on_stop, 416 + playlist_shuffle, 417 + warnon_erase_dynplaylist, 418 + keep_current_track_on_replace_playlist, 419 + show_shuffled_adding_options, 420 + show_queue_options, 421 + album_art, 422 + rewind_across_tracks, 423 + playlist_viewer_icons, 424 + playlist_viewer_indices, 425 + playlist_viewer_track_display, 426 + sort_case, 427 + sort_dir, 428 + sort_file, 429 + interpret_numbers, 430 + poweroff, 431 + spdif_enable, 432 + contrast, 433 + invert, 434 + flip_display, 435 + cursor_style, 436 + screen_scroll_step, 437 + show_path_in_browser, 438 + offset_out_of_view, 439 + disable_mainmenu_scrolling, 440 + icon_file, 441 + viewers_icon_file, 442 + font_file, 443 + glyphs_to_cache, 444 + kbd_file, 445 + backlight_timeout, 446 + caption_backlight, 447 + bl_filter_first_keypress, 448 + backlight_timeout_plugged, 449 + bt_selective_softlock_actions, 450 + bt_selective_softlock_actions_mask, 451 + bl_selective_actions, 452 + bl_selective_actions_mask, 453 + backlight_on_button_hold, 454 + lcd_sleep_after_backlight_off, 455 + brightness, 456 + speaker_mode, 457 + prevent_skip, 458 + touch_mode, 459 + pitch_mode_semitone, 460 + pitch_mode_timestretch, 461 + player_name, 462 + compressor_settings: Some(compressor_settings), 463 + sleeptimer_duration, 464 + sleeptimer_on_startup, 465 + keypress_restarts_sleeptimer, 466 + show_shutdown_message, 467 + hotkey_wps, 468 + hotkey_tree, 469 + resume_rewind, 470 + depth_3d, 471 + roll_off, 472 + power_mode, 473 + keyclick_hardware, 474 + start_directory, 475 + root_menu_customized, 476 + shortcuts_replaces_qs, 477 + play_frequency, 478 + volume_limit, 479 + volume_adjust_mode, 480 + volume_adjust_norm_steps, 481 + surround_enabled, 482 + surround_balance, 483 + surround_fx1, 484 + surround_fx2, 485 + surround_method2, 486 + surround_mix, 487 + pbe, 488 + pbe_precut, 489 + afr_enabled, 490 + governor, 491 + stereosw_mode, 492 + } 493 + } 494 + } 495 + 496 + impl From<SystemStatus> for GetGlobalStatusResponse { 497 + fn from(status: SystemStatus) -> Self { 498 + let resume_index = status.resume_index; 499 + let resume_crc32 = status.resume_crc32; 500 + let resume_elapsed = status.resume_elapsed; 501 + let resume_offset = status.resume_offset; 502 + let runtime = status.runtime; 503 + let topruntime = status.topruntime; 504 + let dircache_size = status.dircache_size; 505 + let last_screen = status.last_screen as i32; 506 + let viewer_icon_count = status.viewer_icon_count; 507 + let last_volume_change = status.last_volume_change; 508 + 509 + GetGlobalStatusResponse { 510 + resume_index, 511 + resume_crc32, 512 + resume_elapsed, 513 + resume_offset, 514 + runtime, 515 + topruntime, 516 + dircache_size, 517 + last_screen, 518 + viewer_icon_count, 519 + last_volume_change, 520 + } 521 + } 522 + } 523 + } 524 + } 525 + 526 + pub fn rockbox_url() -> String { 527 + let port = std::env::var("ROCKBOX_TCP_PORT").unwrap_or_else(|_| "6063".to_string()); 528 + format!("http://127.0.0.1:{}", port) 529 + }
+2
crates/rpc/src/metadata.rs
··· 1 + #[derive(Default)] 2 + pub struct Metadata;
+139
crates/rpc/src/playback.rs
··· 1 + use std::sync::{mpsc::Sender, Arc, Mutex}; 2 + 3 + use crate::api::rockbox::v1alpha1::{playback_service_server::PlaybackService, *}; 4 + use rockbox_sys::{self as rb, events::RockboxCommand}; 5 + 6 + pub struct Playback { 7 + cmd_tx: Arc<Mutex<Sender<RockboxCommand>>>, 8 + } 9 + 10 + impl Playback { 11 + pub fn new(cmd_tx: Arc<Mutex<Sender<RockboxCommand>>>) -> Self { 12 + Self { cmd_tx } 13 + } 14 + } 15 + 16 + #[tonic::async_trait] 17 + impl PlaybackService for Playback { 18 + async fn play( 19 + &self, 20 + request: tonic::Request<PlayRequest>, 21 + ) -> Result<tonic::Response<PlayResponse>, tonic::Status> { 22 + let params = request.into_inner(); 23 + self.cmd_tx 24 + .lock() 25 + .unwrap() 26 + .send(RockboxCommand::Play(params.elapsed, params.offset)) 27 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 28 + Ok(tonic::Response::new(PlayResponse::default())) 29 + } 30 + 31 + async fn pause( 32 + &self, 33 + request: tonic::Request<PauseRequest>, 34 + ) -> Result<tonic::Response<PauseResponse>, tonic::Status> { 35 + self.cmd_tx 36 + .lock() 37 + .unwrap() 38 + .send(RockboxCommand::Pause) 39 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 40 + Ok(tonic::Response::new(PauseResponse::default())) 41 + } 42 + 43 + async fn resume( 44 + &self, 45 + request: tonic::Request<ResumeRequest>, 46 + ) -> Result<tonic::Response<ResumeResponse>, tonic::Status> { 47 + self.cmd_tx 48 + .lock() 49 + .unwrap() 50 + .send(RockboxCommand::Resume) 51 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 52 + Ok(tonic::Response::new(ResumeResponse::default())) 53 + } 54 + 55 + async fn next( 56 + &self, 57 + request: tonic::Request<NextRequest>, 58 + ) -> Result<tonic::Response<NextResponse>, tonic::Status> { 59 + self.cmd_tx 60 + .lock() 61 + .unwrap() 62 + .send(RockboxCommand::Next) 63 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 64 + Ok(tonic::Response::new(NextResponse::default())) 65 + } 66 + 67 + async fn previous( 68 + &self, 69 + request: tonic::Request<PreviousRequest>, 70 + ) -> Result<tonic::Response<PreviousResponse>, tonic::Status> { 71 + self.cmd_tx 72 + .lock() 73 + .unwrap() 74 + .send(RockboxCommand::Prev) 75 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 76 + Ok(tonic::Response::new(PreviousResponse::default())) 77 + } 78 + 79 + async fn fast_forward_rewind( 80 + &self, 81 + request: tonic::Request<FastForwardRewindRequest>, 82 + ) -> Result<tonic::Response<FastForwardRewindResponse>, tonic::Status> { 83 + let params = request.into_inner(); 84 + self.cmd_tx 85 + .lock() 86 + .unwrap() 87 + .send(RockboxCommand::FfRewind(params.new_time)) 88 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 89 + Ok(tonic::Response::new(FastForwardRewindResponse::default())) 90 + } 91 + 92 + async fn status( 93 + &self, 94 + request: tonic::Request<StatusRequest>, 95 + ) -> Result<tonic::Response<StatusResponse>, tonic::Status> { 96 + let status = rb::playback::status(); 97 + Ok(tonic::Response::new(StatusResponse::default())) 98 + } 99 + 100 + async fn current_track( 101 + &self, 102 + request: tonic::Request<CurrentTrackRequest>, 103 + ) -> Result<tonic::Response<CurrentTrackResponse>, tonic::Status> { 104 + let track = rb::playback::current_track(); 105 + Ok(tonic::Response::new(track.into())) 106 + } 107 + 108 + async fn flush_and_reload_tracks( 109 + &self, 110 + request: tonic::Request<FlushAndReloadTracksRequest>, 111 + ) -> Result<tonic::Response<FlushAndReloadTracksResponse>, tonic::Status> { 112 + self.cmd_tx 113 + .lock() 114 + .unwrap() 115 + .send(RockboxCommand::FlushAndReloadTracks) 116 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 117 + Ok(tonic::Response::new(FlushAndReloadTracksResponse::default())) 118 + } 119 + 120 + async fn get_file_position( 121 + &self, 122 + request: tonic::Request<GetFilePositionRequest>, 123 + ) -> Result<tonic::Response<GetFilePositionResponse>, tonic::Status> { 124 + let position = rb::playback::get_file_pos(); 125 + Ok(tonic::Response::new(GetFilePositionResponse { position })) 126 + } 127 + 128 + async fn hard_stop( 129 + &self, 130 + request: tonic::Request<HardStopRequest>, 131 + ) -> Result<tonic::Response<HardStopResponse>, tonic::Status> { 132 + self.cmd_tx 133 + .lock() 134 + .unwrap() 135 + .send(RockboxCommand::Stop) 136 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 137 + Ok(tonic::Response::new(HardStopResponse::default())) 138 + } 139 + }
+155
crates/rpc/src/playlist.rs
··· 1 + use std::sync::{mpsc::Sender, Arc, Mutex}; 2 + 3 + use rockbox_sys::events::RockboxCommand; 4 + 5 + use crate::api::rockbox::v1alpha1::{playlist_service_server::PlaylistService, *}; 6 + 7 + pub struct Playlist { 8 + cmd_tx: Arc<Mutex<Sender<RockboxCommand>>>, 9 + } 10 + 11 + impl Playlist { 12 + pub fn new(cmd_tx: Arc<Mutex<Sender<RockboxCommand>>>) -> Self { 13 + Self { cmd_tx } 14 + } 15 + } 16 + 17 + #[tonic::async_trait] 18 + impl PlaylistService for Playlist { 19 + async fn get_current( 20 + &self, 21 + request: tonic::Request<GetCurrentRequest>, 22 + ) -> Result<tonic::Response<GetCurrentResponse>, tonic::Status> { 23 + Ok(tonic::Response::new(GetCurrentResponse::default())) 24 + } 25 + 26 + async fn get_resume_info( 27 + &self, 28 + request: tonic::Request<GetResumeInfoRequest>, 29 + ) -> Result<tonic::Response<GetResumeInfoResponse>, tonic::Status> { 30 + Ok(tonic::Response::new(GetResumeInfoResponse::default())) 31 + } 32 + 33 + async fn get_track_info( 34 + &self, 35 + request: tonic::Request<GetTrackInfoRequest>, 36 + ) -> Result<tonic::Response<GetTrackInfoResponse>, tonic::Status> { 37 + Ok(tonic::Response::new(GetTrackInfoResponse::default())) 38 + } 39 + 40 + async fn get_first_index( 41 + &self, 42 + request: tonic::Request<GetFirstIndexRequest>, 43 + ) -> Result<tonic::Response<GetFirstIndexResponse>, tonic::Status> { 44 + Ok(tonic::Response::new(GetFirstIndexResponse::default())) 45 + } 46 + 47 + async fn get_display_index( 48 + &self, 49 + request: tonic::Request<GetDisplayIndexRequest>, 50 + ) -> Result<tonic::Response<GetDisplayIndexResponse>, tonic::Status> { 51 + Ok(tonic::Response::new(GetDisplayIndexResponse::default())) 52 + } 53 + 54 + async fn amount( 55 + &self, 56 + request: tonic::Request<AmountRequest>, 57 + ) -> Result<tonic::Response<AmountResponse>, tonic::Status> { 58 + Ok(tonic::Response::new(AmountResponse::default())) 59 + } 60 + 61 + async fn playlist_resume( 62 + &self, 63 + request: tonic::Request<PlaylistResumeRequest>, 64 + ) -> Result<tonic::Response<PlaylistResumeResponse>, tonic::Status> { 65 + self.cmd_tx 66 + .lock() 67 + .unwrap() 68 + .send(RockboxCommand::PlaylistResume) 69 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 70 + Ok(tonic::Response::new(PlaylistResumeResponse::default())) 71 + } 72 + 73 + async fn resume_track( 74 + &self, 75 + request: tonic::Request<ResumeTrackRequest>, 76 + ) -> Result<tonic::Response<ResumeTrackResponse>, tonic::Status> { 77 + let params = request.into_inner(); 78 + self.cmd_tx 79 + .lock() 80 + .unwrap() 81 + .send(RockboxCommand::PlaylistResumeTrack) 82 + .map_err(|_| tonic::Status::internal("Failed to send command"))?; 83 + Ok(tonic::Response::new(ResumeTrackResponse::default())) 84 + } 85 + 86 + async fn set_modified( 87 + &self, 88 + request: tonic::Request<SetModifiedRequest>, 89 + ) -> Result<tonic::Response<SetModifiedResponse>, tonic::Status> { 90 + Ok(tonic::Response::new(SetModifiedResponse::default())) 91 + } 92 + 93 + async fn start( 94 + &self, 95 + request: tonic::Request<StartRequest>, 96 + ) -> Result<tonic::Response<StartResponse>, tonic::Status> { 97 + Ok(tonic::Response::new(StartResponse::default())) 98 + } 99 + 100 + async fn sync( 101 + &self, 102 + request: tonic::Request<SyncRequest>, 103 + ) -> Result<tonic::Response<SyncResponse>, tonic::Status> { 104 + Ok(tonic::Response::new(SyncResponse::default())) 105 + } 106 + 107 + async fn remove_all_tracks( 108 + &self, 109 + request: tonic::Request<RemoveAllTracksRequest>, 110 + ) -> Result<tonic::Response<RemoveAllTracksResponse>, tonic::Status> { 111 + Ok(tonic::Response::new(RemoveAllTracksResponse::default())) 112 + } 113 + 114 + async fn create_playlist( 115 + &self, 116 + request: tonic::Request<CreatePlaylistRequest>, 117 + ) -> Result<tonic::Response<CreatePlaylistResponse>, tonic::Status> { 118 + Ok(tonic::Response::new(CreatePlaylistResponse::default())) 119 + } 120 + 121 + async fn insert_track( 122 + &self, 123 + request: tonic::Request<InsertTrackRequest>, 124 + ) -> Result<tonic::Response<InsertTrackResponse>, tonic::Status> { 125 + Ok(tonic::Response::new(InsertTrackResponse::default())) 126 + } 127 + 128 + async fn insert_directory( 129 + &self, 130 + request: tonic::Request<InsertDirectoryRequest>, 131 + ) -> Result<tonic::Response<InsertDirectoryResponse>, tonic::Status> { 132 + Ok(tonic::Response::new(InsertDirectoryResponse::default())) 133 + } 134 + 135 + async fn insert_playlist( 136 + &self, 137 + request: tonic::Request<InsertPlaylistRequest>, 138 + ) -> Result<tonic::Response<InsertPlaylistResponse>, tonic::Status> { 139 + Ok(tonic::Response::new(InsertPlaylistResponse::default())) 140 + } 141 + 142 + async fn shuffle_playlist( 143 + &self, 144 + request: tonic::Request<ShufflePlaylistRequest>, 145 + ) -> Result<tonic::Response<ShufflePlaylistResponse>, tonic::Status> { 146 + Ok(tonic::Response::new(ShufflePlaylistResponse::default())) 147 + } 148 + 149 + async fn warn_on_playlist_erase( 150 + &self, 151 + request: tonic::Request<WarnOnPlaylistEraseRequest>, 152 + ) -> Result<tonic::Response<WarnOnPlaylistEraseResponse>, tonic::Status> { 153 + Ok(tonic::Response::new(WarnOnPlaylistEraseResponse::default())) 154 + } 155 + }
+69
crates/rpc/src/server.rs
··· 1 + use std::net::SocketAddr; 2 + use std::sync::mpsc::Sender; 3 + use std::sync::{Arc, Mutex}; 4 + 5 + use crate::api::rockbox::v1alpha1::browse_service_server::BrowseServiceServer; 6 + use crate::api::rockbox::v1alpha1::playback_service_server::PlaybackServiceServer; 7 + use crate::api::rockbox::v1alpha1::playlist_service_server::PlaylistServiceServer; 8 + use crate::api::rockbox::v1alpha1::settings_service_server::SettingsServiceServer; 9 + use crate::api::rockbox::v1alpha1::sound_service_server::SoundServiceServer; 10 + use crate::api::rockbox::FILE_DESCRIPTOR_SET; 11 + use crate::browse::Browse; 12 + use crate::playback::Playback; 13 + use crate::playlist::Playlist; 14 + use crate::settings::Settings; 15 + use crate::sound::Sound; 16 + use crate::system::System; 17 + use owo_colors::OwoColorize; 18 + use rockbox_sys::events::RockboxCommand; 19 + use tonic::transport::Server; 20 + 21 + pub async fn start( 22 + cmd_tx: Arc<Mutex<Sender<RockboxCommand>>>, 23 + ) -> Result<(), Box<dyn std::error::Error>> { 24 + let rockbox_port: u16 = std::env::var("ROCKBOX_PORT") 25 + .unwrap_or_else(|_| "6061".to_string()) 26 + .parse() 27 + .expect("ROCKBOX_PORT must be a number"); 28 + 29 + let addr: SocketAddr = format!("0.0.0.0:{}", rockbox_port).parse()?; 30 + 31 + let host_and_port = format!("0.0.0.0:{}", rockbox_port); 32 + 33 + println!( 34 + "{} server is running on {}", 35 + "Rockbox gRPC".bright_purple(), 36 + host_and_port.bright_green() 37 + ); 38 + 39 + let client = reqwest::Client::new(); 40 + 41 + Server::builder() 42 + .accept_http1(true) 43 + .add_service( 44 + tonic_reflection::server::Builder::configure() 45 + .register_encoded_file_descriptor_set(FILE_DESCRIPTOR_SET) 46 + .build_v1alpha()?, 47 + ) 48 + .add_service(tonic_web::enable(PlaylistServiceServer::new( 49 + Playlist::new(cmd_tx.clone()), 50 + ))) 51 + .add_service(tonic_web::enable(PlaybackServiceServer::new( 52 + Playback::new(cmd_tx.clone()), 53 + ))) 54 + .add_service(tonic_web::enable(BrowseServiceServer::new( 55 + Browse::default(), 56 + ))) 57 + .add_service(tonic_web::enable(SoundServiceServer::new(Sound::default()))) 58 + .add_service(tonic_web::enable(SettingsServiceServer::new( 59 + Settings::new(client.clone()), 60 + ))) 61 + .add_service(tonic_web::enable( 62 + crate::api::rockbox::v1alpha1::system_service_server::SystemServiceServer::new( 63 + System::new(client.clone()), 64 + ), 65 + )) 66 + .serve(addr) 67 + .await?; 68 + Ok(()) 69 + }
+57
crates/rpc/src/settings.rs
··· 1 + use rockbox_sys::types::user_settings::UserSettings; 2 + use tonic::{Request, Response, Status}; 3 + 4 + use crate::{ 5 + api::rockbox::v1alpha1::{ 6 + settings_service_server::SettingsService, GetGlobalSettingsRequest, 7 + GetGlobalSettingsResponse, GetSettingsListRequest, GetSettingsListResponse, 8 + }, 9 + rockbox_url, 10 + }; 11 + 12 + #[derive(Default)] 13 + pub struct Settings { 14 + client: reqwest::Client, 15 + } 16 + 17 + impl Settings { 18 + pub fn new(client: reqwest::Client) -> Self { 19 + Self { client } 20 + } 21 + } 22 + 23 + #[tonic::async_trait] 24 + impl SettingsService for Settings { 25 + async fn get_global_settings( 26 + &self, 27 + _request: Request<GetGlobalSettingsRequest>, 28 + ) -> Result<Response<GetGlobalSettingsResponse>, Status> { 29 + let url = format!("{}/settings", rockbox_url()); 30 + let response = self 31 + .client 32 + .get(url) 33 + .send() 34 + .await 35 + .map_err(|e| Status::internal(e.to_string()))?; 36 + let settings = response 37 + .json::<UserSettings>() 38 + .await 39 + .map_err(|e| Status::internal(e.to_string()))?; 40 + Ok(Response::new(settings.into())) 41 + } 42 + 43 + async fn get_settings_list( 44 + &self, 45 + _request: Request<GetSettingsListRequest>, 46 + ) -> Result<Response<GetSettingsListResponse>, Status> { 47 + let url = format!("{}/settingslist", rockbox_url()); 48 + let _response = self 49 + .client 50 + .get(url) 51 + .send() 52 + .await 53 + .map_err(|e| Status::internal(e.to_string()))?; 54 + //let settings = response.json::<UserSettings>().await?; 55 + todo!() 56 + } 57 + }
+112
crates/rpc/src/sound.rs
··· 1 + use crate::api::rockbox::v1alpha1::{sound_service_server::SoundService, *}; 2 + 3 + #[derive(Default)] 4 + pub struct Sound; 5 + 6 + #[tonic::async_trait] 7 + impl SoundService for Sound { 8 + async fn adjust_volume( 9 + &self, 10 + request: tonic::Request<AdjustVolumeRequest>, 11 + ) -> Result<tonic::Response<AdjustVolumeResponse>, tonic::Status> { 12 + Ok(tonic::Response::new(AdjustVolumeResponse::default())) 13 + } 14 + 15 + async fn sound_set( 16 + &self, 17 + request: tonic::Request<SoundSetRequest>, 18 + ) -> Result<tonic::Response<SoundSetResponse>, tonic::Status> { 19 + Ok(tonic::Response::new(SoundSetResponse::default())) 20 + } 21 + 22 + async fn sound_current( 23 + &self, 24 + request: tonic::Request<SoundCurrentRequest>, 25 + ) -> Result<tonic::Response<SoundCurrentResponse>, tonic::Status> { 26 + Ok(tonic::Response::new(SoundCurrentResponse::default())) 27 + } 28 + 29 + async fn sound_default( 30 + &self, 31 + request: tonic::Request<SoundDefaultRequest>, 32 + ) -> Result<tonic::Response<SoundDefaultResponse>, tonic::Status> { 33 + Ok(tonic::Response::new(SoundDefaultResponse::default())) 34 + } 35 + 36 + async fn sound_min( 37 + &self, 38 + request: tonic::Request<SoundMinRequest>, 39 + ) -> Result<tonic::Response<SoundMinResponse>, tonic::Status> { 40 + Ok(tonic::Response::new(SoundMinResponse::default())) 41 + } 42 + 43 + async fn sound_max( 44 + &self, 45 + request: tonic::Request<SoundMaxRequest>, 46 + ) -> Result<tonic::Response<SoundMaxResponse>, tonic::Status> { 47 + Ok(tonic::Response::new(SoundMaxResponse::default())) 48 + } 49 + 50 + async fn sound_unit( 51 + &self, 52 + request: tonic::Request<SoundUnitRequest>, 53 + ) -> Result<tonic::Response<SoundUnitResponse>, tonic::Status> { 54 + Ok(tonic::Response::new(SoundUnitResponse::default())) 55 + } 56 + 57 + async fn sound_val2_phys( 58 + &self, 59 + request: tonic::Request<SoundVal2PhysRequest>, 60 + ) -> Result<tonic::Response<SoundVal2PhysResponse>, tonic::Status> { 61 + Ok(tonic::Response::new(SoundVal2PhysResponse::default())) 62 + } 63 + 64 + async fn get_pitch( 65 + &self, 66 + request: tonic::Request<GetPitchRequest>, 67 + ) -> Result<tonic::Response<GetPitchResponse>, tonic::Status> { 68 + Ok(tonic::Response::new(GetPitchResponse::default())) 69 + } 70 + 71 + async fn set_pitch( 72 + &self, 73 + request: tonic::Request<SetPitchRequest>, 74 + ) -> Result<tonic::Response<SetPitchResponse>, tonic::Status> { 75 + Ok(tonic::Response::new(SetPitchResponse::default())) 76 + } 77 + 78 + async fn beep_play( 79 + &self, 80 + request: tonic::Request<BeepPlayRequest>, 81 + ) -> Result<tonic::Response<BeepPlayResponse>, tonic::Status> { 82 + Ok(tonic::Response::new(BeepPlayResponse::default())) 83 + } 84 + 85 + async fn pcmbuf_fade( 86 + &self, 87 + request: tonic::Request<PcmbufFadeRequest>, 88 + ) -> Result<tonic::Response<PcmbufFadeResponse>, tonic::Status> { 89 + Ok(tonic::Response::new(PcmbufFadeResponse::default())) 90 + } 91 + 92 + async fn pcmbuf_set_low_latency( 93 + &self, 94 + request: tonic::Request<PcmbufSetLowLatencyRequest>, 95 + ) -> Result<tonic::Response<PcmbufSetLowLatencyResponse>, tonic::Status> { 96 + Ok(tonic::Response::new(PcmbufSetLowLatencyResponse::default())) 97 + } 98 + 99 + async fn system_sound_play( 100 + &self, 101 + request: tonic::Request<SystemSoundPlayRequest>, 102 + ) -> Result<tonic::Response<SystemSoundPlayResponse>, tonic::Status> { 103 + Ok(tonic::Response::new(SystemSoundPlayResponse::default())) 104 + } 105 + 106 + async fn keyclick_click( 107 + &self, 108 + request: tonic::Request<KeyclickClickRequest>, 109 + ) -> Result<tonic::Response<KeyclickClickResponse>, tonic::Status> { 110 + Ok(tonic::Response::new(KeyclickClickResponse::default())) 111 + } 112 + }
+61
crates/rpc/src/system.rs
··· 1 + use rockbox_sys::types::{system_status::SystemStatus, RockboxVersion}; 2 + use tonic::{Request, Response, Status}; 3 + 4 + use crate::{ 5 + api::rockbox::v1alpha1::{ 6 + system_service_server::SystemService, GetGlobalStatusRequest, GetGlobalStatusResponse, 7 + GetRockboxVersionRequest, GetRockboxVersionResponse, 8 + }, 9 + rockbox_url, 10 + }; 11 + 12 + #[derive(Default)] 13 + pub struct System { 14 + client: reqwest::Client, 15 + } 16 + 17 + impl System { 18 + pub fn new(client: reqwest::Client) -> Self { 19 + Self { client } 20 + } 21 + } 22 + 23 + #[tonic::async_trait] 24 + impl SystemService for System { 25 + async fn get_global_status( 26 + &self, 27 + _request: Request<GetGlobalStatusRequest>, 28 + ) -> Result<Response<GetGlobalStatusResponse>, Status> { 29 + let url = format!("{}/status", rockbox_url()); 30 + let response = self 31 + .client 32 + .get(url) 33 + .send() 34 + .await 35 + .map_err(|e| Status::internal(e.to_string()))?; 36 + let status = response 37 + .json::<SystemStatus>() 38 + .await 39 + .map_err(|e| Status::internal(e.to_string()))?; 40 + Ok(Response::new(status.into())) 41 + } 42 + 43 + async fn get_rockbox_version( 44 + &self, 45 + _request: Request<GetRockboxVersionRequest>, 46 + ) -> Result<Response<GetRockboxVersionResponse>, Status> { 47 + let url = format!("{}/version", rockbox_url()); 48 + let response = self 49 + .client 50 + .get(url) 51 + .send() 52 + .await 53 + .map_err(|e| Status::internal(e.to_string()))?; 54 + let version = response 55 + .json::<RockboxVersion>() 56 + .await 57 + .map_err(|e| Status::internal(e.to_string()))? 58 + .version; 59 + Ok(Response::new(GetRockboxVersionResponse { version })) 60 + } 61 + }
+2
crates/rpc/src/tagcache.rs
··· 1 + #[derive(Default)] 2 + pub struct Tagcache;
+16
crates/server/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "rockbox-server" 4 + version = "0.1.0" 5 + 6 + [lib] 7 + crate-type = ["staticlib"] 8 + 9 + [dependencies] 10 + owo-colors = "4.0.0" 11 + reqwest = {version = "0.12.7", features = ["blocking", "rustls-tls"], default-features = false} 12 + rockbox-graphql = {path = "../graphql"} 13 + rockbox-rpc = {path = "../rpc"} 14 + rockbox-sys = {path = "../sys"} 15 + serde_json = "1.0.128" 16 + tokio = {version = "1.40.0", features = ["full"]}
+242
crates/server/src/lib.rs
··· 1 + use owo_colors::OwoColorize; 2 + use rockbox_sys::{self as rb, events::RockboxCommand}; 3 + use std::{ 4 + ffi::c_char, 5 + io::{BufRead, BufReader, Write}, 6 + net::{TcpListener, TcpStream}, 7 + sync::{Arc, Mutex}, 8 + thread, 9 + }; 10 + 11 + #[no_mangle] 12 + pub extern "C" fn debugfn(args: *const c_char) { 13 + let c_str = unsafe { std::ffi::CStr::from_ptr(args) }; 14 + let str_slice = c_str.to_str().unwrap(); 15 + println!("{}", str_slice); 16 + } 17 + 18 + #[no_mangle] 19 + pub extern "C" fn start_server() { 20 + const BANNER: &str = r#" 21 + __________ __ ___. 22 + Open \______ \ ____ ____ | | _\_ |__ _______ ___ 23 + Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 24 + Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 25 + Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 26 + \/ \/ \/ \/ \/ 27 + "#; 28 + 29 + println!("{}", BANNER.yellow()); 30 + 31 + let port = std::env::var("ROCKBOX_TCP_PORT").unwrap_or_else(|_| "6063".to_string()); 32 + let addr = format!("127.0.0.1:{}", port); 33 + let listener = TcpListener::bind(&addr).unwrap(); 34 + listener.set_nonblocking(true).unwrap(); 35 + 36 + println!( 37 + "{} server is running on {}", 38 + "Rockbox TCP".bright_purple(), 39 + addr.bright_green() 40 + ); 41 + 42 + loop { 43 + match listener.accept() { 44 + Ok((stream, _)) => { 45 + handle_connection(stream); 46 + } 47 + Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => { 48 + // No incoming connection, just sleep and retry 49 + rb::system::sleep(rb::HZ / 2 as f32); 50 + } 51 + Err(e) => { 52 + eprintln!("Error accepting connection: {}", e); 53 + break; 54 + } 55 + } 56 + } 57 + } 58 + 59 + fn handle_connection(mut stream: TcpStream) { 60 + let buf_reader = BufReader::new(&mut stream); 61 + let http_request: Vec<_> = buf_reader 62 + .lines() 63 + .map(|result| result.unwrap()) 64 + .take_while(|line| !line.is_empty()) 65 + .collect(); 66 + 67 + // parse request 68 + let request = http_request[0].split_whitespace().collect::<Vec<_>>(); 69 + let method = request[0]; 70 + let path = request[1]; 71 + 72 + if method != "GET" { 73 + let response = "HTTP/1.1 405 Method Not Allowed\r\n\r\n"; 74 + stream.write_all(response.as_bytes()).unwrap(); 75 + return; 76 + } 77 + 78 + match path { 79 + "/pause" => { 80 + rb::playback::pause(); 81 + } 82 + "/resume" => { 83 + rb::playback::resume(); 84 + } 85 + "/next" => { 86 + rb::playback::next(); 87 + } 88 + "/prev" => { 89 + rb::playback::prev(); 90 + } 91 + "/stop" => { 92 + rb::playback::hard_stop(); 93 + } 94 + "/playlist_resume" => { 95 + rb::playlist::resume(); 96 + } 97 + "/playlist_resume_track" => { 98 + let status = rb::system::get_global_status(); 99 + rb::playlist::resume_track( 100 + status.resume_index, 101 + status.resume_crc32, 102 + status.resume_elapsed.into(), 103 + status.resume_offset.into(), 104 + ); 105 + } 106 + "/version" => { 107 + let version = rb::system::get_rockbox_version(); 108 + let response = format!( 109 + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{}", 110 + serde_json::to_string(&version).unwrap() 111 + ); 112 + stream.write_all(response.as_bytes()).unwrap(); 113 + return; 114 + } 115 + "/status" => { 116 + let status = rb::system::get_global_status(); 117 + let response = format!( 118 + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{}", 119 + serde_json::to_string(&status).unwrap() 120 + ); 121 + stream.write_all(response.as_bytes()).unwrap(); 122 + return; 123 + } 124 + "/settings" => { 125 + let settings = rb::settings::get_global_settings(); 126 + let response = format!( 127 + "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{}", 128 + serde_json::to_string(&settings).unwrap() 129 + ); 130 + stream.write_all(response.as_bytes()).unwrap(); 131 + return; 132 + } 133 + _ => { 134 + if path.starts_with("/play") { 135 + let params: Vec<_> = path.split('?').collect(); 136 + let params: Vec<_> = params[1].split('&').collect(); 137 + let elapsed = params[0].split('=').collect::<Vec<_>>()[1].parse().unwrap(); 138 + let offset = params[1].split('=').collect::<Vec<_>>()[1].parse().unwrap(); 139 + rb::playback::play(elapsed, offset); 140 + let response = "HTTP/1.1 200 OK\r\n\r\n"; 141 + stream.write_all(response.as_bytes()).unwrap(); 142 + return; 143 + } 144 + 145 + if path.starts_with("/ff_rewind") { 146 + let params: Vec<_> = path.split('?').collect(); 147 + let newtime = params[1].split('=').collect::<Vec<_>>()[1].parse().unwrap(); 148 + rb::playback::ff_rewind(newtime); 149 + let response = "HTTP/1.1 200 OK\r\n\r\n"; 150 + stream.write_all(response.as_bytes()).unwrap(); 151 + return; 152 + } 153 + 154 + let response = "HTTP/1.1 404 Not Found\r\n\r\n"; 155 + stream.write_all(response.as_bytes()).unwrap(); 156 + return; 157 + } 158 + } 159 + 160 + let response = "HTTP/1.1 200 OK\r\n\r\n"; 161 + 162 + stream.write_all(response.as_bytes()).unwrap(); 163 + } 164 + 165 + #[no_mangle] 166 + pub extern "C" fn start_servers() { 167 + let (cmd_tx, cmd_rx) = std::sync::mpsc::channel::<RockboxCommand>(); 168 + let cmd_tx = Arc::new(Mutex::new(cmd_tx)); 169 + 170 + thread::spawn(move || { 171 + let port = std::env::var("ROCKBOX_TCP_PORT").unwrap_or_else(|_| "6063".to_string()); 172 + let url = format!("http://127.0.0.1:{}", port); 173 + 174 + while let Ok(event) = cmd_rx.recv() { 175 + match event { 176 + RockboxCommand::Play(elapsed, offset) => { 177 + reqwest::blocking::get(&format!( 178 + "{}/play?elapsed={}&offset={}", 179 + url, elapsed, offset 180 + )) 181 + .unwrap(); 182 + } 183 + RockboxCommand::Pause => { 184 + reqwest::blocking::get(&format!("{}/pause", url)).unwrap(); 185 + } 186 + RockboxCommand::Resume => { 187 + reqwest::blocking::get(&format!("{}/resume", url)).unwrap(); 188 + } 189 + RockboxCommand::Next => { 190 + reqwest::blocking::get(&format!("{}/next", url)).unwrap(); 191 + } 192 + RockboxCommand::Prev => { 193 + reqwest::blocking::get(&format!("{}/prev", url)).unwrap(); 194 + } 195 + RockboxCommand::FfRewind(newtime) => { 196 + reqwest::blocking::get(&format!("{}/ff_rewind?newtime={}", url, newtime)) 197 + .unwrap(); 198 + } 199 + RockboxCommand::FlushAndReloadTracks => { 200 + reqwest::blocking::get(&format!("{}/flush_and_reload_tracks", url)).unwrap(); 201 + } 202 + RockboxCommand::Stop => { 203 + reqwest::blocking::get(&format!("{}/stop", url)).unwrap(); 204 + } 205 + RockboxCommand::PlaylistResume => { 206 + reqwest::blocking::get(&format!("{}/playlist_resume", url)).unwrap(); 207 + } 208 + RockboxCommand::PlaylistResumeTrack => { 209 + reqwest::blocking::get(&format!("{}/playlist_resume_track", url)).unwrap(); 210 + } 211 + } 212 + } 213 + }); 214 + 215 + let cloned_cmd_tx = cmd_tx.clone(); 216 + 217 + thread::spawn(move || { 218 + let runtime = tokio::runtime::Builder::new_current_thread() 219 + .enable_all() 220 + .build() 221 + .unwrap(); 222 + match runtime.block_on(rockbox_rpc::server::start(cmd_tx.clone())) { 223 + Ok(_) => {} 224 + Err(e) => { 225 + eprintln!("Error starting server: {}", e); 226 + } 227 + } 228 + }); 229 + 230 + thread::spawn(move || { 231 + let runtime = tokio::runtime::Builder::new_current_thread() 232 + .enable_all() 233 + .build() 234 + .unwrap(); 235 + match runtime.block_on(rockbox_graphql::server::start(cloned_cmd_tx.clone())) { 236 + Ok(_) => {} 237 + Err(e) => { 238 + eprintln!("Error starting server: {}", e); 239 + } 240 + } 241 + }); 242 + }
+7
crates/sys/Cargo.toml
··· 1 + [package] 2 + edition = "2021" 3 + name = "rockbox-sys" 4 + version = "0.1.0" 5 + 6 + [dependencies] 7 + serde = { version = "1.0.210", features = ["derive"] }
+57
crates/sys/src/browse.rs
··· 1 + use std::ffi::CString; 2 + 3 + use crate::{AddToPlCallback, BrowseContext, Entry, Mp3Entry, PlaylistInsertCb, Tm, TreeContext}; 4 + 5 + pub fn rockbox_browse(ctx: *mut BrowseContext) -> i32 { 6 + unsafe { crate::rockbox_browse(ctx) } 7 + } 8 + 9 + pub fn tree_get_context() -> *mut TreeContext { 10 + unsafe { crate::tree_get_context() } 11 + } 12 + 13 + pub fn tree_get_entries(ctx: *mut TreeContext) -> *mut Entry { 14 + unsafe { crate::tree_get_entries(ctx) } 15 + } 16 + 17 + pub fn tree_get_entry_at(ctx: *mut TreeContext, index: i32) -> *mut Entry { 18 + unsafe { crate::tree_get_entry_at(ctx, index) } 19 + } 20 + 21 + pub fn set_current_file(path: &str) { 22 + let path = CString::new(path).unwrap(); 23 + unsafe { crate::set_current_file(path.as_ptr()) } 24 + } 25 + 26 + pub fn set_dirfilter(filter: i32) { 27 + unsafe { crate::set_dirfilter(filter) } 28 + } 29 + 30 + pub fn onplay_show_playlist_menu(path: &str, attr: i32, playlist_insert_cb: PlaylistInsertCb) { 31 + let path = CString::new(path).unwrap(); 32 + unsafe { crate::onplay_show_playlist_menu(path.as_ptr(), attr, playlist_insert_cb) } 33 + } 34 + 35 + pub fn onplay_show_playlist_cat_menu(track_name: &str, attr: i32, add_to_pl_cb: AddToPlCallback) { 36 + let track_name = CString::new(track_name).unwrap(); 37 + unsafe { crate::onplay_show_playlist_cat_menu(track_name.as_ptr(), attr, add_to_pl_cb) } 38 + } 39 + 40 + pub fn browse_id3( 41 + id3: *mut Mp3Entry, 42 + playlist_display_index: i32, 43 + playlist_amount: i32, 44 + modified: *mut Tm, 45 + track_ct: i32, 46 + ) -> bool { 47 + let ret = unsafe { 48 + crate::browse_id3( 49 + id3, 50 + playlist_display_index, 51 + playlist_amount, 52 + modified, 53 + track_ct, 54 + ) 55 + }; 56 + ret != 0 57 + }
+30
crates/sys/src/dir.rs
··· 1 + use std::ffi::CString; 2 + 3 + use crate::{dirent, Dir, Dirent}; 4 + 5 + pub fn open_dir(dirname: &str) -> *mut Dir { 6 + let dirname = CString::new(dirname).unwrap(); 7 + unsafe { crate::opendir(dirname.as_ptr()) } 8 + } 9 + 10 + pub fn close_dir(dirp: *mut Dir) -> i32 { 11 + unsafe { crate::closedir(dirp) } 12 + } 13 + 14 + pub fn readdir(dirp: *mut Dir) -> *mut crate::dirent { 15 + unsafe { crate::readdir(dirp) } 16 + } 17 + 18 + pub fn mkdir(path: &str) -> i32 { 19 + let path = CString::new(path).unwrap(); 20 + unsafe { crate::mkdir(path.as_ptr()) } 21 + } 22 + 23 + pub fn rmdir(path: &str) -> i32 { 24 + let path = CString::new(path).unwrap(); 25 + unsafe { crate::rmdir(path.as_ptr()) } 26 + } 27 + 28 + pub fn dir_get_info(dirp: *mut Dir, entry: *mut dirent) -> *mut Dirent { 29 + unsafe { crate::dir_get_info(dirp, entry) } 30 + }
+12
crates/sys/src/events.rs
··· 1 + pub enum RockboxCommand { 2 + Pause, 3 + Play(i64, i64), 4 + Resume, 5 + Next, 6 + Prev, 7 + FfRewind(i32), 8 + FlushAndReloadTracks, 9 + Stop, 10 + PlaylistResume, 11 + PlaylistResumeTrack, 12 + }
+119
crates/sys/src/file.rs
··· 1 + pub fn open_utf8() { 2 + unsafe { 3 + crate::open_utf8(); 4 + } 5 + } 6 + 7 + pub fn open() { 8 + unsafe { 9 + crate::open(); 10 + } 11 + } 12 + 13 + pub fn creat() { 14 + unsafe { 15 + crate::creat(); 16 + } 17 + } 18 + 19 + pub fn close() { 20 + unsafe { 21 + crate::close(); 22 + } 23 + } 24 + 25 + pub fn read() { 26 + unsafe { 27 + crate::read(); 28 + } 29 + } 30 + 31 + pub fn lseek() { 32 + unsafe { 33 + crate::lseek(); 34 + } 35 + } 36 + 37 + pub fn write() { 38 + unsafe { 39 + crate::write(); 40 + } 41 + } 42 + 43 + pub fn remove() { 44 + unsafe { 45 + crate::remove(); 46 + } 47 + } 48 + 49 + pub fn rename() { 50 + unsafe { 51 + crate::rename(); 52 + } 53 + } 54 + 55 + pub fn ftruncate() { 56 + unsafe { 57 + crate::ftruncate(); 58 + } 59 + } 60 + 61 + pub fn fdprintf() { 62 + unsafe { 63 + crate::fdprintf(); 64 + } 65 + } 66 + 67 + pub fn read_line() { 68 + unsafe { 69 + crate::read_line(); 70 + } 71 + } 72 + 73 + pub fn settings_parseline() { 74 + unsafe { 75 + crate::settings_parseline(); 76 + } 77 + } 78 + 79 + pub fn reload_directory() { 80 + unsafe { 81 + crate::reload_directory(); 82 + } 83 + } 84 + 85 + pub fn create_numbered_filename() { 86 + unsafe { 87 + crate::create_numbered_filename(); 88 + } 89 + } 90 + 91 + pub fn strip_extension() { 92 + unsafe { 93 + crate::strip_extension(); 94 + } 95 + } 96 + 97 + pub fn crc_32() { 98 + unsafe { 99 + crate::crc_32(); 100 + } 101 + } 102 + 103 + pub fn crc_32r() { 104 + unsafe { 105 + crate::crc_32r(); 106 + } 107 + } 108 + 109 + pub fn filetype_get_attr() { 110 + unsafe { 111 + crate::filetype_get_attr(); 112 + } 113 + } 114 + 115 + pub fn filetype_get_plugin() { 116 + unsafe { 117 + crate::filetype_get_plugin(); 118 + } 119 + }
+1295
crates/sys/src/lib.rs
··· 1 + use std::ffi::{c_char, c_float, c_int, c_long, c_uchar, c_uint, c_ulong, c_void}; 2 + 3 + pub mod browse; 4 + pub mod dir; 5 + pub mod events; 6 + pub mod file; 7 + pub mod menu; 8 + pub mod metadata; 9 + pub mod misc; 10 + pub mod playback; 11 + pub mod playlist; 12 + pub mod plugin; 13 + pub mod settings; 14 + pub mod sound; 15 + pub mod system; 16 + pub mod tagcache; 17 + pub mod types; 18 + 19 + const MAX_PATH: usize = 260; 20 + const ID3V2_BUF_SIZE: usize = 1800; 21 + const MAX_PATHNAME: usize = 80; 22 + const NB_SCREENS: usize = 2; 23 + pub const HZ: f32 = 100.0; 24 + 25 + #[repr(C)] 26 + #[derive(Debug, Copy, Clone)] 27 + pub struct Mp3Entry { 28 + pub path: [c_uchar; MAX_PATH], // char path[MAX_PATH] 29 + pub title: *mut c_char, // char* title 30 + pub artist: *mut c_char, // char* artist 31 + pub album: *mut c_char, // char* album 32 + pub genre_string: *mut c_char, // char* genre_string 33 + pub disc_string: *mut c_char, // char* disc_string 34 + pub track_string: *mut c_char, // char* track_string 35 + pub year_string: *mut c_char, // char* year_string 36 + pub composer: *mut c_char, // char* composer 37 + pub comment: *mut c_char, // char* comment 38 + pub albumartist: *mut c_char, // char* albumartist 39 + pub grouping: *mut c_char, // char* grouping 40 + pub discnum: c_int, // int discnum 41 + pub tracknum: c_int, // int tracknum 42 + pub layer: c_int, // int layer 43 + pub year: c_int, // int year 44 + pub id3version: c_uchar, // unsigned char id3version 45 + pub codectype: c_uint, // unsigned int codectype 46 + pub bitrate: c_uint, // unsigned int bitrate 47 + pub frequency: c_ulong, // unsigned long frequency 48 + pub id3v2len: c_ulong, // unsigned long id3v2len 49 + pub id3v1len: c_ulong, // unsigned long id3v1len 50 + pub first_frame_offset: c_ulong, // unsigned long first_frame_offset 51 + pub filesize: c_ulong, // unsigned long filesize 52 + pub length: c_ulong, // unsigned long length 53 + pub elapsed: c_ulong, // unsigned long elapsed 54 + pub lead_trim: c_int, // int lead_trim 55 + pub tail_trim: c_int, // int tail_trim 56 + pub samples: u64, // uint64_t samples 57 + pub frame_count: c_ulong, // unsigned long frame_count 58 + pub bytesperframe: c_ulong, // unsigned long bytesperframe 59 + pub vbr: bool, // bool vbr 60 + pub has_toc: bool, // bool has_toc 61 + pub toc: [c_uchar; 100], // unsigned char toc[100] 62 + pub needs_upsampling_correction: bool, // bool needs_upsampling_correction 63 + pub id3v2buf: [c_uchar; ID3V2_BUF_SIZE], // char id3v2buf[ID3V2_BUF_SIZE] 64 + pub id3v1buf: [[c_uchar; 92]; 4], // char id3v1buf[4][92] 65 + pub offset: c_ulong, // unsigned long offset 66 + pub index: c_int, // int index 67 + pub skip_resume_adjustments: bool, // bool skip_resume_adjustments 68 + pub autoresumable: c_uchar, // unsigned char autoresumable 69 + pub tagcache_idx: c_long, // long tagcache_idx 70 + pub rating: c_int, // int rating 71 + pub score: c_int, // int score 72 + pub playcount: c_long, // long playcount 73 + pub lastplayed: c_long, // long lastplayed 74 + pub playtime: c_long, // long playtime 75 + pub track_level: c_long, // long track_level 76 + pub album_level: c_long, // long album_level 77 + pub track_gain: c_long, // long track_gain 78 + pub album_gain: c_long, // long album_gain 79 + pub track_peak: c_long, // long track_peak 80 + pub album_peak: c_long, // long album_peak 81 + pub has_embedded_albumart: bool, // bool has_embedded_albumart 82 + pub albumart: *mut c_void, // struct mp3_albumart albumart 83 + pub has_embedded_cuesheet: bool, // bool has_embedded_cuesheet 84 + pub embedded_cuesheet: *mut c_void, // struct embedded_cuesheet embedded_cuesheet 85 + pub cuesheet: *mut c_void, // struct cuesheet* cuesheet 86 + pub mb_track_id: *mut c_char, // char* mb_track_id 87 + pub is_asf_stream: bool, // bool is_asf_stream 88 + } 89 + 90 + const PLAYLIST_CONTROL_FILE: &str = "./config/rockbox.org/.playlist_control"; 91 + const MAX_DIR_LEVELS: usize = 10; 92 + 93 + #[repr(C)] 94 + #[derive(Debug)] 95 + pub struct PlaylistInfo { 96 + pub utf8: bool, // bool utf8 97 + pub control_created: bool, // bool control_created 98 + pub flags: c_uint, // unsigned int flags 99 + pub fd: c_int, // int fd 100 + pub control_fd: c_int, // int control_fd 101 + pub max_playlist_size: c_int, // int max_playlist_size 102 + pub indices: *mut c_ulong, // unsigned long* indices 103 + pub index: c_int, // int index 104 + pub first_index: c_int, // int first_index 105 + pub amount: c_int, // int amount 106 + pub last_insert_pos: c_int, // int last_insert_pos 107 + pub started: bool, // bool started 108 + pub last_shuffled_start: c_int, // int last_shuffled_start 109 + pub seed: c_int, // int seed 110 + pub mutex: *mut c_void, // struct mutex (convert to a void pointer for FFI) 111 + pub dirlen: c_int, // int dirlen 112 + pub filename: [c_uchar; MAX_PATH], // char filename[MAX_PATH] 113 + pub control_filename: 114 + [c_uchar; std::mem::size_of::<[u8; PLAYLIST_CONTROL_FILE.len() + 100 + 8]>()], // char control_filename[sizeof(PLAYLIST_CONTROL_FILE) + 8] 115 + pub dcfrefs_handle: c_int, // int dcfrefs_handle 116 + } 117 + 118 + #[repr(C)] 119 + #[derive(Debug)] 120 + pub struct PlaylistTrackInfo { 121 + pub filename: [c_uchar; MAX_PATH], // char filename[MAX_PATH] 122 + pub attr: c_int, 123 + pub index: c_int, 124 + pub display_index: c_int, 125 + } 126 + 127 + #[repr(C)] 128 + #[derive(Debug, Copy, Clone, PartialEq, Eq)] 129 + pub enum ThemableIcons { 130 + NoIcon = -1, 131 + IconNoIcon, // Icon_NOICON = NOICON 132 + IconAudio, // Icon_Audio 133 + IconFolder, // Icon_Folder 134 + IconPlaylist, // Icon_Playlist 135 + IconCursor, // Icon_Cursor 136 + IconWps, // Icon_Wps 137 + IconFirmware, // Icon_Firmware 138 + IconFont, // Icon_Font 139 + IconLanguage, // Icon_Language 140 + IconConfig, // Icon_Config 141 + IconPlugin, // Icon_Plugin 142 + IconBookmark, // Icon_Bookmark 143 + IconPreset, // Icon_Preset 144 + IconQueued, // Icon_Queued 145 + IconMoving, // Icon_Moving 146 + IconKeyboard, // Icon_Keyboard 147 + IconReverseCursor, // Icon_Reverse_Cursor 148 + IconQuestionmark, // Icon_Questionmark 149 + IconMenuSetting, // Icon_Menu_setting 150 + IconMenuFunctioncall, // Icon_Menu_functioncall 151 + IconSubmenu, // Icon_Submenu 152 + IconSubmenuEntered, // Icon_Submenu_Entered 153 + IconRecording, // Icon_Recording 154 + IconVoice, // Icon_Voice 155 + IconGeneralSettingsMenu, // Icon_General_settings_menu 156 + IconSystemMenu, // Icon_System_menu 157 + IconPlaybackMenu, // Icon_Playback_menu 158 + IconDisplayMenu, // Icon_Display_menu 159 + IconRemoteDisplayMenu, // Icon_Remote_Display_menu 160 + IconRadioScreen, // Icon_Radio_screen 161 + IconFileViewMenu, // Icon_file_view_menu 162 + IconEQ, // Icon_EQ 163 + IconRockbox, // Icon_Rockbox 164 + IconLastThemeable, // Icon_Last_Themeable 165 + } 166 + 167 + #[repr(C)] 168 + #[derive(Debug)] 169 + pub struct TreeCache { 170 + pub entries_handle: c_int, // int entries_handle 171 + pub name_buffer_handle: c_int, // int name_buffer_handle 172 + pub max_entries: c_int, // int max_entries 173 + pub name_buffer_size: c_int, // int name_buffer_size (in bytes) 174 + } 175 + 176 + #[repr(C)] 177 + #[derive(Debug)] 178 + pub struct TreeContext { 179 + pub currdir: [c_uchar; MAX_PATH], // char currdir[MAX_PATH] 180 + pub dirlevel: c_int, // int dirlevel 181 + pub selected_item: c_int, // int selected_item 182 + pub selected_item_history: [c_int; MAX_DIR_LEVELS], // int selected_item_history[MAX_DIR_LEVELS] 183 + pub dirfilter: *mut c_int, // int* dirfilter 184 + pub filesindir: c_int, // int filesindir 185 + pub dirsindir: c_int, // int dirsindir 186 + pub dirlength: c_int, // int dirlength 187 + pub currtable: c_int, // int currtable (db use) 188 + pub currextra: c_int, // int currextra (db use) 189 + pub sort_dir: c_int, // int sort_dir 190 + pub out_of_tree: c_int, // int out_of_tree 191 + pub cache: TreeCache, // struct tree_cache cache 192 + pub dirfull: bool, // bool dirfull 193 + pub is_browsing: bool, // bool is_browsing 194 + pub browse: *mut BrowseContext, // struct browse_context* browse 195 + } 196 + 197 + #[repr(C)] 198 + #[derive(Debug)] 199 + pub struct BrowseContext { 200 + pub dirfilter: c_int, // int dirfilter 201 + pub flags: c_uint, // unsigned flags 202 + pub callback_show_item: 203 + Option<extern "C" fn(name: *mut c_char, attr: c_int, tc: *mut TreeContext) -> bool>, // bool (*callback_show_item)(...) 204 + pub title: *mut c_char, // char* title 205 + pub icon: ThemableIcons, // enum themable_icons icon 206 + pub root: *const c_char, // const char* root 207 + pub selected: *const c_char, // const char* selected 208 + pub buf: *mut c_char, // char* buf 209 + pub bufsize: usize, // size_t bufsize 210 + } 211 + 212 + #[repr(C)] 213 + #[derive(Debug)] 214 + pub struct Entry { 215 + pub name: *mut c_char, // char* name 216 + pub attr: c_int, // int attr (FAT attributes + file type flags) 217 + pub time_write: c_uint, // unsigned time_write (Last write time) 218 + pub customaction: c_int, // int customaction (db use) 219 + } 220 + 221 + pub type PlaylistInsertCb = Option<extern "C" fn()>; 222 + pub type AddToPlCallback = Option<extern "C" fn()>; 223 + pub type ProgressFunc = Option<extern "C" fn(x: c_int)>; 224 + pub type ActionCb = Option<extern "C" fn(file_name: *const c_char) -> c_uchar>; 225 + 226 + #[repr(C)] 227 + #[derive(Debug)] 228 + pub struct Tm { 229 + pub tm_sec: c_int, // Seconds. [0-60] (1 leap second) 230 + pub tm_min: c_int, // Minutes. [0-59] 231 + pub tm_hour: c_int, // Hours. [0-23] 232 + pub tm_mday: c_int, // Day. [1-31] 233 + pub tm_mon: c_int, // Month. [0-11] 234 + pub tm_year: c_int, // Year - 1900 235 + pub tm_wday: c_int, // Day of week. [0-6] 236 + pub tm_yday: c_int, // Days in year. [0-365] 237 + pub tm_isdst: c_int, // DST. [-1/0/1] 238 + pub tm_gmtoff: c_long, // Seconds east of UTC 239 + pub tm_zone: *const c_char, // Timezone abbreviation 240 + } 241 + 242 + #[repr(C)] 243 + #[derive(Debug)] 244 + pub struct Dir {} 245 + 246 + #[repr(C)] 247 + #[derive(Debug)] 248 + pub struct dirent {} 249 + 250 + #[repr(C)] 251 + #[derive(Debug)] 252 + pub struct Dirent { 253 + pub attribute: c_uint, 254 + pub d_name: [c_uchar; MAX_PATH], 255 + } 256 + 257 + const TAG_COUNT: usize = 32; 258 + const SEEK_LIST_SIZE: usize = 32; 259 + const TAGCACHE_MAX_FILTERS: usize = 4; 260 + const TAGCACHE_MAX_CLAUSES: usize = 32; 261 + const EQ_NUM_BANDS: usize = 10; 262 + const QUICKSCREEN_ITEM_COUNT: usize = 4; 263 + const MAX_FILENAME: usize = 32; 264 + 265 + #[repr(C)] 266 + #[derive(Debug)] 267 + pub struct TagcacheSearch { 268 + /* For internal use only. */ 269 + fd: c_int, 270 + masterfd: c_int, 271 + idxfd: [c_int; TAG_COUNT], 272 + seeklist: [TagcacheSeeklistEntry; SEEK_LIST_SIZE], 273 + seek_list_count: c_int, 274 + filter_tag: [i32; TAGCACHE_MAX_FILTERS], 275 + filter_seek: [i32; TAGCACHE_MAX_FILTERS], 276 + filter_count: c_int, 277 + clause: [*mut TagcacheSearchClause; TAGCACHE_MAX_CLAUSES], 278 + clause_count: c_int, 279 + list_position: c_int, 280 + seek_pos: c_int, 281 + position: c_long, 282 + entry_count: c_int, 283 + valid: bool, 284 + initialized: bool, 285 + unique_list: *mut u32, 286 + unique_list_capacity: c_int, 287 + unique_list_count: c_int, 288 + 289 + /* Exported variables. */ 290 + ramsearch: bool, /* Is ram copy of the tagcache being used. */ 291 + ramresult: bool, /* False if result is not static, and must be copied. */ 292 + r#type: c_int, /* The tag type to be searched. */ 293 + result: *mut c_char, /* The result data for all tags. */ 294 + result_len: c_int, /* Length of the result including \0 */ 295 + result_seek: i32, /* Current position in the tag data. */ 296 + idx_id: i32, /* Entry number in the master index. */ 297 + } 298 + 299 + #[repr(C)] 300 + #[derive(Debug)] 301 + pub struct TagcacheSeeklistEntry { 302 + seek: i32, 303 + flag: i32, 304 + idx_id: i32, 305 + } 306 + 307 + #[repr(C)] 308 + #[derive(Debug)] 309 + pub struct TagcacheSearchClause { 310 + tag: c_int, 311 + r#type: c_int, 312 + numeric: bool, 313 + source: c_int, 314 + numeric_data: c_long, 315 + str: *mut c_char, 316 + } 317 + 318 + #[repr(C)] 319 + #[derive(Debug)] 320 + pub struct TagcacheStat { 321 + db_path: [c_uchar; MAX_PATHNAME + 1], // Path to DB root directory 322 + 323 + initialized: bool, // Is tagcache currently busy? 324 + readyvalid: bool, // Has tagcache ready status been ascertained? 325 + ready: bool, // Is tagcache ready to be used? 326 + ramcache: bool, // Is tagcache loaded in RAM? 327 + commit_delayed: bool, // Has commit been delayed until next reboot? 328 + econ: bool, // Is endianess correction enabled? 329 + syncscreen: bool, // Synchronous operation with debug screen? 330 + curentry: *const c_char, // Path of the current entry being scanned 331 + 332 + commit_step: c_int, // Commit progress 333 + ramcache_allocated: c_int, // Has RAM been allocated for ramcache? 334 + ramcache_used: c_int, // How much RAM has been really used? 335 + progress: c_int, // Current progress of disk scan 336 + processed_entries: c_int, // Scanned disk entries so far 337 + total_entries: c_int, // Total entries in tagcache 338 + queue_length: c_int, // Command queue length 339 + } 340 + 341 + #[repr(C)] 342 + pub union StorageType { 343 + int_val: c_int, // assuming it's an integer type, adjust according to the actual definition 344 + // other possible types if storage_type is a union of different types 345 + } 346 + 347 + #[repr(C)] 348 + #[derive(Debug)] 349 + pub struct SoundSetting { 350 + pub setting: c_int, // from the enum in firmware/sound.h 351 + } 352 + 353 + #[repr(C)] 354 + #[derive(Debug)] 355 + pub struct BoolSetting { 356 + pub option_callback: Option<extern "C" fn(bool)>, 357 + pub lang_yes: c_int, 358 + pub lang_no: c_int, 359 + } 360 + 361 + #[repr(C)] 362 + #[derive(Debug)] 363 + pub struct FilenameSetting { 364 + pub prefix: *const c_char, 365 + pub suffix: *const c_char, 366 + pub max_len: c_int, 367 + } 368 + 369 + #[repr(C)] 370 + pub struct IntSetting { 371 + pub option_callback: Option<extern "C" fn(c_int)>, 372 + pub unit: c_int, 373 + pub step: c_int, 374 + pub min: c_int, 375 + pub max: c_int, 376 + pub formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 377 + pub get_talk_id: Option<extern "C" fn(c_int, c_int) -> c_int>, 378 + } 379 + 380 + #[repr(C)] 381 + pub struct ChoiceSetting { 382 + pub option_callback: Option<extern "C" fn(c_int)>, 383 + pub count: c_int, 384 + pub data: ChoiceSettingData, 385 + } 386 + 387 + #[repr(C)] 388 + pub union ChoiceSettingData { 389 + pub desc: *const *const c_uchar, 390 + pub talks: *const c_int, 391 + } 392 + 393 + #[repr(C)] 394 + #[derive(Debug)] 395 + pub struct TableSetting { 396 + pub option_callback: Option<extern "C" fn(c_int)>, 397 + pub formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 398 + pub get_talk_id: Option<extern "C" fn(c_int, c_int) -> c_int>, 399 + pub unit: c_int, 400 + pub count: c_int, 401 + pub values: *const c_int, 402 + } 403 + 404 + #[repr(C)] 405 + #[derive(Debug)] 406 + pub struct CustomSetting { 407 + pub option_callback: Option<extern "C" fn(c_int)>, 408 + pub formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 409 + pub get_talk_id: Option<extern "C" fn(c_int, c_int) -> c_int>, 410 + pub unit: c_int, 411 + pub count: c_int, 412 + pub values: *const c_int, 413 + } 414 + 415 + #[repr(C)] 416 + pub struct SettingsList { 417 + pub flags: c_uint, // uint32_t -> c_uint 418 + pub setting: *mut c_void, // pointer to void 419 + pub lang_id: c_int, // int 420 + pub default_val: StorageType, // union storage_type 421 + pub cfg_name: *const c_char, // const char* 422 + pub cfg_vals: *const c_char, // const char* 423 + 424 + // union with different possible struct types 425 + pub setting_type: SettingsTypeUnion, 426 + } 427 + 428 + #[repr(C)] 429 + pub union SettingsTypeUnion { 430 + pub RESERVED: *const c_void, // void pointer for the reserved field 431 + pub sound_setting: *const SoundSetting, // pointer to SoundSetting struct 432 + pub bool_setting: *const BoolSetting, // pointer to BoolSetting struct 433 + pub filename_setting: *const FilenameSetting, // pointer to FilenameSetting struct 434 + pub int_setting: *const IntSetting, // pointer to IntSetting struct 435 + pub choice_setting: *const ChoiceSetting, // pointer to ChoiceSetting struct 436 + pub table_setting: *const TableSetting, // pointer to TableSetting struct 437 + pub custom_setting: *const CustomSetting, // pointer to CustomSetting struct 438 + } 439 + 440 + #[repr(C)] 441 + pub union FrameBufferData { 442 + pub data: *mut c_void, // void* in C 443 + pub ch_ptr: *mut c_char, // char* in C 444 + pub fb_ptr: *mut c_char, 445 + } 446 + 447 + #[repr(C)] 448 + pub struct FrameBuffer { 449 + pub buffer_data: FrameBufferData, // union data 450 + pub get_address_fn: Option<extern "C" fn(x: c_int, y: c_int) -> *mut c_void>, // Function pointer 451 + pub stride: isize, // ptrdiff_t in C 452 + pub elems: usize, // size_t in C 453 + } 454 + 455 + #[repr(C)] 456 + pub struct Viewport { 457 + pub x: c_int, // int in C 458 + pub y: c_int, // int in C 459 + pub width: c_int, // int in C 460 + pub height: c_int, // int in C 461 + pub flags: c_int, // int in C 462 + pub font: c_int, // int in C 463 + pub drawmode: c_int, // int in C 464 + pub buffer: *mut FrameBuffer, // pointer to FrameBuffer struct 465 + pub fg_pattern: c_uint, // unsigned int in C 466 + pub bg_pattern: c_uint, // unsigned int in C 467 + } 468 + 469 + #[repr(C)] 470 + pub enum OptionType { 471 + RbInt = 0, 472 + RbBool = 1, 473 + } 474 + 475 + #[repr(C)] 476 + pub struct OptItems { 477 + pub string: *const c_uchar, // const unsigned char* 478 + pub voice_id: c_int, // int32_t 479 + } 480 + 481 + pub type PcmPlayCallbackType = 482 + Option<extern "C" fn(start: *const *const c_void, size: *mut c_ulong)>; 483 + 484 + #[repr(C)] 485 + pub enum PcmDmaStatus { 486 + PcmDmaStatusErrDma = -1, // PCM_DMAST_ERR_DMA in C 487 + PcmDmaStatusOk = 0, // PCM_DMAST_OK in C 488 + PcmDmaStatusStarted = 1, // PCM_DMAST_STARTED in C 489 + } 490 + 491 + pub type PcmStatusCallbackType = Option<extern "C" fn(status: PcmDmaStatus) -> PcmDmaStatus>; 492 + 493 + #[repr(C)] 494 + pub struct SampleFormat { 495 + pub version: u8, 496 + pub num_channels: u8, 497 + pub frac_bits: u8, 498 + pub output_scale: u8, 499 + pub frequency: i32, 500 + pub codec_frequency: i32, 501 + } 502 + 503 + #[repr(C)] 504 + pub struct DspBuffer { 505 + pub remcount: i32, // Samples in buffer (In, Int, Out) 506 + 507 + // Union for channel pointers 508 + pub pin: [*const c_void; 2], // Channel pointers (In) 509 + pub p32: [*mut i32; 2], // Channel pointers (Int) 510 + pub p16out: *mut i16, // DSP output buffer (Out) 511 + 512 + // Union for buffer count and proc_mask 513 + pub proc_mask: u32, // In-place effects already applied 514 + pub bufcount: i32, // Buffer length/dest buffer remaining 515 + 516 + pub format: SampleFormat, // Buffer format data 517 + } 518 + 519 + impl DspBuffer { 520 + pub fn new() -> Self { 521 + Self { 522 + remcount: 0, 523 + pin: [std::ptr::null(); 2], 524 + p32: [std::ptr::null_mut(); 2], 525 + p16out: std::ptr::null_mut(), 526 + proc_mask: 0, 527 + bufcount: 0, 528 + format: SampleFormat { 529 + version: 0, 530 + num_channels: 0, 531 + frac_bits: 0, 532 + output_scale: 0, 533 + frequency: 0, 534 + codec_frequency: 0, 535 + }, 536 + } 537 + } 538 + } 539 + 540 + pub type SampleInputFnType = unsafe extern "C" fn(samples: *const u8, size: usize); 541 + 542 + pub type SampleOutputFnType = unsafe extern "C" fn(samples: *const u8, size: usize); 543 + 544 + #[repr(C)] 545 + pub struct DspProcEntry { 546 + pub data: isize, // intptr_t in C 547 + pub process: Option<extern "C" fn(*mut DspProcEntry, *mut *mut DspBuffer)>, 548 + } 549 + 550 + impl DspProcEntry { 551 + pub fn new() -> Self { 552 + Self { 553 + data: 0, 554 + process: None, 555 + } 556 + } 557 + } 558 + 559 + #[repr(C)] 560 + pub struct DspProcSlot { 561 + pub proc_entry: DspProcEntry, // Adjust the type if necessary 562 + pub next: *mut DspProcSlot, 563 + pub mask: u32, 564 + pub version: u8, 565 + pub db_index: u8, 566 + } 567 + 568 + #[repr(C)] 569 + pub struct SampleIoData { 570 + pub outcount: i32, 571 + pub format: SampleFormat, // Replace with actual type 572 + pub sample_depth: i32, 573 + pub stereo_mode: i32, 574 + pub input_samples: SampleInputFnType, 575 + pub sample_buf: DspBuffer, // Replace with actual type 576 + pub sample_buf_p: [*mut i32; 2], 577 + pub output_samples: SampleOutputFnType, 578 + pub output_sampr: u32, 579 + pub format_dirty: u8, 580 + pub output_version: u8, 581 + } 582 + 583 + #[repr(C)] 584 + pub struct DspConfig { 585 + pub io_data: SampleIoData, // Adjust the type if necessary 586 + pub slot_free_mask: u32, 587 + pub proc_mask_enabled: u32, 588 + pub proc_mask_active: u32, 589 + pub proc_slots: *mut DspProcSlot, 590 + } 591 + 592 + #[repr(C)] 593 + pub enum PcmMixerChannel { 594 + Playback = 0, 595 + Voice, 596 + NumChannels, 597 + } 598 + 599 + impl PcmMixerChannel { 600 + // Optionally, add methods for convenience 601 + pub fn as_u32(self) -> u32 { 602 + self as u32 603 + } 604 + 605 + pub fn from_u32(value: u32) -> Option<Self> { 606 + match value { 607 + 0 => Some(PcmMixerChannel::Playback), 608 + 1 => Some(PcmMixerChannel::Voice), 609 + // Include this if HAVE_HARDWARE_BEEP is not defined 610 + // 2 => Some(PcmMixerChannel::Beep), 611 + _ => None, 612 + } 613 + } 614 + } 615 + 616 + #[repr(C)] 617 + pub enum ChannelStatus { 618 + Stopped = 0, 619 + Playing, 620 + Paused, 621 + } 622 + 623 + impl ChannelStatus { 624 + // Optionally, add methods for convenience 625 + pub fn as_u32(self) -> u32 { 626 + self as u32 627 + } 628 + 629 + pub fn from_u32(value: u32) -> Option<Self> { 630 + match value { 631 + 0 => Some(ChannelStatus::Stopped), 632 + 1 => Some(ChannelStatus::Playing), 633 + 2 => Some(ChannelStatus::Paused), 634 + _ => None, 635 + } 636 + } 637 + } 638 + 639 + #[repr(C)] 640 + pub struct PcmPeaks { 641 + pub left: u32, // Left peak value 642 + pub right: u32, // Right peak value 643 + pub period: i64, // For tracking calling period 644 + pub tick: i64, // Last tick called 645 + } 646 + 647 + pub type ChanBufferHookFnType = extern "C" fn(start: *const c_void, size: usize); 648 + 649 + #[repr(C)] 650 + pub enum SystemSound { 651 + KeyClick = 0, 652 + TrackSkip, 653 + TrackNoMore, 654 + ListEdgeBeepWrap, 655 + ListEdgeBeepNoWrap, 656 + } 657 + 658 + #[repr(C)] 659 + #[derive(Debug, Copy, Clone)] 660 + pub struct UserSettings { 661 + // Audio settings 662 + pub volume: c_int, 663 + pub balance: c_int, 664 + pub bass: c_int, 665 + pub treble: c_int, 666 + pub channel_config: c_int, 667 + pub stereo_width: c_int, 668 + 669 + pub bass_cutoff: c_int, 670 + pub treble_cutoff: c_int, 671 + 672 + pub crossfade: c_int, 673 + pub crossfade_fade_in_delay: c_int, 674 + pub crossfade_fade_out_delay: c_int, 675 + pub crossfade_fade_in_duration: c_int, 676 + pub crossfade_fade_out_duration: c_int, 677 + pub crossfade_fade_out_mixmode: c_int, 678 + 679 + // Replaygain 680 + pub replaygain_settings: ReplaygainSettings, 681 + 682 + // Crossfeed 683 + pub crossfeed: c_int, 684 + pub crossfeed_direct_gain: c_uint, 685 + pub crossfeed_cross_gain: c_uint, 686 + pub crossfeed_hf_attenuation: c_uint, 687 + pub crossfeed_hf_cutoff: c_uint, 688 + 689 + // EQ 690 + pub eq_enabled: c_uchar, 691 + pub eq_precut: c_uint, 692 + pub eq_band_settings: [EqBandSetting; EQ_NUM_BANDS], 693 + 694 + // Misc. swcodec 695 + pub beep: c_int, 696 + pub keyclick: c_int, 697 + pub keyclick_repeats: c_int, 698 + pub dithering_enabled: c_uchar, 699 + pub timestretch_enabled: c_uchar, 700 + 701 + // Misc options 702 + pub list_accel_start_delay: c_int, 703 + pub list_accel_wait: c_int, 704 + 705 + pub touchpad_sensitivity: c_int, 706 + pub touchpad_deadzone: c_int, 707 + 708 + pub pause_rewind: c_int, 709 + pub unplug_mode: c_int, 710 + pub unplug_autoresume: c_uchar, 711 + 712 + pub qs_items: [*const SettingsList; QUICKSCREEN_ITEM_COUNT], 713 + 714 + pub timeformat: c_int, 715 + pub disk_spindown: c_int, 716 + pub buffer_margin: c_int, 717 + 718 + pub dirfilter: c_int, 719 + pub show_filename_ext: c_int, 720 + pub default_codepage: c_int, 721 + pub hold_lr_for_scroll_in_list: c_uchar, 722 + pub play_selected: c_uchar, 723 + pub single_mode: c_int, 724 + pub party_mode: c_uchar, 725 + pub cuesheet: c_uchar, 726 + pub car_adapter_mode: c_uchar, 727 + pub car_adapter_mode_delay: c_int, 728 + pub start_in_screen: c_int, 729 + pub ff_rewind_min_step: c_int, 730 + pub ff_rewind_accel: c_int, 731 + 732 + pub peak_meter_release: c_int, 733 + pub peak_meter_hold: c_int, 734 + pub peak_meter_clip_hold: c_int, 735 + pub peak_meter_dbfs: c_uchar, 736 + pub peak_meter_min: c_int, 737 + pub peak_meter_max: c_int, 738 + 739 + pub wps_file: [c_uchar; MAX_FILENAME + 1], 740 + pub sbs_file: [c_uchar; MAX_FILENAME + 1], 741 + pub lang_file: [c_uchar; MAX_FILENAME + 1], 742 + pub playlist_catalog_dir: [c_uchar; MAX_PATHNAME + 1], 743 + pub skip_length: c_int, 744 + pub max_files_in_dir: c_int, 745 + pub max_files_in_playlist: c_int, 746 + pub volume_type: c_int, 747 + pub battery_display: c_int, 748 + pub show_icons: c_uchar, 749 + pub statusbar: c_int, 750 + 751 + pub scrollbar: c_int, 752 + pub scrollbar_width: c_int, 753 + 754 + pub list_line_padding: c_int, 755 + pub list_separator_height: c_int, 756 + pub list_separator_color: c_int, 757 + 758 + pub browse_current: c_uchar, 759 + pub scroll_paginated: c_uchar, 760 + pub list_wraparound: c_uchar, 761 + pub list_order: c_int, 762 + pub scroll_speed: c_int, 763 + pub bidir_limit: c_int, 764 + pub scroll_delay: c_int, 765 + pub scroll_step: c_int, 766 + 767 + pub autoloadbookmark: c_int, 768 + pub autocreatebookmark: c_int, 769 + pub autoupdatebookmark: c_uchar, 770 + pub usemrb: c_int, 771 + 772 + pub dircache: c_uchar, 773 + pub tagcache_ram: c_int, 774 + pub tagcache_autoupdate: c_uchar, 775 + pub autoresume_enable: c_uchar, 776 + pub autoresume_automatic: c_int, 777 + pub autoresume_paths: [c_uchar; MAX_PATHNAME + 1], 778 + pub runtimedb: c_uchar, 779 + pub tagcache_scan_paths: [c_uchar; MAX_PATHNAME + 1], 780 + pub tagcache_db_path: [c_uchar; MAX_PATHNAME + 1], 781 + pub backdrop_file: [c_uchar; MAX_PATHNAME + 1], 782 + 783 + pub bg_color: c_int, 784 + pub fg_color: c_int, 785 + pub lss_color: c_int, 786 + pub lse_color: c_int, 787 + pub lst_color: c_int, 788 + pub colors_file: [c_uchar; MAX_FILENAME + 1], 789 + 790 + pub browser_default: c_int, 791 + 792 + pub repeat_mode: c_int, 793 + pub next_folder: c_int, 794 + pub constrain_next_folder: c_uchar, 795 + pub recursive_dir_insert: c_int, 796 + pub fade_on_stop: c_uchar, 797 + pub playlist_shuffle: c_uchar, 798 + pub warnon_erase_dynplaylist: c_uchar, 799 + pub keep_current_track_on_replace_playlist: c_uchar, 800 + pub show_shuffled_adding_options: c_uchar, 801 + pub show_queue_options: c_int, 802 + pub album_art: c_int, 803 + pub rewind_across_tracks: c_uchar, 804 + 805 + pub playlist_viewer_icons: c_uchar, 806 + pub playlist_viewer_indices: c_uchar, 807 + pub playlist_viewer_track_display: c_int, 808 + 809 + pub talk_menu: c_uchar, 810 + pub talk_dir: c_int, 811 + pub talk_dir_clip: c_uchar, 812 + pub talk_file: c_int, 813 + pub talk_file_clip: c_uchar, 814 + pub talk_filetype: c_uchar, 815 + pub talk_battery_level: c_uchar, 816 + pub talk_mixer_amp: c_int, 817 + 818 + pub sort_case: c_uchar, 819 + pub sort_dir: c_int, 820 + pub sort_file: c_int, 821 + pub interpret_numbers: c_int, 822 + 823 + pub poweroff: c_int, 824 + pub battery_capacity: c_int, 825 + pub battery_type: c_int, 826 + pub spdif_enable: c_uchar, 827 + pub usb_charging: c_int, 828 + 829 + pub contrast: c_int, 830 + pub invert: c_uchar, 831 + pub flip_display: c_uchar, 832 + pub cursor_style: c_int, 833 + pub screen_scroll_step: c_int, 834 + pub show_path_in_browser: c_int, 835 + pub offset_out_of_view: c_uchar, 836 + pub disable_mainmenu_scrolling: c_uchar, 837 + pub icon_file: [c_uchar; MAX_FILENAME + 1], 838 + pub viewers_icon_file: [c_uchar; MAX_FILENAME + 1], 839 + pub font_file: [c_uchar; MAX_FILENAME + 1], 840 + pub glyphs_to_cache: c_int, 841 + pub kbd_file: [c_uchar; MAX_FILENAME + 1], 842 + pub backlight_timeout: c_int, 843 + pub caption_backlight: c_uchar, 844 + pub bl_filter_first_keypress: c_uchar, 845 + pub backlight_timeout_plugged: c_int, 846 + pub bt_selective_softlock_actions: c_uchar, 847 + pub bt_selective_softlock_actions_mask: c_int, 848 + pub bl_selective_actions: c_uchar, 849 + pub bl_selective_actions_mask: c_int, 850 + pub backlight_on_button_hold: c_int, 851 + pub lcd_sleep_after_backlight_off: c_int, 852 + pub brightness: c_int, 853 + 854 + pub speaker_mode: c_int, 855 + pub prevent_skip: c_uchar, 856 + 857 + pub touch_mode: c_int, 858 + pub ts_calibration_data: TouchscreenParameter, 859 + 860 + pub pitch_mode_semitone: c_uchar, 861 + pub pitch_mode_timestretch: c_uchar, 862 + 863 + pub usb_hid: c_uchar, 864 + pub usb_keypad_mode: c_int, 865 + 866 + pub usb_skip_first_drive: c_uchar, 867 + 868 + pub ui_vp_config: [c_uchar; 64], 869 + pub player_name: [c_uchar; 64], 870 + 871 + pub compressor_settings: CompressorSettings, 872 + 873 + pub sleeptimer_duration: c_int, 874 + pub sleeptimer_on_startup: c_uchar, 875 + pub keypress_restarts_sleeptimer: c_uchar, 876 + 877 + pub show_shutdown_message: c_uchar, 878 + 879 + pub hotkey_wps: c_int, 880 + pub hotkey_tree: c_int, 881 + 882 + pub resume_rewind: c_int, 883 + 884 + pub depth_3d: c_int, 885 + 886 + pub roll_off: c_int, 887 + 888 + pub power_mode: c_int, 889 + 890 + pub keyclick_hardware: c_uchar, 891 + 892 + pub start_directory: [c_uchar; MAX_PATHNAME + 1], 893 + pub root_menu_customized: c_uchar, 894 + pub shortcuts_replaces_qs: c_uchar, 895 + 896 + pub play_frequency: c_int, 897 + pub volume_limit: c_int, 898 + 899 + pub volume_adjust_mode: c_int, 900 + pub volume_adjust_norm_steps: c_int, 901 + 902 + pub surround_enabled: c_int, 903 + pub surround_balance: c_int, 904 + pub surround_fx1: c_int, 905 + pub surround_fx2: c_uchar, 906 + pub surround_method2: c_uchar, 907 + pub surround_mix: c_int, 908 + 909 + pub pbe: c_int, 910 + pub pbe_precut: c_int, 911 + 912 + pub afr_enabled: c_int, 913 + 914 + pub governor: c_int, 915 + pub stereosw_mode: c_int, 916 + } 917 + 918 + // Define other structs used in UserSettings 919 + #[repr(C)] 920 + #[derive(Debug, Copy, Clone)] 921 + pub struct ReplaygainSettings { 922 + pub noclip: c_uchar, // scale to prevent clips 923 + pub r#type: c_int, // 0=track gain, 1=album gain, 2=track gain if shuffle is on, album gain otherwise, 4=off 924 + pub preamp: c_int, // scale replaygained tracks by this 925 + } 926 + 927 + #[repr(C)] 928 + #[derive(Debug, Copy, Clone)] 929 + pub struct EqBandSetting { 930 + pub cutoff: c_int, // Hz 931 + pub q: c_int, 932 + pub gain: c_int, // +/- dB 933 + } 934 + 935 + #[repr(C)] 936 + #[derive(Debug, Clone, Copy)] 937 + pub struct TouchscreenParameter { 938 + pub A: c_int, 939 + pub B: c_int, 940 + pub C: c_int, 941 + pub D: c_int, 942 + pub E: c_int, 943 + pub F: c_int, 944 + pub divider: c_int, 945 + } 946 + 947 + #[repr(C)] 948 + #[derive(Debug, Copy, Clone)] 949 + pub struct CompressorSettings { 950 + pub threshold: c_int, 951 + pub makeup_gain: c_int, 952 + pub ratio: c_int, 953 + pub knee: c_int, 954 + pub release_time: c_int, 955 + pub attack_time: c_int, 956 + } 957 + 958 + #[repr(C)] 959 + #[derive(Debug)] 960 + pub struct HwEqBand { 961 + pub gain: c_int, 962 + pub frequency: c_int, 963 + pub width: c_int, 964 + } 965 + 966 + #[repr(C)] 967 + #[derive(Debug)] 968 + pub struct CbmpBitmapInfoEntry { 969 + pub pbmp: *const c_uchar, 970 + pub width: c_uchar, 971 + pub height: c_uchar, // !ASSUMES MULTIPLES OF 8! 972 + pub count: c_uchar, 973 + } 974 + 975 + #[repr(C)] 976 + #[derive(Debug, Clone, Copy)] 977 + pub struct SystemStatus { 978 + pub resume_index: i32, 979 + pub resume_crc32: u32, 980 + pub resume_elapsed: u32, 981 + pub resume_offset: u32, 982 + pub runtime: i32, 983 + pub topruntime: i32, 984 + pub dircache_size: i32, 985 + pub last_screen: i8, 986 + pub viewer_icon_count: i32, 987 + pub last_volume_change: i32, 988 + pub font_id: [i32; NB_SCREENS], 989 + } 990 + 991 + extern "C" { 992 + pub static global_settings: UserSettings; 993 + pub static global_status: SystemStatus; 994 + pub static language_strings: *mut *mut c_char; 995 + pub static core_bitmaps: CbmpBitmapInfoEntry; 996 + 997 + fn get_version() -> *const c_char; 998 + 999 + // Playback control 1000 + fn audio_pause() -> c_void; 1001 + fn audio_play(elapsed: c_long, offset: c_long) -> c_void; 1002 + fn audio_resume() -> c_void; 1003 + fn audio_next() -> c_void; 1004 + fn audio_prev() -> c_void; 1005 + fn audio_ff_rewind(newtime: c_int) -> c_void; 1006 + fn audio_next_track() -> *mut Mp3Entry; 1007 + fn audio_status() -> c_int; 1008 + fn audio_current_track() -> *mut Mp3Entry; 1009 + fn audio_flush_and_reload_tracks() -> c_void; 1010 + fn audio_get_file_pos() -> c_int; 1011 + fn audio_hard_stop() -> c_void; 1012 + 1013 + // Playlist control 1014 + fn playlist_get_current() -> *mut PlaylistInfo; 1015 + fn playlist_get_resume_info(resume_index: *mut c_int) -> c_int; 1016 + fn playlist_get_track_info( 1017 + playlist: *mut PlaylistInfo, 1018 + index: c_int, 1019 + info: *mut PlaylistTrackInfo, 1020 + ) -> c_int; 1021 + fn playlist_get_first_index(playlist: *mut PlaylistInfo) -> c_int; 1022 + fn playlist_get_display_index() -> c_int; 1023 + fn playlist_amount() -> c_int; 1024 + fn playlist_resume() -> c_int; 1025 + fn playlist_resume_track(start_index: c_int, crc: c_uint, elapsed: c_ulong, offset: c_ulong); 1026 + fn playlist_set_modified(playlist: *mut PlaylistInfo, modified: c_uchar); 1027 + fn playlist_start(start_index: c_int, elapsed: c_ulong, offset: c_ulong); 1028 + fn playlist_sync(playlist: *mut PlaylistInfo); 1029 + fn playlist_remove_all_tracks(playlist: *mut PlaylistInfo) -> c_int; 1030 + fn playlist_create(dir: *const c_char, file: *const c_char) -> c_int; 1031 + fn playlist_insert_track( 1032 + playlist: *mut PlaylistInfo, 1033 + filename: *const c_char, 1034 + position: c_int, 1035 + queue: c_uchar, 1036 + sync: c_uchar, 1037 + ) -> c_int; 1038 + fn playlist_insert_directory( 1039 + playlist: *mut PlaylistInfo, 1040 + dir: *const c_char, 1041 + position: c_int, 1042 + queue: c_uchar, 1043 + recurse: c_uchar, 1044 + ) -> c_int; 1045 + fn playlist_insert_playlist( 1046 + playlist: *mut PlaylistInfo, 1047 + filename: *const c_char, 1048 + position: c_int, 1049 + queue: c_uchar, 1050 + ) -> c_int; 1051 + fn playlist_shuffle(random_sed: c_int, start_index: c_int) -> c_int; 1052 + fn warn_on_pl_erase() -> c_uchar; 1053 + 1054 + // Sound 1055 + fn adjust_volume(steps: c_int); 1056 + fn sound_set(setting: c_int, value: c_int); 1057 + fn sound_current(setting: c_int) -> c_int; 1058 + fn sound_default(setting: c_int) -> c_int; 1059 + fn sound_min(setting: c_int) -> c_int; 1060 + fn sound_max(setting: c_int) -> c_int; 1061 + fn sound_unit(setting: c_int) -> *const c_char; 1062 + fn sound_val2phys(setting: c_int, value: c_int) -> c_int; 1063 + fn sound_get_pitch() -> c_int; 1064 + fn sound_set_pitch(pitch: c_int); 1065 + fn pcm_apply_settings(); 1066 + fn pcm_play_data( 1067 + get_more: PcmPlayCallbackType, 1068 + status_cb: PcmStatusCallbackType, 1069 + start: *const *const c_void, 1070 + size: usize, 1071 + ); 1072 + fn pcm_play_stop(); 1073 + fn pcm_set_frequency(frequency: c_uint); 1074 + fn pcm_is_playing() -> c_uchar; 1075 + fn pcm_play_lock(); 1076 + fn pcm_play_unlock(); 1077 + fn beep_play(frequency: c_uint, duration: c_uint, amplitude: c_uint); 1078 + fn dsp_set_crossfeed_type(r#type: c_int); 1079 + fn dsp_eq_enable(enable: c_uchar); 1080 + fn dsp_dither_enable(enable: c_uchar); 1081 + fn dsp_get_timestretch() -> c_int; 1082 + fn dsp_set_timestretch(percent: c_int); 1083 + fn dsp_timestretch_enable(enabled: c_uchar); 1084 + fn dsp_timestretch_available() -> c_uchar; 1085 + fn dsp_configure(dsp: *mut DspConfig, setting: c_uint, value: c_long) -> c_long; 1086 + fn dsp_get_config(dsp_id: c_int) -> *mut DspConfig; 1087 + fn dsp_process(dsp: *mut DspConfig, src: *mut DspBuffer, dst: *mut *mut DspBuffer); 1088 + fn mixer_channel_status(channel: PcmMixerChannel) -> ChannelStatus; 1089 + fn mixer_channel_get_buffer(channel: PcmMixerChannel, count: *mut c_int) -> *mut c_void; 1090 + fn mixer_channel_calculate_peaks(channel: PcmMixerChannel, peaks: *mut PcmPeaks); 1091 + fn mixer_channel_play_data( 1092 + channel: PcmMixerChannel, 1093 + get_more: PcmPlayCallbackType, 1094 + start: *const *const c_void, 1095 + size: usize, 1096 + ); 1097 + fn mixer_channel_play_pause(channel: PcmMixerChannel, play: c_uchar); 1098 + fn mixer_channel_stop(channel: PcmMixerChannel); 1099 + fn mixer_channel_set_amplitude(channel: PcmMixerChannel, amplitude: c_uint); 1100 + fn mixer_channel_get_bytes_waiting(channel: PcmMixerChannel) -> usize; 1101 + fn mixer_channel_set_buffer_hook(channel: PcmMixerChannel, r#fn: ChanBufferHookFnType); 1102 + fn mixer_set_frequency(samplerate: c_uint); 1103 + fn mixer_get_frequency() -> c_uint; 1104 + fn pcmbuf_fade(fade: c_int, r#in: c_uchar); 1105 + fn pcmbuf_set_low_latency(state: c_uchar); 1106 + fn system_sound_play(sound: SystemSound); 1107 + fn keyclick_click(rawbutton: c_uchar, action: c_int); 1108 + 1109 + // Browsing 1110 + fn rockbox_browse(browse: *mut BrowseContext) -> c_int; 1111 + fn tree_get_context() -> *mut TreeContext; 1112 + fn tree_get_entries(t: *mut TreeContext) -> *mut Entry; 1113 + fn tree_get_entry_at(t: *mut TreeContext, index: c_int) -> *mut Entry; 1114 + fn set_current_file(path: *const c_char); 1115 + fn set_dirfilter(l_dirfilter: c_int); 1116 + fn onplay_show_playlist_menu( 1117 + path: *const c_char, // const char* path 1118 + attr: c_int, // int attr 1119 + playlist_insert_cb: PlaylistInsertCb, // void (*playlist_insert_cb)() 1120 + ); 1121 + fn onplay_show_playlist_cat_menu( 1122 + track_name: *const c_char, 1123 + attr: c_int, 1124 + add_to_pl_cb: AddToPlCallback, 1125 + ); 1126 + fn browse_id3( 1127 + id3: *mut Mp3Entry, 1128 + playlist_display_index: c_int, 1129 + playlist_amount: c_int, 1130 + modified: *mut Tm, 1131 + track_ct: c_int, 1132 + ) -> c_uchar; 1133 + 1134 + // Directory 1135 + fn opendir(dirname: *const c_char) -> *mut Dir; 1136 + fn closedir(dirp: *mut Dir) -> c_int; 1137 + fn readdir(dirp: *mut Dir) -> *mut dirent; 1138 + fn mkdir(path: *const c_char) -> c_int; 1139 + fn rmdir(path: *const c_char) -> c_int; 1140 + fn dir_get_info(dirp: *mut Dir, entry: *mut dirent) -> *mut Dirent; 1141 + 1142 + // File 1143 + fn open_utf8(); 1144 + fn open(); 1145 + fn creat(); 1146 + fn close(); 1147 + fn read(); 1148 + fn lseek(); 1149 + fn write(); 1150 + fn remove(); 1151 + fn rename(); 1152 + fn ftruncate(); 1153 + fn fdprintf(); 1154 + fn read_line(); 1155 + fn settings_parseline(); 1156 + fn reload_directory(); 1157 + fn create_numbered_filename(); 1158 + fn strip_extension(); 1159 + fn crc_32(); 1160 + fn crc_32r(); 1161 + fn filetype_get_attr(); 1162 + fn filetype_get_plugin(); 1163 + 1164 + // Metadata 1165 + fn get_metadata(id3: *mut Mp3Entry, fd: c_int, trackname: *const c_char) -> c_uchar; 1166 + fn get_codec_string(codectype: c_int) -> *const c_char; 1167 + fn count_mp3_frames( 1168 + fd: c_int, 1169 + startpos: c_int, 1170 + filesize: c_int, 1171 + progressfunc: ProgressFunc, 1172 + buf: *mut c_uchar, 1173 + buflen: usize, 1174 + ) -> c_int; 1175 + fn create_xing_header( 1176 + fd: c_int, 1177 + startpos: c_long, 1178 + filesize: c_long, 1179 + buf: *mut c_uchar, 1180 + num_frames: c_ulong, 1181 + rec_time: c_ulong, 1182 + header_template: c_ulong, 1183 + progressfunc: ProgressFunc, 1184 + generate_toc: c_uchar, 1185 + tempbuf: *mut c_uchar, 1186 + tembuf_len: usize, 1187 + ) -> c_int; 1188 + fn tagcache_search(tcs: *mut TagcacheSearch, tag: c_int) -> c_uchar; 1189 + fn tagcache_search_set_uniqbuf(tcs: *mut TagcacheSearch, buffer: *mut c_void, length: c_long); 1190 + fn tagcache_search_add_filter(tcs: *mut TagcacheSearch, tag: c_int, seek: c_int) -> c_uchar; 1191 + fn tagcache_get_next(tcs: *mut TagcacheSearch, buf: *mut c_char, size: c_long) -> c_uchar; 1192 + // fn tagcahe_retrieve(tcs: *mut TagcacheSearch, idxid: c_int, tag: c_int) -> c_uchar; 1193 + // fn tagcache_search_finish(tcs: *mut TagcacheSearch); 1194 + fn tagcache_get_numeric(tcs: *mut TagcacheSearch, tag: c_int) -> c_long; 1195 + fn tagcache_get_stat() -> *mut TagcacheStat; 1196 + fn tagcache_commit_finalize(); 1197 + fn tagtree_subentries_do_action(cb: ActionCb) -> c_uchar; 1198 + fn search_albumart_files( 1199 + id3: *mut Mp3Entry, 1200 + size_string: *const c_char, 1201 + buf: *mut c_char, 1202 + buflen: c_int, 1203 + ) -> c_uchar; 1204 + 1205 + // Kernel / System 1206 + fn sleep(ticks: c_float); 1207 + fn r#yield(); 1208 + fn current_tick(); 1209 + fn default_event_handler(event: c_long); 1210 + fn create_thread(); 1211 + fn thread_self(); 1212 + fn thread_exit(); 1213 + fn thread_wait(); 1214 + fn thread_thaw(); 1215 + fn thread_set_priority(thread_id: c_uint, priority: c_int); 1216 + fn mutex_init(); 1217 + fn mutex_lock(); 1218 + fn mutex_unlock(); 1219 + fn semaphore_init(); 1220 + fn semaphore_wait(); 1221 + fn semaphore_release(); 1222 + fn reset_poweroff_timer(); 1223 + fn set_sleeptimer_duration(); 1224 + fn get_sleep_timer(); 1225 + 1226 + // Menu 1227 + fn root_menu_get_options(); 1228 + fn do_menu(); 1229 + fn root_menu_set_default(); 1230 + fn root_menu_write_to_cfg(); 1231 + fn root_menu_load_from_cfg(); 1232 + 1233 + // Settings 1234 + fn get_settings_list(count: *mut c_int) -> *mut SettingsList; 1235 + fn find_setting(variable: *const c_void) -> *mut SettingsList; 1236 + fn settings_save() -> c_int; 1237 + fn option_screen( 1238 + setting: *mut SettingsList, 1239 + parent: [Viewport; NB_SCREENS], 1240 + use_temp_var: c_uchar, 1241 + option_title: *mut c_uchar, 1242 + ) -> c_uchar; 1243 + fn set_option( 1244 + string: *const c_char, 1245 + options: *const OptItems, 1246 + numoptions: c_int, 1247 + function: Option<extern "C" fn(x: c_int) -> c_uchar>, 1248 + ) -> c_uchar; 1249 + fn set_bool_options( 1250 + string: *const c_char, 1251 + variable: *const c_uchar, 1252 + yes_str: *const c_char, 1253 + yes_voice: c_int, 1254 + no_str: *const c_char, 1255 + no_voice: c_int, 1256 + function: Option<extern "C" fn(x: c_int) -> c_uchar>, 1257 + ); 1258 + fn set_int( 1259 + unit: *const c_char, 1260 + voice_unit: c_int, 1261 + variable: *const c_int, 1262 + function: Option<extern "C" fn(c_int)>, 1263 + step: c_int, 1264 + min: c_int, 1265 + max: c_int, 1266 + formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 1267 + ); 1268 + fn set_int_ex( 1269 + unit: *const c_char, 1270 + voice_unit: c_int, 1271 + variable: *const c_int, 1272 + function: Option<extern "C" fn(c_int)>, 1273 + step: c_int, 1274 + min: c_int, 1275 + max: c_int, 1276 + formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 1277 + get_talk_id: Option<extern "C" fn(c_int, c_int) -> c_int>, 1278 + ); 1279 + fn set_bool(string: *const c_char, variable: *const c_uchar) -> c_uchar; 1280 + 1281 + // Misc 1282 + fn codec_load_file(); 1283 + fn codec_run_proc(); 1284 + fn codec_close(); 1285 + fn read_bmp_file(); 1286 + fn read_bmp_fd(); 1287 + fn read_jpeg_file(); 1288 + fn read_jpeg_fd(); 1289 + 1290 + // Plugin 1291 + fn plugin_open(); 1292 + fn plugin_get_buffer(); 1293 + fn plugin_get_current_filename(); 1294 + fn plugin_reserve_buffer(); 1295 + }
+35
crates/sys/src/menu.rs
··· 1 + pub fn root_menu_get_options() { 2 + unsafe { 3 + crate::root_menu_get_options(); 4 + } 5 + } 6 + 7 + pub fn do_menu() { 8 + unsafe { 9 + crate::do_menu(); 10 + } 11 + } 12 + 13 + pub fn root_menu_set_default() { 14 + unsafe { 15 + crate::root_menu_set_default(); 16 + } 17 + } 18 + 19 + pub fn root_menu_write_to_cfg() { 20 + unsafe { 21 + crate::root_menu_write_to_cfg(); 22 + } 23 + } 24 + 25 + pub fn root_menu_load_from_cfg() { 26 + unsafe { 27 + crate::root_menu_load_from_cfg(); 28 + } 29 + } 30 + 31 + pub fn root_menu_get_option() { 32 + unsafe { 33 + crate::root_menu_get_options(); 34 + } 35 + }
+57
crates/sys/src/metadata.rs
··· 1 + use std::ffi::{c_uchar, CStr, CString}; 2 + 3 + use crate::{Mp3Entry, ProgressFunc}; 4 + 5 + pub fn get_metadata(id3: *mut Mp3Entry, fd: i32, trackname: &str) -> bool { 6 + let trackname = CString::new(trackname).unwrap(); 7 + let ret = unsafe { crate::get_metadata(id3, fd, trackname.as_ptr()) }; 8 + ret != 0 9 + } 10 + 11 + pub fn get_codec_string(codectype: i32) -> String { 12 + let res = unsafe { crate::get_codec_string(codectype) }; 13 + let codec_string = unsafe { CStr::from_ptr(res) }; 14 + codec_string.to_str().unwrap().to_string() 15 + } 16 + 17 + pub fn count_mp3_frames( 18 + fd: i32, 19 + startpos: i32, 20 + filesize: i32, 21 + progressfunc: ProgressFunc, 22 + buf: *mut c_uchar, 23 + buflen: usize, 24 + ) -> i32 { 25 + unsafe { crate::count_mp3_frames(fd, startpos, filesize, progressfunc, buf, buflen) } 26 + } 27 + 28 + pub fn create_xing_header( 29 + fd: i32, 30 + startpos: i64, 31 + filesize: i64, 32 + buf: *mut c_uchar, 33 + num_frames: u64, 34 + rec_time: u64, 35 + header_template: u64, 36 + progressfunc: ProgressFunc, 37 + generate_toc: bool, 38 + tempbuf: *mut c_uchar, 39 + tembuf_len: usize, 40 + ) -> i32 { 41 + let generate_toc = if generate_toc { 1 } else { 0 }; 42 + unsafe { 43 + crate::create_xing_header( 44 + fd, 45 + startpos, 46 + filesize, 47 + buf, 48 + num_frames, 49 + rec_time, 50 + header_template, 51 + progressfunc, 52 + generate_toc, 53 + tempbuf, 54 + tembuf_len, 55 + ) 56 + } 57 + }
+41
crates/sys/src/misc.rs
··· 1 + pub fn codec_load_file() { 2 + unsafe { 3 + crate::codec_load_file(); 4 + } 5 + } 6 + 7 + pub fn codec_run_proc() { 8 + unsafe { 9 + crate::codec_run_proc(); 10 + } 11 + } 12 + 13 + pub fn codec_close() { 14 + unsafe { 15 + crate::codec_close(); 16 + } 17 + } 18 + 19 + pub fn read_bmp_file() { 20 + unsafe { 21 + crate::read_bmp_file(); 22 + } 23 + } 24 + 25 + pub fn read_bmp_fd() { 26 + unsafe { 27 + crate::read_bmp_fd(); 28 + } 29 + } 30 + 31 + pub fn read_jpeg_file() { 32 + unsafe { 33 + crate::read_jpeg_file(); 34 + } 35 + } 36 + 37 + pub fn read_jpeg_fd() { 38 + unsafe { 39 + crate::read_jpeg_fd(); 40 + } 41 + }
+67
crates/sys/src/playback.rs
··· 1 + use crate::types::mp3_entry::Mp3Entry; 2 + 3 + pub fn pause() { 4 + unsafe { 5 + crate::audio_pause(); 6 + } 7 + } 8 + 9 + pub fn play(elapsed: i64, offset: i64) { 10 + unsafe { 11 + crate::audio_play(elapsed, offset); 12 + } 13 + } 14 + 15 + pub fn resume() { 16 + unsafe { 17 + crate::audio_resume(); 18 + } 19 + } 20 + 21 + pub fn next() { 22 + unsafe { 23 + crate::audio_next(); 24 + } 25 + } 26 + 27 + pub fn prev() { 28 + unsafe { 29 + crate::audio_prev(); 30 + } 31 + } 32 + 33 + pub fn ff_rewind(newtime: i32) { 34 + unsafe { 35 + crate::audio_ff_rewind(newtime); 36 + } 37 + } 38 + 39 + pub fn next_track() -> Mp3Entry { 40 + let track = unsafe { crate::audio_next_track().as_ref().unwrap() }; 41 + (*track).into() 42 + } 43 + 44 + pub fn status() -> i32 { 45 + unsafe { crate::audio_status() } 46 + } 47 + 48 + pub fn current_track() -> Mp3Entry { 49 + let track = unsafe { crate::audio_current_track().as_ref().unwrap() }; 50 + (*track).into() 51 + } 52 + 53 + pub fn flush_and_reload_tracks() { 54 + unsafe { 55 + crate::audio_flush_and_reload_tracks(); 56 + } 57 + } 58 + 59 + pub fn get_file_pos() -> i32 { 60 + unsafe { crate::audio_get_file_pos() } 61 + } 62 + 63 + pub fn hard_stop() { 64 + unsafe { 65 + crate::audio_hard_stop(); 66 + } 67 + }
+119
crates/sys/src/playlist.rs
··· 1 + use crate::{PlaylistInfo, PlaylistTrackInfo}; 2 + use std::ffi::{c_int, CString}; 3 + 4 + pub fn get_current() -> *mut PlaylistInfo { 5 + unsafe { crate::playlist_get_current() } 6 + } 7 + 8 + pub fn get_resume_info(mut resume_index: i32) -> i32 { 9 + unsafe { crate::playlist_get_resume_info(&mut resume_index as *mut i32 as *mut c_int) } 10 + } 11 + 12 + pub fn get_track_info( 13 + playlist: *mut PlaylistInfo, 14 + index: i32, 15 + info: *mut PlaylistTrackInfo, 16 + ) -> i32 { 17 + unsafe { 18 + crate::playlist_get_track_info(playlist, index, info as *mut crate::PlaylistTrackInfo) 19 + } 20 + } 21 + 22 + pub fn get_first_index(info: *mut PlaylistInfo) -> i32 { 23 + unsafe { crate::playlist_get_first_index(info) } 24 + } 25 + 26 + pub fn get_display_index() -> i32 { 27 + unsafe { crate::playlist_get_display_index() } 28 + } 29 + 30 + pub fn amount() -> i32 { 31 + unsafe { crate::playlist_amount() } 32 + } 33 + 34 + pub fn resume() -> i32 { 35 + unsafe { crate::playlist_resume() } 36 + } 37 + 38 + pub fn resume_track(start_index: i32, crc: u32, elapsed: u64, offset: u64) { 39 + unsafe { crate::playlist_resume_track(start_index, crc, elapsed, offset) } 40 + } 41 + 42 + pub fn set_modified(playlist: *mut PlaylistInfo, modified: bool) { 43 + unsafe { crate::playlist_set_modified(playlist, modified as u8) } 44 + } 45 + 46 + pub fn start(start_index: i32, elapsed: u64, offset: u64) { 47 + unsafe { crate::playlist_start(start_index, elapsed, offset) } 48 + } 49 + 50 + pub fn sync(playlist: *mut PlaylistInfo) { 51 + unsafe { crate::playlist_sync(playlist) } 52 + } 53 + 54 + pub fn remove_all_tracks(playlist: *mut PlaylistInfo) -> i32 { 55 + unsafe { crate::playlist_remove_all_tracks(playlist) } 56 + } 57 + 58 + pub fn create(dir: &str, file: &str) -> i32 { 59 + let dir = CString::new(dir).unwrap(); 60 + let file = CString::new(file).unwrap(); 61 + unsafe { crate::playlist_create(dir.as_ptr(), file.as_ptr()) } 62 + } 63 + 64 + pub fn insert_track( 65 + playlist: *mut PlaylistInfo, 66 + filename: &str, 67 + position: i32, 68 + queue: bool, 69 + sync: bool, 70 + ) -> i32 { 71 + let filename = CString::new(filename).unwrap(); 72 + unsafe { 73 + crate::playlist_insert_track( 74 + playlist, 75 + filename.as_ptr(), 76 + position, 77 + queue as u8, 78 + sync as u8, 79 + ) 80 + } 81 + } 82 + 83 + pub fn insert_directory( 84 + playlist: *mut PlaylistInfo, 85 + dir: &str, 86 + position: i32, 87 + queue: bool, 88 + recurse: bool, 89 + ) -> i32 { 90 + let dir = CString::new(dir).unwrap(); 91 + unsafe { 92 + crate::playlist_insert_directory( 93 + playlist, 94 + dir.as_ptr(), 95 + position, 96 + queue as u8, 97 + recurse as u8, 98 + ) 99 + } 100 + } 101 + 102 + pub fn insert_playlist( 103 + playlist: *mut PlaylistInfo, 104 + filename: &str, 105 + position: i32, 106 + queue: bool, 107 + ) -> i32 { 108 + let filename = CString::new(filename).unwrap(); 109 + unsafe { crate::playlist_insert_playlist(playlist, filename.as_ptr(), position, queue as u8) } 110 + } 111 + 112 + pub fn shuffle(random_sed: i32, start_index: i32) -> i32 { 113 + unsafe { crate::playlist_shuffle(random_sed, start_index) } 114 + } 115 + 116 + pub fn warn_on_pl_erase() -> bool { 117 + let ret = unsafe { crate::warn_on_pl_erase() }; 118 + ret != 0 119 + }
+23
crates/sys/src/plugin.rs
··· 1 + pub fn plugin_open() { 2 + unsafe { 3 + crate::plugin_open(); 4 + } 5 + } 6 + 7 + pub fn plugin_get_buffer() { 8 + unsafe { 9 + crate::plugin_get_buffer(); 10 + } 11 + } 12 + 13 + pub fn plugin_get_current_filename() { 14 + unsafe { 15 + crate::plugin_get_current_filename(); 16 + } 17 + } 18 + 19 + pub fn plugin_reserve_buffer() { 20 + unsafe { 21 + crate::plugin_reserve_buffer(); 22 + } 23 + }
+124
crates/sys/src/settings.rs
··· 1 + use std::ffi::{c_char, c_int, c_uchar, c_void, CString}; 2 + 3 + use crate::{types::user_settings::UserSettings, OptItems, SettingsList, Viewport, NB_SCREENS}; 4 + 5 + pub fn get_global_settings() -> UserSettings { 6 + unsafe { crate::global_settings }.into() 7 + } 8 + 9 + pub fn get_settings_list(mut count: i32) -> *mut SettingsList { 10 + unsafe { crate::get_settings_list(&mut count as *mut i32 as *mut c_int) } 11 + } 12 + 13 + pub fn find_setting(variable: *const c_void) -> *mut SettingsList { 14 + unsafe { crate::find_setting(variable) } 15 + } 16 + 17 + pub fn settings_save() -> i32 { 18 + unsafe { crate::settings_save() } 19 + } 20 + 21 + pub fn option_screen( 22 + setting: *mut SettingsList, 23 + parent: [Viewport; NB_SCREENS], 24 + use_temp_var: bool, 25 + option_title: *mut c_uchar, 26 + ) -> bool { 27 + let use_temp_var = if use_temp_var { 1 } else { 0 }; 28 + let ret = unsafe { crate::option_screen(setting, parent, use_temp_var, option_title) }; 29 + ret != 0 30 + } 31 + 32 + pub fn set_option( 33 + string: &str, 34 + options: *const OptItems, 35 + numoptions: i32, 36 + function: Option<extern "C" fn(x: c_int) -> c_uchar>, 37 + ) -> bool { 38 + let sttring = CString::new(string).unwrap(); 39 + let ret = unsafe { crate::set_option(sttring.as_ptr(), options, numoptions, function) }; 40 + ret != 0 41 + } 42 + 43 + pub fn set_bool_options( 44 + string: &str, 45 + variable: *const c_uchar, 46 + yes_str: &str, 47 + yes_voice: i32, 48 + no_str: &str, 49 + no_voice: i32, 50 + function: Option<extern "C" fn(x: c_int) -> c_uchar>, 51 + ) { 52 + let string = CString::new(string).unwrap(); 53 + let yes_str = CString::new(yes_str).unwrap(); 54 + let no_str = CString::new(no_str).unwrap(); 55 + unsafe { 56 + crate::set_bool_options( 57 + string.as_ptr(), 58 + variable, 59 + yes_str.as_ptr(), 60 + yes_voice, 61 + no_str.as_ptr(), 62 + no_voice, 63 + function, 64 + ) 65 + } 66 + } 67 + 68 + pub fn set_int( 69 + unit: &str, 70 + voice_unit: i32, 71 + variable: *const c_int, 72 + function: Option<extern "C" fn(c_int)>, 73 + step: c_int, 74 + min: c_int, 75 + max: c_int, 76 + formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 77 + ) { 78 + let unit = CString::new(unit).unwrap(); 79 + unsafe { 80 + crate::set_int( 81 + unit.as_ptr(), 82 + voice_unit, 83 + variable, 84 + function, 85 + step, 86 + min, 87 + max, 88 + formatter, 89 + ) 90 + } 91 + } 92 + 93 + pub fn set_int_ex( 94 + unit: &str, 95 + voice_unit: i32, 96 + variable: *const c_int, 97 + function: Option<extern "C" fn(c_int)>, 98 + step: i32, 99 + min: i32, 100 + max: i32, 101 + formatter: Option<extern "C" fn(*mut c_char, usize, c_int, *const c_char) -> *const c_char>, 102 + get_talk_id: Option<extern "C" fn(c_int, c_int) -> c_int>, 103 + ) { 104 + let unit = CString::new(unit).unwrap(); 105 + unsafe { 106 + crate::set_int_ex( 107 + unit.as_ptr(), 108 + voice_unit, 109 + variable, 110 + function, 111 + step, 112 + min, 113 + max, 114 + formatter, 115 + get_talk_id, 116 + ) 117 + } 118 + } 119 + 120 + pub fn set_bool(string: &str, variable: *const c_uchar) -> bool { 121 + let string = CString::new(string).unwrap(); 122 + let ret = unsafe { crate::set_bool(string.as_ptr(), variable) }; 123 + ret != 0 124 + }
+45
crates/sys/src/sound/dsp.rs
··· 1 + use crate::{DspBuffer, DspConfig}; 2 + 3 + pub fn set_crossfeed_type(r#type: i32) { 4 + unsafe { crate::dsp_set_crossfeed_type(r#type) } 5 + } 6 + 7 + pub fn eq_enable(enable: bool) { 8 + let enable = if enable { 1 } else { 0 }; 9 + unsafe { crate::dsp_eq_enable(enable) } 10 + } 11 + 12 + pub fn dither_enable(enable: bool) { 13 + let enable = if enable { 1 } else { 0 }; 14 + unsafe { crate::dsp_dither_enable(enable) } 15 + } 16 + 17 + pub fn get_timestretch() -> i32 { 18 + unsafe { crate::dsp_get_timestretch() } 19 + } 20 + 21 + pub fn set_timestretch(percent: i32) { 22 + unsafe { crate::dsp_set_timestretch(percent) } 23 + } 24 + 25 + pub fn timestretch_enable(enabled: bool) { 26 + let enabled = if enabled { 1 } else { 0 }; 27 + unsafe { crate::dsp_timestretch_enable(enabled) } 28 + } 29 + 30 + pub fn timestretch_available() -> bool { 31 + let ret = unsafe { crate::dsp_timestretch_available() }; 32 + ret != 0 33 + } 34 + 35 + pub fn configure(dsp: *mut DspConfig, setting: u32, value: i64) -> i64 { 36 + unsafe { crate::dsp_configure(dsp, setting, value) } 37 + } 38 + 39 + pub fn get_config(dsp_id: i32) -> *mut DspConfig { 40 + unsafe { crate::dsp_get_config(dsp_id) } 41 + } 42 + 43 + pub fn process(dsp: *mut DspConfig, src: *mut DspBuffer, dst: *mut *mut DspBuffer) { 44 + unsafe { crate::dsp_process(dsp, src, dst) } 45 + }
+61
crates/sys/src/sound/mixer.rs
··· 1 + use std::ffi::{c_int, c_void}; 2 + 3 + use crate::{ChanBufferHookFnType, ChannelStatus, PcmMixerChannel, PcmPeaks, PcmPlayCallbackType}; 4 + 5 + pub fn channel_status(channel: PcmMixerChannel) -> ChannelStatus { 6 + unsafe { crate::mixer_channel_status(channel) } 7 + } 8 + 9 + pub fn channel_get_buffer(channel: PcmMixerChannel, count: *mut c_int) -> *mut c_void { 10 + unsafe { crate::mixer_channel_get_buffer(channel, count) } 11 + } 12 + 13 + pub fn channel_calculate_peaks(channel: PcmMixerChannel, peaks: *mut PcmPeaks) { 14 + unsafe { 15 + crate::mixer_channel_calculate_peaks(channel, peaks); 16 + } 17 + } 18 + 19 + pub fn channel_play_data( 20 + channel: PcmMixerChannel, 21 + get_more: PcmPlayCallbackType, 22 + start: *const *const c_void, 23 + size: usize, 24 + ) { 25 + unsafe { crate::mixer_channel_play_data(channel, get_more, start, size) } 26 + } 27 + 28 + pub fn channel_play_pause(channel: PcmMixerChannel, play: bool) { 29 + let play = if play { 1 } else { 0 }; 30 + unsafe { crate::mixer_channel_play_pause(channel, play) } 31 + } 32 + 33 + pub fn channel_stop(channel: PcmMixerChannel) { 34 + unsafe { 35 + crate::mixer_channel_stop(channel); 36 + } 37 + } 38 + 39 + pub fn channel_set_amplitude(channel: PcmMixerChannel, amplitude: u32) { 40 + unsafe { 41 + crate::mixer_channel_set_amplitude(channel, amplitude); 42 + } 43 + } 44 + 45 + pub fn channel_get_bytes_waiting(channel: PcmMixerChannel) -> usize { 46 + unsafe { crate::mixer_channel_get_bytes_waiting(channel) } 47 + } 48 + 49 + pub fn channel_set_buffer_hook(channel: PcmMixerChannel, r#fn: ChanBufferHookFnType) { 50 + unsafe { crate::mixer_channel_set_buffer_hook(channel, r#fn) } 51 + } 52 + 53 + pub fn set_frequency(samplerate: u32) { 54 + unsafe { 55 + crate::mixer_set_frequency(samplerate); 56 + } 57 + } 58 + 59 + pub fn get_frequency() -> u32 { 60 + unsafe { crate::mixer_get_frequency() } 61 + }
+76
crates/sys/src/sound/mod.rs
··· 1 + use std::ffi::CStr; 2 + 3 + use crate::SystemSound; 4 + 5 + pub mod dsp; 6 + pub mod mixer; 7 + pub mod pcm; 8 + 9 + pub fn adjust_volume(steps: i32) { 10 + unsafe { crate::adjust_volume(steps) } 11 + } 12 + 13 + pub fn set(setting: i32, value: i32) { 14 + unsafe { crate::sound_set(setting, value) } 15 + } 16 + 17 + pub fn current(setting: i32) -> i32 { 18 + unsafe { crate::sound_current(setting) } 19 + } 20 + 21 + pub fn default(setting: i32) -> i32 { 22 + unsafe { crate::sound_default(setting) } 23 + } 24 + 25 + pub fn min(setting: i32) -> i32 { 26 + unsafe { crate::sound_min(setting) } 27 + } 28 + 29 + pub fn max(setting: i32) -> i32 { 30 + unsafe { crate::sound_max(setting) } 31 + } 32 + 33 + pub fn unit(setting: i32) -> String { 34 + let ret = unsafe { crate::sound_unit(setting) }; 35 + let unit = unsafe { CStr::from_ptr(ret) }; 36 + unit.to_str().unwrap().to_string() 37 + } 38 + 39 + pub fn val2phys(setting: i32, value: i32) -> i32 { 40 + unsafe { crate::sound_val2phys(setting, value) } 41 + } 42 + 43 + pub fn get_pitch() -> i32 { 44 + unsafe { crate::sound_get_pitch() } 45 + } 46 + 47 + pub fn set_pitch(pitch: i32) { 48 + unsafe { crate::sound_set_pitch(pitch) } 49 + } 50 + 51 + pub fn beep_play(frequency: u32, duration: u32, amplitude: u32) { 52 + unsafe { crate::beep_play(frequency, duration, amplitude) } 53 + } 54 + 55 + pub fn pcmbuf_fade(fade: i32, r#in: bool) { 56 + let r#in = if r#in { 1 } else { 0 }; 57 + unsafe { 58 + crate::pcmbuf_fade(fade, r#in); 59 + } 60 + } 61 + 62 + pub fn pcmbuf_set_low_latency(state: bool) { 63 + let state = if state { 1 } else { 0 }; 64 + unsafe { 65 + crate::pcmbuf_set_low_latency(state); 66 + } 67 + } 68 + 69 + pub fn system_sound_play(sound: SystemSound) { 70 + unsafe { crate::system_sound_play(sound) } 71 + } 72 + 73 + pub fn keyclick_click(rawbutton: bool, action: i32) { 74 + let rawbutton = if rawbutton { 1 } else { 0 }; 75 + unsafe { crate::keyclick_click(rawbutton, action) } 76 + }
+45
crates/sys/src/sound/pcm.rs
··· 1 + use std::ffi::c_void; 2 + 3 + use crate::{PcmPlayCallbackType, PcmStatusCallbackType}; 4 + 5 + pub fn apply_settings() { 6 + unsafe { 7 + crate::pcm_apply_settings(); 8 + } 9 + } 10 + 11 + pub fn play_data( 12 + get_more: PcmPlayCallbackType, 13 + status_cb: PcmStatusCallbackType, 14 + start: *const *const c_void, 15 + size: usize, 16 + ) { 17 + unsafe { crate::pcm_play_data(get_more, status_cb, start, size) } 18 + } 19 + 20 + pub fn play_stop() { 21 + unsafe { 22 + crate::pcm_play_stop(); 23 + } 24 + } 25 + 26 + pub fn set_frequency(frequency: u32) { 27 + unsafe { crate::pcm_set_frequency(frequency) } 28 + } 29 + 30 + pub fn is_playing() -> bool { 31 + let ret = unsafe { crate::pcm_is_playing() }; 32 + ret != 0 33 + } 34 + 35 + pub fn play_lock() { 36 + unsafe { 37 + crate::pcm_play_lock(); 38 + } 39 + } 40 + 41 + pub fn play_unlock() { 42 + unsafe { 43 + crate::pcm_play_unlock(); 44 + } 45 + }
+130
crates/sys/src/system.rs
··· 1 + use crate::types::{system_status::SystemStatus, RockboxVersion}; 2 + 3 + pub fn get_rockbox_version() -> RockboxVersion { 4 + let version = unsafe { 5 + let version = crate::get_version(); 6 + std::ffi::CStr::from_ptr(version) 7 + .to_str() 8 + .unwrap() 9 + .to_string() 10 + }; 11 + RockboxVersion { version } 12 + } 13 + 14 + pub fn get_global_status() -> SystemStatus { 15 + unsafe { crate::global_status }.into() 16 + } 17 + 18 + pub fn sleep(ticks: f32) { 19 + unsafe { 20 + crate::sleep(ticks); 21 + } 22 + } 23 + 24 + pub fn r#yield() { 25 + unsafe { 26 + crate::r#yield(); 27 + } 28 + } 29 + 30 + pub fn current_tick() { 31 + unsafe { 32 + crate::current_tick(); 33 + } 34 + } 35 + 36 + pub fn default_event_handler(event: i64) { 37 + unsafe { 38 + crate::default_event_handler(event); 39 + } 40 + } 41 + 42 + pub fn create_thread() { 43 + unsafe { 44 + crate::create_thread(); 45 + } 46 + } 47 + 48 + pub fn thread_self() { 49 + unsafe { 50 + crate::thread_self(); 51 + } 52 + } 53 + 54 + pub fn thread_exit() { 55 + unsafe { 56 + crate::thread_exit(); 57 + } 58 + } 59 + 60 + pub fn thread_wait() { 61 + unsafe { 62 + crate::thread_wait(); 63 + } 64 + } 65 + 66 + pub fn thread_thaw() { 67 + unsafe { 68 + crate::thread_thaw(); 69 + } 70 + } 71 + 72 + pub fn thread_set_priority(thread_id: u32, priority: i32) { 73 + unsafe { 74 + crate::thread_set_priority(thread_id, priority); 75 + } 76 + } 77 + 78 + pub fn mutex_init() { 79 + unsafe { 80 + crate::mutex_init(); 81 + } 82 + } 83 + 84 + pub fn mutex_lock() { 85 + unsafe { 86 + crate::mutex_lock(); 87 + } 88 + } 89 + 90 + pub fn mutex_unlock() { 91 + unsafe { 92 + crate::mutex_unlock(); 93 + } 94 + } 95 + 96 + pub fn semaphore_init() { 97 + unsafe { 98 + crate::semaphore_init(); 99 + } 100 + } 101 + 102 + pub fn semaphore_wait() { 103 + unsafe { 104 + crate::semaphore_wait(); 105 + } 106 + } 107 + 108 + pub fn semaphore_release() { 109 + unsafe { 110 + crate::semaphore_release(); 111 + } 112 + } 113 + 114 + pub fn reset_poweroff_timer() { 115 + unsafe { 116 + crate::reset_poweroff_timer(); 117 + } 118 + } 119 + 120 + pub fn set_sleeptimer_duration() { 121 + unsafe { 122 + crate::set_sleeptimer_duration(); 123 + } 124 + } 125 + 126 + pub fn get_sleep_timer() { 127 + unsafe { 128 + crate::get_sleep_timer(); 129 + } 130 + }
+51
crates/sys/src/tagcache.rs
··· 1 + use std::ffi::{c_char, c_void}; 2 + 3 + use crate::{ActionCb, Mp3Entry, TagcacheSearch, TagcacheStat}; 4 + 5 + pub fn search(tcs: *mut TagcacheSearch, tag: i32) -> bool { 6 + let ret = unsafe { crate::tagcache_search(tcs, tag) }; 7 + ret != 0 8 + } 9 + 10 + pub fn search_set_uniqbuf(tcs: *mut TagcacheSearch, buffer: *mut c_void, length: i64) { 11 + unsafe { crate::tagcache_search_set_uniqbuf(tcs, buffer, length) } 12 + } 13 + 14 + pub fn search_add_filter(tcs: *mut TagcacheSearch, tag: i32, seek: i32) -> bool { 15 + let ret = unsafe { crate::tagcache_search_add_filter(tcs, tag, seek) }; 16 + ret != 0 17 + } 18 + 19 + pub fn get_next(tcs: *mut TagcacheSearch, buf: *mut c_char, size: i64) -> bool { 20 + let ret = unsafe { crate::tagcache_get_next(tcs, buf, size) }; 21 + ret != 0 22 + } 23 + 24 + pub fn get_numeric(tcs: *mut TagcacheSearch, tag: i32) -> i64 { 25 + unsafe { crate::tagcache_get_numeric(tcs, tag) } 26 + } 27 + 28 + pub fn get_stat() -> *mut TagcacheStat { 29 + unsafe { crate::tagcache_get_stat() } 30 + } 31 + 32 + pub fn commit_finalize() { 33 + unsafe { 34 + crate::tagcache_commit_finalize(); 35 + } 36 + } 37 + 38 + pub fn tagtree_subentries_do_action(cb: ActionCb) -> bool { 39 + let ret = unsafe { crate::tagtree_subentries_do_action(cb) }; 40 + ret != 0 41 + } 42 + 43 + pub fn search_albumart_files( 44 + id3: *mut Mp3Entry, 45 + size_string: *const c_char, 46 + buf: *mut c_char, 47 + buflen: i32, 48 + ) -> bool { 49 + let ret = unsafe { crate::search_albumart_files(id3, size_string, buf, buflen) }; 50 + ret != 0 51 + }
+10
crates/sys/src/types/mod.rs
··· 1 + use serde::{Deserialize, Serialize}; 2 + 3 + pub mod mp3_entry; 4 + pub mod system_status; 5 + pub mod user_settings; 6 + 7 + #[derive(Serialize, Deserialize)] 8 + pub struct RockboxVersion { 9 + pub version: String, 10 + }
+172
crates/sys/src/types/mp3_entry.rs
··· 1 + use serde::Serialize; 2 + 3 + #[derive(Serialize)] 4 + pub struct Mp3Entry { 5 + pub path: String, 6 + pub title: String, // char* title 7 + pub artist: String, // char* artist 8 + pub album: String, // char* album 9 + pub genre_string: String, // char* genre_string 10 + pub disc_string: String, // char* disc_string 11 + pub track_string: String, // char* track_string 12 + pub year_string: String, // char* year_string 13 + pub composer: String, // char* composer 14 + pub comment: String, // char* comment 15 + pub albumartist: String, // char* albumartist 16 + pub grouping: String, // char* grouping 17 + pub discnum: i32, // int discnum 18 + pub tracknum: i32, // int tracknum 19 + pub layer: i32, // int layer 20 + pub year: i32, // int year 21 + pub id3version: i32, // unsigned char id3version 22 + pub codectype: u32, // unsigned int codectype 23 + pub bitrate: u32, // unsigned int bitrate 24 + pub frequency: u64, // unsigned long frequency 25 + pub id3v2len: u64, // unsigned long id3v2len 26 + pub id3v1len: u64, // unsigned long id3v1len 27 + pub first_frame_offset: u64, // unsigned long first_frame_offset 28 + pub filesize: u64, // unsigned long filesize 29 + pub length: u64, // unsigned long length 30 + pub elapsed: u64, // unsigned long elapsed 31 + pub lead_trim: i32, // int lead_trim 32 + pub tail_trim: i32, // int tail_trim 33 + pub samples: u64, // uint64_t samples 34 + pub frame_count: u64, // unsigned long frame_count 35 + pub bytesperframe: u64, // unsigned long bytesperframe 36 + pub vbr: bool, // bool vbr 37 + pub has_toc: bool, // bool has_toc 38 + pub toc: String, // unsigned char toc[100] 39 + pub needs_upsampling_correction: bool, // bool needs_upsampling_correction 40 + pub offset: u64, // unsigned long offset 41 + pub index: i32, // int index 42 + pub skip_resume_adjustments: bool, // bool skip_resume_adjustments 43 + pub autoresumable: i32, // unsigned char autoresumable 44 + pub tagcache_idx: i64, // long tagcache_idx 45 + pub rating: i32, // int rating 46 + pub score: i32, // int score 47 + pub playcount: i64, // long playcount 48 + pub lastplayed: i64, // long lastplayed 49 + pub playtime: i64, // long playtime 50 + pub track_level: i64, // long track_level 51 + pub album_level: i64, // long album_level 52 + pub track_gain: i64, // long track_gain 53 + pub album_gain: i64, // long album_gain 54 + pub track_peak: i64, // long track_peak 55 + pub album_peak: i64, // long album_peak 56 + pub has_embedded_albumart: bool, // bool has_embedded_albumart 57 + pub mb_track_id: String, // char* mb_track_id 58 + pub is_asf_stream: bool, // bool is_asf_stream 59 + } 60 + 61 + impl From<crate::Mp3Entry> for Mp3Entry { 62 + fn from(entry: crate::Mp3Entry) -> Self { 63 + Self { 64 + path: String::from_utf8_lossy(&entry.path).to_string(), 65 + title: unsafe { 66 + std::ffi::CStr::from_ptr(entry.title) 67 + .to_string_lossy() 68 + .into_owned() 69 + }, 70 + artist: unsafe { 71 + std::ffi::CStr::from_ptr(entry.artist) 72 + .to_string_lossy() 73 + .into_owned() 74 + }, 75 + album: unsafe { 76 + std::ffi::CStr::from_ptr(entry.album) 77 + .to_string_lossy() 78 + .into_owned() 79 + }, 80 + genre_string: unsafe { 81 + std::ffi::CStr::from_ptr(entry.genre_string) 82 + .to_string_lossy() 83 + .into_owned() 84 + }, 85 + disc_string: unsafe { 86 + std::ffi::CStr::from_ptr(entry.disc_string) 87 + .to_string_lossy() 88 + .into_owned() 89 + }, 90 + track_string: unsafe { 91 + std::ffi::CStr::from_ptr(entry.track_string) 92 + .to_string_lossy() 93 + .into_owned() 94 + }, 95 + year_string: unsafe { 96 + std::ffi::CStr::from_ptr(entry.year_string) 97 + .to_string_lossy() 98 + .into_owned() 99 + }, 100 + composer: unsafe { 101 + std::ffi::CStr::from_ptr(entry.composer) 102 + .to_string_lossy() 103 + .into_owned() 104 + }, 105 + comment: unsafe { 106 + std::ffi::CStr::from_ptr(entry.comment) 107 + .to_string_lossy() 108 + .into_owned() 109 + }, 110 + albumartist: unsafe { 111 + std::ffi::CStr::from_ptr(entry.albumartist) 112 + .to_string_lossy() 113 + .into_owned() 114 + }, 115 + grouping: unsafe { 116 + std::ffi::CStr::from_ptr(entry.grouping) 117 + .to_string_lossy() 118 + .into_owned() 119 + }, 120 + discnum: entry.discnum, 121 + tracknum: entry.tracknum, 122 + layer: entry.layer, 123 + year: entry.year, 124 + id3version: entry.id3version as i32, 125 + codectype: entry.codectype, 126 + bitrate: entry.bitrate, 127 + frequency: entry.frequency, 128 + id3v2len: entry.id3v2len, 129 + id3v1len: entry.id3v1len, 130 + first_frame_offset: entry.first_frame_offset, 131 + filesize: entry.filesize, 132 + length: entry.length, 133 + elapsed: entry.elapsed, 134 + lead_trim: entry.lead_trim, 135 + tail_trim: entry.tail_trim, 136 + samples: entry.samples, 137 + frame_count: entry.frame_count, 138 + bytesperframe: entry.bytesperframe, 139 + vbr: entry.vbr, 140 + has_toc: entry.has_toc, 141 + toc: unsafe { 142 + std::ffi::CStr::from_ptr(entry.toc.as_ptr() as *const i8) 143 + .to_string_lossy() 144 + .into_owned() 145 + }, 146 + needs_upsampling_correction: entry.needs_upsampling_correction, 147 + offset: entry.offset, 148 + index: entry.index, 149 + skip_resume_adjustments: entry.skip_resume_adjustments, 150 + autoresumable: entry.autoresumable as i32, 151 + tagcache_idx: entry.tagcache_idx, 152 + rating: entry.rating, 153 + score: entry.score, 154 + playcount: entry.playcount, 155 + lastplayed: entry.lastplayed, 156 + playtime: entry.playtime, 157 + track_level: entry.track_level, 158 + album_level: entry.album_level, 159 + track_gain: entry.track_gain, 160 + album_gain: entry.album_gain, 161 + track_peak: entry.track_peak, 162 + album_peak: entry.album_peak, 163 + has_embedded_albumart: entry.has_embedded_albumart, 164 + mb_track_id: unsafe { 165 + std::ffi::CStr::from_ptr(entry.mb_track_id) 166 + .to_string_lossy() 167 + .into_owned() 168 + }, 169 + is_asf_stream: entry.is_asf_stream, 170 + } 171 + } 172 + }
crates/sys/src/types/rockbox_version.rs

This is a binary file and will not be displayed.

+32
crates/sys/src/types/system_status.rs
··· 1 + use serde::{Deserialize, Serialize}; 2 + 3 + #[derive(Serialize, Deserialize)] 4 + pub struct SystemStatus { 5 + pub resume_index: i32, 6 + pub resume_crc32: u32, 7 + pub resume_elapsed: u32, 8 + pub resume_offset: u32, 9 + pub runtime: i32, 10 + pub topruntime: i32, 11 + pub dircache_size: i32, 12 + pub last_screen: i8, 13 + pub viewer_icon_count: i32, 14 + pub last_volume_change: i32, 15 + } 16 + 17 + impl From<crate::SystemStatus> for SystemStatus { 18 + fn from(status: crate::SystemStatus) -> Self { 19 + Self { 20 + resume_index: status.resume_index, 21 + resume_crc32: status.resume_crc32, 22 + resume_elapsed: status.resume_elapsed, 23 + resume_offset: status.resume_offset, 24 + runtime: status.runtime, 25 + topruntime: status.topruntime, 26 + dircache_size: status.dircache_size, 27 + last_screen: status.last_screen, 28 + viewer_icon_count: status.viewer_icon_count, 29 + last_volume_change: status.last_volume_change, 30 + } 31 + } 32 + }
+612
crates/sys/src/types/user_settings.rs
··· 1 + use std::ffi::CStr; 2 + 3 + use serde::{Deserialize, Serialize}; 4 + 5 + #[derive(Serialize, Deserialize)] 6 + pub struct ReplaygainSettings { 7 + pub noclip: bool, // scale to prevent clips 8 + pub r#type: i32, // 0=track gain, 1=album gain, 2=track gain if shuffle is on, album gain otherwise, 4=off 9 + pub preamp: i32, // scale replaygained tracks by this 10 + } 11 + 12 + impl From<crate::ReplaygainSettings> for ReplaygainSettings { 13 + fn from(settings: crate::ReplaygainSettings) -> Self { 14 + let noclip = if settings.noclip == 1 { true } else { false }; 15 + Self { 16 + noclip, 17 + r#type: settings.r#type, 18 + preamp: settings.preamp, 19 + } 20 + } 21 + } 22 + 23 + #[derive(Serialize, Deserialize)] 24 + pub struct EqBandSetting { 25 + pub cutoff: i32, // Hz 26 + pub q: i32, 27 + pub gain: i32, // +/- dB 28 + } 29 + 30 + impl From<crate::EqBandSetting> for EqBandSetting { 31 + fn from(setting: crate::EqBandSetting) -> Self { 32 + Self { 33 + cutoff: setting.cutoff, 34 + q: setting.q, 35 + gain: setting.gain, 36 + } 37 + } 38 + } 39 + 40 + #[derive(Serialize, Deserialize)] 41 + pub struct TouchscreenParameter { 42 + pub A: i32, 43 + pub B: i32, 44 + pub C: i32, 45 + pub D: i32, 46 + pub E: i32, 47 + pub F: i32, 48 + pub divider: i32, 49 + } 50 + 51 + impl From<crate::TouchscreenParameter> for TouchscreenParameter { 52 + fn from(parameter: crate::TouchscreenParameter) -> Self { 53 + Self { 54 + A: parameter.A, 55 + B: parameter.B, 56 + C: parameter.C, 57 + D: parameter.D, 58 + E: parameter.E, 59 + F: parameter.F, 60 + divider: parameter.divider, 61 + } 62 + } 63 + } 64 + 65 + #[derive(Serialize, Deserialize)] 66 + pub struct CompressorSettings { 67 + pub threshold: i32, 68 + pub makeup_gain: i32, 69 + pub ratio: i32, 70 + pub knee: i32, 71 + pub release_time: i32, 72 + pub attack_time: i32, 73 + } 74 + 75 + impl From<crate::CompressorSettings> for CompressorSettings { 76 + fn from(settings: crate::CompressorSettings) -> Self { 77 + Self { 78 + threshold: settings.threshold, 79 + makeup_gain: settings.makeup_gain, 80 + ratio: settings.ratio, 81 + knee: settings.knee, 82 + release_time: settings.release_time, 83 + attack_time: settings.attack_time, 84 + } 85 + } 86 + } 87 + 88 + #[derive(Serialize, Deserialize)] 89 + pub struct UserSettings { 90 + // Audio settings 91 + pub volume: i32, 92 + pub balance: i32, 93 + pub bass: i32, 94 + pub treble: i32, 95 + pub channel_config: i32, 96 + pub stereo_width: i32, 97 + 98 + pub bass_cutoff: i32, 99 + pub treble_cutoff: i32, 100 + 101 + pub crossfade: i32, 102 + pub crossfade_fade_in_delay: i32, 103 + pub crossfade_fade_out_delay: i32, 104 + pub crossfade_fade_in_duration: i32, 105 + pub crossfade_fade_out_duration: i32, 106 + pub crossfade_fade_out_mixmode: i32, 107 + 108 + // Replaygain 109 + pub replaygain_settings: ReplaygainSettings, 110 + 111 + // Crossfeed 112 + pub crossfeed: i32, 113 + pub crossfeed_direct_gain: u32, 114 + pub crossfeed_cross_gain: u32, 115 + pub crossfeed_hf_attenuation: u32, 116 + pub crossfeed_hf_cutoff: u32, 117 + 118 + // EQ 119 + pub eq_enabled: bool, 120 + pub eq_precut: u32, 121 + pub eq_band_settings: Vec<EqBandSetting>, 122 + 123 + // Misc. swcodec 124 + pub beep: i32, 125 + pub keyclick: i32, 126 + pub keyclick_repeats: i32, 127 + pub dithering_enabled: bool, 128 + pub timestretch_enabled: bool, 129 + 130 + // Misc options 131 + pub list_accel_start_delay: i32, 132 + pub list_accel_wait: i32, 133 + 134 + pub touchpad_sensitivity: i32, 135 + pub touchpad_deadzone: i32, 136 + 137 + pub pause_rewind: i32, 138 + pub unplug_mode: i32, 139 + pub unplug_autoresume: bool, 140 + 141 + pub timeformat: i32, 142 + pub disk_spindown: i32, 143 + pub buffer_margin: i32, 144 + 145 + pub dirfilter: i32, 146 + pub show_filename_ext: i32, 147 + pub default_codepage: i32, 148 + pub hold_lr_for_scroll_in_list: bool, 149 + pub play_selected: bool, 150 + pub single_mode: i32, 151 + pub party_mode: bool, 152 + pub cuesheet: bool, 153 + pub car_adapter_mode: bool, 154 + pub car_adapter_mode_delay: i32, 155 + pub start_in_screen: i32, 156 + pub ff_rewind_min_step: i32, 157 + pub ff_rewind_accel: i32, 158 + 159 + pub peak_meter_release: i32, 160 + pub peak_meter_hold: i32, 161 + pub peak_meter_clip_hold: i32, 162 + pub peak_meter_dbfs: bool, 163 + pub peak_meter_min: i32, 164 + pub peak_meter_max: i32, 165 + 166 + pub wps_file: String, 167 + pub sbs_file: String, 168 + pub lang_file: String, 169 + pub playlist_catalog_dir: String, 170 + pub skip_length: i32, 171 + pub max_files_in_dir: i32, 172 + pub max_files_in_playlist: i32, 173 + pub volume_type: i32, 174 + pub battery_display: i32, 175 + pub show_icons: bool, 176 + pub statusbar: i32, 177 + 178 + pub scrollbar: i32, 179 + pub scrollbar_width: i32, 180 + 181 + pub list_line_padding: i32, 182 + pub list_separator_height: i32, 183 + pub list_separator_color: i32, 184 + 185 + pub browse_current: bool, 186 + pub scroll_paginated: bool, 187 + pub list_wraparound: bool, 188 + pub list_order: i32, 189 + pub scroll_speed: i32, 190 + pub bidir_limit: i32, 191 + pub scroll_delay: i32, 192 + pub scroll_step: i32, 193 + 194 + pub autoloadbookmark: i32, 195 + pub autocreatebookmark: i32, 196 + pub autoupdatebookmark: bool, 197 + pub usemrb: i32, 198 + 199 + pub dircache: bool, 200 + pub tagcache_ram: i32, 201 + pub tagcache_autoupdate: bool, 202 + pub autoresume_enable: bool, 203 + pub autoresume_automatic: i32, 204 + pub autoresume_paths: String, 205 + pub runtimedb: bool, 206 + pub tagcache_scan_paths: String, 207 + pub tagcache_db_path: String, 208 + pub backdrop_file: String, 209 + 210 + pub bg_color: i32, 211 + pub fg_color: i32, 212 + pub lss_color: i32, 213 + pub lse_color: i32, 214 + pub lst_color: i32, 215 + pub colors_file: String, 216 + 217 + pub browser_default: i32, 218 + 219 + pub repeat_mode: i32, 220 + pub next_folder: i32, 221 + pub constrain_next_folder: bool, 222 + pub recursive_dir_insert: i32, 223 + pub fade_on_stop: bool, 224 + pub playlist_shuffle: bool, 225 + pub warnon_erase_dynplaylist: bool, 226 + pub keep_current_track_on_replace_playlist: bool, 227 + pub show_shuffled_adding_options: bool, 228 + pub show_queue_options: i32, 229 + pub album_art: i32, 230 + pub rewind_across_tracks: bool, 231 + 232 + pub playlist_viewer_icons: bool, 233 + pub playlist_viewer_indices: bool, 234 + pub playlist_viewer_track_display: i32, 235 + 236 + pub talk_menu: bool, 237 + pub talk_dir: i32, 238 + pub talk_dir_clip: bool, 239 + pub talk_file: i32, 240 + pub talk_file_clip: bool, 241 + pub talk_filetype: bool, 242 + pub talk_battery_level: bool, 243 + pub talk_mixer_amp: i32, 244 + 245 + pub sort_case: bool, 246 + pub sort_dir: i32, 247 + pub sort_file: i32, 248 + pub interpret_numbers: i32, 249 + 250 + pub poweroff: i32, 251 + pub battery_capacity: i32, 252 + pub battery_type: i32, 253 + pub spdif_enable: bool, 254 + pub usb_charging: i32, 255 + 256 + pub contrast: i32, 257 + pub invert: bool, 258 + pub flip_display: bool, 259 + pub cursor_style: i32, 260 + pub screen_scroll_step: i32, 261 + pub show_path_in_browser: i32, 262 + pub offset_out_of_view: bool, 263 + pub disable_mainmenu_scrolling: bool, 264 + pub icon_file: String, 265 + pub viewers_icon_file: String, 266 + pub font_file: String, 267 + pub glyphs_to_cache: i32, 268 + pub kbd_file: String, 269 + pub backlight_timeout: i32, 270 + pub caption_backlight: bool, 271 + pub bl_filter_first_keypress: bool, 272 + pub backlight_timeout_plugged: i32, 273 + pub bt_selective_softlock_actions: bool, 274 + pub bt_selective_softlock_actions_mask: i32, 275 + pub bl_selective_actions: bool, 276 + pub bl_selective_actions_mask: i32, 277 + pub backlight_on_button_hold: i32, 278 + pub lcd_sleep_after_backlight_off: i32, 279 + pub brightness: i32, 280 + 281 + pub speaker_mode: i32, 282 + pub prevent_skip: bool, 283 + 284 + pub touch_mode: i32, 285 + pub ts_calibration_data: TouchscreenParameter, 286 + 287 + pub pitch_mode_semitone: bool, 288 + pub pitch_mode_timestretch: bool, 289 + 290 + pub usb_hid: bool, 291 + pub usb_keypad_mode: i32, 292 + 293 + pub usb_skip_first_drive: bool, 294 + 295 + pub player_name: String, 296 + 297 + pub compressor_settings: CompressorSettings, 298 + 299 + pub sleeptimer_duration: i32, 300 + pub sleeptimer_on_startup: bool, 301 + pub keypress_restarts_sleeptimer: bool, 302 + 303 + pub show_shutdown_message: bool, 304 + 305 + pub hotkey_wps: i32, 306 + pub hotkey_tree: i32, 307 + 308 + pub resume_rewind: i32, 309 + 310 + pub depth_3d: i32, 311 + 312 + pub roll_off: i32, 313 + 314 + pub power_mode: i32, 315 + 316 + pub keyclick_hardware: bool, 317 + 318 + pub start_directory: String, 319 + pub root_menu_customized: bool, 320 + pub shortcuts_replaces_qs: bool, 321 + 322 + pub play_frequency: i32, 323 + pub volume_limit: i32, 324 + 325 + pub volume_adjust_mode: i32, 326 + pub volume_adjust_norm_steps: i32, 327 + 328 + pub surround_enabled: i32, 329 + pub surround_balance: i32, 330 + pub surround_fx1: i32, 331 + pub surround_fx2: bool, 332 + pub surround_method2: bool, 333 + pub surround_mix: i32, 334 + 335 + pub pbe: i32, 336 + pub pbe_precut: i32, 337 + 338 + pub afr_enabled: i32, 339 + 340 + pub governor: i32, 341 + pub stereosw_mode: i32, 342 + } 343 + 344 + impl From<crate::UserSettings> for UserSettings { 345 + fn from(settings: crate::UserSettings) -> Self { 346 + Self { 347 + volume: settings.volume, 348 + balance: settings.balance, 349 + bass: settings.bass, 350 + treble: settings.treble, 351 + channel_config: settings.channel_config, 352 + stereo_width: settings.stereo_width, 353 + bass_cutoff: settings.bass_cutoff, 354 + treble_cutoff: settings.treble_cutoff, 355 + crossfade: settings.crossfade, 356 + crossfade_fade_in_delay: settings.crossfade_fade_in_delay, 357 + crossfade_fade_out_delay: settings.crossfade_fade_out_delay, 358 + crossfade_fade_in_duration: settings.crossfade_fade_in_duration, 359 + crossfade_fade_out_duration: settings.crossfade_fade_out_duration, 360 + crossfade_fade_out_mixmode: settings.crossfade_fade_out_mixmode, 361 + replaygain_settings: ReplaygainSettings::from(settings.replaygain_settings), 362 + crossfeed: settings.crossfeed, 363 + crossfeed_direct_gain: settings.crossfeed_direct_gain as u32, 364 + crossfeed_cross_gain: settings.crossfeed_cross_gain as u32, 365 + crossfeed_hf_attenuation: settings.crossfeed_hf_attenuation as u32, 366 + crossfeed_hf_cutoff: settings.crossfeed_hf_cutoff as u32, 367 + eq_enabled: settings.eq_enabled != 0, 368 + eq_precut: settings.eq_precut as u32, 369 + eq_band_settings: settings 370 + .eq_band_settings 371 + .into_iter() 372 + .map(EqBandSetting::from) 373 + .collect(), 374 + beep: settings.beep, 375 + keyclick: settings.keyclick, 376 + keyclick_repeats: settings.keyclick_repeats, 377 + dithering_enabled: settings.dithering_enabled != 0, 378 + timestretch_enabled: settings.timestretch_enabled != 0, 379 + list_accel_start_delay: settings.list_accel_start_delay, 380 + list_accel_wait: settings.list_accel_wait, 381 + touchpad_sensitivity: settings.touchpad_sensitivity, 382 + touchpad_deadzone: settings.touchpad_deadzone, 383 + pause_rewind: settings.pause_rewind, 384 + unplug_mode: settings.unplug_mode, 385 + unplug_autoresume: settings.unplug_autoresume != 0, 386 + timeformat: settings.timeformat, 387 + disk_spindown: settings.disk_spindown, 388 + buffer_margin: settings.buffer_margin, 389 + dirfilter: settings.dirfilter, 390 + show_filename_ext: settings.show_filename_ext, 391 + default_codepage: settings.default_codepage, 392 + hold_lr_for_scroll_in_list: settings.hold_lr_for_scroll_in_list != 0, 393 + play_selected: settings.play_selected != 0, 394 + single_mode: settings.single_mode, 395 + party_mode: settings.party_mode != 0, 396 + cuesheet: settings.cuesheet != 0, 397 + car_adapter_mode: settings.car_adapter_mode != 0, 398 + car_adapter_mode_delay: settings.car_adapter_mode_delay, 399 + start_in_screen: settings.start_in_screen, 400 + ff_rewind_min_step: settings.ff_rewind_min_step, 401 + ff_rewind_accel: settings.ff_rewind_accel, 402 + peak_meter_release: settings.peak_meter_release, 403 + peak_meter_hold: settings.peak_meter_hold, 404 + peak_meter_clip_hold: settings.peak_meter_clip_hold, 405 + peak_meter_dbfs: settings.peak_meter_dbfs != 0, 406 + peak_meter_min: settings.peak_meter_min, 407 + peak_meter_max: settings.peak_meter_max, 408 + wps_file: unsafe { 409 + CStr::from_ptr(settings.wps_file.as_ptr() as *const i8) 410 + .to_string_lossy() 411 + .into_owned() 412 + }, 413 + sbs_file: unsafe { 414 + CStr::from_ptr(settings.sbs_file.as_ptr() as *const i8) 415 + .to_string_lossy() 416 + .into_owned() 417 + }, 418 + lang_file: unsafe { 419 + CStr::from_ptr(settings.lang_file.as_ptr() as *const i8) 420 + .to_string_lossy() 421 + .into_owned() 422 + }, 423 + playlist_catalog_dir: unsafe { 424 + CStr::from_ptr(settings.playlist_catalog_dir.as_ptr() as *const i8) 425 + .to_string_lossy() 426 + .into_owned() 427 + }, 428 + skip_length: settings.skip_length, 429 + max_files_in_dir: settings.max_files_in_dir, 430 + max_files_in_playlist: settings.max_files_in_playlist, 431 + volume_type: settings.volume_type, 432 + battery_display: settings.battery_display, 433 + show_icons: settings.show_icons != 0, 434 + statusbar: settings.statusbar, 435 + scrollbar: settings.scrollbar, 436 + scrollbar_width: settings.scrollbar_width, 437 + list_line_padding: settings.list_line_padding, 438 + list_separator_height: settings.list_separator_height, 439 + list_separator_color: settings.list_separator_color, 440 + browse_current: settings.browse_current != 0, 441 + scroll_paginated: settings.scroll_paginated != 0, 442 + list_wraparound: settings.list_wraparound != 0, 443 + list_order: settings.list_order, 444 + scroll_speed: settings.scroll_speed, 445 + bidir_limit: settings.bidir_limit, 446 + scroll_delay: settings.scroll_delay, 447 + scroll_step: settings.scroll_step, 448 + autoloadbookmark: settings.autoloadbookmark, 449 + autocreatebookmark: settings.autocreatebookmark, 450 + autoupdatebookmark: settings.autoupdatebookmark != 0, 451 + usemrb: settings.usemrb, 452 + dircache: settings.dircache != 0, 453 + tagcache_ram: settings.tagcache_ram, 454 + tagcache_autoupdate: settings.tagcache_autoupdate != 0, 455 + autoresume_enable: settings.autoresume_enable != 0, 456 + autoresume_automatic: settings.autoresume_automatic, 457 + autoresume_paths: unsafe { 458 + CStr::from_ptr(settings.autoresume_paths.as_ptr() as *const i8) 459 + .to_string_lossy() 460 + .into_owned() 461 + }, 462 + runtimedb: settings.runtimedb != 0, 463 + tagcache_scan_paths: unsafe { 464 + CStr::from_ptr(settings.tagcache_scan_paths.as_ptr() as *const i8) 465 + .to_string_lossy() 466 + .into_owned() 467 + }, 468 + tagcache_db_path: unsafe { 469 + CStr::from_ptr(settings.tagcache_db_path.as_ptr() as *const i8) 470 + .to_string_lossy() 471 + .into_owned() 472 + }, 473 + backdrop_file: unsafe { 474 + CStr::from_ptr(settings.backdrop_file.as_ptr() as *const i8) 475 + .to_string_lossy() 476 + .into_owned() 477 + }, 478 + bg_color: settings.bg_color, 479 + fg_color: settings.fg_color, 480 + lss_color: settings.lss_color, 481 + lse_color: settings.lse_color, 482 + lst_color: settings.lst_color, 483 + colors_file: unsafe { 484 + CStr::from_ptr(settings.colors_file.as_ptr() as *const i8) 485 + .to_string_lossy() 486 + .into_owned() 487 + }, 488 + browser_default: settings.browser_default, 489 + repeat_mode: settings.repeat_mode, 490 + next_folder: settings.next_folder, 491 + constrain_next_folder: settings.constrain_next_folder != 0, 492 + recursive_dir_insert: settings.recursive_dir_insert, 493 + fade_on_stop: settings.fade_on_stop != 0, 494 + playlist_shuffle: settings.playlist_shuffle != 0, 495 + warnon_erase_dynplaylist: settings.warnon_erase_dynplaylist != 0, 496 + keep_current_track_on_replace_playlist: settings.keep_current_track_on_replace_playlist 497 + != 0, 498 + show_shuffled_adding_options: settings.show_shuffled_adding_options != 0, 499 + show_queue_options: settings.show_queue_options, 500 + album_art: settings.album_art, 501 + rewind_across_tracks: settings.rewind_across_tracks != 0, 502 + playlist_viewer_icons: settings.playlist_viewer_icons != 0, 503 + playlist_viewer_indices: settings.playlist_viewer_indices != 0, 504 + playlist_viewer_track_display: settings.playlist_viewer_track_display, 505 + talk_menu: settings.talk_menu != 0, 506 + talk_dir: settings.talk_dir, 507 + talk_dir_clip: settings.talk_dir_clip != 0, 508 + talk_file: settings.talk_file, 509 + talk_file_clip: settings.talk_file_clip != 0, 510 + talk_filetype: settings.talk_filetype != 0, 511 + talk_battery_level: settings.talk_battery_level != 0, 512 + talk_mixer_amp: settings.talk_mixer_amp, 513 + sort_case: settings.sort_case != 0, 514 + sort_dir: settings.sort_dir, 515 + sort_file: settings.sort_file, 516 + interpret_numbers: settings.interpret_numbers, 517 + poweroff: settings.poweroff, 518 + battery_capacity: settings.battery_capacity, 519 + battery_type: settings.battery_type, 520 + spdif_enable: settings.spdif_enable != 0, 521 + usb_charging: settings.usb_charging, 522 + contrast: settings.contrast, 523 + invert: settings.invert != 0, 524 + flip_display: settings.flip_display != 0, 525 + cursor_style: settings.cursor_style, 526 + screen_scroll_step: settings.screen_scroll_step, 527 + show_path_in_browser: settings.show_path_in_browser, 528 + offset_out_of_view: settings.offset_out_of_view != 0, 529 + disable_mainmenu_scrolling: settings.disable_mainmenu_scrolling != 0, 530 + icon_file: unsafe { 531 + CStr::from_ptr(settings.icon_file.as_ptr() as *const i8) 532 + .to_string_lossy() 533 + .into_owned() 534 + }, 535 + viewers_icon_file: unsafe { 536 + CStr::from_ptr(settings.viewers_icon_file.as_ptr() as *const i8) 537 + .to_string_lossy() 538 + .into_owned() 539 + }, 540 + font_file: unsafe { 541 + CStr::from_ptr(settings.font_file.as_ptr() as *const i8) 542 + .to_string_lossy() 543 + .into_owned() 544 + }, 545 + glyphs_to_cache: settings.glyphs_to_cache, 546 + kbd_file: unsafe { 547 + CStr::from_ptr(settings.kbd_file.as_ptr() as *const i8) 548 + .to_string_lossy() 549 + .into_owned() 550 + }, 551 + backlight_timeout: settings.backlight_timeout, 552 + caption_backlight: settings.caption_backlight != 0, 553 + bl_filter_first_keypress: settings.bl_filter_first_keypress != 0, 554 + backlight_timeout_plugged: settings.backlight_timeout_plugged, 555 + bt_selective_softlock_actions: settings.bt_selective_softlock_actions != 0, 556 + bt_selective_softlock_actions_mask: settings.bt_selective_softlock_actions_mask, 557 + bl_selective_actions: settings.bl_selective_actions != 0, 558 + bl_selective_actions_mask: settings.bl_selective_actions_mask, 559 + backlight_on_button_hold: settings.backlight_on_button_hold, 560 + lcd_sleep_after_backlight_off: settings.lcd_sleep_after_backlight_off, 561 + brightness: settings.brightness, 562 + speaker_mode: settings.speaker_mode, 563 + prevent_skip: settings.prevent_skip != 0, 564 + touch_mode: settings.touch_mode, 565 + ts_calibration_data: TouchscreenParameter::from(settings.ts_calibration_data), 566 + pitch_mode_semitone: settings.pitch_mode_semitone != 0, 567 + pitch_mode_timestretch: settings.pitch_mode_timestretch != 0, 568 + usb_hid: settings.usb_hid != 0, 569 + usb_keypad_mode: settings.usb_keypad_mode, 570 + usb_skip_first_drive: settings.usb_skip_first_drive != 0, 571 + player_name: unsafe { 572 + CStr::from_ptr(settings.player_name.as_ptr() as *const i8) 573 + .to_string_lossy() 574 + .into_owned() 575 + }, 576 + compressor_settings: CompressorSettings::from(settings.compressor_settings), 577 + sleeptimer_duration: settings.sleeptimer_duration, 578 + sleeptimer_on_startup: settings.sleeptimer_on_startup != 0, 579 + keypress_restarts_sleeptimer: settings.keypress_restarts_sleeptimer != 0, 580 + show_shutdown_message: settings.show_shutdown_message != 0, 581 + hotkey_wps: settings.hotkey_wps, 582 + hotkey_tree: settings.hotkey_tree, 583 + resume_rewind: settings.resume_rewind, 584 + depth_3d: settings.depth_3d, 585 + roll_off: settings.roll_off, 586 + power_mode: settings.power_mode, 587 + keyclick_hardware: settings.keyclick_hardware != 0, 588 + start_directory: unsafe { 589 + CStr::from_ptr(settings.start_directory.as_ptr() as *const i8) 590 + .to_string_lossy() 591 + .into_owned() 592 + }, 593 + root_menu_customized: settings.root_menu_customized != 0, 594 + shortcuts_replaces_qs: settings.shortcuts_replaces_qs != 0, 595 + play_frequency: settings.play_frequency, 596 + volume_limit: settings.volume_limit, 597 + volume_adjust_mode: settings.volume_adjust_mode, 598 + volume_adjust_norm_steps: settings.volume_adjust_norm_steps, 599 + surround_enabled: settings.surround_enabled, 600 + surround_balance: settings.surround_balance, 601 + surround_fx1: settings.surround_fx1, 602 + surround_fx2: settings.surround_fx2 != 0, 603 + surround_method2: settings.surround_method2 != 0, 604 + surround_mix: settings.surround_mix, 605 + pbe: settings.pbe, 606 + pbe_precut: settings.pbe_precut, 607 + afr_enabled: settings.afr_enabled, 608 + governor: settings.governor, 609 + stereosw_mode: settings.stereosw_mode, 610 + } 611 + } 612 + }
docs/preview.png

This is a binary file and will not be displayed.

docs/rockbox-server-architecture.jpg

This is a binary file and will not be displayed.

+5
firmware/common/version.c
··· 21 21 22 22 #include "rbversion.h" 23 23 const char rbversion[] = RBVERSION; 24 + 25 + const char *get_version(void) 26 + { 27 + return rbversion; 28 + }
+12
flake.nix
··· 34 34 pkgs.pkg-config 35 35 pkgs.gcc 36 36 pkgs.zlib 37 + pkgs.cargo 38 + pkgs.rustc 39 + pkgs.protobuf 40 + pkgs.buf 41 + pkgs.libunwind 37 42 ]; 38 43 39 44 # Smaller binaries and avoids shipping glibc. ··· 100 105 pkgs.pkg-config 101 106 pkgs.gcc 102 107 pkgs.zlib 108 + pkgs.cargo 109 + pkgs.rustc 110 + pkgs.protobuf 111 + pkgs.buf 112 + pkgs.libunwind 113 + pkgs.evans 114 + pkgs.grpcurl 103 115 ]; 104 116 }; 105 117 }));
+7 -3
tools/root.make
··· 412 412 413 413 ziginstall: zig 414 414 @echo "Installing your build in your '$(RBPREFIX)' dir" 415 - cd .. && zig build install-rockbox 415 + cd .. && cargo build -p rockbox-server --release && zig build install-rockbox 416 416 417 417 symlinkinstall: simext1 418 418 @echo "Installing a full setup with links in your '$(RBPREFIX)' dir" 419 419 $(SILENT)$(TOOLSDIR)/buildzip.pl $(VERBOSEOPT) --app=$(APPLICATION) -m "$(MODELNAME)" -i "$(TARGET_ID)" $(INSTALL) -z "zip -r0" -r "$(ROOTDIR)" --rbdir="$(RBDIR)" -f 2 $(TARGET) $(BINARY) -l 420 420 endif 421 421 422 - zig: $(BUILDDIR)/lang/lang.h $(BUILDDIR)/lang_enum.h $(BUILDDIR)/lang/lang_core.c $(BUILDDIR)/lang/max_language_size.h $(BUILDDIR)/sysfont.o $(BUILDDIR)/rbversion.h $(PBMPHFILES) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/settings.lua $(LUA_BUILDDIR)/buttons.lua $(LUA_BUILDDIR)/rb_defines.lua $(LUA_BUILDDIR)/sound_defines.lua $(LUA_BUILDDIR)/rocklib_aux.c $(BUILDDIR)/credits.raw credits.raw $(DEPFILE) $(TOOLS) $(CODECS) 423 - cd .. && zig build all 422 + $(BUILDDIR)/apps/recorder/jpeg_load.o: $(ROOTDIR)/apps/recorder/jpeg_load.c 423 + mkdir -p $(BUILDDIR)/apps/recorder 424 + $(SILENT)$(CC) $(CFLAGS) -c -o $(BUILDDIR)/apps/recorder/jpeg_load.o $(ROOTDIR)/apps/recorder/jpeg_load.c 425 + 426 + zig: $(BUILDDIR)/apps/recorder/jpeg_load.o $(BUILDDIR)/lang/lang.h $(BUILDDIR)/lang_enum.h $(BUILDDIR)/lang/lang_core.c $(BUILDDIR)/lang/max_language_size.h $(BUILDDIR)/sysfont.o $(BUILDDIR)/rbversion.h $(PBMPHFILES) $(LUA_BUILDDIR)/actions.lua $(LUA_BUILDDIR)/settings.lua $(LUA_BUILDDIR)/buttons.lua $(LUA_BUILDDIR)/rb_defines.lua $(LUA_BUILDDIR)/sound_defines.lua $(LUA_BUILDDIR)/rocklib_aux.c $(BUILDDIR)/credits.raw credits.raw $(DEPFILE) $(TOOLS) $(CODECS) 427 + cd .. && cargo build -p rockbox-server --release && zig build all 424 428 help: 425 429 @echo "A few helpful make targets" 426 430 @echo ""