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.

Add Snapcast TCP PCM sink and stream metadata

Register PCM_SINK_SNAPCAST_TCP and add a native pcm-tcp.c implementation
with FFI hooks (settings, sys bindings, discovery, UI and firmware
SOURCES).
Document FIFO vs TCP modes and mDNS auto-discovery. Note: TCP sink
reconnects on next play after errors and will drop the in-flight buffer
on
EPIPE; FIFO/stdout behavior is unchanged.

Add save_stream_metadata/update_stream_metadata and a playback metadata
override API so stream title/artist/album/length are surfaced
immediately.
Also add a netstream guard to clamp huge seeks that can hang streaming.

+3834 -1541
+1
Cargo.lock
··· 9503 9503 "reqwest", 9504 9504 "rockbox-sys", 9505 9505 "serde", 9506 + "serde_json", 9506 9507 "socket2 0.5.7", 9507 9508 "sqlx", 9508 9509 "tokio",
+39 -5
README.md
··· 31 31 ### Audio output 32 32 - [x] Built-in SDL audio 33 33 - [x] AirPlay (RAOP) — single or multi-room fan-out to Apple TV, HomePod, Airport Express, shairport-sync 34 - - [x] Snapcast (FIFO/pipe) — synchronised multi-room via snapserver 34 + - [x] Snapcast — synchronised multi-room via snapserver (FIFO/pipe **and** direct TCP with mDNS auto-discovery) 35 35 - [x] Squeezelite (Slim Protocol + HTTP broadcast) — synchronised multi-room 36 36 - [x] Chromecast 37 37 - [x] Gapless playback and crossfading ··· 204 204 205 205 Uses SDL2 audio — plays through the OS default device. No extra setup needed. 206 206 207 - ### Snapcast (FIFO / pipe) 207 + ### Snapcast 208 + 209 + Rockbox supports two ways to feed [Snapcast](https://github.com/badaix/snapcast) 210 + for synchronised multi-room playback. Both write raw **S16LE stereo 44100 Hz** 211 + PCM to snapserver. 212 + 213 + #### TCP (recommended — auto-discovery) 214 + 215 + ```toml 216 + music_dir = "/path/to/Music" 217 + audio_output = "snapcast_tcp" 218 + snapcast_tcp_host = "192.168.1.x" # IP of the machine running snapserver 219 + snapcast_tcp_port = 4953 # default snapserver TCP source port 220 + ``` 221 + 222 + Connects directly to snapserver's TCP source port. No named FIFO or filesystem 223 + dependency needed. 224 + 225 + ```ini 226 + # /etc/snapserver.conf (or /usr/local/etc/snapserver.conf on macOS) 227 + [stream] 228 + source = tcp://0.0.0.0:4953?name=default&sampleformat=44100:16:2 229 + ``` 230 + 231 + > **Startup order**: start `snapserver` first so it is already listening when 232 + > rockboxd begins playback. If the connection drops (e.g. snapserver restarts), 233 + > it is re-established automatically on the next play call. 234 + 235 + > **Auto-discovery**: rockboxd scans for `_snapcast._tcp.local.` via mDNS at 236 + > startup. Discovered servers appear in the web UI and desktop app device 237 + > picker — just click to connect, no config file editing needed. 238 + 239 + #### FIFO / pipe 208 240 209 241 ```toml 210 242 music_dir = "/path/to/Music" ··· 212 244 fifo_path = "/tmp/snapfifo" # named FIFO for snapserver; use "-" for stdout 213 245 ``` 214 246 215 - Writes raw **S16LE stereo 44100 Hz** PCM to a named FIFO. Feed it into 216 - [Snapcast](https://github.com/badaix/snapcast) for synchronised multi-room 217 - playback: 247 + Writes to a named FIFO. Use this when you need stdout piping or prefer the 248 + traditional pipe model. 218 249 219 250 ```ini 220 251 # /etc/snapserver.conf (or /usr/local/etc/snapserver.conf on macOS) ··· 231 262 ```sh 232 263 rockboxd | ffplay -f s16le -ar 44100 -ac 2 - 233 264 ``` 265 + 266 + See [SNAPCAST.md](./SNAPCAST.md) for a detailed comparison of both modes, 267 + connection lifecycle, reconnect behaviour, and macOS quirks. 234 268 235 269 ### AirPlay (RAOP) — single or multi-room 236 270
+285 -217
SNAPCAST.md
··· 1 - # Snapcast / FIFO PCM Sink 1 + # Snapcast — FIFO & TCP PCM Sinks 2 2 3 3 This document traces every hop an audio frame takes from the Rockbox C firmware 4 - through the FIFO PCM sink to a Snapcast server (or any other pipe consumer). 4 + through the Snapcast PCM sinks to a Snapcast server. 5 + 6 + Two complementary sinks are available: 7 + 8 + | Sink | Setting value | Transport | Snapserver source type | 9 + |------|--------------|-----------|------------------------| 10 + | FIFO / pipe | `audio_output = "fifo"` | Named FIFO or stdout | `pipe://` | 11 + | TCP (direct) | `audio_output = "snapcast_tcp"` | TCP socket | `tcp://` | 12 + 13 + The **FIFO sink** is the traditional approach: rockboxd writes to a named pipe 14 + that snapserver reads. The **TCP sink** connects directly to snapserver's TCP 15 + source port — no FIFO, no filesystem dependency, auto-discoverable via mDNS. 5 16 6 17 --- 7 18 8 19 ## Table of contents 9 20 10 21 1. [Overview](#overview) 11 - 2. [Layer map](#layer-map) 12 - 3. [PCM sink vtable (`pcm-fifo.c`)](#pcm-sink-vtable-pcm-fifoc) 13 - 4. [The DMA thread](#the-dma-thread) 14 - 5. [FIFO pre-open strategy](#fifo-pre-open-strategy) 15 - 6. [stdout mode](#stdout-mode) 16 - 7. [Track transitions and EOF prevention](#track-transitions-and-eof-prevention) 17 - 8. [FFI boundary (`crates/sys`)](#ffi-boundary-cratessys) 18 - 9. [Settings and startup (`crates/settings`)](#settings-and-startup-cratessettings) 19 - 10. [Snapcast integration](#snapcast-integration) 20 - 11. [Startup order](#startup-order) 21 - 12. [Snapserver configuration (macOS)](#snapserver-configuration-macos) 22 - 13. [Other pipe consumers](#other-pipe-consumers) 23 - 14. [Gotchas and known limits](#gotchas-and-known-limits) 22 + 2. [Choosing FIFO vs TCP](#choosing-fifo-vs-tcp) 23 + 3. [FIFO sink](#fifo-sink) 24 + - [Layer map](#fifo-layer-map) 25 + - [PCM sink vtable](#pcm-sink-vtable-pcm-fifoc) 26 + - [The DMA thread](#the-dma-thread) 27 + - [FIFO pre-open strategy](#fifo-pre-open-strategy) 28 + - [stdout mode](#stdout-mode) 29 + - [Track transitions and EOF prevention](#track-transitions-and-eof-prevention) 30 + - [Startup order](#startup-order-fifo) 31 + - [Snapserver configuration](#snapserver-configuration-fifo) 32 + 4. [TCP sink](#tcp-sink) 33 + - [Layer map](#tcp-layer-map) 34 + - [PCM sink vtable](#pcm-sink-vtable-pcm-tcpc) 35 + - [Connection lifecycle](#connection-lifecycle) 36 + - [Reconnect on error](#reconnect-on-error) 37 + - [Startup order](#startup-order-tcp) 38 + - [Snapserver configuration](#snapserver-configuration-tcp) 39 + 5. [Auto-discovery via mDNS](#auto-discovery-via-mdns) 40 + 6. [FFI boundary (`crates/sys`)](#ffi-boundary-cratessys) 41 + 7. [Settings and startup (`crates/settings`)](#settings-and-startup-cratessettings) 42 + 8. [Other pipe consumers](#other-pipe-consumers) 43 + 9. [Gotchas and known limits](#gotchas-and-known-limits) 24 44 25 45 --- 26 46 27 47 ## Overview 28 48 29 - The FIFO sink writes raw **S16LE stereo PCM at 44100 Hz** to either a named 30 - FIFO (pipe) or stdout. Its primary use case is feeding 31 - [Snapcast](https://github.com/badaix/snapcast) for synchronized multi-room 32 - playback, but any consumer that reads a raw PCM stream works — `ffplay`, 33 - `aplay`, `sox`, custom scripts, etc. 49 + Both sinks write raw **S16LE stereo PCM at 44100 Hz** — the same byte stream 50 + snapserver expects regardless of source type. There is no Rust crate involved; 51 + both are pure-C PCM sinks with a thin Rust FFI wrapper for configuration. 52 + 53 + --- 34 54 35 - There is no Rust crate involved. This is a pure-C PCM sink with a thin Rust 36 - FFI wrapper for configuration. 55 + ## Choosing FIFO vs TCP 56 + 57 + | | FIFO sink | TCP sink | 58 + |---|---|---| 59 + | Filesystem entry required | Yes (`/tmp/snapfifo`) | No | 60 + | Snapserver source type | `pipe://` | `tcp://` | 61 + | Startup order sensitive | Yes — rockboxd first | Yes — snapserver first | 62 + | Reconnect on snapserver restart | No (FIFO stays open) | Yes (auto on next play) | 63 + | Auto-discovered in UI | No (static virtual device) | Yes (mDNS `_snapcast._tcp.local.`) | 64 + | stdout pipe support | Yes (`fifo_path = "-"`) | No | 65 + | Config | `fifo_path` | `snapcast_tcp_host` + `snapcast_tcp_port` | 66 + 67 + **Use FIFO** when you want stdout piping or prefer the traditional pipe model. 68 + 69 + **Use TCP** when you want UI-based auto-discovery, multiple snapservers, or 70 + don't want a filesystem dependency. 37 71 38 72 --- 39 73 40 - ## Layer map 74 + ## FIFO sink 75 + 76 + ### FIFO layer map 41 77 42 78 ``` 43 79 ┌────────────────────────────────────────────────────────┐ ··· 65 101 └────────────────────────────────────────────────────────┘ 66 102 ``` 67 103 68 - --- 104 + ### PCM sink vtable (`pcm-fifo.c`) 69 105 70 - ## PCM sink vtable (`pcm-fifo.c`) 71 - 72 - `firmware/target/hosted/pcm-fifo.c` implements `struct pcm_sink` with the 73 - following vtable: 106 + `firmware/target/hosted/pcm-fifo.c` implements `struct pcm_sink`: 74 107 75 108 | Op | Implementation | 76 109 |-------------------|-------------------------------------------------------------| ··· 81 114 | `play` | `sink_dma_start` — opens fd if needed, spawns `fifo_thread` | 82 115 | `stop` | `sink_dma_stop` — signals thread, joins; keeps fd open | 83 116 84 - `fifo_pcm_sink` is registered at index `PCM_SINK_FIFO = 1` in the `sinks[]` 85 - array in `firmware/pcm.c`. 117 + `fifo_pcm_sink` is registered at index `PCM_SINK_FIFO = 1` in `firmware/pcm.c`. 86 118 87 - --- 88 - 89 - ## The DMA thread 119 + ### The DMA thread 90 120 91 121 `sink_dma_start(addr, size)` stores the initial PCM pointer/length under the 92 122 mutex, then spawns `fifo_thread`. The thread mimics a hardware DMA interrupt ··· 95 125 ``` 96 126 while not stopped: 97 127 1. lock → grab (data, size) → clear pcm_data/pcm_size → unlock 98 - 2. if data: 99 - while size > 0 and not stopped: 100 - n = write(fifo_fd, data, size) 101 - handle EINTR/EAGAIN (retry) 102 - advance data pointer, decrement size 128 + 2. while size > 0 and not stopped: 129 + n = write(fifo_fd, data, size) 130 + handle EINTR/EAGAIN (retry) 131 + advance data pointer, decrement size 103 132 3. lock → pcm_play_dma_complete_callback(OK, &pcm_data, &pcm_size) → unlock 104 133 4. if no more data: break 105 - 5. pcm_play_dma_status_callback(STARTED) ← tells audio engine chunk consumed 134 + 5. pcm_play_dma_status_callback(STARTED) 106 135 ``` 107 136 108 - The inner write loop handles partial writes and `EINTR`/`EAGAIN` correctly, 109 - advancing the pointer on each successful `write()` call. Pacing comes 110 - naturally from the blocking FIFO write — the kernel suspends the thread until 111 - the reader drains data, keeping throughput locked to the consumer's read rate. 137 + Pacing comes naturally from the blocking FIFO write — the kernel suspends the 138 + thread until the reader drains data, locking throughput to the consumer's rate. 112 139 113 - --- 140 + ### FIFO pre-open strategy 114 141 115 - ## FIFO pre-open strategy 142 + `pcm_fifo_set_path(path)` is called once at startup: 116 143 117 - `pcm_fifo_set_path(path)` is called once at startup from Rust settings code. 118 - It does two things: 119 - 120 - ### 1. Create the FIFO 144 + #### 1. Create the FIFO 121 145 122 146 ```c 123 147 mkfifo(path, 0666); // EEXIST is ignored 124 148 ``` 125 149 126 - This ensures the filesystem entry exists before snapserver starts, so 127 - snapserver's `open()` can succeed immediately. 128 - 129 - ### 2. Open with a permanent writer reference 150 + #### 2. Open with a permanent writer reference 130 151 131 152 ```c 132 153 fd = open(path, O_RDWR | O_NONBLOCK); 133 154 // then clear O_NONBLOCK: 134 - flags = fcntl(fd, F_GETFL); 135 155 fcntl(fd, F_SETFL, flags & ~O_NONBLOCK); 136 156 ``` 137 157 138 - **Why `O_RDWR`?** On Linux and macOS, opening a FIFO `O_WRONLY` blocks until 139 - a reader is present. `O_RDWR` succeeds immediately even with no reader, and 140 - critically it keeps the FIFO's open-writer-count at ≥1 for the entire lifetime 141 - of the process. This means: 142 - 143 - - A reader that comes and goes (snapserver restart, client reconnect) never 144 - causes the FIFO writer to receive `EPIPE` or the reader to see premature EOF. 145 - - Between tracks, when `fifo_thread` exits and `fifo_fd` is not closed, 146 - snapserver's reader stays connected and continues to block-read cleanly. 147 - 148 - **Why clear `O_NONBLOCK`?** After pre-opening, writes must block when the 149 - kernel pipe buffer is full, providing natural back-pressure / pacing. If 150 - `O_NONBLOCK` were left set, writes would return `EAGAIN` when the consumer is 151 - slow, corrupting the stream. 158 + **Why `O_RDWR`?** Opening `O_WRONLY` blocks until a reader is present. `O_RDWR` 159 + succeeds immediately and keeps the open-writer-count at ≥1 for the process 160 + lifetime — snapserver never sees premature EOF between tracks. 152 161 153 - --- 162 + **Why clear `O_NONBLOCK`?** Writes must block when the kernel buffer is full to 163 + provide natural back-pressure. Leaving `O_NONBLOCK` set would produce `EAGAIN` 164 + and corrupt the stream. 154 165 155 - ## stdout mode 166 + ### stdout mode 156 167 157 - When `fifo_path = "-"`, the sink writes to stdout. This enables piping: 168 + When `fifo_path = "-"`, the sink writes to stdout: 158 169 159 170 ```sh 160 171 rockboxd | ffplay -f s16le -ar 44100 -ac 2 - 161 172 ``` 162 173 163 - Because Rockbox C code internally uses `printf()`/`puts()` on fd 1, stdout 164 - mode redirects fd 1 to stderr before any PCM is written: 174 + `pcm_fifo_set_path("-")` redirects fd 1 to stderr before any PCM is written so 175 + internal `printf()` output never pollutes the PCM stream. 165 176 166 - ```c 167 - static void redirect_stdout_to_stderr(void) 168 - { 169 - stdout_pcm_fd = dup(STDOUT_FILENO); // save real stdout 170 - dup2(STDERR_FILENO, STDOUT_FILENO); // fd 1 → stderr 171 - } 172 - ``` 177 + ### Track transitions and EOF prevention 173 178 174 - All subsequent `printf()` output goes to stderr (visible in the terminal but 175 - not in the pipe), while PCM writes go to `stdout_pcm_fd` — the saved copy of 176 - the original stdout. The PCM stream is never polluted by log output. 179 + `sink_dma_stop()` does **not** close `fifo_fd`. On POSIX, a named FIFO's read 180 + end sees EOF only when all write-side fds are closed. By keeping `fifo_fd` open 181 + across track boundaries, snapserver sees a continuous stream with no gaps. 177 182 178 - This works only if `redirect_stdout_to_stderr()` is called before any C code 179 - writes to fd 1. `pcm_fifo_set_path("-")` calls it at startup, which is before 180 - any audio decoding begins. 183 + ### Startup order (FIFO) 181 184 182 - --- 185 + **rockboxd must start before snapserver.** 183 186 184 - ## Track transitions and EOF prevention 187 + ``` 188 + 1. rockboxd starts → pcm_fifo_set_path() → FIFO created, O_RDWR fd held 189 + 2. snapserver starts → opens FIFO O_RDONLY → blocks until data flows 190 + 3. Playback begins → fifo_thread writes → snapserver distributes to clients 191 + ``` 185 192 186 - `sink_dma_stop()` **does not close `fifo_fd`**: 193 + ### Snapserver configuration (FIFO) 187 194 188 - ```c 189 - static void sink_dma_stop(void) 190 - { 191 - fifo_stop = true; 192 - if (fifo_running) { 193 - pthread_join(fifo_tid, NULL); 194 - fifo_running = false; 195 - } 196 - // fifo_fd intentionally left open 197 - } 195 + ```ini 196 + # /etc/snapserver.conf (or /usr/local/etc/snapserver.conf on macOS) 197 + [stream] 198 + source = pipe:///tmp/snapfifo?name=default&sampleformat=44100:16:2 198 199 ``` 199 200 200 - On POSIX, a named FIFO's read end sees EOF only when all write-side file 201 - descriptors are closed. By keeping `fifo_fd` open across track boundaries, 202 - the consumer (snapserver) sees a continuous stream with no gaps. It never has 203 - to reconnect or re-open the pipe. 204 - 205 - The only time `fifo_fd` is closed is if `pcm_fifo_set_path()` is called again 206 - with a new path — an operation that doesn't happen at runtime. 201 + > On macOS, snapserver ≥ v0.35.0 ignores the `-s` CLI flag. Use the config 202 + > file. 207 203 208 204 --- 209 205 210 - ## FFI boundary (`crates/sys`) 206 + ## TCP sink 211 207 212 - `crates/sys/src/lib.rs` declares the C function: 208 + ### TCP layer map 213 209 214 - ```rust 215 - extern "C" { 216 - pub fn pcm_fifo_set_path(path: *const c_char); 217 - } 218 210 ``` 219 - 220 - `crates/sys/src/sound/pcm.rs` wraps it safely: 221 - 222 - ```rust 223 - pub fn fifo_set_path(path: &str) { 224 - let cpath = CString::new(path).expect("path must not contain null bytes"); 225 - unsafe { crate::pcm_fifo_set_path(cpath.as_ptr()) } 226 - std::mem::forget(cpath); // C code only reads during init — leaking is fine 227 - } 211 + ┌────────────────────────────────────────────────────────┐ 212 + │ Rockbox C firmware (pcm.c, audio thread) │ 213 + │ pcm_play_data() → sink.ops.play() │ 214 + │ pcm_play_dma_complete_callback() per chunk │ 215 + └───────────────────┬────────────────────────────────────┘ 216 + │ raw S16LE stereo PCM chunks 217 + ┌───────────────────▼────────────────────────────────────┐ 218 + │ firmware/target/hosted/pcm-tcp.c │ 219 + │ pcm_tcp_set_host() / pcm_tcp_set_port() │ 220 + │ sink_dma_start() — connects if needed, spawns thread│ 221 + │ tcp_thread() — blocking write() loop │ 222 + │ sink_dma_stop() — signals thread, keeps socket │ 223 + └───────────────────┬────────────────────────────────────┘ 224 + │ blocking write() over TCP 225 + ┌───────────────────▼────────────────────────────────────┐ 226 + │ TCP socket (snapserver host:port) │ 227 + └───────────────────┬────────────────────────────────────┘ 228 + │ recv() 229 + ┌───────────────────▼────────────────────────────────────┐ 230 + │ snapserver (tcp:// source, server mode) │ 231 + │ │ │ 232 + │ ┌───┴──────┬──────────┐ │ 233 + │ ▼ ▼ ▼ │ 234 + │ snapclient snapclient snapclient │ 235 + └────────────────────────────────────────────────────────┘ 228 236 ``` 229 237 230 - `std::mem::forget` is used because `pcm_fifo_set_path` stores a raw pointer to 231 - the string and reads it later (e.g. in `sink_dma_start`'s fallback path). 232 - Dropping the `CString` would free the memory while C still holds a dangling 233 - pointer. Since this is a one-time startup call, leaking is acceptable. 238 + ### PCM sink vtable (`pcm-tcp.c`) 234 239 235 - `pcm_switch_sink(PCM_SINK_FIFO)` switches the active sink. This is also an 236 - `extern "C"` call wrapped in `pcm::switch_sink(sink: i32) -> bool`. 240 + `firmware/target/hosted/pcm-tcp.c` implements `struct pcm_sink`: 237 241 238 - --- 242 + | Op | Implementation | 243 + |-------------------|-------------------------------------------------------------| 244 + | `init` | `pthread_mutex_init` (recursive) | 245 + | `postinit` | no-op | 246 + | `set_freq` | no-op (output is always 44100 Hz; snapserver must match) | 247 + | `lock` / `unlock` | `pthread_mutex_lock/unlock` | 248 + | `play` | `sink_dma_start` — connects if needed, spawns `tcp_thread` | 249 + | `stop` | `sink_dma_stop` — signals thread, joins; keeps socket open | 239 250 240 - ## Settings and startup (`crates/settings`) 251 + `tcp_pcm_sink` is registered at index `PCM_SINK_SNAPCAST_TCP = 6` in 252 + `firmware/pcm.c`. 241 253 242 - `crates/settings/src/lib.rs:load_settings()` reads 243 - `~/.config/rockbox.org/settings.toml` and handles the FIFO case: 254 + ### Connection lifecycle 244 255 245 - ```rust 246 - Some("fifo") => { 247 - let path = settings.fifo_path.as_deref().unwrap_or("/tmp/rockbox.fifo"); 248 - pcm::fifo_set_path(path); 249 - pcm::switch_sink(pcm::PCM_SINK_FIFO); 250 - tracing::info!("audio output: fifo ({})", path); 256 + `sink_dma_start()` calls `tcp_connect_once()` if `tcp_fd < 0`: 257 + 258 + ```c 259 + static int tcp_connect_once(void) 260 + { 261 + // getaddrinfo(tcp_host, port) → socket() → connect() 262 + // returns fd on success, -1 on failure (logs error, drops audio) 251 263 } 252 264 ``` 253 265 254 - Relevant `settings.toml` keys: 266 + The socket is kept open across `stop()` → `play()` transitions, just as the 267 + FIFO fd is. snapserver's reader sees a continuous stream between tracks. 255 268 256 - | Key | Type | Default | Description | 257 - |----------------|--------|-----------------------|---------------------------------------| 258 - | `audio_output` | string | `"builtin"` | Set to `"fifo"` to activate this sink | 259 - | `fifo_path` | string | `"/tmp/rockbox.fifo"` | FIFO path, or `"-"` for stdout | 269 + ### Reconnect on error 260 270 261 - --- 271 + If `write()` returns a hard error (`EPIPE`, `ECONNRESET`, etc.), `tcp_thread` 272 + closes the socket (`tcp_fd = -1`) and sets `tcp_stop = true`. The next call to 273 + `sink_dma_start()` finds `tcp_fd < 0` and attempts a fresh `connect()`. This 274 + handles snapserver restarts gracefully — the connection is re-established 275 + automatically on the next track or resume. 262 276 263 - ## Snapcast integration 277 + ### Startup order (TCP) 264 278 265 - [Snapcast](https://github.com/badaix/snapcast) is a synchronised multi-room 266 - audio system. snapserver reads a PCM source and distributes it to one or more 267 - snapclient instances with sub-millisecond synchronisation. 268 - 269 - The FIFO sink is designed to feed snapserver's `pipe://` source type. Once 270 - configured, the stream looks like: 279 + **snapserver must be running and listening before playback starts.** 271 280 272 281 ``` 273 - rockboxd ──write()──▶ /tmp/snapfifo ──read()──▶ snapserver 274 - 275 - ┌──────────┴──────────┐ 276 - ▼ ▼ 277 - snapclient snapclient 278 - (living room) (kitchen) 282 + 1. snapserver starts → listens on tcp://0.0.0.0:4953 283 + 2. rockboxd starts → pcm_tcp_set_host/port() stores config 284 + 3. Playback begins → sink_dma_start() → tcp_connect_once() → connects 285 + 4. tcp_thread writes → snapserver receives → distributes to clients 279 286 ``` 280 287 281 - ### snapserver configuration 288 + Unlike the FIFO sink there is no permanent pre-connection at startup. The 289 + socket is opened on the first `play()` call. 282 290 283 - Add a stream source to `/etc/snapserver.conf` (or 284 - `/usr/local/etc/snapserver.conf` on macOS): 291 + ### Snapserver configuration (TCP) 285 292 286 293 ```ini 294 + # /etc/snapserver.conf (or /usr/local/etc/snapserver.conf on macOS) 287 295 [stream] 288 - source = pipe:///tmp/snapfifo?name=default&sampleformat=44100:16:2 296 + source = tcp://0.0.0.0:4953?name=default&sampleformat=44100:16:2 289 297 ``` 290 298 291 - The `sampleformat=44100:16:2` parameter is required on snapserver v0.35+. 292 - The `-s` CLI flag is **ignored** on macOS; it must be set in the config file. 299 + `settings.toml` (manual config, not needed when selecting from the UI): 300 + 301 + ```toml 302 + audio_output = "snapcast_tcp" 303 + snapcast_tcp_host = "192.168.1.x" # IP of the machine running snapserver 304 + snapcast_tcp_port = 4953 # default snapserver TCP source port 305 + ``` 306 + 307 + --- 308 + 309 + ## Auto-discovery via mDNS 310 + 311 + snapserver advertises itself via mDNS as `_snapcast._tcp.local.`. rockboxd 312 + scans for this service at startup via `scan_snapcast_servers()` in 313 + `crates/server/src/scan.rs`, which browses `_snapcast._tcp.local.` using the 314 + `mdns-sd` crate and adds discovered servers to the shared devices list. 315 + 316 + Discovered servers appear immediately in: 293 317 294 - Start snapserver after rockboxd is running (see startup order below): 318 + - **Web UI** — the device picker in the control bar (lime-green radio icon) 319 + - **Desktop app (GPUI)** — the device picker popup 295 320 296 - ```sh 297 - snapserver 298 - ``` 321 + Clicking a discovered server calls `PUT /devices/:id/connect`, which: 299 322 300 - Connect clients: 323 + 1. Calls `pcm_tcp_set_host(device.ip)` and `pcm_tcp_set_port(device.port)`. 324 + 2. Calls `pcm_switch_sink(PCM_SINK_SNAPCAST_TCP)`. 325 + 3. Persists `audio_output = "snapcast_tcp"`, `snapcast_tcp_host`, and 326 + `snapcast_tcp_port` to `settings.toml` so the selection survives restart. 301 327 302 - ```sh 303 - snapclient --host localhost --player default 304 - ``` 328 + No manual `settings.toml` editing is needed when using the UI. 305 329 306 330 --- 307 331 308 - ## Startup order 332 + ## FFI boundary (`crates/sys`) 333 + 334 + ### FIFO 335 + 336 + ```rust 337 + // crates/sys/src/lib.rs 338 + extern "C" { fn pcm_fifo_set_path(path: *const c_char); } 339 + 340 + // crates/sys/src/sound/pcm.rs 341 + pub fn fifo_set_path(path: &str) { 342 + let cpath = CString::new(path).expect("path must not contain null bytes"); 343 + unsafe { crate::pcm_fifo_set_path(cpath.as_ptr()) } 344 + std::mem::forget(cpath); // C code stores and re-reads pointer at runtime 345 + } 346 + ``` 309 347 310 - **rockboxd must start before snapserver.** 348 + ### TCP 311 349 312 - If snapserver opens the FIFO first (before rockboxd calls `pcm_fifo_set_path` 313 - which does the `O_RDWR` open), it gets the sole writer reference. When 314 - snapserver later closes its end, the FIFO appears to have no writers and 315 - subsequent readers see immediate EOF. 350 + ```rust 351 + // crates/sys/src/lib.rs 352 + extern "C" { 353 + fn pcm_tcp_set_host(host: *const c_char); 354 + fn pcm_tcp_set_port(port: c_ushort); 355 + } 316 356 317 - Correct order: 357 + // crates/sys/src/sound/pcm.rs 358 + pub fn tcp_set_host(host: &str) { 359 + let chost = CString::new(host).expect("host must not contain null bytes"); 360 + unsafe { crate::pcm_tcp_set_host(chost.as_ptr()) } 361 + std::mem::forget(chost); 362 + } 318 363 364 + pub fn tcp_set_port(port: u16) { 365 + unsafe { crate::pcm_tcp_set_port(port) } 366 + } 319 367 ``` 320 - 1. rockboxd starts → pcm_fifo_set_path() → FIFO created, O_RDWR fd held 321 - 2. snapserver starts → opens FIFO O_RDONLY → blocks until data flows 322 - 3. Playback begins → fifo_thread writes → snapserver reads → clients play 323 - ``` 368 + 369 + `std::mem::forget` is used in both cases because the C code stores the raw 370 + pointer and reads it later (in `sink_dma_start`'s connect / fallback path). 371 + Dropping the `CString` would free the memory while C holds a dangling pointer. 372 + Since these are startup-time config calls, leaking is acceptable. 324 373 325 374 --- 326 375 327 - ## Snapserver configuration (macOS) 376 + ## Settings and startup (`crates/settings`) 328 377 329 - On macOS, snapserver's `-s` (stream source) command-line flag is silently 330 - ignored. The only way to configure the source is via the config file: 378 + `crates/settings/src/lib.rs:load_settings()` handles both sinks: 331 379 332 - ```ini 333 - # /usr/local/etc/snapserver.conf 334 - [stream] 335 - source = pipe:///tmp/snapfifo?name=default&sampleformat=44100:16:2 380 + ```rust 381 + Some("fifo") => { 382 + let path = settings.fifo_path.as_deref().unwrap_or("/tmp/rockbox.fifo"); 383 + pcm::fifo_set_path(path); 384 + pcm::switch_sink(pcm::PCM_SINK_FIFO); 385 + } 386 + Some("snapcast_tcp") => { 387 + if let Some(ref host) = settings.snapcast_tcp_host { 388 + let port = settings.snapcast_tcp_port.unwrap_or(4953); 389 + pcm::tcp_set_host(host); 390 + pcm::tcp_set_port(port); 391 + pcm::switch_sink(pcm::PCM_SINK_SNAPCAST_TCP); 392 + } 393 + } 336 394 ``` 337 395 338 - Verify snapserver is reading it: 396 + ### All Snapcast settings keys 339 397 340 - ```sh 341 - snapserver --config /usr/local/etc/snapserver.conf 342 - ``` 398 + | Key | Type | Default | Sink | Description | 399 + |----------------------|--------|-----------------------|-------|------------------------------------------| 400 + | `audio_output` | string | `"builtin"` | both | `"fifo"` or `"snapcast_tcp"` | 401 + | `fifo_path` | string | `"/tmp/rockbox.fifo"` | FIFO | FIFO path, or `"-"` for stdout | 402 + | `snapcast_tcp_host` | string | — | TCP | IP / hostname of the snapserver machine | 403 + | `snapcast_tcp_port` | u16 | `4953` | TCP | snapserver TCP source port | 343 404 344 405 --- 345 406 346 407 ## Other pipe consumers 347 408 348 - Since the FIFO carries raw S16LE stereo 44100 Hz PCM, it works with any tool 349 - that accepts that format: 409 + Since both sinks carry raw S16LE stereo 44100 Hz PCM, the FIFO sink works with 410 + any tool that accepts that format: 350 411 351 412 ```sh 352 - # Play directly with ffplay 413 + # Play directly with ffplay (stdout mode) 353 414 rockboxd | ffplay -f s16le -ar 44100 -ac 2 - 354 415 355 - # Encode on the fly with ffmpeg 416 + # Encode on the fly 356 417 rockboxd | ffmpeg -f s16le -ar 44100 -ac 2 -i - output.mp3 357 418 358 419 # Play with sox ··· 362 423 rockboxd | aplay -f S16_LE -r 44100 -c 2 363 424 ``` 364 425 365 - All of these require `fifo_path = "-"` in `settings.toml` so rockboxd writes 366 - to stdout. 426 + All of these require `fifo_path = "-"` and are only available with the FIFO 427 + sink. The TCP sink does not support stdout mode. 367 428 368 429 --- 369 430 370 431 ## Gotchas and known limits 371 432 372 - ### 1. Startup order is critical 433 + ### 1. Startup order is critical for both sinks 373 434 374 - As described above, rockboxd must open the FIFO before snapserver. If 375 - snapserver opens it first and later closes its write end, snapclient may see 376 - EOF and stop buffering. Restart snapserver after rockboxd in that case. 435 + - **FIFO**: rockboxd must open the FIFO before snapserver. Reverse order causes 436 + snapserver to hold the only writer reference; when it closes, readers see EOF. 437 + Restart snapserver if this happens. 438 + - **TCP**: snapserver must be listening before playback starts. If snapserver 439 + is not yet running, `sink_dma_start` logs a warning and drops audio for that 440 + buffer. It reconnects automatically on the next play call. 377 441 378 442 ### 2. Fixed 44100 Hz, S16LE stereo 379 443 380 - The FIFO sink does not resample. The `set_freq` op is a no-op. If Rockbox 381 - decodes a 48 kHz or 96 kHz track, the firmware resamples it internally to 382 - the codec's sample rate, but the PCM output is always delivered to the sink 383 - at 44100 Hz. Configure snapserver and any other consumer to match. 444 + Neither sink resamples. `set_freq` is a no-op. The firmware resamples tracks 445 + internally before they reach the sink, but the output is always 44100 Hz. 446 + Configure `sampleformat=44100:16:2` on the snapserver side. 384 447 385 448 ### 3. No volume control through the sink 386 449 387 450 Volume is applied by the Rockbox DSP pipeline before PCM reaches the sink. 388 - The FIFO sink itself has no volume knob. Adjust volume through the Rockbox 389 - API or client applications. 451 + Adjust volume through the Rockbox API or client applications. 390 452 391 453 ### 4. Consumer back-pressure controls playback speed 392 454 393 - Because `fifo_fd` is in blocking mode, a slow or stalled consumer will cause 394 - `write()` to block, which stalls `fifo_thread`, which eventually stalls the 395 - DMA callback loop, which pauses decoding. This is correct behavior for 396 - synchronized output, but it means a crashed or frozen snapserver will freeze 455 + Both sinks use blocking `write()`. A slow or stalled consumer stalls 456 + `write()`, which stalls the DMA callback loop, which pauses decoding. This 457 + is correct for synchronized output but means a crashed consumer freezes 397 458 playback. Restart snapserver to recover. 398 459 399 460 ### 5. macOS `snapserver.conf` vs CLI flag 400 461 401 - The `-s` flag to snapserver is silently ignored on macOS (at least v0.35.0). 402 - Always use the config file. See [Snapserver configuration (macOS)](#snapserver-configuration-macos). 462 + The `-s` flag to snapserver is silently ignored on macOS (≥ v0.35.0). 463 + Always use the config file for both `pipe://` and `tcp://` sources. 464 + 465 + ### 6. TCP reconnect drops in-flight buffer 466 + 467 + When the write loop detects `EPIPE` it closes the socket immediately. The 468 + current audio buffer is discarded. Reconnection happens on the next 469 + `sink_dma_start()` call, so there will be a brief audio gap when snapserver 470 + restarts. 403 471 404 - ### 6. Logging uses `tracing`, never `println!` 472 + ### 7. Logging uses `tracing`, never `println!` 405 473 406 474 All Rust-side diagnostic output must go through `tracing`. `println!` and 407 - `eprintln!` bypass the log filter and — in stdout mode — corrupt the PCM 408 - stream. Use `RUST_LOG=debug rockboxd` to see debug output on stderr. 475 + `eprintln!` bypass the log filter and — in stdout/FIFO mode — can corrupt the 476 + PCM stream. Use `RUST_LOG=debug rockboxd` to see debug output on stderr.
+98
crates/library/src/audio_scan.rs
··· 253 253 Ok(()) 254 254 } 255 255 256 + /// Save metadata for a streaming URL directly to the DB without probing the stream. 257 + /// Called by the UPnP renderer which already has title/artist/album/duration from DIDL-Lite. 258 + pub async fn save_stream_metadata( 259 + pool: Pool<Sqlite>, 260 + url: &str, 261 + title: &str, 262 + artist: &str, 263 + album: &str, 264 + duration_ms: u32, 265 + ) -> Result<(), Error> { 266 + let track_md5 = format!("{:x}", md5::compute(url.as_bytes())); 267 + let length_secs = duration_ms / 1000; 268 + 269 + if repo::track::find_by_md5(pool.clone(), &track_md5) 270 + .await? 271 + .is_some() 272 + { 273 + repo::track::update_stream_metadata(pool, &track_md5, title, artist, album, length_secs) 274 + .await?; 275 + return Ok(()); 276 + } 277 + 278 + let artist_id = repo::artist::save( 279 + pool.clone(), 280 + Artist { 281 + id: cuid::cuid1()?, 282 + name: artist.to_string(), 283 + bio: None, 284 + image: None, 285 + genres: None, 286 + }, 287 + ) 288 + .await?; 289 + 290 + let album_md5 = format!( 291 + "{:x}", 292 + md5::compute(format!("{}{}", artist, album).as_bytes()) 293 + ); 294 + let album_id = repo::album::save( 295 + pool.clone(), 296 + Album { 297 + id: cuid::cuid1()?, 298 + title: album.to_string(), 299 + artist: artist.to_string(), 300 + year: 0, 301 + year_string: String::new(), 302 + album_art: None, 303 + md5: album_md5, 304 + artist_id: artist_id.clone(), 305 + label: None, 306 + copyright_message: None, 307 + }, 308 + ) 309 + .await?; 310 + 311 + let track_id = repo::track::save( 312 + pool.clone(), 313 + Track { 314 + id: cuid::cuid1()?, 315 + path: url.to_string(), 316 + title: title.to_string(), 317 + artist: artist.to_string(), 318 + album: album.to_string(), 319 + album_artist: artist.to_string(), 320 + length: length_secs, 321 + md5: track_md5, 322 + artist_id: artist_id.clone(), 323 + album_id: album_id.clone(), 324 + created_at: Utc::now(), 325 + updated_at: Utc::now(), 326 + ..Default::default() 327 + }, 328 + ) 329 + .await?; 330 + 331 + repo::album_tracks::save( 332 + pool.clone(), 333 + AlbumTracks { 334 + id: cuid::cuid1()?, 335 + album_id, 336 + track_id: track_id.clone(), 337 + }, 338 + ) 339 + .await?; 340 + 341 + repo::artist_tracks::save( 342 + pool.clone(), 343 + ArtistTracks { 344 + id: cuid::cuid1()?, 345 + artist_id, 346 + track_id, 347 + }, 348 + ) 349 + .await?; 350 + 351 + Ok(()) 352 + } 353 + 256 354 fn is_remote_path(path: &str) -> bool { 257 355 path.starts_with("http://") || path.starts_with("https://") 258 356 }
+22
crates/library/src/repo/track.rs
··· 155 155 Ok(result) 156 156 } 157 157 158 + pub async fn update_stream_metadata( 159 + pool: Pool<Sqlite>, 160 + md5: &str, 161 + title: &str, 162 + artist: &str, 163 + album: &str, 164 + length: u32, 165 + ) -> Result<(), Error> { 166 + sqlx::query( 167 + "UPDATE track SET title = $2, artist = $3, album = $4, length = $5, updated_at = $6 WHERE md5 = $1", 168 + ) 169 + .bind(md5) 170 + .bind(title) 171 + .bind(artist) 172 + .bind(album) 173 + .bind(length) 174 + .bind(chrono::Utc::now()) 175 + .execute(&pool) 176 + .await?; 177 + Ok(()) 178 + } 179 + 158 180 pub async fn find_by_artist_album_date( 159 181 pool: Pool<Sqlite>, 160 182 artist: &str,
+20 -4
crates/netstream/src/lib.rs
··· 332 332 _ => return -1, 333 333 }; 334 334 335 - // Guard: never issue a Range request past EOF — the server would return 416 336 - // and seek_to would leave response=None, permanently breaking the stream. 337 - // This can happen when the C MP4 parser has a uint32_t underflow in its 338 - // atom-size arithmetic and tries to seek gigabytes forward. 335 + // Guard 1: never seek gigabytes forward regardless of content_length. 336 + // A seek >256 MB past current position is always a codec arithmetic bug 337 + // (e.g. WAV trying to skip a 0xFFFFFFFF-byte data chunk, or MP4 with 338 + // uint32_t underflow). Issue a Range request for such an offset and the 339 + // server either returns 416 or streams from the beginning — either way 340 + // skip_bytes would block for hours reading a live stream. 341 + const MAX_SKIP: u64 = 256 * 1024 * 1024; // 256 MB 342 + if new_pos > state.pos && new_pos - state.pos > MAX_SKIP { 343 + warn!( 344 + "[netstream] rb_net_lseek: h={} off={} whence={} huge skip ({} bytes) clamped", 345 + h, 346 + off, 347 + whence, 348 + new_pos - state.pos 349 + ); 350 + return -1; 351 + } 352 + 353 + // Guard 2: never issue a Range request past EOF — the server would return 354 + // 416 and leave response=None, permanently breaking the stream. 339 355 if let Some(cl) = state.content_length { 340 356 if new_pos >= cl { 341 357 warn!(
+3 -1
crates/rpc/src/lib.rs
··· 948 948 chromecast_host: None, 949 949 chromecast_http_port: None, 950 950 chromecast_port: None, 951 + snapcast_tcp_host: None, 952 + snapcast_tcp_port: None, 951 953 } 952 954 } 953 955 } ··· 1021 1023 .await 1022 1024 .map_err(|e| tonic::Status::internal(e.to_string()))?; 1023 1025 1024 - if !player.host.is_empty() && player.port != 0 { 1026 + if player.is_cast_device { 1025 1027 let client = reqwest::Client::new(); 1026 1028 let body = serde_json::json!({ 1027 1029 "tracks": $tracks,
+14
crates/server/src/handlers/devices.rs
··· 87 87 pcm::upnp_set_renderer_url(url); 88 88 } 89 89 pcm::upnp_set_http_port(http_port); 90 + // Reset renderer state so the very next sink_dma_start always fires 91 + // SetAVTransportURI + Play — without this, switching back to UPnP after 92 + // using another output would leave RENDERER_PLAYING=true and send no 93 + // play command, silently producing no audio until daemon restart. 94 + pcm::upnp_reset_renderer(); 90 95 pcm::switch_sink(pcm::PCM_SINK_UPNP); 91 96 *GLOBAL_MUTEX.lock().unwrap() = 0; 92 97 } ··· 99 104 pcm::chromecast_set_device_host(&device.ip); 100 105 pcm::chromecast_set_device_port(device.port); 101 106 pcm::switch_sink(pcm::PCM_SINK_CHROMECAST); 107 + *GLOBAL_MUTEX.lock().unwrap() = 0; 108 + } 109 + "snapcast" => { 110 + settings.audio_output = Some("snapcast_tcp".to_string()); 111 + settings.snapcast_tcp_host = Some(device.ip.clone()); 112 + settings.snapcast_tcp_port = Some(device.port); 113 + pcm::tcp_set_host(&device.ip); 114 + pcm::tcp_set_port(device.port); 115 + pcm::switch_sink(pcm::PCM_SINK_SNAPCAST_TCP); 102 116 *GLOBAL_MUTEX.lock().unwrap() = 0; 103 117 } 104 118 other => {
+1
crates/server/src/handlers/mod.rs
··· 77 77 async_handler!(saved_playlists, delete_playlist_folder); 78 78 async_handler!(tracks, get_tracks); 79 79 async_handler!(tracks, get_track); 80 + async_handler!(tracks, save_stream_track_metadata); 80 81 async_handler!(system, get_rockbox_version); 81 82 async_handler!(system, get_status); 82 83 async_handler!(system, scan_library);
+23
crates/server/src/handlers/playlists.rs
··· 45 45 46 46 let player_mutex = PLAYER_MUTEX.lock().unwrap(); 47 47 48 + // For HTTP streams: flush the audio thread's message queue before replacing 49 + // the playlist. Stale Q_AUDIO_FILL_BUFFER messages from a previous HTTP 50 + // session (e.g. auto-resume) would otherwise act on the new playlist's 51 + // handle with the old stream context, causing the new play to be silently 52 + // ignored. For local files the queue is always drained by the time the 53 + // user starts a new playlist, so hard_stop is a no-op cost there. 54 + let current_is_http = rb::playback::current_track() 55 + .map(|t| t.path.starts_with("http://") || t.path.starts_with("https://")) 56 + .unwrap_or(false); 57 + let new_is_http = new_playlist.tracks[0].starts_with("http://") 58 + || new_playlist.tracks[0].starts_with("https://"); 59 + if current_is_http || new_is_http { 60 + rb::playback::hard_stop(); 61 + } 62 + 48 63 // Always create a fresh playlist so the currently-playing track is 49 64 // fully replaced rather than appended to. 50 65 // Local paths: use the track's parent directory (required by Rockbox). ··· 308 323 async fn persist_remote_track_metadata(ctx: &Context, tracks: &[String]) -> Result<(), Error> { 309 324 for track in tracks { 310 325 if track.starts_with("http://") || track.starts_with("https://") { 326 + // Raw PCM streams served at /stream.wav have no embedded metadata and 327 + // probing them would block for ~47 s (8 MB at audio bitrate) then time out. 328 + if reqwest::Url::parse(track) 329 + .map(|u| u.path() == "/stream.wav") 330 + .unwrap_or(false) 331 + { 332 + continue; 333 + } 311 334 if find_internal_track_by_url(ctx, track).await?.is_some() { 312 335 continue; 313 336 }
+37 -1
crates/server/src/handlers/tracks.rs
··· 1 1 use anyhow::Error; 2 - use rockbox_library::repo; 2 + use rockbox_library::{audio_scan, repo}; 3 + use serde::Deserialize; 3 4 4 5 use crate::http::{Context, Request, Response}; 5 6 ··· 14 15 res.json(&track); 15 16 Ok(()) 16 17 } 18 + 19 + #[derive(Deserialize)] 20 + struct StreamMetadataBody { 21 + url: String, 22 + title: String, 23 + artist: String, 24 + album: String, 25 + duration_ms: u32, 26 + } 27 + 28 + pub async fn save_stream_track_metadata( 29 + ctx: &Context, 30 + req: &Request, 31 + res: &mut Response, 32 + ) -> Result<(), Error> { 33 + let body = match req.body.as_ref() { 34 + Some(b) => b, 35 + None => { 36 + res.set_status(400); 37 + return Ok(()); 38 + } 39 + }; 40 + let params: StreamMetadataBody = serde_json::from_str(body)?; 41 + audio_scan::save_stream_metadata( 42 + ctx.pool.clone(), 43 + &params.url, 44 + &params.title, 45 + &params.artist, 46 + &params.album, 47 + params.duration_ms, 48 + ) 49 + .await?; 50 + res.set_status(204); 51 + Ok(()) 52 + }
+21 -2
crates/server/src/http.rs
··· 25 25 kv::{build_tracks_kv, KV}, 26 26 player_events::listen_for_playback_changes, 27 27 scan::{ 28 - scan_airplay_devices, scan_chromecast_devices, scan_squeezelite_clients, scan_upnp_devices, 29 - virtual_devices, 28 + scan_airplay_devices, scan_chromecast_devices, scan_snapcast_servers, 29 + scan_squeezelite_clients, scan_upnp_devices, virtual_devices, 30 30 }, 31 31 }; 32 32 ··· 324 324 ..Default::default() 325 325 }) 326 326 } 327 + "snapcast_tcp" => { 328 + let host = s.snapcast_tcp_host.clone().unwrap_or_default(); 329 + Some(Device { 330 + id: format!("snapcast-{}", host), 331 + name: if host.is_empty() { 332 + "Snapcast".to_string() 333 + } else { 334 + format!("Snapcast ({})", host) 335 + }, 336 + host: host.clone(), 337 + ip: host, 338 + port: s.snapcast_tcp_port.unwrap_or(4953), 339 + service: "snapcast".to_string(), 340 + app: "Snapcast".to_string(), 341 + is_cast_device: true, 342 + ..Default::default() 343 + }) 344 + } 327 345 _ => virtual_devices() 328 346 .into_iter() 329 347 .find(|d| d.service == "builtin"), ··· 347 365 scan_chromecast_devices(devices.clone()); 348 366 scan_upnp_devices(devices.clone()); 349 367 scan_airplay_devices(devices.clone()); 368 + scan_snapcast_servers(devices.clone()); 350 369 scan_squeezelite_clients(devices.clone()); 351 370 listen_for_playback_changes(player.clone(), db_pool.clone()); 352 371
+1
crates/server/src/lib.rs
··· 153 153 154 154 app.get("/tracks", get_tracks); 155 155 app.get("/tracks/:id", get_track); 156 + app.put("/tracks/stream-metadata", save_stream_track_metadata); 156 157 157 158 app.get("/version", get_rockbox_version); 158 159 app.get("/status", get_status);
+30 -1
crates/server/src/scan.rs
··· 1 1 use futures_util::StreamExt; 2 2 use rockbox_discovery::{discover, CHROMECAST_SERVICE_NAME}; 3 3 use rockbox_graphql::simplebroker::SimpleBroker; 4 - use rockbox_types::device::{Device, AIRPLAY_DEVICE, AIRPLAY_SERVICE_NAME, UPNP_DLNA_DEVICE}; 4 + use rockbox_types::device::{ 5 + Device, AIRPLAY_DEVICE, AIRPLAY_SERVICE_NAME, SNAPCAST_SERVICE_NAME, UPNP_DLNA_DEVICE, 6 + }; 5 7 use std::{ 6 8 sync::{Arc, Mutex}, 7 9 thread, ··· 117 119 device.is_cast_device = true; 118 120 devices.push(device.clone()); 119 121 SimpleBroker::<Device>::publish(device); 122 + } 123 + }); 124 + }); 125 + } 126 + 127 + /// Discover Snapcast servers on the local network via mDNS (`_snapcast._tcp.local.`). 128 + /// Runs in a background thread; newly found servers are added to the shared device list. 129 + pub fn scan_snapcast_servers(devices: Arc<Mutex<Vec<Device>>>) { 130 + thread::spawn(move || { 131 + tokio::runtime::Runtime::new().unwrap().block_on(async { 132 + let services = discover(SNAPCAST_SERVICE_NAME); 133 + tokio::pin!(services); 134 + while let Some(info) = services.next().await { 135 + let device = Device::from(info.clone()); 136 + 137 + let mut devs = devices.lock().unwrap(); 138 + if devs.iter().any(|d| d.id == device.id) { 139 + continue; 140 + } 141 + tracing::info!( 142 + "snapcast: discovered server {} ({}:{})", 143 + device.name, 144 + device.ip, 145 + device.port 146 + ); 147 + SimpleBroker::<Device>::publish(device.clone()); 148 + devs.push(device); 120 149 } 121 150 }); 122 151 });
+68 -10
crates/settings/src/lib.rs
··· 17 17 rb::system::set_sleeptimer_duration(0); 18 18 } 19 19 20 + let home = std::env::var("HOME")?; 21 + let default_music_dir = format!("{}/Music", home); 22 + // Ensure the default music directory always exists. 23 + if let Err(e) = std::fs::create_dir_all(&default_music_dir) { 24 + tracing::warn!("could not create default music dir {default_music_dir}: {e}"); 25 + } 26 + 20 27 if let Some(music_dir) = settings.clone().music_dir { 21 - if let Ok(_) = std::fs::metadata(&music_dir) { 22 - std::env::set_var( 23 - "ROCKBOX_LIBRARY", 24 - music_dir.replace("$HOME", &std::env::var("HOME")?), 25 - ); 28 + let resolved = music_dir.replace("$HOME", &home); 29 + if std::fs::metadata(&resolved).is_ok() { 30 + std::env::set_var("ROCKBOX_LIBRARY", &resolved); 31 + } else { 32 + // Configured dir doesn't exist yet; fall back to the default so 33 + // the library scanner has somewhere to point. 34 + std::env::set_var("ROCKBOX_LIBRARY", &default_music_dir); 26 35 } 36 + } else { 37 + std::env::set_var("ROCKBOX_LIBRARY", &default_music_dir); 27 38 } 28 39 29 40 rb::settings::save_settings(settings.clone(), new_settings.is_none()); ··· 98 109 } 99 110 pcm::switch_sink(pcm::PCM_SINK_CHROMECAST); 100 111 } 112 + Some("snapcast_tcp") => { 113 + if let Some(ref host) = settings.snapcast_tcp_host { 114 + let port = settings.snapcast_tcp_port.unwrap_or(4953); 115 + pcm::tcp_set_host(host); 116 + pcm::tcp_set_port(port); 117 + pcm::switch_sink(pcm::PCM_SINK_SNAPCAST_TCP); 118 + tracing::info!("audio output: snapcast_tcp ({}:{})", host, port); 119 + } else { 120 + tracing::warn!( 121 + "audio output: snapcast_tcp selected but no snapcast_tcp_host configured" 122 + ); 123 + } 124 + } 101 125 Some("builtin") | None => { 102 126 tracing::info!("audio output: builtin (SDL)"); 103 127 } ··· 134 158 } 135 159 136 160 pub fn write_settings() -> Result<(), Error> { 137 - let settings = rb::settings::get_global_settings(); 138 - let mut settings: NewGlobalSettings = settings.into(); 161 + let from_c: NewGlobalSettings = rb::settings::get_global_settings().into(); 139 162 let home = std::env::var("HOME")?; 140 163 141 - settings.music_dir = 142 - Some(std::env::var("ROCKBOX_LIBRARY").unwrap_or(format!("{}/Music", home))); 164 + // Start from whatever is already on disk so Rust-only fields 165 + // (audio_output, upnp_*, airplay_*, fifo_path, etc.) are never lost 166 + // when writing back only the C-firmware-owned settings. 167 + let mut settings = read_settings().unwrap_or_default(); 143 168 144 - let content = toml::to_string(&settings)?; 169 + // Only update music_dir when ROCKBOX_LIBRARY was explicitly set at runtime. 170 + // If it was never set (e.g. the directory didn't exist at startup), keep 171 + // whatever the TOML already has to avoid resetting to the default ~/Music. 172 + if let Ok(library) = std::env::var("ROCKBOX_LIBRARY") { 173 + settings.music_dir = Some(library); 174 + } 175 + settings.playlist_shuffle = from_c.playlist_shuffle; 176 + settings.repeat_mode = from_c.repeat_mode; 177 + settings.bass = from_c.bass; 178 + settings.treble = from_c.treble; 179 + settings.bass_cutoff = from_c.bass_cutoff; 180 + settings.treble_cutoff = from_c.treble_cutoff; 181 + settings.crossfade = from_c.crossfade; 182 + settings.fade_on_stop = from_c.fade_on_stop; 183 + settings.fade_in_delay = from_c.fade_in_delay; 184 + settings.fade_in_duration = from_c.fade_in_duration; 185 + settings.fade_out_delay = from_c.fade_out_delay; 186 + settings.fade_out_duration = from_c.fade_out_duration; 187 + settings.fade_out_mixmode = from_c.fade_out_mixmode; 188 + settings.balance = from_c.balance; 189 + settings.stereo_width = from_c.stereo_width; 190 + settings.stereosw_mode = from_c.stereosw_mode; 191 + settings.surround_enabled = from_c.surround_enabled; 192 + settings.surround_balance = from_c.surround_balance; 193 + settings.surround_fx1 = from_c.surround_fx1; 194 + settings.surround_fx2 = from_c.surround_fx2; 195 + settings.party_mode = from_c.party_mode; 196 + settings.channel_config = from_c.channel_config; 197 + settings.player_name = from_c.player_name; 198 + settings.eq_enabled = from_c.eq_enabled; 199 + settings.eq_band_settings = from_c.eq_band_settings; 200 + settings.replaygain_settings = from_c.replaygain_settings; 201 + settings.compressor_settings = from_c.compressor_settings; 145 202 203 + let content = toml::to_string(&settings)?; 146 204 let path = format!("{}/.config/rockbox.org/settings.toml", home); 147 205 std::fs::write(&path, content)?; 148 206 Ok(())
+3
crates/sys/src/lib.rs
··· 1156 1156 fn pcm_upnp_set_http_port(port: c_ushort); 1157 1157 fn pcm_upnp_set_renderer_url(url: *const c_char); 1158 1158 fn pcm_upnp_set_sample_rate(rate: c_uint); 1159 + fn pcm_upnp_reset_renderer(); 1159 1160 fn pcm_chromecast_set_http_port(port: c_ushort); 1160 1161 fn pcm_chromecast_set_device_host(host: *const c_char); 1161 1162 fn pcm_chromecast_set_device_port(port: c_ushort); 1162 1163 fn pcm_chromecast_teardown(); 1164 + fn pcm_tcp_set_host(host: *const c_char); 1165 + fn pcm_tcp_set_port(port: c_ushort); 1163 1166 fn beep_play(frequency: c_uint, duration: c_uint, amplitude: c_uint); 1164 1167 fn dsp_set_crossfeed_type(r#type: c_int); 1165 1168 fn dsp_eq_enable(enable: c_uchar);
+70 -1
crates/sys/src/playback.rs
··· 1 1 use crate::types::{audio_status::AudioStatus, file_position::FilePosition, mp3_entry::Mp3Entry}; 2 + use std::collections::HashMap; 3 + use std::sync::{Mutex, OnceLock}; 4 + 5 + struct MetadataOverride { 6 + title: String, 7 + artist: String, 8 + album: String, 9 + /// Milliseconds; 0 means "don't override". 10 + length_ms: u64, 11 + /// Remote URL of the album art image, empty means "no override". 12 + album_art_url: String, 13 + } 14 + 15 + static METADATA_OVERRIDES: OnceLock<Mutex<HashMap<String, MetadataOverride>>> = OnceLock::new(); 16 + 17 + fn overrides() -> &'static Mutex<HashMap<String, MetadataOverride>> { 18 + METADATA_OVERRIDES.get_or_init(|| Mutex::new(HashMap::new())) 19 + } 20 + 21 + /// Store metadata that will be overlaid on top of whatever the C codec parsed 22 + /// whenever `current_track()` returns a track whose path matches `url`. 23 + /// Call this before or just after starting playback so all callers (HTTP API, 24 + /// gRPC, GraphQL, MPD) immediately see meaningful values. 25 + pub fn set_metadata_override( 26 + url: &str, 27 + title: &str, 28 + artist: &str, 29 + album: &str, 30 + length_ms: u64, 31 + album_art_url: &str, 32 + ) { 33 + overrides().lock().unwrap().insert( 34 + url.to_string(), 35 + MetadataOverride { 36 + title: title.to_string(), 37 + artist: artist.to_string(), 38 + album: album.to_string(), 39 + length_ms, 40 + album_art_url: album_art_url.to_string(), 41 + }, 42 + ); 43 + } 44 + 45 + /// Remove a previously-registered override (e.g. when the stream stops). 46 + pub fn clear_metadata_override(url: &str) { 47 + overrides().lock().unwrap().remove(url); 48 + } 2 49 3 50 pub fn pause() { 4 51 unsafe { ··· 66 113 let track = unsafe { track.as_ref() }; 67 114 68 115 match track { 69 - Some(track) => Some((*track).into()), 116 + Some(track) => { 117 + let mut entry: Mp3Entry = (*track).into(); 118 + if let Ok(map) = overrides().lock() { 119 + if let Some(ov) = map.get(&entry.path) { 120 + if !ov.title.is_empty() { 121 + entry.title = ov.title.clone(); 122 + } 123 + if !ov.artist.is_empty() { 124 + entry.artist = ov.artist.clone(); 125 + } 126 + if !ov.album.is_empty() { 127 + entry.album = ov.album.clone(); 128 + } 129 + if ov.length_ms > 0 { 130 + entry.length = ov.length_ms; 131 + } 132 + if !ov.album_art_url.is_empty() { 133 + entry.album_art = Some(ov.album_art_url.clone()); 134 + } 135 + } 136 + } 137 + Some(entry) 138 + } 70 139 None => None, 71 140 } 72 141 }
+17
crates/sys/src/sound/pcm.rs
··· 8 8 pub const PCM_SINK_SQUEEZELITE: i32 = 3; 9 9 pub const PCM_SINK_UPNP: i32 = 4; 10 10 pub const PCM_SINK_CHROMECAST: i32 = 5; 11 + pub const PCM_SINK_SNAPCAST_TCP: i32 = 6; 11 12 12 13 pub fn apply_settings() { 13 14 unsafe { ··· 101 102 unsafe { crate::pcm_upnp_set_renderer_url(std::ptr::null()) } 102 103 } 103 104 105 + /// Reset renderer-side state so the next play always sends SetAVTransportURI+Play. 106 + /// Call this before switch_sink(PCM_SINK_UPNP) so output switching works live. 107 + pub fn upnp_reset_renderer() { 108 + unsafe { crate::pcm_upnp_reset_renderer() } 109 + } 110 + 104 111 pub fn chromecast_set_http_port(port: u16) { 105 112 unsafe { crate::pcm_chromecast_set_http_port(port) } 106 113 } ··· 118 125 pub fn chromecast_teardown() { 119 126 unsafe { crate::pcm_chromecast_teardown() } 120 127 } 128 + 129 + pub fn tcp_set_host(host: &str) { 130 + let chost = CString::new(host).expect("host must not contain null bytes"); 131 + unsafe { crate::pcm_tcp_set_host(chost.as_ptr()) } 132 + std::mem::forget(chost); 133 + } 134 + 135 + pub fn tcp_set_port(port: u16) { 136 + unsafe { crate::pcm_tcp_set_port(port) } 137 + }
+6
crates/sys/src/types/user_settings.rs
··· 721 721 pub chromecast_port: Option<u16>, 722 722 /// HTTP port for the Chromecast WAV stream (default: 7881) 723 723 pub chromecast_http_port: Option<u16>, 724 + /// Host address of the Snapcast TCP source (required for snapcast_tcp output) 725 + pub snapcast_tcp_host: Option<String>, 726 + /// TCP port for the Snapcast source (default: 4953) 727 + pub snapcast_tcp_port: Option<u16>, 724 728 } 725 729 726 730 impl From<UserSettings> for NewGlobalSettings { ··· 771 775 chromecast_host: None, 772 776 chromecast_port: None, 773 777 chromecast_http_port: None, 778 + snapcast_tcp_host: None, 779 + snapcast_tcp_port: None, 774 780 } 775 781 } 776 782 }
+42
crates/types/src/device.rs
··· 6 6 pub const AIRPLAY_SERVICE_NAME: &str = "_raop._tcp.local."; 7 7 pub const ROCKBOX_SERVICE_NAME: &str = "_rockbox._tcp.local."; 8 8 pub const XBMC_SERVICE_NAME: &str = "_xbmc-jsonrpc-h._tcp.local."; 9 + pub const SNAPCAST_SERVICE_NAME: &str = "_snapcast._tcp.local."; 9 10 10 11 pub const AIRPLAY_DEVICE: &str = "AirPlay"; 11 12 pub const CHROMECAST_DEVICE: &str = "Chromecast"; 12 13 pub const XBMC_DEVICE: &str = "XBMC"; 13 14 pub const MUSIC_PLAYER_DEVICE: &str = "MusicPlayer"; 14 15 pub const UPNP_DLNA_DEVICE: &str = "UPnP/DLNA"; 16 + 17 + // Port for Snapcast TCP source input (not the client streaming port 1704 advertised via mDNS). 18 + pub const SNAPCAST_TCP_SOURCE_PORT: u16 = 4953; 15 19 pub const ROCKBOX_DEVICE: &str = "Rockbox"; 20 + pub const SNAPCAST_DEVICE: &str = "Snapcast"; 16 21 17 22 #[derive(Default, Clone, Serialize, Deserialize)] 18 23 pub struct Device { ··· 120 125 port: srv.get_port(), 121 126 service: srv.get_fullname().to_owned(), 122 127 app: "chromecast".to_owned(), 128 + is_connected: false, 129 + base_url: None, 130 + is_cast_device: true, 131 + is_source_device: false, 132 + is_current_device: false, 133 + }; 134 + } 135 + 136 + if srv.get_fullname().contains(SNAPCAST_SERVICE_NAME) { 137 + let ip = srv 138 + .get_addresses() 139 + .iter() 140 + .next() 141 + .map(|a| a.to_string()) 142 + .unwrap_or_default(); 143 + let name = srv 144 + .get_fullname() 145 + .replace(SNAPCAST_SERVICE_NAME, "") 146 + .trim_matches('.') 147 + .to_owned(); 148 + let name = if name.is_empty() { 149 + SNAPCAST_DEVICE.to_owned() 150 + } else { 151 + name 152 + }; 153 + return Self { 154 + id: format!("snapcast-{}", ip), 155 + name, 156 + host: srv 157 + .get_hostname() 158 + .split_at(srv.get_hostname().len() - 1) 159 + .0 160 + .to_owned(), 161 + ip, 162 + port: SNAPCAST_TCP_SOURCE_PORT, 163 + service: "snapcast".to_owned(), 164 + app: SNAPCAST_DEVICE.to_owned(), 123 165 is_connected: false, 124 166 base_url: None, 125 167 is_cast_device: true,
+1
crates/upnp/Cargo.toml
··· 19 19 tracing = { workspace = true } 20 20 uuid = { workspace = true } 21 21 serde = { workspace = true } 22 + serde_json = { workspace = true } 22 23 socket2 = { workspace = true } 23 24 sqlx = { version = "0.8.2", features = ["runtime-tokio", "sqlite"] } 24 25 bytes = { workspace = true }
+2532 -1255
crates/upnp/src/api/rockbox.v1alpha1.rs
··· 43 43 dead_code, 44 44 missing_docs, 45 45 clippy::wildcard_imports, 46 - clippy::let_unit_value 46 + clippy::let_unit_value, 47 47 )] 48 - use tonic::codegen::http::Uri; 49 48 use tonic::codegen::*; 49 + use tonic::codegen::http::Uri; 50 50 #[derive(Debug, Clone)] 51 51 pub struct BrowseServiceClient<T> { 52 52 inner: tonic::client::Grpc<T>, ··· 90 90 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 91 91 >, 92 92 >, 93 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 94 - Into<StdError> + std::marker::Send + std::marker::Sync, 93 + <T as tonic::codegen::Service< 94 + http::Request<tonic::body::BoxBody>, 95 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 95 96 { 96 97 BrowseServiceClient::new(InterceptedService::new(inner, interceptor)) 97 98 } ··· 129 130 pub async fn tree_get_entries( 130 131 &mut self, 131 132 request: impl tonic::IntoRequest<super::TreeGetEntriesRequest>, 132 - ) -> std::result::Result<tonic::Response<super::TreeGetEntriesResponse>, tonic::Status> 133 - { 134 - self.inner.ready().await.map_err(|e| { 135 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 136 - })?; 133 + ) -> std::result::Result< 134 + tonic::Response<super::TreeGetEntriesResponse>, 135 + tonic::Status, 136 + > { 137 + self.inner 138 + .ready() 139 + .await 140 + .map_err(|e| { 141 + tonic::Status::unknown( 142 + format!("Service was not ready: {}", e.into()), 143 + ) 144 + })?; 137 145 let codec = tonic::codec::ProstCodec::default(); 138 146 let path = http::uri::PathAndQuery::from_static( 139 147 "/rockbox.v1alpha1.BrowseService/TreeGetEntries", 140 148 ); 141 149 let mut req = request.into_request(); 142 - req.extensions_mut().insert(GrpcMethod::new( 143 - "rockbox.v1alpha1.BrowseService", 144 - "TreeGetEntries", 145 - )); 150 + req.extensions_mut() 151 + .insert( 152 + GrpcMethod::new("rockbox.v1alpha1.BrowseService", "TreeGetEntries"), 153 + ); 146 154 self.inner.unary(req, path, codec).await 147 155 } 148 156 } ··· 154 162 dead_code, 155 163 missing_docs, 156 164 clippy::wildcard_imports, 157 - clippy::let_unit_value 165 + clippy::let_unit_value, 158 166 )] 159 167 use tonic::codegen::*; 160 168 /// Generated trait containing gRPC methods that should be implemented for use with BrowseServiceServer. ··· 163 171 async fn tree_get_entries( 164 172 &self, 165 173 request: tonic::Request<super::TreeGetEntriesRequest>, 166 - ) -> std::result::Result<tonic::Response<super::TreeGetEntriesResponse>, tonic::Status>; 174 + ) -> std::result::Result< 175 + tonic::Response<super::TreeGetEntriesResponse>, 176 + tonic::Status, 177 + >; 167 178 } 168 179 #[derive(Debug)] 169 180 pub struct BrowseServiceServer<T> { ··· 186 197 max_encoding_message_size: None, 187 198 } 188 199 } 189 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 200 + pub fn with_interceptor<F>( 201 + inner: T, 202 + interceptor: F, 203 + ) -> InterceptedService<Self, F> 190 204 where 191 205 F: tonic::service::Interceptor, 192 206 { ··· 241 255 "/rockbox.v1alpha1.BrowseService/TreeGetEntries" => { 242 256 #[allow(non_camel_case_types)] 243 257 struct TreeGetEntriesSvc<T: BrowseService>(pub Arc<T>); 244 - impl<T: BrowseService> tonic::server::UnaryService<super::TreeGetEntriesRequest> 245 - for TreeGetEntriesSvc<T> 246 - { 258 + impl< 259 + T: BrowseService, 260 + > tonic::server::UnaryService<super::TreeGetEntriesRequest> 261 + for TreeGetEntriesSvc<T> { 247 262 type Response = super::TreeGetEntriesResponse; 248 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 263 + type Future = BoxFuture< 264 + tonic::Response<Self::Response>, 265 + tonic::Status, 266 + >; 249 267 fn call( 250 268 &mut self, 251 269 request: tonic::Request<super::TreeGetEntriesRequest>, 252 270 ) -> Self::Future { 253 271 let inner = Arc::clone(&self.0); 254 272 let fut = async move { 255 - <T as BrowseService>::tree_get_entries(&inner, request).await 273 + <T as BrowseService>::tree_get_entries(&inner, request) 274 + .await 256 275 }; 257 276 Box::pin(fut) 258 277 } ··· 279 298 }; 280 299 Box::pin(fut) 281 300 } 282 - _ => Box::pin(async move { 283 - let mut response = http::Response::new(empty_body()); 284 - let headers = response.headers_mut(); 285 - headers.insert( 286 - tonic::Status::GRPC_STATUS, 287 - (tonic::Code::Unimplemented as i32).into(), 288 - ); 289 - headers.insert( 290 - http::header::CONTENT_TYPE, 291 - tonic::metadata::GRPC_CONTENT_TYPE, 292 - ); 293 - Ok(response) 294 - }), 301 + _ => { 302 + Box::pin(async move { 303 + let mut response = http::Response::new(empty_body()); 304 + let headers = response.headers_mut(); 305 + headers 306 + .insert( 307 + tonic::Status::GRPC_STATUS, 308 + (tonic::Code::Unimplemented as i32).into(), 309 + ); 310 + headers 311 + .insert( 312 + http::header::CONTENT_TYPE, 313 + tonic::metadata::GRPC_CONTENT_TYPE, 314 + ); 315 + Ok(response) 316 + }) 317 + } 295 318 } 296 319 } 297 320 } ··· 548 571 dead_code, 549 572 missing_docs, 550 573 clippy::wildcard_imports, 551 - clippy::let_unit_value 574 + clippy::let_unit_value, 552 575 )] 553 - use tonic::codegen::http::Uri; 554 576 use tonic::codegen::*; 577 + use tonic::codegen::http::Uri; 555 578 #[derive(Debug, Clone)] 556 579 pub struct LibraryServiceClient<T> { 557 580 inner: tonic::client::Grpc<T>, ··· 595 618 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 596 619 >, 597 620 >, 598 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 599 - Into<StdError> + std::marker::Send + std::marker::Sync, 621 + <T as tonic::codegen::Service< 622 + http::Request<tonic::body::BoxBody>, 623 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 600 624 { 601 625 LibraryServiceClient::new(InterceptedService::new(inner, interceptor)) 602 626 } ··· 634 658 pub async fn get_albums( 635 659 &mut self, 636 660 request: impl tonic::IntoRequest<super::GetAlbumsRequest>, 637 - ) -> std::result::Result<tonic::Response<super::GetAlbumsResponse>, tonic::Status> { 638 - self.inner.ready().await.map_err(|e| { 639 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 640 - })?; 661 + ) -> std::result::Result< 662 + tonic::Response<super::GetAlbumsResponse>, 663 + tonic::Status, 664 + > { 665 + self.inner 666 + .ready() 667 + .await 668 + .map_err(|e| { 669 + tonic::Status::unknown( 670 + format!("Service was not ready: {}", e.into()), 671 + ) 672 + })?; 641 673 let codec = tonic::codec::ProstCodec::default(); 642 - let path = 643 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/GetAlbums"); 674 + let path = http::uri::PathAndQuery::from_static( 675 + "/rockbox.v1alpha1.LibraryService/GetAlbums", 676 + ); 644 677 let mut req = request.into_request(); 645 - req.extensions_mut().insert(GrpcMethod::new( 646 - "rockbox.v1alpha1.LibraryService", 647 - "GetAlbums", 648 - )); 678 + req.extensions_mut() 679 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetAlbums")); 649 680 self.inner.unary(req, path, codec).await 650 681 } 651 682 pub async fn get_artists( 652 683 &mut self, 653 684 request: impl tonic::IntoRequest<super::GetArtistsRequest>, 654 - ) -> std::result::Result<tonic::Response<super::GetArtistsResponse>, tonic::Status> 655 - { 656 - self.inner.ready().await.map_err(|e| { 657 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 658 - })?; 685 + ) -> std::result::Result< 686 + tonic::Response<super::GetArtistsResponse>, 687 + tonic::Status, 688 + > { 689 + self.inner 690 + .ready() 691 + .await 692 + .map_err(|e| { 693 + tonic::Status::unknown( 694 + format!("Service was not ready: {}", e.into()), 695 + ) 696 + })?; 659 697 let codec = tonic::codec::ProstCodec::default(); 660 - let path = 661 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/GetArtists"); 698 + let path = http::uri::PathAndQuery::from_static( 699 + "/rockbox.v1alpha1.LibraryService/GetArtists", 700 + ); 662 701 let mut req = request.into_request(); 663 - req.extensions_mut().insert(GrpcMethod::new( 664 - "rockbox.v1alpha1.LibraryService", 665 - "GetArtists", 666 - )); 702 + req.extensions_mut() 703 + .insert( 704 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetArtists"), 705 + ); 667 706 self.inner.unary(req, path, codec).await 668 707 } 669 708 pub async fn get_tracks( 670 709 &mut self, 671 710 request: impl tonic::IntoRequest<super::GetTracksRequest>, 672 - ) -> std::result::Result<tonic::Response<super::GetTracksResponse>, tonic::Status> { 673 - self.inner.ready().await.map_err(|e| { 674 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 675 - })?; 711 + ) -> std::result::Result< 712 + tonic::Response<super::GetTracksResponse>, 713 + tonic::Status, 714 + > { 715 + self.inner 716 + .ready() 717 + .await 718 + .map_err(|e| { 719 + tonic::Status::unknown( 720 + format!("Service was not ready: {}", e.into()), 721 + ) 722 + })?; 676 723 let codec = tonic::codec::ProstCodec::default(); 677 - let path = 678 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/GetTracks"); 724 + let path = http::uri::PathAndQuery::from_static( 725 + "/rockbox.v1alpha1.LibraryService/GetTracks", 726 + ); 679 727 let mut req = request.into_request(); 680 - req.extensions_mut().insert(GrpcMethod::new( 681 - "rockbox.v1alpha1.LibraryService", 682 - "GetTracks", 683 - )); 728 + req.extensions_mut() 729 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetTracks")); 684 730 self.inner.unary(req, path, codec).await 685 731 } 686 732 pub async fn get_album( 687 733 &mut self, 688 734 request: impl tonic::IntoRequest<super::GetAlbumRequest>, 689 - ) -> std::result::Result<tonic::Response<super::GetAlbumResponse>, tonic::Status> { 690 - self.inner.ready().await.map_err(|e| { 691 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 692 - })?; 735 + ) -> std::result::Result< 736 + tonic::Response<super::GetAlbumResponse>, 737 + tonic::Status, 738 + > { 739 + self.inner 740 + .ready() 741 + .await 742 + .map_err(|e| { 743 + tonic::Status::unknown( 744 + format!("Service was not ready: {}", e.into()), 745 + ) 746 + })?; 693 747 let codec = tonic::codec::ProstCodec::default(); 694 - let path = 695 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/GetAlbum"); 748 + let path = http::uri::PathAndQuery::from_static( 749 + "/rockbox.v1alpha1.LibraryService/GetAlbum", 750 + ); 696 751 let mut req = request.into_request(); 697 - req.extensions_mut().insert(GrpcMethod::new( 698 - "rockbox.v1alpha1.LibraryService", 699 - "GetAlbum", 700 - )); 752 + req.extensions_mut() 753 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetAlbum")); 701 754 self.inner.unary(req, path, codec).await 702 755 } 703 756 pub async fn get_artist( 704 757 &mut self, 705 758 request: impl tonic::IntoRequest<super::GetArtistRequest>, 706 - ) -> std::result::Result<tonic::Response<super::GetArtistResponse>, tonic::Status> { 707 - self.inner.ready().await.map_err(|e| { 708 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 709 - })?; 759 + ) -> std::result::Result< 760 + tonic::Response<super::GetArtistResponse>, 761 + tonic::Status, 762 + > { 763 + self.inner 764 + .ready() 765 + .await 766 + .map_err(|e| { 767 + tonic::Status::unknown( 768 + format!("Service was not ready: {}", e.into()), 769 + ) 770 + })?; 710 771 let codec = tonic::codec::ProstCodec::default(); 711 - let path = 712 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/GetArtist"); 772 + let path = http::uri::PathAndQuery::from_static( 773 + "/rockbox.v1alpha1.LibraryService/GetArtist", 774 + ); 713 775 let mut req = request.into_request(); 714 - req.extensions_mut().insert(GrpcMethod::new( 715 - "rockbox.v1alpha1.LibraryService", 716 - "GetArtist", 717 - )); 776 + req.extensions_mut() 777 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetArtist")); 718 778 self.inner.unary(req, path, codec).await 719 779 } 720 780 pub async fn get_track( 721 781 &mut self, 722 782 request: impl tonic::IntoRequest<super::GetTrackRequest>, 723 - ) -> std::result::Result<tonic::Response<super::GetTrackResponse>, tonic::Status> { 724 - self.inner.ready().await.map_err(|e| { 725 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 726 - })?; 783 + ) -> std::result::Result< 784 + tonic::Response<super::GetTrackResponse>, 785 + tonic::Status, 786 + > { 787 + self.inner 788 + .ready() 789 + .await 790 + .map_err(|e| { 791 + tonic::Status::unknown( 792 + format!("Service was not ready: {}", e.into()), 793 + ) 794 + })?; 727 795 let codec = tonic::codec::ProstCodec::default(); 728 - let path = 729 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/GetTrack"); 796 + let path = http::uri::PathAndQuery::from_static( 797 + "/rockbox.v1alpha1.LibraryService/GetTrack", 798 + ); 730 799 let mut req = request.into_request(); 731 - req.extensions_mut().insert(GrpcMethod::new( 732 - "rockbox.v1alpha1.LibraryService", 733 - "GetTrack", 734 - )); 800 + req.extensions_mut() 801 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetTrack")); 735 802 self.inner.unary(req, path, codec).await 736 803 } 737 804 pub async fn like_track( 738 805 &mut self, 739 806 request: impl tonic::IntoRequest<super::LikeTrackRequest>, 740 - ) -> std::result::Result<tonic::Response<super::LikeTrackResponse>, tonic::Status> { 741 - self.inner.ready().await.map_err(|e| { 742 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 743 - })?; 807 + ) -> std::result::Result< 808 + tonic::Response<super::LikeTrackResponse>, 809 + tonic::Status, 810 + > { 811 + self.inner 812 + .ready() 813 + .await 814 + .map_err(|e| { 815 + tonic::Status::unknown( 816 + format!("Service was not ready: {}", e.into()), 817 + ) 818 + })?; 744 819 let codec = tonic::codec::ProstCodec::default(); 745 - let path = 746 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/LikeTrack"); 820 + let path = http::uri::PathAndQuery::from_static( 821 + "/rockbox.v1alpha1.LibraryService/LikeTrack", 822 + ); 747 823 let mut req = request.into_request(); 748 - req.extensions_mut().insert(GrpcMethod::new( 749 - "rockbox.v1alpha1.LibraryService", 750 - "LikeTrack", 751 - )); 824 + req.extensions_mut() 825 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "LikeTrack")); 752 826 self.inner.unary(req, path, codec).await 753 827 } 754 828 pub async fn unlike_track( 755 829 &mut self, 756 830 request: impl tonic::IntoRequest<super::UnlikeTrackRequest>, 757 - ) -> std::result::Result<tonic::Response<super::UnlikeTrackResponse>, tonic::Status> 758 - { 759 - self.inner.ready().await.map_err(|e| { 760 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 761 - })?; 831 + ) -> std::result::Result< 832 + tonic::Response<super::UnlikeTrackResponse>, 833 + tonic::Status, 834 + > { 835 + self.inner 836 + .ready() 837 + .await 838 + .map_err(|e| { 839 + tonic::Status::unknown( 840 + format!("Service was not ready: {}", e.into()), 841 + ) 842 + })?; 762 843 let codec = tonic::codec::ProstCodec::default(); 763 844 let path = http::uri::PathAndQuery::from_static( 764 845 "/rockbox.v1alpha1.LibraryService/UnlikeTrack", 765 846 ); 766 847 let mut req = request.into_request(); 767 - req.extensions_mut().insert(GrpcMethod::new( 768 - "rockbox.v1alpha1.LibraryService", 769 - "UnlikeTrack", 770 - )); 848 + req.extensions_mut() 849 + .insert( 850 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "UnlikeTrack"), 851 + ); 771 852 self.inner.unary(req, path, codec).await 772 853 } 773 854 pub async fn like_album( 774 855 &mut self, 775 856 request: impl tonic::IntoRequest<super::LikeAlbumRequest>, 776 - ) -> std::result::Result<tonic::Response<super::LikeAlbumResponse>, tonic::Status> { 777 - self.inner.ready().await.map_err(|e| { 778 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 779 - })?; 857 + ) -> std::result::Result< 858 + tonic::Response<super::LikeAlbumResponse>, 859 + tonic::Status, 860 + > { 861 + self.inner 862 + .ready() 863 + .await 864 + .map_err(|e| { 865 + tonic::Status::unknown( 866 + format!("Service was not ready: {}", e.into()), 867 + ) 868 + })?; 780 869 let codec = tonic::codec::ProstCodec::default(); 781 - let path = 782 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/LikeAlbum"); 870 + let path = http::uri::PathAndQuery::from_static( 871 + "/rockbox.v1alpha1.LibraryService/LikeAlbum", 872 + ); 783 873 let mut req = request.into_request(); 784 - req.extensions_mut().insert(GrpcMethod::new( 785 - "rockbox.v1alpha1.LibraryService", 786 - "LikeAlbum", 787 - )); 874 + req.extensions_mut() 875 + .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "LikeAlbum")); 788 876 self.inner.unary(req, path, codec).await 789 877 } 790 878 pub async fn unlike_album( 791 879 &mut self, 792 880 request: impl tonic::IntoRequest<super::UnlikeAlbumRequest>, 793 - ) -> std::result::Result<tonic::Response<super::UnlikeAlbumResponse>, tonic::Status> 794 - { 795 - self.inner.ready().await.map_err(|e| { 796 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 797 - })?; 881 + ) -> std::result::Result< 882 + tonic::Response<super::UnlikeAlbumResponse>, 883 + tonic::Status, 884 + > { 885 + self.inner 886 + .ready() 887 + .await 888 + .map_err(|e| { 889 + tonic::Status::unknown( 890 + format!("Service was not ready: {}", e.into()), 891 + ) 892 + })?; 798 893 let codec = tonic::codec::ProstCodec::default(); 799 894 let path = http::uri::PathAndQuery::from_static( 800 895 "/rockbox.v1alpha1.LibraryService/UnlikeAlbum", 801 896 ); 802 897 let mut req = request.into_request(); 803 - req.extensions_mut().insert(GrpcMethod::new( 804 - "rockbox.v1alpha1.LibraryService", 805 - "UnlikeAlbum", 806 - )); 898 + req.extensions_mut() 899 + .insert( 900 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "UnlikeAlbum"), 901 + ); 807 902 self.inner.unary(req, path, codec).await 808 903 } 809 904 pub async fn get_liked_tracks( 810 905 &mut self, 811 906 request: impl tonic::IntoRequest<super::GetLikedTracksRequest>, 812 - ) -> std::result::Result<tonic::Response<super::GetLikedTracksResponse>, tonic::Status> 813 - { 814 - self.inner.ready().await.map_err(|e| { 815 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 816 - })?; 907 + ) -> std::result::Result< 908 + tonic::Response<super::GetLikedTracksResponse>, 909 + tonic::Status, 910 + > { 911 + self.inner 912 + .ready() 913 + .await 914 + .map_err(|e| { 915 + tonic::Status::unknown( 916 + format!("Service was not ready: {}", e.into()), 917 + ) 918 + })?; 817 919 let codec = tonic::codec::ProstCodec::default(); 818 920 let path = http::uri::PathAndQuery::from_static( 819 921 "/rockbox.v1alpha1.LibraryService/GetLikedTracks", 820 922 ); 821 923 let mut req = request.into_request(); 822 - req.extensions_mut().insert(GrpcMethod::new( 823 - "rockbox.v1alpha1.LibraryService", 824 - "GetLikedTracks", 825 - )); 924 + req.extensions_mut() 925 + .insert( 926 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetLikedTracks"), 927 + ); 826 928 self.inner.unary(req, path, codec).await 827 929 } 828 930 pub async fn get_liked_albums( 829 931 &mut self, 830 932 request: impl tonic::IntoRequest<super::GetLikedAlbumsRequest>, 831 - ) -> std::result::Result<tonic::Response<super::GetLikedAlbumsResponse>, tonic::Status> 832 - { 833 - self.inner.ready().await.map_err(|e| { 834 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 835 - })?; 933 + ) -> std::result::Result< 934 + tonic::Response<super::GetLikedAlbumsResponse>, 935 + tonic::Status, 936 + > { 937 + self.inner 938 + .ready() 939 + .await 940 + .map_err(|e| { 941 + tonic::Status::unknown( 942 + format!("Service was not ready: {}", e.into()), 943 + ) 944 + })?; 836 945 let codec = tonic::codec::ProstCodec::default(); 837 946 let path = http::uri::PathAndQuery::from_static( 838 947 "/rockbox.v1alpha1.LibraryService/GetLikedAlbums", 839 948 ); 840 949 let mut req = request.into_request(); 841 - req.extensions_mut().insert(GrpcMethod::new( 842 - "rockbox.v1alpha1.LibraryService", 843 - "GetLikedAlbums", 844 - )); 950 + req.extensions_mut() 951 + .insert( 952 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "GetLikedAlbums"), 953 + ); 845 954 self.inner.unary(req, path, codec).await 846 955 } 847 956 pub async fn scan_library( 848 957 &mut self, 849 958 request: impl tonic::IntoRequest<super::ScanLibraryRequest>, 850 - ) -> std::result::Result<tonic::Response<super::ScanLibraryResponse>, tonic::Status> 851 - { 852 - self.inner.ready().await.map_err(|e| { 853 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 854 - })?; 959 + ) -> std::result::Result< 960 + tonic::Response<super::ScanLibraryResponse>, 961 + tonic::Status, 962 + > { 963 + self.inner 964 + .ready() 965 + .await 966 + .map_err(|e| { 967 + tonic::Status::unknown( 968 + format!("Service was not ready: {}", e.into()), 969 + ) 970 + })?; 855 971 let codec = tonic::codec::ProstCodec::default(); 856 972 let path = http::uri::PathAndQuery::from_static( 857 973 "/rockbox.v1alpha1.LibraryService/ScanLibrary", 858 974 ); 859 975 let mut req = request.into_request(); 860 - req.extensions_mut().insert(GrpcMethod::new( 861 - "rockbox.v1alpha1.LibraryService", 862 - "ScanLibrary", 863 - )); 976 + req.extensions_mut() 977 + .insert( 978 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "ScanLibrary"), 979 + ); 864 980 self.inner.unary(req, path, codec).await 865 981 } 866 982 pub async fn stream_library( ··· 870 986 tonic::Response<tonic::codec::Streaming<super::StreamLibraryResponse>>, 871 987 tonic::Status, 872 988 > { 873 - self.inner.ready().await.map_err(|e| { 874 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 875 - })?; 989 + self.inner 990 + .ready() 991 + .await 992 + .map_err(|e| { 993 + tonic::Status::unknown( 994 + format!("Service was not ready: {}", e.into()), 995 + ) 996 + })?; 876 997 let codec = tonic::codec::ProstCodec::default(); 877 998 let path = http::uri::PathAndQuery::from_static( 878 999 "/rockbox.v1alpha1.LibraryService/StreamLibrary", 879 1000 ); 880 1001 let mut req = request.into_request(); 881 - req.extensions_mut().insert(GrpcMethod::new( 882 - "rockbox.v1alpha1.LibraryService", 883 - "StreamLibrary", 884 - )); 1002 + req.extensions_mut() 1003 + .insert( 1004 + GrpcMethod::new("rockbox.v1alpha1.LibraryService", "StreamLibrary"), 1005 + ); 885 1006 self.inner.server_streaming(req, path, codec).await 886 1007 } 887 1008 pub async fn search( 888 1009 &mut self, 889 1010 request: impl tonic::IntoRequest<super::SearchRequest>, 890 1011 ) -> std::result::Result<tonic::Response<super::SearchResponse>, tonic::Status> { 891 - self.inner.ready().await.map_err(|e| { 892 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 893 - })?; 1012 + self.inner 1013 + .ready() 1014 + .await 1015 + .map_err(|e| { 1016 + tonic::Status::unknown( 1017 + format!("Service was not ready: {}", e.into()), 1018 + ) 1019 + })?; 894 1020 let codec = tonic::codec::ProstCodec::default(); 895 - let path = 896 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.LibraryService/Search"); 1021 + let path = http::uri::PathAndQuery::from_static( 1022 + "/rockbox.v1alpha1.LibraryService/Search", 1023 + ); 897 1024 let mut req = request.into_request(); 898 1025 req.extensions_mut() 899 1026 .insert(GrpcMethod::new("rockbox.v1alpha1.LibraryService", "Search")); ··· 908 1035 dead_code, 909 1036 missing_docs, 910 1037 clippy::wildcard_imports, 911 - clippy::let_unit_value 1038 + clippy::let_unit_value, 912 1039 )] 913 1040 use tonic::codegen::*; 914 1041 /// Generated trait containing gRPC methods that should be implemented for use with LibraryServiceServer. ··· 917 1044 async fn get_albums( 918 1045 &self, 919 1046 request: tonic::Request<super::GetAlbumsRequest>, 920 - ) -> std::result::Result<tonic::Response<super::GetAlbumsResponse>, tonic::Status>; 1047 + ) -> std::result::Result< 1048 + tonic::Response<super::GetAlbumsResponse>, 1049 + tonic::Status, 1050 + >; 921 1051 async fn get_artists( 922 1052 &self, 923 1053 request: tonic::Request<super::GetArtistsRequest>, 924 - ) -> std::result::Result<tonic::Response<super::GetArtistsResponse>, tonic::Status>; 1054 + ) -> std::result::Result< 1055 + tonic::Response<super::GetArtistsResponse>, 1056 + tonic::Status, 1057 + >; 925 1058 async fn get_tracks( 926 1059 &self, 927 1060 request: tonic::Request<super::GetTracksRequest>, 928 - ) -> std::result::Result<tonic::Response<super::GetTracksResponse>, tonic::Status>; 1061 + ) -> std::result::Result< 1062 + tonic::Response<super::GetTracksResponse>, 1063 + tonic::Status, 1064 + >; 929 1065 async fn get_album( 930 1066 &self, 931 1067 request: tonic::Request<super::GetAlbumRequest>, 932 - ) -> std::result::Result<tonic::Response<super::GetAlbumResponse>, tonic::Status>; 1068 + ) -> std::result::Result< 1069 + tonic::Response<super::GetAlbumResponse>, 1070 + tonic::Status, 1071 + >; 933 1072 async fn get_artist( 934 1073 &self, 935 1074 request: tonic::Request<super::GetArtistRequest>, 936 - ) -> std::result::Result<tonic::Response<super::GetArtistResponse>, tonic::Status>; 1075 + ) -> std::result::Result< 1076 + tonic::Response<super::GetArtistResponse>, 1077 + tonic::Status, 1078 + >; 937 1079 async fn get_track( 938 1080 &self, 939 1081 request: tonic::Request<super::GetTrackRequest>, 940 - ) -> std::result::Result<tonic::Response<super::GetTrackResponse>, tonic::Status>; 1082 + ) -> std::result::Result< 1083 + tonic::Response<super::GetTrackResponse>, 1084 + tonic::Status, 1085 + >; 941 1086 async fn like_track( 942 1087 &self, 943 1088 request: tonic::Request<super::LikeTrackRequest>, 944 - ) -> std::result::Result<tonic::Response<super::LikeTrackResponse>, tonic::Status>; 1089 + ) -> std::result::Result< 1090 + tonic::Response<super::LikeTrackResponse>, 1091 + tonic::Status, 1092 + >; 945 1093 async fn unlike_track( 946 1094 &self, 947 1095 request: tonic::Request<super::UnlikeTrackRequest>, 948 - ) -> std::result::Result<tonic::Response<super::UnlikeTrackResponse>, tonic::Status>; 1096 + ) -> std::result::Result< 1097 + tonic::Response<super::UnlikeTrackResponse>, 1098 + tonic::Status, 1099 + >; 949 1100 async fn like_album( 950 1101 &self, 951 1102 request: tonic::Request<super::LikeAlbumRequest>, 952 - ) -> std::result::Result<tonic::Response<super::LikeAlbumResponse>, tonic::Status>; 1103 + ) -> std::result::Result< 1104 + tonic::Response<super::LikeAlbumResponse>, 1105 + tonic::Status, 1106 + >; 953 1107 async fn unlike_album( 954 1108 &self, 955 1109 request: tonic::Request<super::UnlikeAlbumRequest>, 956 - ) -> std::result::Result<tonic::Response<super::UnlikeAlbumResponse>, tonic::Status>; 1110 + ) -> std::result::Result< 1111 + tonic::Response<super::UnlikeAlbumResponse>, 1112 + tonic::Status, 1113 + >; 957 1114 async fn get_liked_tracks( 958 1115 &self, 959 1116 request: tonic::Request<super::GetLikedTracksRequest>, 960 - ) -> std::result::Result<tonic::Response<super::GetLikedTracksResponse>, tonic::Status>; 1117 + ) -> std::result::Result< 1118 + tonic::Response<super::GetLikedTracksResponse>, 1119 + tonic::Status, 1120 + >; 961 1121 async fn get_liked_albums( 962 1122 &self, 963 1123 request: tonic::Request<super::GetLikedAlbumsRequest>, 964 - ) -> std::result::Result<tonic::Response<super::GetLikedAlbumsResponse>, tonic::Status>; 1124 + ) -> std::result::Result< 1125 + tonic::Response<super::GetLikedAlbumsResponse>, 1126 + tonic::Status, 1127 + >; 965 1128 async fn scan_library( 966 1129 &self, 967 1130 request: tonic::Request<super::ScanLibraryRequest>, 968 - ) -> std::result::Result<tonic::Response<super::ScanLibraryResponse>, tonic::Status>; 1131 + ) -> std::result::Result< 1132 + tonic::Response<super::ScanLibraryResponse>, 1133 + tonic::Status, 1134 + >; 969 1135 /// Server streaming response type for the StreamLibrary method. 970 1136 type StreamLibraryStream: tonic::codegen::tokio_stream::Stream< 971 1137 Item = std::result::Result<super::StreamLibraryResponse, tonic::Status>, 972 - > + std::marker::Send 1138 + > 1139 + + std::marker::Send 973 1140 + 'static; 974 1141 async fn stream_library( 975 1142 &self, 976 1143 request: tonic::Request<super::StreamLibraryRequest>, 977 - ) -> std::result::Result<tonic::Response<Self::StreamLibraryStream>, tonic::Status>; 1144 + ) -> std::result::Result< 1145 + tonic::Response<Self::StreamLibraryStream>, 1146 + tonic::Status, 1147 + >; 978 1148 async fn search( 979 1149 &self, 980 1150 request: tonic::Request<super::SearchRequest>, ··· 1001 1171 max_encoding_message_size: None, 1002 1172 } 1003 1173 } 1004 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 1174 + pub fn with_interceptor<F>( 1175 + inner: T, 1176 + interceptor: F, 1177 + ) -> InterceptedService<Self, F> 1005 1178 where 1006 1179 F: tonic::service::Interceptor, 1007 1180 { ··· 1056 1229 "/rockbox.v1alpha1.LibraryService/GetAlbums" => { 1057 1230 #[allow(non_camel_case_types)] 1058 1231 struct GetAlbumsSvc<T: LibraryService>(pub Arc<T>); 1059 - impl<T: LibraryService> tonic::server::UnaryService<super::GetAlbumsRequest> for GetAlbumsSvc<T> { 1232 + impl< 1233 + T: LibraryService, 1234 + > tonic::server::UnaryService<super::GetAlbumsRequest> 1235 + for GetAlbumsSvc<T> { 1060 1236 type Response = super::GetAlbumsResponse; 1061 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1237 + type Future = BoxFuture< 1238 + tonic::Response<Self::Response>, 1239 + tonic::Status, 1240 + >; 1062 1241 fn call( 1063 1242 &mut self, 1064 1243 request: tonic::Request<super::GetAlbumsRequest>, ··· 1095 1274 "/rockbox.v1alpha1.LibraryService/GetArtists" => { 1096 1275 #[allow(non_camel_case_types)] 1097 1276 struct GetArtistsSvc<T: LibraryService>(pub Arc<T>); 1098 - impl<T: LibraryService> tonic::server::UnaryService<super::GetArtistsRequest> for GetArtistsSvc<T> { 1277 + impl< 1278 + T: LibraryService, 1279 + > tonic::server::UnaryService<super::GetArtistsRequest> 1280 + for GetArtistsSvc<T> { 1099 1281 type Response = super::GetArtistsResponse; 1100 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1282 + type Future = BoxFuture< 1283 + tonic::Response<Self::Response>, 1284 + tonic::Status, 1285 + >; 1101 1286 fn call( 1102 1287 &mut self, 1103 1288 request: tonic::Request<super::GetArtistsRequest>, ··· 1134 1319 "/rockbox.v1alpha1.LibraryService/GetTracks" => { 1135 1320 #[allow(non_camel_case_types)] 1136 1321 struct GetTracksSvc<T: LibraryService>(pub Arc<T>); 1137 - impl<T: LibraryService> tonic::server::UnaryService<super::GetTracksRequest> for GetTracksSvc<T> { 1322 + impl< 1323 + T: LibraryService, 1324 + > tonic::server::UnaryService<super::GetTracksRequest> 1325 + for GetTracksSvc<T> { 1138 1326 type Response = super::GetTracksResponse; 1139 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1327 + type Future = BoxFuture< 1328 + tonic::Response<Self::Response>, 1329 + tonic::Status, 1330 + >; 1140 1331 fn call( 1141 1332 &mut self, 1142 1333 request: tonic::Request<super::GetTracksRequest>, ··· 1173 1364 "/rockbox.v1alpha1.LibraryService/GetAlbum" => { 1174 1365 #[allow(non_camel_case_types)] 1175 1366 struct GetAlbumSvc<T: LibraryService>(pub Arc<T>); 1176 - impl<T: LibraryService> tonic::server::UnaryService<super::GetAlbumRequest> for GetAlbumSvc<T> { 1367 + impl< 1368 + T: LibraryService, 1369 + > tonic::server::UnaryService<super::GetAlbumRequest> 1370 + for GetAlbumSvc<T> { 1177 1371 type Response = super::GetAlbumResponse; 1178 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1372 + type Future = BoxFuture< 1373 + tonic::Response<Self::Response>, 1374 + tonic::Status, 1375 + >; 1179 1376 fn call( 1180 1377 &mut self, 1181 1378 request: tonic::Request<super::GetAlbumRequest>, ··· 1212 1409 "/rockbox.v1alpha1.LibraryService/GetArtist" => { 1213 1410 #[allow(non_camel_case_types)] 1214 1411 struct GetArtistSvc<T: LibraryService>(pub Arc<T>); 1215 - impl<T: LibraryService> tonic::server::UnaryService<super::GetArtistRequest> for GetArtistSvc<T> { 1412 + impl< 1413 + T: LibraryService, 1414 + > tonic::server::UnaryService<super::GetArtistRequest> 1415 + for GetArtistSvc<T> { 1216 1416 type Response = super::GetArtistResponse; 1217 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1417 + type Future = BoxFuture< 1418 + tonic::Response<Self::Response>, 1419 + tonic::Status, 1420 + >; 1218 1421 fn call( 1219 1422 &mut self, 1220 1423 request: tonic::Request<super::GetArtistRequest>, ··· 1251 1454 "/rockbox.v1alpha1.LibraryService/GetTrack" => { 1252 1455 #[allow(non_camel_case_types)] 1253 1456 struct GetTrackSvc<T: LibraryService>(pub Arc<T>); 1254 - impl<T: LibraryService> tonic::server::UnaryService<super::GetTrackRequest> for GetTrackSvc<T> { 1457 + impl< 1458 + T: LibraryService, 1459 + > tonic::server::UnaryService<super::GetTrackRequest> 1460 + for GetTrackSvc<T> { 1255 1461 type Response = super::GetTrackResponse; 1256 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1462 + type Future = BoxFuture< 1463 + tonic::Response<Self::Response>, 1464 + tonic::Status, 1465 + >; 1257 1466 fn call( 1258 1467 &mut self, 1259 1468 request: tonic::Request<super::GetTrackRequest>, ··· 1290 1499 "/rockbox.v1alpha1.LibraryService/LikeTrack" => { 1291 1500 #[allow(non_camel_case_types)] 1292 1501 struct LikeTrackSvc<T: LibraryService>(pub Arc<T>); 1293 - impl<T: LibraryService> tonic::server::UnaryService<super::LikeTrackRequest> for LikeTrackSvc<T> { 1502 + impl< 1503 + T: LibraryService, 1504 + > tonic::server::UnaryService<super::LikeTrackRequest> 1505 + for LikeTrackSvc<T> { 1294 1506 type Response = super::LikeTrackResponse; 1295 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1507 + type Future = BoxFuture< 1508 + tonic::Response<Self::Response>, 1509 + tonic::Status, 1510 + >; 1296 1511 fn call( 1297 1512 &mut self, 1298 1513 request: tonic::Request<super::LikeTrackRequest>, ··· 1329 1544 "/rockbox.v1alpha1.LibraryService/UnlikeTrack" => { 1330 1545 #[allow(non_camel_case_types)] 1331 1546 struct UnlikeTrackSvc<T: LibraryService>(pub Arc<T>); 1332 - impl<T: LibraryService> tonic::server::UnaryService<super::UnlikeTrackRequest> 1333 - for UnlikeTrackSvc<T> 1334 - { 1547 + impl< 1548 + T: LibraryService, 1549 + > tonic::server::UnaryService<super::UnlikeTrackRequest> 1550 + for UnlikeTrackSvc<T> { 1335 1551 type Response = super::UnlikeTrackResponse; 1336 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1552 + type Future = BoxFuture< 1553 + tonic::Response<Self::Response>, 1554 + tonic::Status, 1555 + >; 1337 1556 fn call( 1338 1557 &mut self, 1339 1558 request: tonic::Request<super::UnlikeTrackRequest>, ··· 1370 1589 "/rockbox.v1alpha1.LibraryService/LikeAlbum" => { 1371 1590 #[allow(non_camel_case_types)] 1372 1591 struct LikeAlbumSvc<T: LibraryService>(pub Arc<T>); 1373 - impl<T: LibraryService> tonic::server::UnaryService<super::LikeAlbumRequest> for LikeAlbumSvc<T> { 1592 + impl< 1593 + T: LibraryService, 1594 + > tonic::server::UnaryService<super::LikeAlbumRequest> 1595 + for LikeAlbumSvc<T> { 1374 1596 type Response = super::LikeAlbumResponse; 1375 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1597 + type Future = BoxFuture< 1598 + tonic::Response<Self::Response>, 1599 + tonic::Status, 1600 + >; 1376 1601 fn call( 1377 1602 &mut self, 1378 1603 request: tonic::Request<super::LikeAlbumRequest>, ··· 1409 1634 "/rockbox.v1alpha1.LibraryService/UnlikeAlbum" => { 1410 1635 #[allow(non_camel_case_types)] 1411 1636 struct UnlikeAlbumSvc<T: LibraryService>(pub Arc<T>); 1412 - impl<T: LibraryService> tonic::server::UnaryService<super::UnlikeAlbumRequest> 1413 - for UnlikeAlbumSvc<T> 1414 - { 1637 + impl< 1638 + T: LibraryService, 1639 + > tonic::server::UnaryService<super::UnlikeAlbumRequest> 1640 + for UnlikeAlbumSvc<T> { 1415 1641 type Response = super::UnlikeAlbumResponse; 1416 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1642 + type Future = BoxFuture< 1643 + tonic::Response<Self::Response>, 1644 + tonic::Status, 1645 + >; 1417 1646 fn call( 1418 1647 &mut self, 1419 1648 request: tonic::Request<super::UnlikeAlbumRequest>, ··· 1450 1679 "/rockbox.v1alpha1.LibraryService/GetLikedTracks" => { 1451 1680 #[allow(non_camel_case_types)] 1452 1681 struct GetLikedTracksSvc<T: LibraryService>(pub Arc<T>); 1453 - impl<T: LibraryService> 1454 - tonic::server::UnaryService<super::GetLikedTracksRequest> 1455 - for GetLikedTracksSvc<T> 1456 - { 1682 + impl< 1683 + T: LibraryService, 1684 + > tonic::server::UnaryService<super::GetLikedTracksRequest> 1685 + for GetLikedTracksSvc<T> { 1457 1686 type Response = super::GetLikedTracksResponse; 1458 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1687 + type Future = BoxFuture< 1688 + tonic::Response<Self::Response>, 1689 + tonic::Status, 1690 + >; 1459 1691 fn call( 1460 1692 &mut self, 1461 1693 request: tonic::Request<super::GetLikedTracksRequest>, 1462 1694 ) -> Self::Future { 1463 1695 let inner = Arc::clone(&self.0); 1464 1696 let fut = async move { 1465 - <T as LibraryService>::get_liked_tracks(&inner, request).await 1697 + <T as LibraryService>::get_liked_tracks(&inner, request) 1698 + .await 1466 1699 }; 1467 1700 Box::pin(fut) 1468 1701 } ··· 1492 1725 "/rockbox.v1alpha1.LibraryService/GetLikedAlbums" => { 1493 1726 #[allow(non_camel_case_types)] 1494 1727 struct GetLikedAlbumsSvc<T: LibraryService>(pub Arc<T>); 1495 - impl<T: LibraryService> 1496 - tonic::server::UnaryService<super::GetLikedAlbumsRequest> 1497 - for GetLikedAlbumsSvc<T> 1498 - { 1728 + impl< 1729 + T: LibraryService, 1730 + > tonic::server::UnaryService<super::GetLikedAlbumsRequest> 1731 + for GetLikedAlbumsSvc<T> { 1499 1732 type Response = super::GetLikedAlbumsResponse; 1500 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1733 + type Future = BoxFuture< 1734 + tonic::Response<Self::Response>, 1735 + tonic::Status, 1736 + >; 1501 1737 fn call( 1502 1738 &mut self, 1503 1739 request: tonic::Request<super::GetLikedAlbumsRequest>, 1504 1740 ) -> Self::Future { 1505 1741 let inner = Arc::clone(&self.0); 1506 1742 let fut = async move { 1507 - <T as LibraryService>::get_liked_albums(&inner, request).await 1743 + <T as LibraryService>::get_liked_albums(&inner, request) 1744 + .await 1508 1745 }; 1509 1746 Box::pin(fut) 1510 1747 } ··· 1534 1771 "/rockbox.v1alpha1.LibraryService/ScanLibrary" => { 1535 1772 #[allow(non_camel_case_types)] 1536 1773 struct ScanLibrarySvc<T: LibraryService>(pub Arc<T>); 1537 - impl<T: LibraryService> tonic::server::UnaryService<super::ScanLibraryRequest> 1538 - for ScanLibrarySvc<T> 1539 - { 1774 + impl< 1775 + T: LibraryService, 1776 + > tonic::server::UnaryService<super::ScanLibraryRequest> 1777 + for ScanLibrarySvc<T> { 1540 1778 type Response = super::ScanLibraryResponse; 1541 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1779 + type Future = BoxFuture< 1780 + tonic::Response<Self::Response>, 1781 + tonic::Status, 1782 + >; 1542 1783 fn call( 1543 1784 &mut self, 1544 1785 request: tonic::Request<super::ScanLibraryRequest>, ··· 1575 1816 "/rockbox.v1alpha1.LibraryService/StreamLibrary" => { 1576 1817 #[allow(non_camel_case_types)] 1577 1818 struct StreamLibrarySvc<T: LibraryService>(pub Arc<T>); 1578 - impl<T: LibraryService> 1579 - tonic::server::ServerStreamingService<super::StreamLibraryRequest> 1580 - for StreamLibrarySvc<T> 1581 - { 1819 + impl< 1820 + T: LibraryService, 1821 + > tonic::server::ServerStreamingService<super::StreamLibraryRequest> 1822 + for StreamLibrarySvc<T> { 1582 1823 type Response = super::StreamLibraryResponse; 1583 1824 type ResponseStream = T::StreamLibraryStream; 1584 - type Future = 1585 - BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>; 1825 + type Future = BoxFuture< 1826 + tonic::Response<Self::ResponseStream>, 1827 + tonic::Status, 1828 + >; 1586 1829 fn call( 1587 1830 &mut self, 1588 1831 request: tonic::Request<super::StreamLibraryRequest>, ··· 1619 1862 "/rockbox.v1alpha1.LibraryService/Search" => { 1620 1863 #[allow(non_camel_case_types)] 1621 1864 struct SearchSvc<T: LibraryService>(pub Arc<T>); 1622 - impl<T: LibraryService> tonic::server::UnaryService<super::SearchRequest> for SearchSvc<T> { 1865 + impl< 1866 + T: LibraryService, 1867 + > tonic::server::UnaryService<super::SearchRequest> 1868 + for SearchSvc<T> { 1623 1869 type Response = super::SearchResponse; 1624 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 1870 + type Future = BoxFuture< 1871 + tonic::Response<Self::Response>, 1872 + tonic::Status, 1873 + >; 1625 1874 fn call( 1626 1875 &mut self, 1627 1876 request: tonic::Request<super::SearchRequest>, 1628 1877 ) -> Self::Future { 1629 1878 let inner = Arc::clone(&self.0); 1630 - let fut = 1631 - async move { <T as LibraryService>::search(&inner, request).await }; 1879 + let fut = async move { 1880 + <T as LibraryService>::search(&inner, request).await 1881 + }; 1632 1882 Box::pin(fut) 1633 1883 } 1634 1884 } ··· 1654 1904 }; 1655 1905 Box::pin(fut) 1656 1906 } 1657 - _ => Box::pin(async move { 1658 - let mut response = http::Response::new(empty_body()); 1659 - let headers = response.headers_mut(); 1660 - headers.insert( 1661 - tonic::Status::GRPC_STATUS, 1662 - (tonic::Code::Unimplemented as i32).into(), 1663 - ); 1664 - headers.insert( 1665 - http::header::CONTENT_TYPE, 1666 - tonic::metadata::GRPC_CONTENT_TYPE, 1667 - ); 1668 - Ok(response) 1669 - }), 1907 + _ => { 1908 + Box::pin(async move { 1909 + let mut response = http::Response::new(empty_body()); 1910 + let headers = response.headers_mut(); 1911 + headers 1912 + .insert( 1913 + tonic::Status::GRPC_STATUS, 1914 + (tonic::Code::Unimplemented as i32).into(), 1915 + ); 1916 + headers 1917 + .insert( 1918 + http::header::CONTENT_TYPE, 1919 + tonic::metadata::GRPC_CONTENT_TYPE, 1920 + ); 1921 + Ok(response) 1922 + }) 1923 + } 1670 1924 } 1671 1925 } 1672 1926 } ··· 1695 1949 dead_code, 1696 1950 missing_docs, 1697 1951 clippy::wildcard_imports, 1698 - clippy::let_unit_value 1952 + clippy::let_unit_value, 1699 1953 )] 1700 - use tonic::codegen::http::Uri; 1701 1954 use tonic::codegen::*; 1955 + use tonic::codegen::http::Uri; 1702 1956 #[derive(Debug, Clone)] 1703 1957 pub struct MetadataServiceClient<T> { 1704 1958 inner: tonic::client::Grpc<T>, ··· 1742 1996 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 1743 1997 >, 1744 1998 >, 1745 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 1746 - Into<StdError> + std::marker::Send + std::marker::Sync, 1999 + <T as tonic::codegen::Service< 2000 + http::Request<tonic::body::BoxBody>, 2001 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 1747 2002 { 1748 2003 MetadataServiceClient::new(InterceptedService::new(inner, interceptor)) 1749 2004 } ··· 1787 2042 dead_code, 1788 2043 missing_docs, 1789 2044 clippy::wildcard_imports, 1790 - clippy::let_unit_value 2045 + clippy::let_unit_value, 1791 2046 )] 1792 2047 use tonic::codegen::*; 1793 2048 /// Generated trait containing gRPC methods that should be implemented for use with MetadataServiceServer. ··· 1814 2069 max_encoding_message_size: None, 1815 2070 } 1816 2071 } 1817 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 2072 + pub fn with_interceptor<F>( 2073 + inner: T, 2074 + interceptor: F, 2075 + ) -> InterceptedService<Self, F> 1818 2076 where 1819 2077 F: tonic::service::Interceptor, 1820 2078 { ··· 1866 2124 } 1867 2125 fn call(&mut self, req: http::Request<B>) -> Self::Future { 1868 2126 match req.uri().path() { 1869 - _ => Box::pin(async move { 1870 - let mut response = http::Response::new(empty_body()); 1871 - let headers = response.headers_mut(); 1872 - headers.insert( 1873 - tonic::Status::GRPC_STATUS, 1874 - (tonic::Code::Unimplemented as i32).into(), 1875 - ); 1876 - headers.insert( 1877 - http::header::CONTENT_TYPE, 1878 - tonic::metadata::GRPC_CONTENT_TYPE, 1879 - ); 1880 - Ok(response) 1881 - }), 2127 + _ => { 2128 + Box::pin(async move { 2129 + let mut response = http::Response::new(empty_body()); 2130 + let headers = response.headers_mut(); 2131 + headers 2132 + .insert( 2133 + tonic::Status::GRPC_STATUS, 2134 + (tonic::Code::Unimplemented as i32).into(), 2135 + ); 2136 + headers 2137 + .insert( 2138 + http::header::CONTENT_TYPE, 2139 + tonic::metadata::GRPC_CONTENT_TYPE, 2140 + ); 2141 + Ok(response) 2142 + }) 2143 + } 1882 2144 } 1883 2145 } 1884 2146 } ··· 2162 2424 dead_code, 2163 2425 missing_docs, 2164 2426 clippy::wildcard_imports, 2165 - clippy::let_unit_value 2427 + clippy::let_unit_value, 2166 2428 )] 2167 - use tonic::codegen::http::Uri; 2168 2429 use tonic::codegen::*; 2430 + use tonic::codegen::http::Uri; 2169 2431 #[derive(Debug, Clone)] 2170 2432 pub struct PlaybackServiceClient<T> { 2171 2433 inner: tonic::client::Grpc<T>, ··· 2209 2471 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 2210 2472 >, 2211 2473 >, 2212 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 2213 - Into<StdError> + std::marker::Send + std::marker::Sync, 2474 + <T as tonic::codegen::Service< 2475 + http::Request<tonic::body::BoxBody>, 2476 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 2214 2477 { 2215 2478 PlaybackServiceClient::new(InterceptedService::new(inner, interceptor)) 2216 2479 } ··· 2249 2512 &mut self, 2250 2513 request: impl tonic::IntoRequest<super::PlayRequest>, 2251 2514 ) -> std::result::Result<tonic::Response<super::PlayResponse>, tonic::Status> { 2252 - self.inner.ready().await.map_err(|e| { 2253 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2254 - })?; 2515 + self.inner 2516 + .ready() 2517 + .await 2518 + .map_err(|e| { 2519 + tonic::Status::unknown( 2520 + format!("Service was not ready: {}", e.into()), 2521 + ) 2522 + })?; 2255 2523 let codec = tonic::codec::ProstCodec::default(); 2256 - let path = 2257 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/Play"); 2524 + let path = http::uri::PathAndQuery::from_static( 2525 + "/rockbox.v1alpha1.PlaybackService/Play", 2526 + ); 2258 2527 let mut req = request.into_request(); 2259 2528 req.extensions_mut() 2260 2529 .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Play")); ··· 2264 2533 &mut self, 2265 2534 request: impl tonic::IntoRequest<super::PauseRequest>, 2266 2535 ) -> std::result::Result<tonic::Response<super::PauseResponse>, tonic::Status> { 2267 - self.inner.ready().await.map_err(|e| { 2268 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2269 - })?; 2536 + self.inner 2537 + .ready() 2538 + .await 2539 + .map_err(|e| { 2540 + tonic::Status::unknown( 2541 + format!("Service was not ready: {}", e.into()), 2542 + ) 2543 + })?; 2270 2544 let codec = tonic::codec::ProstCodec::default(); 2271 - let path = 2272 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/Pause"); 2545 + let path = http::uri::PathAndQuery::from_static( 2546 + "/rockbox.v1alpha1.PlaybackService/Pause", 2547 + ); 2273 2548 let mut req = request.into_request(); 2274 2549 req.extensions_mut() 2275 2550 .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Pause")); ··· 2278 2553 pub async fn play_or_pause( 2279 2554 &mut self, 2280 2555 request: impl tonic::IntoRequest<super::PlayOrPauseRequest>, 2281 - ) -> std::result::Result<tonic::Response<super::PlayOrPauseResponse>, tonic::Status> 2282 - { 2283 - self.inner.ready().await.map_err(|e| { 2284 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2285 - })?; 2556 + ) -> std::result::Result< 2557 + tonic::Response<super::PlayOrPauseResponse>, 2558 + tonic::Status, 2559 + > { 2560 + self.inner 2561 + .ready() 2562 + .await 2563 + .map_err(|e| { 2564 + tonic::Status::unknown( 2565 + format!("Service was not ready: {}", e.into()), 2566 + ) 2567 + })?; 2286 2568 let codec = tonic::codec::ProstCodec::default(); 2287 2569 let path = http::uri::PathAndQuery::from_static( 2288 2570 "/rockbox.v1alpha1.PlaybackService/PlayOrPause", 2289 2571 ); 2290 2572 let mut req = request.into_request(); 2291 - req.extensions_mut().insert(GrpcMethod::new( 2292 - "rockbox.v1alpha1.PlaybackService", 2293 - "PlayOrPause", 2294 - )); 2573 + req.extensions_mut() 2574 + .insert( 2575 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayOrPause"), 2576 + ); 2295 2577 self.inner.unary(req, path, codec).await 2296 2578 } 2297 2579 pub async fn resume( 2298 2580 &mut self, 2299 2581 request: impl tonic::IntoRequest<super::ResumeRequest>, 2300 2582 ) -> std::result::Result<tonic::Response<super::ResumeResponse>, tonic::Status> { 2301 - self.inner.ready().await.map_err(|e| { 2302 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2303 - })?; 2583 + self.inner 2584 + .ready() 2585 + .await 2586 + .map_err(|e| { 2587 + tonic::Status::unknown( 2588 + format!("Service was not ready: {}", e.into()), 2589 + ) 2590 + })?; 2304 2591 let codec = tonic::codec::ProstCodec::default(); 2305 - let path = 2306 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/Resume"); 2592 + let path = http::uri::PathAndQuery::from_static( 2593 + "/rockbox.v1alpha1.PlaybackService/Resume", 2594 + ); 2307 2595 let mut req = request.into_request(); 2308 - req.extensions_mut().insert(GrpcMethod::new( 2309 - "rockbox.v1alpha1.PlaybackService", 2310 - "Resume", 2311 - )); 2596 + req.extensions_mut() 2597 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Resume")); 2312 2598 self.inner.unary(req, path, codec).await 2313 2599 } 2314 2600 pub async fn next( 2315 2601 &mut self, 2316 2602 request: impl tonic::IntoRequest<super::NextRequest>, 2317 2603 ) -> std::result::Result<tonic::Response<super::NextResponse>, tonic::Status> { 2318 - self.inner.ready().await.map_err(|e| { 2319 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2320 - })?; 2604 + self.inner 2605 + .ready() 2606 + .await 2607 + .map_err(|e| { 2608 + tonic::Status::unknown( 2609 + format!("Service was not ready: {}", e.into()), 2610 + ) 2611 + })?; 2321 2612 let codec = tonic::codec::ProstCodec::default(); 2322 - let path = 2323 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/Next"); 2613 + let path = http::uri::PathAndQuery::from_static( 2614 + "/rockbox.v1alpha1.PlaybackService/Next", 2615 + ); 2324 2616 let mut req = request.into_request(); 2325 2617 req.extensions_mut() 2326 2618 .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Next")); ··· 2329 2621 pub async fn previous( 2330 2622 &mut self, 2331 2623 request: impl tonic::IntoRequest<super::PreviousRequest>, 2332 - ) -> std::result::Result<tonic::Response<super::PreviousResponse>, tonic::Status> { 2333 - self.inner.ready().await.map_err(|e| { 2334 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2335 - })?; 2624 + ) -> std::result::Result< 2625 + tonic::Response<super::PreviousResponse>, 2626 + tonic::Status, 2627 + > { 2628 + self.inner 2629 + .ready() 2630 + .await 2631 + .map_err(|e| { 2632 + tonic::Status::unknown( 2633 + format!("Service was not ready: {}", e.into()), 2634 + ) 2635 + })?; 2336 2636 let codec = tonic::codec::ProstCodec::default(); 2337 - let path = 2338 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/Previous"); 2637 + let path = http::uri::PathAndQuery::from_static( 2638 + "/rockbox.v1alpha1.PlaybackService/Previous", 2639 + ); 2339 2640 let mut req = request.into_request(); 2340 - req.extensions_mut().insert(GrpcMethod::new( 2341 - "rockbox.v1alpha1.PlaybackService", 2342 - "Previous", 2343 - )); 2641 + req.extensions_mut() 2642 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Previous")); 2344 2643 self.inner.unary(req, path, codec).await 2345 2644 } 2346 2645 pub async fn fast_forward_rewind( 2347 2646 &mut self, 2348 2647 request: impl tonic::IntoRequest<super::FastForwardRewindRequest>, 2349 - ) -> std::result::Result<tonic::Response<super::FastForwardRewindResponse>, tonic::Status> 2350 - { 2351 - self.inner.ready().await.map_err(|e| { 2352 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2353 - })?; 2648 + ) -> std::result::Result< 2649 + tonic::Response<super::FastForwardRewindResponse>, 2650 + tonic::Status, 2651 + > { 2652 + self.inner 2653 + .ready() 2654 + .await 2655 + .map_err(|e| { 2656 + tonic::Status::unknown( 2657 + format!("Service was not ready: {}", e.into()), 2658 + ) 2659 + })?; 2354 2660 let codec = tonic::codec::ProstCodec::default(); 2355 2661 let path = http::uri::PathAndQuery::from_static( 2356 2662 "/rockbox.v1alpha1.PlaybackService/FastForwardRewind", 2357 2663 ); 2358 2664 let mut req = request.into_request(); 2359 - req.extensions_mut().insert(GrpcMethod::new( 2360 - "rockbox.v1alpha1.PlaybackService", 2361 - "FastForwardRewind", 2362 - )); 2665 + req.extensions_mut() 2666 + .insert( 2667 + GrpcMethod::new( 2668 + "rockbox.v1alpha1.PlaybackService", 2669 + "FastForwardRewind", 2670 + ), 2671 + ); 2363 2672 self.inner.unary(req, path, codec).await 2364 2673 } 2365 2674 pub async fn status( 2366 2675 &mut self, 2367 2676 request: impl tonic::IntoRequest<super::StatusRequest>, 2368 2677 ) -> std::result::Result<tonic::Response<super::StatusResponse>, tonic::Status> { 2369 - self.inner.ready().await.map_err(|e| { 2370 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2371 - })?; 2678 + self.inner 2679 + .ready() 2680 + .await 2681 + .map_err(|e| { 2682 + tonic::Status::unknown( 2683 + format!("Service was not ready: {}", e.into()), 2684 + ) 2685 + })?; 2372 2686 let codec = tonic::codec::ProstCodec::default(); 2373 - let path = 2374 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/Status"); 2687 + let path = http::uri::PathAndQuery::from_static( 2688 + "/rockbox.v1alpha1.PlaybackService/Status", 2689 + ); 2375 2690 let mut req = request.into_request(); 2376 - req.extensions_mut().insert(GrpcMethod::new( 2377 - "rockbox.v1alpha1.PlaybackService", 2378 - "Status", 2379 - )); 2691 + req.extensions_mut() 2692 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "Status")); 2380 2693 self.inner.unary(req, path, codec).await 2381 2694 } 2382 2695 pub async fn current_track( 2383 2696 &mut self, 2384 2697 request: impl tonic::IntoRequest<super::CurrentTrackRequest>, 2385 - ) -> std::result::Result<tonic::Response<super::CurrentTrackResponse>, tonic::Status> 2386 - { 2387 - self.inner.ready().await.map_err(|e| { 2388 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2389 - })?; 2698 + ) -> std::result::Result< 2699 + tonic::Response<super::CurrentTrackResponse>, 2700 + tonic::Status, 2701 + > { 2702 + self.inner 2703 + .ready() 2704 + .await 2705 + .map_err(|e| { 2706 + tonic::Status::unknown( 2707 + format!("Service was not ready: {}", e.into()), 2708 + ) 2709 + })?; 2390 2710 let codec = tonic::codec::ProstCodec::default(); 2391 2711 let path = http::uri::PathAndQuery::from_static( 2392 2712 "/rockbox.v1alpha1.PlaybackService/CurrentTrack", 2393 2713 ); 2394 2714 let mut req = request.into_request(); 2395 - req.extensions_mut().insert(GrpcMethod::new( 2396 - "rockbox.v1alpha1.PlaybackService", 2397 - "CurrentTrack", 2398 - )); 2715 + req.extensions_mut() 2716 + .insert( 2717 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "CurrentTrack"), 2718 + ); 2399 2719 self.inner.unary(req, path, codec).await 2400 2720 } 2401 2721 pub async fn next_track( 2402 2722 &mut self, 2403 2723 request: impl tonic::IntoRequest<super::NextTrackRequest>, 2404 - ) -> std::result::Result<tonic::Response<super::NextTrackResponse>, tonic::Status> { 2405 - self.inner.ready().await.map_err(|e| { 2406 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2407 - })?; 2724 + ) -> std::result::Result< 2725 + tonic::Response<super::NextTrackResponse>, 2726 + tonic::Status, 2727 + > { 2728 + self.inner 2729 + .ready() 2730 + .await 2731 + .map_err(|e| { 2732 + tonic::Status::unknown( 2733 + format!("Service was not ready: {}", e.into()), 2734 + ) 2735 + })?; 2408 2736 let codec = tonic::codec::ProstCodec::default(); 2409 - let path = 2410 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/NextTrack"); 2737 + let path = http::uri::PathAndQuery::from_static( 2738 + "/rockbox.v1alpha1.PlaybackService/NextTrack", 2739 + ); 2411 2740 let mut req = request.into_request(); 2412 - req.extensions_mut().insert(GrpcMethod::new( 2413 - "rockbox.v1alpha1.PlaybackService", 2414 - "NextTrack", 2415 - )); 2741 + req.extensions_mut() 2742 + .insert( 2743 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "NextTrack"), 2744 + ); 2416 2745 self.inner.unary(req, path, codec).await 2417 2746 } 2418 2747 pub async fn flush_and_reload_tracks( 2419 2748 &mut self, 2420 2749 request: impl tonic::IntoRequest<super::FlushAndReloadTracksRequest>, 2421 - ) -> std::result::Result<tonic::Response<super::FlushAndReloadTracksResponse>, tonic::Status> 2422 - { 2423 - self.inner.ready().await.map_err(|e| { 2424 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2425 - })?; 2750 + ) -> std::result::Result< 2751 + tonic::Response<super::FlushAndReloadTracksResponse>, 2752 + tonic::Status, 2753 + > { 2754 + self.inner 2755 + .ready() 2756 + .await 2757 + .map_err(|e| { 2758 + tonic::Status::unknown( 2759 + format!("Service was not ready: {}", e.into()), 2760 + ) 2761 + })?; 2426 2762 let codec = tonic::codec::ProstCodec::default(); 2427 2763 let path = http::uri::PathAndQuery::from_static( 2428 2764 "/rockbox.v1alpha1.PlaybackService/FlushAndReloadTracks", 2429 2765 ); 2430 2766 let mut req = request.into_request(); 2431 - req.extensions_mut().insert(GrpcMethod::new( 2432 - "rockbox.v1alpha1.PlaybackService", 2433 - "FlushAndReloadTracks", 2434 - )); 2767 + req.extensions_mut() 2768 + .insert( 2769 + GrpcMethod::new( 2770 + "rockbox.v1alpha1.PlaybackService", 2771 + "FlushAndReloadTracks", 2772 + ), 2773 + ); 2435 2774 self.inner.unary(req, path, codec).await 2436 2775 } 2437 2776 pub async fn get_file_position( 2438 2777 &mut self, 2439 2778 request: impl tonic::IntoRequest<super::GetFilePositionRequest>, 2440 - ) -> std::result::Result<tonic::Response<super::GetFilePositionResponse>, tonic::Status> 2441 - { 2442 - self.inner.ready().await.map_err(|e| { 2443 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2444 - })?; 2779 + ) -> std::result::Result< 2780 + tonic::Response<super::GetFilePositionResponse>, 2781 + tonic::Status, 2782 + > { 2783 + self.inner 2784 + .ready() 2785 + .await 2786 + .map_err(|e| { 2787 + tonic::Status::unknown( 2788 + format!("Service was not ready: {}", e.into()), 2789 + ) 2790 + })?; 2445 2791 let codec = tonic::codec::ProstCodec::default(); 2446 2792 let path = http::uri::PathAndQuery::from_static( 2447 2793 "/rockbox.v1alpha1.PlaybackService/GetFilePosition", 2448 2794 ); 2449 2795 let mut req = request.into_request(); 2450 - req.extensions_mut().insert(GrpcMethod::new( 2451 - "rockbox.v1alpha1.PlaybackService", 2452 - "GetFilePosition", 2453 - )); 2796 + req.extensions_mut() 2797 + .insert( 2798 + GrpcMethod::new( 2799 + "rockbox.v1alpha1.PlaybackService", 2800 + "GetFilePosition", 2801 + ), 2802 + ); 2454 2803 self.inner.unary(req, path, codec).await 2455 2804 } 2456 2805 pub async fn hard_stop( 2457 2806 &mut self, 2458 2807 request: impl tonic::IntoRequest<super::HardStopRequest>, 2459 - ) -> std::result::Result<tonic::Response<super::HardStopResponse>, tonic::Status> { 2460 - self.inner.ready().await.map_err(|e| { 2461 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2462 - })?; 2808 + ) -> std::result::Result< 2809 + tonic::Response<super::HardStopResponse>, 2810 + tonic::Status, 2811 + > { 2812 + self.inner 2813 + .ready() 2814 + .await 2815 + .map_err(|e| { 2816 + tonic::Status::unknown( 2817 + format!("Service was not ready: {}", e.into()), 2818 + ) 2819 + })?; 2463 2820 let codec = tonic::codec::ProstCodec::default(); 2464 - let path = 2465 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/HardStop"); 2821 + let path = http::uri::PathAndQuery::from_static( 2822 + "/rockbox.v1alpha1.PlaybackService/HardStop", 2823 + ); 2466 2824 let mut req = request.into_request(); 2467 - req.extensions_mut().insert(GrpcMethod::new( 2468 - "rockbox.v1alpha1.PlaybackService", 2469 - "HardStop", 2470 - )); 2825 + req.extensions_mut() 2826 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "HardStop")); 2471 2827 self.inner.unary(req, path, codec).await 2472 2828 } 2473 2829 pub async fn play_album( 2474 2830 &mut self, 2475 2831 request: impl tonic::IntoRequest<super::PlayAlbumRequest>, 2476 - ) -> std::result::Result<tonic::Response<super::PlayAlbumResponse>, tonic::Status> { 2477 - self.inner.ready().await.map_err(|e| { 2478 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2479 - })?; 2832 + ) -> std::result::Result< 2833 + tonic::Response<super::PlayAlbumResponse>, 2834 + tonic::Status, 2835 + > { 2836 + self.inner 2837 + .ready() 2838 + .await 2839 + .map_err(|e| { 2840 + tonic::Status::unknown( 2841 + format!("Service was not ready: {}", e.into()), 2842 + ) 2843 + })?; 2480 2844 let codec = tonic::codec::ProstCodec::default(); 2481 - let path = 2482 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/PlayAlbum"); 2845 + let path = http::uri::PathAndQuery::from_static( 2846 + "/rockbox.v1alpha1.PlaybackService/PlayAlbum", 2847 + ); 2483 2848 let mut req = request.into_request(); 2484 - req.extensions_mut().insert(GrpcMethod::new( 2485 - "rockbox.v1alpha1.PlaybackService", 2486 - "PlayAlbum", 2487 - )); 2849 + req.extensions_mut() 2850 + .insert( 2851 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayAlbum"), 2852 + ); 2488 2853 self.inner.unary(req, path, codec).await 2489 2854 } 2490 2855 pub async fn play_artist_tracks( 2491 2856 &mut self, 2492 2857 request: impl tonic::IntoRequest<super::PlayArtistTracksRequest>, 2493 - ) -> std::result::Result<tonic::Response<super::PlayArtistTracksResponse>, tonic::Status> 2494 - { 2495 - self.inner.ready().await.map_err(|e| { 2496 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2497 - })?; 2858 + ) -> std::result::Result< 2859 + tonic::Response<super::PlayArtistTracksResponse>, 2860 + tonic::Status, 2861 + > { 2862 + self.inner 2863 + .ready() 2864 + .await 2865 + .map_err(|e| { 2866 + tonic::Status::unknown( 2867 + format!("Service was not ready: {}", e.into()), 2868 + ) 2869 + })?; 2498 2870 let codec = tonic::codec::ProstCodec::default(); 2499 2871 let path = http::uri::PathAndQuery::from_static( 2500 2872 "/rockbox.v1alpha1.PlaybackService/PlayArtistTracks", 2501 2873 ); 2502 2874 let mut req = request.into_request(); 2503 - req.extensions_mut().insert(GrpcMethod::new( 2504 - "rockbox.v1alpha1.PlaybackService", 2505 - "PlayArtistTracks", 2506 - )); 2875 + req.extensions_mut() 2876 + .insert( 2877 + GrpcMethod::new( 2878 + "rockbox.v1alpha1.PlaybackService", 2879 + "PlayArtistTracks", 2880 + ), 2881 + ); 2507 2882 self.inner.unary(req, path, codec).await 2508 2883 } 2509 2884 pub async fn play_playlist( 2510 2885 &mut self, 2511 2886 request: impl tonic::IntoRequest<super::PlayPlaylistRequest>, 2512 - ) -> std::result::Result<tonic::Response<super::PlayPlaylistResponse>, tonic::Status> 2513 - { 2514 - self.inner.ready().await.map_err(|e| { 2515 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2516 - })?; 2887 + ) -> std::result::Result< 2888 + tonic::Response<super::PlayPlaylistResponse>, 2889 + tonic::Status, 2890 + > { 2891 + self.inner 2892 + .ready() 2893 + .await 2894 + .map_err(|e| { 2895 + tonic::Status::unknown( 2896 + format!("Service was not ready: {}", e.into()), 2897 + ) 2898 + })?; 2517 2899 let codec = tonic::codec::ProstCodec::default(); 2518 2900 let path = http::uri::PathAndQuery::from_static( 2519 2901 "/rockbox.v1alpha1.PlaybackService/PlayPlaylist", 2520 2902 ); 2521 2903 let mut req = request.into_request(); 2522 - req.extensions_mut().insert(GrpcMethod::new( 2523 - "rockbox.v1alpha1.PlaybackService", 2524 - "PlayPlaylist", 2525 - )); 2904 + req.extensions_mut() 2905 + .insert( 2906 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayPlaylist"), 2907 + ); 2526 2908 self.inner.unary(req, path, codec).await 2527 2909 } 2528 2910 pub async fn play_directory( 2529 2911 &mut self, 2530 2912 request: impl tonic::IntoRequest<super::PlayDirectoryRequest>, 2531 - ) -> std::result::Result<tonic::Response<super::PlayDirectoryResponse>, tonic::Status> 2532 - { 2533 - self.inner.ready().await.map_err(|e| { 2534 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2535 - })?; 2913 + ) -> std::result::Result< 2914 + tonic::Response<super::PlayDirectoryResponse>, 2915 + tonic::Status, 2916 + > { 2917 + self.inner 2918 + .ready() 2919 + .await 2920 + .map_err(|e| { 2921 + tonic::Status::unknown( 2922 + format!("Service was not ready: {}", e.into()), 2923 + ) 2924 + })?; 2536 2925 let codec = tonic::codec::ProstCodec::default(); 2537 2926 let path = http::uri::PathAndQuery::from_static( 2538 2927 "/rockbox.v1alpha1.PlaybackService/PlayDirectory", 2539 2928 ); 2540 2929 let mut req = request.into_request(); 2541 - req.extensions_mut().insert(GrpcMethod::new( 2542 - "rockbox.v1alpha1.PlaybackService", 2543 - "PlayDirectory", 2544 - )); 2930 + req.extensions_mut() 2931 + .insert( 2932 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayDirectory"), 2933 + ); 2545 2934 self.inner.unary(req, path, codec).await 2546 2935 } 2547 2936 pub async fn play_music_directory( 2548 2937 &mut self, 2549 2938 request: impl tonic::IntoRequest<super::PlayMusicDirectoryRequest>, 2550 - ) -> std::result::Result<tonic::Response<super::PlayMusicDirectoryResponse>, tonic::Status> 2551 - { 2552 - self.inner.ready().await.map_err(|e| { 2553 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2554 - })?; 2939 + ) -> std::result::Result< 2940 + tonic::Response<super::PlayMusicDirectoryResponse>, 2941 + tonic::Status, 2942 + > { 2943 + self.inner 2944 + .ready() 2945 + .await 2946 + .map_err(|e| { 2947 + tonic::Status::unknown( 2948 + format!("Service was not ready: {}", e.into()), 2949 + ) 2950 + })?; 2555 2951 let codec = tonic::codec::ProstCodec::default(); 2556 2952 let path = http::uri::PathAndQuery::from_static( 2557 2953 "/rockbox.v1alpha1.PlaybackService/PlayMusicDirectory", 2558 2954 ); 2559 2955 let mut req = request.into_request(); 2560 - req.extensions_mut().insert(GrpcMethod::new( 2561 - "rockbox.v1alpha1.PlaybackService", 2562 - "PlayMusicDirectory", 2563 - )); 2956 + req.extensions_mut() 2957 + .insert( 2958 + GrpcMethod::new( 2959 + "rockbox.v1alpha1.PlaybackService", 2960 + "PlayMusicDirectory", 2961 + ), 2962 + ); 2564 2963 self.inner.unary(req, path, codec).await 2565 2964 } 2566 2965 pub async fn play_track( 2567 2966 &mut self, 2568 2967 request: impl tonic::IntoRequest<super::PlayTrackRequest>, 2569 - ) -> std::result::Result<tonic::Response<super::PlayTrackResponse>, tonic::Status> { 2570 - self.inner.ready().await.map_err(|e| { 2571 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2572 - })?; 2968 + ) -> std::result::Result< 2969 + tonic::Response<super::PlayTrackResponse>, 2970 + tonic::Status, 2971 + > { 2972 + self.inner 2973 + .ready() 2974 + .await 2975 + .map_err(|e| { 2976 + tonic::Status::unknown( 2977 + format!("Service was not ready: {}", e.into()), 2978 + ) 2979 + })?; 2573 2980 let codec = tonic::codec::ProstCodec::default(); 2574 - let path = 2575 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaybackService/PlayTrack"); 2981 + let path = http::uri::PathAndQuery::from_static( 2982 + "/rockbox.v1alpha1.PlaybackService/PlayTrack", 2983 + ); 2576 2984 let mut req = request.into_request(); 2577 - req.extensions_mut().insert(GrpcMethod::new( 2578 - "rockbox.v1alpha1.PlaybackService", 2579 - "PlayTrack", 2580 - )); 2985 + req.extensions_mut() 2986 + .insert( 2987 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayTrack"), 2988 + ); 2581 2989 self.inner.unary(req, path, codec).await 2582 2990 } 2583 2991 pub async fn play_liked_tracks( 2584 2992 &mut self, 2585 2993 request: impl tonic::IntoRequest<super::PlayLikedTracksRequest>, 2586 - ) -> std::result::Result<tonic::Response<super::PlayLikedTracksResponse>, tonic::Status> 2587 - { 2588 - self.inner.ready().await.map_err(|e| { 2589 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2590 - })?; 2994 + ) -> std::result::Result< 2995 + tonic::Response<super::PlayLikedTracksResponse>, 2996 + tonic::Status, 2997 + > { 2998 + self.inner 2999 + .ready() 3000 + .await 3001 + .map_err(|e| { 3002 + tonic::Status::unknown( 3003 + format!("Service was not ready: {}", e.into()), 3004 + ) 3005 + })?; 2591 3006 let codec = tonic::codec::ProstCodec::default(); 2592 3007 let path = http::uri::PathAndQuery::from_static( 2593 3008 "/rockbox.v1alpha1.PlaybackService/PlayLikedTracks", 2594 3009 ); 2595 3010 let mut req = request.into_request(); 2596 - req.extensions_mut().insert(GrpcMethod::new( 2597 - "rockbox.v1alpha1.PlaybackService", 2598 - "PlayLikedTracks", 2599 - )); 3011 + req.extensions_mut() 3012 + .insert( 3013 + GrpcMethod::new( 3014 + "rockbox.v1alpha1.PlaybackService", 3015 + "PlayLikedTracks", 3016 + ), 3017 + ); 2600 3018 self.inner.unary(req, path, codec).await 2601 3019 } 2602 3020 pub async fn play_all_tracks( 2603 3021 &mut self, 2604 3022 request: impl tonic::IntoRequest<super::PlayAllTracksRequest>, 2605 - ) -> std::result::Result<tonic::Response<super::PlayAllTracksResponse>, tonic::Status> 2606 - { 2607 - self.inner.ready().await.map_err(|e| { 2608 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2609 - })?; 3023 + ) -> std::result::Result< 3024 + tonic::Response<super::PlayAllTracksResponse>, 3025 + tonic::Status, 3026 + > { 3027 + self.inner 3028 + .ready() 3029 + .await 3030 + .map_err(|e| { 3031 + tonic::Status::unknown( 3032 + format!("Service was not ready: {}", e.into()), 3033 + ) 3034 + })?; 2610 3035 let codec = tonic::codec::ProstCodec::default(); 2611 3036 let path = http::uri::PathAndQuery::from_static( 2612 3037 "/rockbox.v1alpha1.PlaybackService/PlayAllTracks", 2613 3038 ); 2614 3039 let mut req = request.into_request(); 2615 - req.extensions_mut().insert(GrpcMethod::new( 2616 - "rockbox.v1alpha1.PlaybackService", 2617 - "PlayAllTracks", 2618 - )); 3040 + req.extensions_mut() 3041 + .insert( 3042 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "PlayAllTracks"), 3043 + ); 2619 3044 self.inner.unary(req, path, codec).await 2620 3045 } 2621 3046 pub async fn stream_current_track( ··· 2625 3050 tonic::Response<tonic::codec::Streaming<super::CurrentTrackResponse>>, 2626 3051 tonic::Status, 2627 3052 > { 2628 - self.inner.ready().await.map_err(|e| { 2629 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2630 - })?; 3053 + self.inner 3054 + .ready() 3055 + .await 3056 + .map_err(|e| { 3057 + tonic::Status::unknown( 3058 + format!("Service was not ready: {}", e.into()), 3059 + ) 3060 + })?; 2631 3061 let codec = tonic::codec::ProstCodec::default(); 2632 3062 let path = http::uri::PathAndQuery::from_static( 2633 3063 "/rockbox.v1alpha1.PlaybackService/StreamCurrentTrack", 2634 3064 ); 2635 3065 let mut req = request.into_request(); 2636 - req.extensions_mut().insert(GrpcMethod::new( 2637 - "rockbox.v1alpha1.PlaybackService", 2638 - "StreamCurrentTrack", 2639 - )); 3066 + req.extensions_mut() 3067 + .insert( 3068 + GrpcMethod::new( 3069 + "rockbox.v1alpha1.PlaybackService", 3070 + "StreamCurrentTrack", 3071 + ), 3072 + ); 2640 3073 self.inner.server_streaming(req, path, codec).await 2641 3074 } 2642 3075 pub async fn stream_status( ··· 2646 3079 tonic::Response<tonic::codec::Streaming<super::StatusResponse>>, 2647 3080 tonic::Status, 2648 3081 > { 2649 - self.inner.ready().await.map_err(|e| { 2650 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2651 - })?; 3082 + self.inner 3083 + .ready() 3084 + .await 3085 + .map_err(|e| { 3086 + tonic::Status::unknown( 3087 + format!("Service was not ready: {}", e.into()), 3088 + ) 3089 + })?; 2652 3090 let codec = tonic::codec::ProstCodec::default(); 2653 3091 let path = http::uri::PathAndQuery::from_static( 2654 3092 "/rockbox.v1alpha1.PlaybackService/StreamStatus", 2655 3093 ); 2656 3094 let mut req = request.into_request(); 2657 - req.extensions_mut().insert(GrpcMethod::new( 2658 - "rockbox.v1alpha1.PlaybackService", 2659 - "StreamStatus", 2660 - )); 3095 + req.extensions_mut() 3096 + .insert( 3097 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "StreamStatus"), 3098 + ); 2661 3099 self.inner.server_streaming(req, path, codec).await 2662 3100 } 2663 3101 pub async fn stream_playlist( ··· 2667 3105 tonic::Response<tonic::codec::Streaming<super::PlaylistResponse>>, 2668 3106 tonic::Status, 2669 3107 > { 2670 - self.inner.ready().await.map_err(|e| { 2671 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 2672 - })?; 3108 + self.inner 3109 + .ready() 3110 + .await 3111 + .map_err(|e| { 3112 + tonic::Status::unknown( 3113 + format!("Service was not ready: {}", e.into()), 3114 + ) 3115 + })?; 2673 3116 let codec = tonic::codec::ProstCodec::default(); 2674 3117 let path = http::uri::PathAndQuery::from_static( 2675 3118 "/rockbox.v1alpha1.PlaybackService/StreamPlaylist", 2676 3119 ); 2677 3120 let mut req = request.into_request(); 2678 - req.extensions_mut().insert(GrpcMethod::new( 2679 - "rockbox.v1alpha1.PlaybackService", 2680 - "StreamPlaylist", 2681 - )); 3121 + req.extensions_mut() 3122 + .insert( 3123 + GrpcMethod::new("rockbox.v1alpha1.PlaybackService", "StreamPlaylist"), 3124 + ); 2682 3125 self.inner.server_streaming(req, path, codec).await 2683 3126 } 2684 3127 } ··· 2690 3133 dead_code, 2691 3134 missing_docs, 2692 3135 clippy::wildcard_imports, 2693 - clippy::let_unit_value 3136 + clippy::let_unit_value, 2694 3137 )] 2695 3138 use tonic::codegen::*; 2696 3139 /// Generated trait containing gRPC methods that should be implemented for use with PlaybackServiceServer. ··· 2707 3150 async fn play_or_pause( 2708 3151 &self, 2709 3152 request: tonic::Request<super::PlayOrPauseRequest>, 2710 - ) -> std::result::Result<tonic::Response<super::PlayOrPauseResponse>, tonic::Status>; 3153 + ) -> std::result::Result< 3154 + tonic::Response<super::PlayOrPauseResponse>, 3155 + tonic::Status, 3156 + >; 2711 3157 async fn resume( 2712 3158 &self, 2713 3159 request: tonic::Request<super::ResumeRequest>, ··· 2719 3165 async fn previous( 2720 3166 &self, 2721 3167 request: tonic::Request<super::PreviousRequest>, 2722 - ) -> std::result::Result<tonic::Response<super::PreviousResponse>, tonic::Status>; 3168 + ) -> std::result::Result< 3169 + tonic::Response<super::PreviousResponse>, 3170 + tonic::Status, 3171 + >; 2723 3172 async fn fast_forward_rewind( 2724 3173 &self, 2725 3174 request: tonic::Request<super::FastForwardRewindRequest>, 2726 - ) -> std::result::Result<tonic::Response<super::FastForwardRewindResponse>, tonic::Status>; 3175 + ) -> std::result::Result< 3176 + tonic::Response<super::FastForwardRewindResponse>, 3177 + tonic::Status, 3178 + >; 2727 3179 async fn status( 2728 3180 &self, 2729 3181 request: tonic::Request<super::StatusRequest>, ··· 2731 3183 async fn current_track( 2732 3184 &self, 2733 3185 request: tonic::Request<super::CurrentTrackRequest>, 2734 - ) -> std::result::Result<tonic::Response<super::CurrentTrackResponse>, tonic::Status>; 3186 + ) -> std::result::Result< 3187 + tonic::Response<super::CurrentTrackResponse>, 3188 + tonic::Status, 3189 + >; 2735 3190 async fn next_track( 2736 3191 &self, 2737 3192 request: tonic::Request<super::NextTrackRequest>, 2738 - ) -> std::result::Result<tonic::Response<super::NextTrackResponse>, tonic::Status>; 3193 + ) -> std::result::Result< 3194 + tonic::Response<super::NextTrackResponse>, 3195 + tonic::Status, 3196 + >; 2739 3197 async fn flush_and_reload_tracks( 2740 3198 &self, 2741 3199 request: tonic::Request<super::FlushAndReloadTracksRequest>, 2742 - ) -> std::result::Result<tonic::Response<super::FlushAndReloadTracksResponse>, tonic::Status>; 3200 + ) -> std::result::Result< 3201 + tonic::Response<super::FlushAndReloadTracksResponse>, 3202 + tonic::Status, 3203 + >; 2743 3204 async fn get_file_position( 2744 3205 &self, 2745 3206 request: tonic::Request<super::GetFilePositionRequest>, 2746 - ) -> std::result::Result<tonic::Response<super::GetFilePositionResponse>, tonic::Status>; 3207 + ) -> std::result::Result< 3208 + tonic::Response<super::GetFilePositionResponse>, 3209 + tonic::Status, 3210 + >; 2747 3211 async fn hard_stop( 2748 3212 &self, 2749 3213 request: tonic::Request<super::HardStopRequest>, 2750 - ) -> std::result::Result<tonic::Response<super::HardStopResponse>, tonic::Status>; 3214 + ) -> std::result::Result< 3215 + tonic::Response<super::HardStopResponse>, 3216 + tonic::Status, 3217 + >; 2751 3218 async fn play_album( 2752 3219 &self, 2753 3220 request: tonic::Request<super::PlayAlbumRequest>, 2754 - ) -> std::result::Result<tonic::Response<super::PlayAlbumResponse>, tonic::Status>; 3221 + ) -> std::result::Result< 3222 + tonic::Response<super::PlayAlbumResponse>, 3223 + tonic::Status, 3224 + >; 2755 3225 async fn play_artist_tracks( 2756 3226 &self, 2757 3227 request: tonic::Request<super::PlayArtistTracksRequest>, 2758 - ) -> std::result::Result<tonic::Response<super::PlayArtistTracksResponse>, tonic::Status>; 3228 + ) -> std::result::Result< 3229 + tonic::Response<super::PlayArtistTracksResponse>, 3230 + tonic::Status, 3231 + >; 2759 3232 async fn play_playlist( 2760 3233 &self, 2761 3234 request: tonic::Request<super::PlayPlaylistRequest>, 2762 - ) -> std::result::Result<tonic::Response<super::PlayPlaylistResponse>, tonic::Status>; 3235 + ) -> std::result::Result< 3236 + tonic::Response<super::PlayPlaylistResponse>, 3237 + tonic::Status, 3238 + >; 2763 3239 async fn play_directory( 2764 3240 &self, 2765 3241 request: tonic::Request<super::PlayDirectoryRequest>, 2766 - ) -> std::result::Result<tonic::Response<super::PlayDirectoryResponse>, tonic::Status>; 3242 + ) -> std::result::Result< 3243 + tonic::Response<super::PlayDirectoryResponse>, 3244 + tonic::Status, 3245 + >; 2767 3246 async fn play_music_directory( 2768 3247 &self, 2769 3248 request: tonic::Request<super::PlayMusicDirectoryRequest>, 2770 - ) -> std::result::Result<tonic::Response<super::PlayMusicDirectoryResponse>, tonic::Status>; 3249 + ) -> std::result::Result< 3250 + tonic::Response<super::PlayMusicDirectoryResponse>, 3251 + tonic::Status, 3252 + >; 2771 3253 async fn play_track( 2772 3254 &self, 2773 3255 request: tonic::Request<super::PlayTrackRequest>, 2774 - ) -> std::result::Result<tonic::Response<super::PlayTrackResponse>, tonic::Status>; 3256 + ) -> std::result::Result< 3257 + tonic::Response<super::PlayTrackResponse>, 3258 + tonic::Status, 3259 + >; 2775 3260 async fn play_liked_tracks( 2776 3261 &self, 2777 3262 request: tonic::Request<super::PlayLikedTracksRequest>, 2778 - ) -> std::result::Result<tonic::Response<super::PlayLikedTracksResponse>, tonic::Status>; 3263 + ) -> std::result::Result< 3264 + tonic::Response<super::PlayLikedTracksResponse>, 3265 + tonic::Status, 3266 + >; 2779 3267 async fn play_all_tracks( 2780 3268 &self, 2781 3269 request: tonic::Request<super::PlayAllTracksRequest>, 2782 - ) -> std::result::Result<tonic::Response<super::PlayAllTracksResponse>, tonic::Status>; 3270 + ) -> std::result::Result< 3271 + tonic::Response<super::PlayAllTracksResponse>, 3272 + tonic::Status, 3273 + >; 2783 3274 /// Server streaming response type for the StreamCurrentTrack method. 2784 3275 type StreamCurrentTrackStream: tonic::codegen::tokio_stream::Stream< 2785 3276 Item = std::result::Result<super::CurrentTrackResponse, tonic::Status>, 2786 - > + std::marker::Send 3277 + > 3278 + + std::marker::Send 2787 3279 + 'static; 2788 3280 async fn stream_current_track( 2789 3281 &self, 2790 3282 request: tonic::Request<super::StreamCurrentTrackRequest>, 2791 - ) -> std::result::Result<tonic::Response<Self::StreamCurrentTrackStream>, tonic::Status>; 3283 + ) -> std::result::Result< 3284 + tonic::Response<Self::StreamCurrentTrackStream>, 3285 + tonic::Status, 3286 + >; 2792 3287 /// Server streaming response type for the StreamStatus method. 2793 3288 type StreamStatusStream: tonic::codegen::tokio_stream::Stream< 2794 3289 Item = std::result::Result<super::StatusResponse, tonic::Status>, 2795 - > + std::marker::Send 3290 + > 3291 + + std::marker::Send 2796 3292 + 'static; 2797 3293 async fn stream_status( 2798 3294 &self, 2799 3295 request: tonic::Request<super::StreamStatusRequest>, 2800 - ) -> std::result::Result<tonic::Response<Self::StreamStatusStream>, tonic::Status>; 3296 + ) -> std::result::Result< 3297 + tonic::Response<Self::StreamStatusStream>, 3298 + tonic::Status, 3299 + >; 2801 3300 /// Server streaming response type for the StreamPlaylist method. 2802 3301 type StreamPlaylistStream: tonic::codegen::tokio_stream::Stream< 2803 3302 Item = std::result::Result<super::PlaylistResponse, tonic::Status>, 2804 - > + std::marker::Send 3303 + > 3304 + + std::marker::Send 2805 3305 + 'static; 2806 3306 async fn stream_playlist( 2807 3307 &self, 2808 3308 request: tonic::Request<super::StreamPlaylistRequest>, 2809 - ) -> std::result::Result<tonic::Response<Self::StreamPlaylistStream>, tonic::Status>; 3309 + ) -> std::result::Result< 3310 + tonic::Response<Self::StreamPlaylistStream>, 3311 + tonic::Status, 3312 + >; 2810 3313 } 2811 3314 #[derive(Debug)] 2812 3315 pub struct PlaybackServiceServer<T> { ··· 2829 3332 max_encoding_message_size: None, 2830 3333 } 2831 3334 } 2832 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 3335 + pub fn with_interceptor<F>( 3336 + inner: T, 3337 + interceptor: F, 3338 + ) -> InterceptedService<Self, F> 2833 3339 where 2834 3340 F: tonic::service::Interceptor, 2835 3341 { ··· 2884 3390 "/rockbox.v1alpha1.PlaybackService/Play" => { 2885 3391 #[allow(non_camel_case_types)] 2886 3392 struct PlaySvc<T: PlaybackService>(pub Arc<T>); 2887 - impl<T: PlaybackService> tonic::server::UnaryService<super::PlayRequest> for PlaySvc<T> { 3393 + impl< 3394 + T: PlaybackService, 3395 + > tonic::server::UnaryService<super::PlayRequest> for PlaySvc<T> { 2888 3396 type Response = super::PlayResponse; 2889 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3397 + type Future = BoxFuture< 3398 + tonic::Response<Self::Response>, 3399 + tonic::Status, 3400 + >; 2890 3401 fn call( 2891 3402 &mut self, 2892 3403 request: tonic::Request<super::PlayRequest>, 2893 3404 ) -> Self::Future { 2894 3405 let inner = Arc::clone(&self.0); 2895 - let fut = 2896 - async move { <T as PlaybackService>::play(&inner, request).await }; 3406 + let fut = async move { 3407 + <T as PlaybackService>::play(&inner, request).await 3408 + }; 2897 3409 Box::pin(fut) 2898 3410 } 2899 3411 } ··· 2922 3434 "/rockbox.v1alpha1.PlaybackService/Pause" => { 2923 3435 #[allow(non_camel_case_types)] 2924 3436 struct PauseSvc<T: PlaybackService>(pub Arc<T>); 2925 - impl<T: PlaybackService> tonic::server::UnaryService<super::PauseRequest> for PauseSvc<T> { 3437 + impl< 3438 + T: PlaybackService, 3439 + > tonic::server::UnaryService<super::PauseRequest> for PauseSvc<T> { 2926 3440 type Response = super::PauseResponse; 2927 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3441 + type Future = BoxFuture< 3442 + tonic::Response<Self::Response>, 3443 + tonic::Status, 3444 + >; 2928 3445 fn call( 2929 3446 &mut self, 2930 3447 request: tonic::Request<super::PauseRequest>, 2931 3448 ) -> Self::Future { 2932 3449 let inner = Arc::clone(&self.0); 2933 - let fut = 2934 - async move { <T as PlaybackService>::pause(&inner, request).await }; 3450 + let fut = async move { 3451 + <T as PlaybackService>::pause(&inner, request).await 3452 + }; 2935 3453 Box::pin(fut) 2936 3454 } 2937 3455 } ··· 2960 3478 "/rockbox.v1alpha1.PlaybackService/PlayOrPause" => { 2961 3479 #[allow(non_camel_case_types)] 2962 3480 struct PlayOrPauseSvc<T: PlaybackService>(pub Arc<T>); 2963 - impl<T: PlaybackService> tonic::server::UnaryService<super::PlayOrPauseRequest> 2964 - for PlayOrPauseSvc<T> 2965 - { 3481 + impl< 3482 + T: PlaybackService, 3483 + > tonic::server::UnaryService<super::PlayOrPauseRequest> 3484 + for PlayOrPauseSvc<T> { 2966 3485 type Response = super::PlayOrPauseResponse; 2967 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3486 + type Future = BoxFuture< 3487 + tonic::Response<Self::Response>, 3488 + tonic::Status, 3489 + >; 2968 3490 fn call( 2969 3491 &mut self, 2970 3492 request: tonic::Request<super::PlayOrPauseRequest>, ··· 3001 3523 "/rockbox.v1alpha1.PlaybackService/Resume" => { 3002 3524 #[allow(non_camel_case_types)] 3003 3525 struct ResumeSvc<T: PlaybackService>(pub Arc<T>); 3004 - impl<T: PlaybackService> tonic::server::UnaryService<super::ResumeRequest> for ResumeSvc<T> { 3526 + impl< 3527 + T: PlaybackService, 3528 + > tonic::server::UnaryService<super::ResumeRequest> 3529 + for ResumeSvc<T> { 3005 3530 type Response = super::ResumeResponse; 3006 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3531 + type Future = BoxFuture< 3532 + tonic::Response<Self::Response>, 3533 + tonic::Status, 3534 + >; 3007 3535 fn call( 3008 3536 &mut self, 3009 3537 request: tonic::Request<super::ResumeRequest>, ··· 3040 3568 "/rockbox.v1alpha1.PlaybackService/Next" => { 3041 3569 #[allow(non_camel_case_types)] 3042 3570 struct NextSvc<T: PlaybackService>(pub Arc<T>); 3043 - impl<T: PlaybackService> tonic::server::UnaryService<super::NextRequest> for NextSvc<T> { 3571 + impl< 3572 + T: PlaybackService, 3573 + > tonic::server::UnaryService<super::NextRequest> for NextSvc<T> { 3044 3574 type Response = super::NextResponse; 3045 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3575 + type Future = BoxFuture< 3576 + tonic::Response<Self::Response>, 3577 + tonic::Status, 3578 + >; 3046 3579 fn call( 3047 3580 &mut self, 3048 3581 request: tonic::Request<super::NextRequest>, 3049 3582 ) -> Self::Future { 3050 3583 let inner = Arc::clone(&self.0); 3051 - let fut = 3052 - async move { <T as PlaybackService>::next(&inner, request).await }; 3584 + let fut = async move { 3585 + <T as PlaybackService>::next(&inner, request).await 3586 + }; 3053 3587 Box::pin(fut) 3054 3588 } 3055 3589 } ··· 3078 3612 "/rockbox.v1alpha1.PlaybackService/Previous" => { 3079 3613 #[allow(non_camel_case_types)] 3080 3614 struct PreviousSvc<T: PlaybackService>(pub Arc<T>); 3081 - impl<T: PlaybackService> tonic::server::UnaryService<super::PreviousRequest> for PreviousSvc<T> { 3615 + impl< 3616 + T: PlaybackService, 3617 + > tonic::server::UnaryService<super::PreviousRequest> 3618 + for PreviousSvc<T> { 3082 3619 type Response = super::PreviousResponse; 3083 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3620 + type Future = BoxFuture< 3621 + tonic::Response<Self::Response>, 3622 + tonic::Status, 3623 + >; 3084 3624 fn call( 3085 3625 &mut self, 3086 3626 request: tonic::Request<super::PreviousRequest>, ··· 3117 3657 "/rockbox.v1alpha1.PlaybackService/FastForwardRewind" => { 3118 3658 #[allow(non_camel_case_types)] 3119 3659 struct FastForwardRewindSvc<T: PlaybackService>(pub Arc<T>); 3120 - impl<T: PlaybackService> 3121 - tonic::server::UnaryService<super::FastForwardRewindRequest> 3122 - for FastForwardRewindSvc<T> 3123 - { 3660 + impl< 3661 + T: PlaybackService, 3662 + > tonic::server::UnaryService<super::FastForwardRewindRequest> 3663 + for FastForwardRewindSvc<T> { 3124 3664 type Response = super::FastForwardRewindResponse; 3125 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3665 + type Future = BoxFuture< 3666 + tonic::Response<Self::Response>, 3667 + tonic::Status, 3668 + >; 3126 3669 fn call( 3127 3670 &mut self, 3128 3671 request: tonic::Request<super::FastForwardRewindRequest>, 3129 3672 ) -> Self::Future { 3130 3673 let inner = Arc::clone(&self.0); 3131 3674 let fut = async move { 3132 - <T as PlaybackService>::fast_forward_rewind(&inner, request).await 3675 + <T as PlaybackService>::fast_forward_rewind(&inner, request) 3676 + .await 3133 3677 }; 3134 3678 Box::pin(fut) 3135 3679 } ··· 3159 3703 "/rockbox.v1alpha1.PlaybackService/Status" => { 3160 3704 #[allow(non_camel_case_types)] 3161 3705 struct StatusSvc<T: PlaybackService>(pub Arc<T>); 3162 - impl<T: PlaybackService> tonic::server::UnaryService<super::StatusRequest> for StatusSvc<T> { 3706 + impl< 3707 + T: PlaybackService, 3708 + > tonic::server::UnaryService<super::StatusRequest> 3709 + for StatusSvc<T> { 3163 3710 type Response = super::StatusResponse; 3164 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3711 + type Future = BoxFuture< 3712 + tonic::Response<Self::Response>, 3713 + tonic::Status, 3714 + >; 3165 3715 fn call( 3166 3716 &mut self, 3167 3717 request: tonic::Request<super::StatusRequest>, ··· 3198 3748 "/rockbox.v1alpha1.PlaybackService/CurrentTrack" => { 3199 3749 #[allow(non_camel_case_types)] 3200 3750 struct CurrentTrackSvc<T: PlaybackService>(pub Arc<T>); 3201 - impl<T: PlaybackService> tonic::server::UnaryService<super::CurrentTrackRequest> 3202 - for CurrentTrackSvc<T> 3203 - { 3751 + impl< 3752 + T: PlaybackService, 3753 + > tonic::server::UnaryService<super::CurrentTrackRequest> 3754 + for CurrentTrackSvc<T> { 3204 3755 type Response = super::CurrentTrackResponse; 3205 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3756 + type Future = BoxFuture< 3757 + tonic::Response<Self::Response>, 3758 + tonic::Status, 3759 + >; 3206 3760 fn call( 3207 3761 &mut self, 3208 3762 request: tonic::Request<super::CurrentTrackRequest>, ··· 3239 3793 "/rockbox.v1alpha1.PlaybackService/NextTrack" => { 3240 3794 #[allow(non_camel_case_types)] 3241 3795 struct NextTrackSvc<T: PlaybackService>(pub Arc<T>); 3242 - impl<T: PlaybackService> tonic::server::UnaryService<super::NextTrackRequest> for NextTrackSvc<T> { 3796 + impl< 3797 + T: PlaybackService, 3798 + > tonic::server::UnaryService<super::NextTrackRequest> 3799 + for NextTrackSvc<T> { 3243 3800 type Response = super::NextTrackResponse; 3244 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3801 + type Future = BoxFuture< 3802 + tonic::Response<Self::Response>, 3803 + tonic::Status, 3804 + >; 3245 3805 fn call( 3246 3806 &mut self, 3247 3807 request: tonic::Request<super::NextTrackRequest>, ··· 3278 3838 "/rockbox.v1alpha1.PlaybackService/FlushAndReloadTracks" => { 3279 3839 #[allow(non_camel_case_types)] 3280 3840 struct FlushAndReloadTracksSvc<T: PlaybackService>(pub Arc<T>); 3281 - impl<T: PlaybackService> 3282 - tonic::server::UnaryService<super::FlushAndReloadTracksRequest> 3283 - for FlushAndReloadTracksSvc<T> 3284 - { 3841 + impl< 3842 + T: PlaybackService, 3843 + > tonic::server::UnaryService<super::FlushAndReloadTracksRequest> 3844 + for FlushAndReloadTracksSvc<T> { 3285 3845 type Response = super::FlushAndReloadTracksResponse; 3286 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3846 + type Future = BoxFuture< 3847 + tonic::Response<Self::Response>, 3848 + tonic::Status, 3849 + >; 3287 3850 fn call( 3288 3851 &mut self, 3289 3852 request: tonic::Request<super::FlushAndReloadTracksRequest>, 3290 3853 ) -> Self::Future { 3291 3854 let inner = Arc::clone(&self.0); 3292 3855 let fut = async move { 3293 - <T as PlaybackService>::flush_and_reload_tracks(&inner, request) 3856 + <T as PlaybackService>::flush_and_reload_tracks( 3857 + &inner, 3858 + request, 3859 + ) 3294 3860 .await 3295 3861 }; 3296 3862 Box::pin(fut) ··· 3321 3887 "/rockbox.v1alpha1.PlaybackService/GetFilePosition" => { 3322 3888 #[allow(non_camel_case_types)] 3323 3889 struct GetFilePositionSvc<T: PlaybackService>(pub Arc<T>); 3324 - impl<T: PlaybackService> 3325 - tonic::server::UnaryService<super::GetFilePositionRequest> 3326 - for GetFilePositionSvc<T> 3327 - { 3890 + impl< 3891 + T: PlaybackService, 3892 + > tonic::server::UnaryService<super::GetFilePositionRequest> 3893 + for GetFilePositionSvc<T> { 3328 3894 type Response = super::GetFilePositionResponse; 3329 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3895 + type Future = BoxFuture< 3896 + tonic::Response<Self::Response>, 3897 + tonic::Status, 3898 + >; 3330 3899 fn call( 3331 3900 &mut self, 3332 3901 request: tonic::Request<super::GetFilePositionRequest>, 3333 3902 ) -> Self::Future { 3334 3903 let inner = Arc::clone(&self.0); 3335 3904 let fut = async move { 3336 - <T as PlaybackService>::get_file_position(&inner, request).await 3905 + <T as PlaybackService>::get_file_position(&inner, request) 3906 + .await 3337 3907 }; 3338 3908 Box::pin(fut) 3339 3909 } ··· 3363 3933 "/rockbox.v1alpha1.PlaybackService/HardStop" => { 3364 3934 #[allow(non_camel_case_types)] 3365 3935 struct HardStopSvc<T: PlaybackService>(pub Arc<T>); 3366 - impl<T: PlaybackService> tonic::server::UnaryService<super::HardStopRequest> for HardStopSvc<T> { 3936 + impl< 3937 + T: PlaybackService, 3938 + > tonic::server::UnaryService<super::HardStopRequest> 3939 + for HardStopSvc<T> { 3367 3940 type Response = super::HardStopResponse; 3368 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3941 + type Future = BoxFuture< 3942 + tonic::Response<Self::Response>, 3943 + tonic::Status, 3944 + >; 3369 3945 fn call( 3370 3946 &mut self, 3371 3947 request: tonic::Request<super::HardStopRequest>, ··· 3402 3978 "/rockbox.v1alpha1.PlaybackService/PlayAlbum" => { 3403 3979 #[allow(non_camel_case_types)] 3404 3980 struct PlayAlbumSvc<T: PlaybackService>(pub Arc<T>); 3405 - impl<T: PlaybackService> tonic::server::UnaryService<super::PlayAlbumRequest> for PlayAlbumSvc<T> { 3981 + impl< 3982 + T: PlaybackService, 3983 + > tonic::server::UnaryService<super::PlayAlbumRequest> 3984 + for PlayAlbumSvc<T> { 3406 3985 type Response = super::PlayAlbumResponse; 3407 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 3986 + type Future = BoxFuture< 3987 + tonic::Response<Self::Response>, 3988 + tonic::Status, 3989 + >; 3408 3990 fn call( 3409 3991 &mut self, 3410 3992 request: tonic::Request<super::PlayAlbumRequest>, ··· 3441 4023 "/rockbox.v1alpha1.PlaybackService/PlayArtistTracks" => { 3442 4024 #[allow(non_camel_case_types)] 3443 4025 struct PlayArtistTracksSvc<T: PlaybackService>(pub Arc<T>); 3444 - impl<T: PlaybackService> 3445 - tonic::server::UnaryService<super::PlayArtistTracksRequest> 3446 - for PlayArtistTracksSvc<T> 3447 - { 4026 + impl< 4027 + T: PlaybackService, 4028 + > tonic::server::UnaryService<super::PlayArtistTracksRequest> 4029 + for PlayArtistTracksSvc<T> { 3448 4030 type Response = super::PlayArtistTracksResponse; 3449 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4031 + type Future = BoxFuture< 4032 + tonic::Response<Self::Response>, 4033 + tonic::Status, 4034 + >; 3450 4035 fn call( 3451 4036 &mut self, 3452 4037 request: tonic::Request<super::PlayArtistTracksRequest>, 3453 4038 ) -> Self::Future { 3454 4039 let inner = Arc::clone(&self.0); 3455 4040 let fut = async move { 3456 - <T as PlaybackService>::play_artist_tracks(&inner, request).await 4041 + <T as PlaybackService>::play_artist_tracks(&inner, request) 4042 + .await 3457 4043 }; 3458 4044 Box::pin(fut) 3459 4045 } ··· 3483 4069 "/rockbox.v1alpha1.PlaybackService/PlayPlaylist" => { 3484 4070 #[allow(non_camel_case_types)] 3485 4071 struct PlayPlaylistSvc<T: PlaybackService>(pub Arc<T>); 3486 - impl<T: PlaybackService> tonic::server::UnaryService<super::PlayPlaylistRequest> 3487 - for PlayPlaylistSvc<T> 3488 - { 4072 + impl< 4073 + T: PlaybackService, 4074 + > tonic::server::UnaryService<super::PlayPlaylistRequest> 4075 + for PlayPlaylistSvc<T> { 3489 4076 type Response = super::PlayPlaylistResponse; 3490 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4077 + type Future = BoxFuture< 4078 + tonic::Response<Self::Response>, 4079 + tonic::Status, 4080 + >; 3491 4081 fn call( 3492 4082 &mut self, 3493 4083 request: tonic::Request<super::PlayPlaylistRequest>, ··· 3524 4114 "/rockbox.v1alpha1.PlaybackService/PlayDirectory" => { 3525 4115 #[allow(non_camel_case_types)] 3526 4116 struct PlayDirectorySvc<T: PlaybackService>(pub Arc<T>); 3527 - impl<T: PlaybackService> 3528 - tonic::server::UnaryService<super::PlayDirectoryRequest> 3529 - for PlayDirectorySvc<T> 3530 - { 4117 + impl< 4118 + T: PlaybackService, 4119 + > tonic::server::UnaryService<super::PlayDirectoryRequest> 4120 + for PlayDirectorySvc<T> { 3531 4121 type Response = super::PlayDirectoryResponse; 3532 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4122 + type Future = BoxFuture< 4123 + tonic::Response<Self::Response>, 4124 + tonic::Status, 4125 + >; 3533 4126 fn call( 3534 4127 &mut self, 3535 4128 request: tonic::Request<super::PlayDirectoryRequest>, 3536 4129 ) -> Self::Future { 3537 4130 let inner = Arc::clone(&self.0); 3538 4131 let fut = async move { 3539 - <T as PlaybackService>::play_directory(&inner, request).await 4132 + <T as PlaybackService>::play_directory(&inner, request) 4133 + .await 3540 4134 }; 3541 4135 Box::pin(fut) 3542 4136 } ··· 3566 4160 "/rockbox.v1alpha1.PlaybackService/PlayMusicDirectory" => { 3567 4161 #[allow(non_camel_case_types)] 3568 4162 struct PlayMusicDirectorySvc<T: PlaybackService>(pub Arc<T>); 3569 - impl<T: PlaybackService> 3570 - tonic::server::UnaryService<super::PlayMusicDirectoryRequest> 3571 - for PlayMusicDirectorySvc<T> 3572 - { 4163 + impl< 4164 + T: PlaybackService, 4165 + > tonic::server::UnaryService<super::PlayMusicDirectoryRequest> 4166 + for PlayMusicDirectorySvc<T> { 3573 4167 type Response = super::PlayMusicDirectoryResponse; 3574 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4168 + type Future = BoxFuture< 4169 + tonic::Response<Self::Response>, 4170 + tonic::Status, 4171 + >; 3575 4172 fn call( 3576 4173 &mut self, 3577 4174 request: tonic::Request<super::PlayMusicDirectoryRequest>, 3578 4175 ) -> Self::Future { 3579 4176 let inner = Arc::clone(&self.0); 3580 4177 let fut = async move { 3581 - <T as PlaybackService>::play_music_directory(&inner, request).await 4178 + <T as PlaybackService>::play_music_directory( 4179 + &inner, 4180 + request, 4181 + ) 4182 + .await 3582 4183 }; 3583 4184 Box::pin(fut) 3584 4185 } ··· 3608 4209 "/rockbox.v1alpha1.PlaybackService/PlayTrack" => { 3609 4210 #[allow(non_camel_case_types)] 3610 4211 struct PlayTrackSvc<T: PlaybackService>(pub Arc<T>); 3611 - impl<T: PlaybackService> tonic::server::UnaryService<super::PlayTrackRequest> for PlayTrackSvc<T> { 4212 + impl< 4213 + T: PlaybackService, 4214 + > tonic::server::UnaryService<super::PlayTrackRequest> 4215 + for PlayTrackSvc<T> { 3612 4216 type Response = super::PlayTrackResponse; 3613 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4217 + type Future = BoxFuture< 4218 + tonic::Response<Self::Response>, 4219 + tonic::Status, 4220 + >; 3614 4221 fn call( 3615 4222 &mut self, 3616 4223 request: tonic::Request<super::PlayTrackRequest>, ··· 3647 4254 "/rockbox.v1alpha1.PlaybackService/PlayLikedTracks" => { 3648 4255 #[allow(non_camel_case_types)] 3649 4256 struct PlayLikedTracksSvc<T: PlaybackService>(pub Arc<T>); 3650 - impl<T: PlaybackService> 3651 - tonic::server::UnaryService<super::PlayLikedTracksRequest> 3652 - for PlayLikedTracksSvc<T> 3653 - { 4257 + impl< 4258 + T: PlaybackService, 4259 + > tonic::server::UnaryService<super::PlayLikedTracksRequest> 4260 + for PlayLikedTracksSvc<T> { 3654 4261 type Response = super::PlayLikedTracksResponse; 3655 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4262 + type Future = BoxFuture< 4263 + tonic::Response<Self::Response>, 4264 + tonic::Status, 4265 + >; 3656 4266 fn call( 3657 4267 &mut self, 3658 4268 request: tonic::Request<super::PlayLikedTracksRequest>, 3659 4269 ) -> Self::Future { 3660 4270 let inner = Arc::clone(&self.0); 3661 4271 let fut = async move { 3662 - <T as PlaybackService>::play_liked_tracks(&inner, request).await 4272 + <T as PlaybackService>::play_liked_tracks(&inner, request) 4273 + .await 3663 4274 }; 3664 4275 Box::pin(fut) 3665 4276 } ··· 3689 4300 "/rockbox.v1alpha1.PlaybackService/PlayAllTracks" => { 3690 4301 #[allow(non_camel_case_types)] 3691 4302 struct PlayAllTracksSvc<T: PlaybackService>(pub Arc<T>); 3692 - impl<T: PlaybackService> 3693 - tonic::server::UnaryService<super::PlayAllTracksRequest> 3694 - for PlayAllTracksSvc<T> 3695 - { 4303 + impl< 4304 + T: PlaybackService, 4305 + > tonic::server::UnaryService<super::PlayAllTracksRequest> 4306 + for PlayAllTracksSvc<T> { 3696 4307 type Response = super::PlayAllTracksResponse; 3697 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 4308 + type Future = BoxFuture< 4309 + tonic::Response<Self::Response>, 4310 + tonic::Status, 4311 + >; 3698 4312 fn call( 3699 4313 &mut self, 3700 4314 request: tonic::Request<super::PlayAllTracksRequest>, 3701 4315 ) -> Self::Future { 3702 4316 let inner = Arc::clone(&self.0); 3703 4317 let fut = async move { 3704 - <T as PlaybackService>::play_all_tracks(&inner, request).await 4318 + <T as PlaybackService>::play_all_tracks(&inner, request) 4319 + .await 3705 4320 }; 3706 4321 Box::pin(fut) 3707 4322 } ··· 3731 4346 "/rockbox.v1alpha1.PlaybackService/StreamCurrentTrack" => { 3732 4347 #[allow(non_camel_case_types)] 3733 4348 struct StreamCurrentTrackSvc<T: PlaybackService>(pub Arc<T>); 3734 - impl<T: PlaybackService> 3735 - tonic::server::ServerStreamingService<super::StreamCurrentTrackRequest> 3736 - for StreamCurrentTrackSvc<T> 3737 - { 4349 + impl< 4350 + T: PlaybackService, 4351 + > tonic::server::ServerStreamingService< 4352 + super::StreamCurrentTrackRequest, 4353 + > for StreamCurrentTrackSvc<T> { 3738 4354 type Response = super::CurrentTrackResponse; 3739 4355 type ResponseStream = T::StreamCurrentTrackStream; 3740 - type Future = 3741 - BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>; 4356 + type Future = BoxFuture< 4357 + tonic::Response<Self::ResponseStream>, 4358 + tonic::Status, 4359 + >; 3742 4360 fn call( 3743 4361 &mut self, 3744 4362 request: tonic::Request<super::StreamCurrentTrackRequest>, 3745 4363 ) -> Self::Future { 3746 4364 let inner = Arc::clone(&self.0); 3747 4365 let fut = async move { 3748 - <T as PlaybackService>::stream_current_track(&inner, request).await 4366 + <T as PlaybackService>::stream_current_track( 4367 + &inner, 4368 + request, 4369 + ) 4370 + .await 3749 4371 }; 3750 4372 Box::pin(fut) 3751 4373 } ··· 3775 4397 "/rockbox.v1alpha1.PlaybackService/StreamStatus" => { 3776 4398 #[allow(non_camel_case_types)] 3777 4399 struct StreamStatusSvc<T: PlaybackService>(pub Arc<T>); 3778 - impl<T: PlaybackService> 3779 - tonic::server::ServerStreamingService<super::StreamStatusRequest> 3780 - for StreamStatusSvc<T> 3781 - { 4400 + impl< 4401 + T: PlaybackService, 4402 + > tonic::server::ServerStreamingService<super::StreamStatusRequest> 4403 + for StreamStatusSvc<T> { 3782 4404 type Response = super::StatusResponse; 3783 4405 type ResponseStream = T::StreamStatusStream; 3784 - type Future = 3785 - BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>; 4406 + type Future = BoxFuture< 4407 + tonic::Response<Self::ResponseStream>, 4408 + tonic::Status, 4409 + >; 3786 4410 fn call( 3787 4411 &mut self, 3788 4412 request: tonic::Request<super::StreamStatusRequest>, ··· 3819 4443 "/rockbox.v1alpha1.PlaybackService/StreamPlaylist" => { 3820 4444 #[allow(non_camel_case_types)] 3821 4445 struct StreamPlaylistSvc<T: PlaybackService>(pub Arc<T>); 3822 - impl<T: PlaybackService> 3823 - tonic::server::ServerStreamingService<super::StreamPlaylistRequest> 3824 - for StreamPlaylistSvc<T> 3825 - { 4446 + impl< 4447 + T: PlaybackService, 4448 + > tonic::server::ServerStreamingService<super::StreamPlaylistRequest> 4449 + for StreamPlaylistSvc<T> { 3826 4450 type Response = super::PlaylistResponse; 3827 4451 type ResponseStream = T::StreamPlaylistStream; 3828 - type Future = 3829 - BoxFuture<tonic::Response<Self::ResponseStream>, tonic::Status>; 4452 + type Future = BoxFuture< 4453 + tonic::Response<Self::ResponseStream>, 4454 + tonic::Status, 4455 + >; 3830 4456 fn call( 3831 4457 &mut self, 3832 4458 request: tonic::Request<super::StreamPlaylistRequest>, 3833 4459 ) -> Self::Future { 3834 4460 let inner = Arc::clone(&self.0); 3835 4461 let fut = async move { 3836 - <T as PlaybackService>::stream_playlist(&inner, request).await 4462 + <T as PlaybackService>::stream_playlist(&inner, request) 4463 + .await 3837 4464 }; 3838 4465 Box::pin(fut) 3839 4466 } ··· 3860 4487 }; 3861 4488 Box::pin(fut) 3862 4489 } 3863 - _ => Box::pin(async move { 3864 - let mut response = http::Response::new(empty_body()); 3865 - let headers = response.headers_mut(); 3866 - headers.insert( 3867 - tonic::Status::GRPC_STATUS, 3868 - (tonic::Code::Unimplemented as i32).into(), 3869 - ); 3870 - headers.insert( 3871 - http::header::CONTENT_TYPE, 3872 - tonic::metadata::GRPC_CONTENT_TYPE, 3873 - ); 3874 - Ok(response) 3875 - }), 4490 + _ => { 4491 + Box::pin(async move { 4492 + let mut response = http::Response::new(empty_body()); 4493 + let headers = response.headers_mut(); 4494 + headers 4495 + .insert( 4496 + tonic::Status::GRPC_STATUS, 4497 + (tonic::Code::Unimplemented as i32).into(), 4498 + ); 4499 + headers 4500 + .insert( 4501 + http::header::CONTENT_TYPE, 4502 + tonic::metadata::GRPC_CONTENT_TYPE, 4503 + ); 4504 + Ok(response) 4505 + }) 4506 + } 3876 4507 } 3877 4508 } 3878 4509 } ··· 4079 4710 dead_code, 4080 4711 missing_docs, 4081 4712 clippy::wildcard_imports, 4082 - clippy::let_unit_value 4713 + clippy::let_unit_value, 4083 4714 )] 4084 - use tonic::codegen::http::Uri; 4085 4715 use tonic::codegen::*; 4716 + use tonic::codegen::http::Uri; 4086 4717 #[derive(Debug, Clone)] 4087 4718 pub struct PlaylistServiceClient<T> { 4088 4719 inner: tonic::client::Grpc<T>, ··· 4126 4757 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 4127 4758 >, 4128 4759 >, 4129 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 4130 - Into<StdError> + std::marker::Send + std::marker::Sync, 4760 + <T as tonic::codegen::Service< 4761 + http::Request<tonic::body::BoxBody>, 4762 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 4131 4763 { 4132 4764 PlaylistServiceClient::new(InterceptedService::new(inner, interceptor)) 4133 4765 } ··· 4165 4797 pub async fn get_current( 4166 4798 &mut self, 4167 4799 request: impl tonic::IntoRequest<super::GetCurrentRequest>, 4168 - ) -> std::result::Result<tonic::Response<super::GetCurrentResponse>, tonic::Status> 4169 - { 4170 - self.inner.ready().await.map_err(|e| { 4171 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4172 - })?; 4800 + ) -> std::result::Result< 4801 + tonic::Response<super::GetCurrentResponse>, 4802 + tonic::Status, 4803 + > { 4804 + self.inner 4805 + .ready() 4806 + .await 4807 + .map_err(|e| { 4808 + tonic::Status::unknown( 4809 + format!("Service was not ready: {}", e.into()), 4810 + ) 4811 + })?; 4173 4812 let codec = tonic::codec::ProstCodec::default(); 4174 4813 let path = http::uri::PathAndQuery::from_static( 4175 4814 "/rockbox.v1alpha1.PlaylistService/GetCurrent", 4176 4815 ); 4177 4816 let mut req = request.into_request(); 4178 - req.extensions_mut().insert(GrpcMethod::new( 4179 - "rockbox.v1alpha1.PlaylistService", 4180 - "GetCurrent", 4181 - )); 4817 + req.extensions_mut() 4818 + .insert( 4819 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetCurrent"), 4820 + ); 4182 4821 self.inner.unary(req, path, codec).await 4183 4822 } 4184 4823 pub async fn get_resume_info( 4185 4824 &mut self, 4186 4825 request: impl tonic::IntoRequest<super::GetResumeInfoRequest>, 4187 - ) -> std::result::Result<tonic::Response<super::GetResumeInfoResponse>, tonic::Status> 4188 - { 4189 - self.inner.ready().await.map_err(|e| { 4190 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4191 - })?; 4826 + ) -> std::result::Result< 4827 + tonic::Response<super::GetResumeInfoResponse>, 4828 + tonic::Status, 4829 + > { 4830 + self.inner 4831 + .ready() 4832 + .await 4833 + .map_err(|e| { 4834 + tonic::Status::unknown( 4835 + format!("Service was not ready: {}", e.into()), 4836 + ) 4837 + })?; 4192 4838 let codec = tonic::codec::ProstCodec::default(); 4193 4839 let path = http::uri::PathAndQuery::from_static( 4194 4840 "/rockbox.v1alpha1.PlaylistService/GetResumeInfo", 4195 4841 ); 4196 4842 let mut req = request.into_request(); 4197 - req.extensions_mut().insert(GrpcMethod::new( 4198 - "rockbox.v1alpha1.PlaylistService", 4199 - "GetResumeInfo", 4200 - )); 4843 + req.extensions_mut() 4844 + .insert( 4845 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetResumeInfo"), 4846 + ); 4201 4847 self.inner.unary(req, path, codec).await 4202 4848 } 4203 4849 pub async fn get_track_info( 4204 4850 &mut self, 4205 4851 request: impl tonic::IntoRequest<super::GetTrackInfoRequest>, 4206 - ) -> std::result::Result<tonic::Response<super::GetTrackInfoResponse>, tonic::Status> 4207 - { 4208 - self.inner.ready().await.map_err(|e| { 4209 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4210 - })?; 4852 + ) -> std::result::Result< 4853 + tonic::Response<super::GetTrackInfoResponse>, 4854 + tonic::Status, 4855 + > { 4856 + self.inner 4857 + .ready() 4858 + .await 4859 + .map_err(|e| { 4860 + tonic::Status::unknown( 4861 + format!("Service was not ready: {}", e.into()), 4862 + ) 4863 + })?; 4211 4864 let codec = tonic::codec::ProstCodec::default(); 4212 4865 let path = http::uri::PathAndQuery::from_static( 4213 4866 "/rockbox.v1alpha1.PlaylistService/GetTrackInfo", 4214 4867 ); 4215 4868 let mut req = request.into_request(); 4216 - req.extensions_mut().insert(GrpcMethod::new( 4217 - "rockbox.v1alpha1.PlaylistService", 4218 - "GetTrackInfo", 4219 - )); 4869 + req.extensions_mut() 4870 + .insert( 4871 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetTrackInfo"), 4872 + ); 4220 4873 self.inner.unary(req, path, codec).await 4221 4874 } 4222 4875 pub async fn get_first_index( 4223 4876 &mut self, 4224 4877 request: impl tonic::IntoRequest<super::GetFirstIndexRequest>, 4225 - ) -> std::result::Result<tonic::Response<super::GetFirstIndexResponse>, tonic::Status> 4226 - { 4227 - self.inner.ready().await.map_err(|e| { 4228 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4229 - })?; 4878 + ) -> std::result::Result< 4879 + tonic::Response<super::GetFirstIndexResponse>, 4880 + tonic::Status, 4881 + > { 4882 + self.inner 4883 + .ready() 4884 + .await 4885 + .map_err(|e| { 4886 + tonic::Status::unknown( 4887 + format!("Service was not ready: {}", e.into()), 4888 + ) 4889 + })?; 4230 4890 let codec = tonic::codec::ProstCodec::default(); 4231 4891 let path = http::uri::PathAndQuery::from_static( 4232 4892 "/rockbox.v1alpha1.PlaylistService/GetFirstIndex", 4233 4893 ); 4234 4894 let mut req = request.into_request(); 4235 - req.extensions_mut().insert(GrpcMethod::new( 4236 - "rockbox.v1alpha1.PlaylistService", 4237 - "GetFirstIndex", 4238 - )); 4895 + req.extensions_mut() 4896 + .insert( 4897 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "GetFirstIndex"), 4898 + ); 4239 4899 self.inner.unary(req, path, codec).await 4240 4900 } 4241 4901 pub async fn get_display_index( 4242 4902 &mut self, 4243 4903 request: impl tonic::IntoRequest<super::GetDisplayIndexRequest>, 4244 - ) -> std::result::Result<tonic::Response<super::GetDisplayIndexResponse>, tonic::Status> 4245 - { 4246 - self.inner.ready().await.map_err(|e| { 4247 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4248 - })?; 4904 + ) -> std::result::Result< 4905 + tonic::Response<super::GetDisplayIndexResponse>, 4906 + tonic::Status, 4907 + > { 4908 + self.inner 4909 + .ready() 4910 + .await 4911 + .map_err(|e| { 4912 + tonic::Status::unknown( 4913 + format!("Service was not ready: {}", e.into()), 4914 + ) 4915 + })?; 4249 4916 let codec = tonic::codec::ProstCodec::default(); 4250 4917 let path = http::uri::PathAndQuery::from_static( 4251 4918 "/rockbox.v1alpha1.PlaylistService/GetDisplayIndex", 4252 4919 ); 4253 4920 let mut req = request.into_request(); 4254 - req.extensions_mut().insert(GrpcMethod::new( 4255 - "rockbox.v1alpha1.PlaylistService", 4256 - "GetDisplayIndex", 4257 - )); 4921 + req.extensions_mut() 4922 + .insert( 4923 + GrpcMethod::new( 4924 + "rockbox.v1alpha1.PlaylistService", 4925 + "GetDisplayIndex", 4926 + ), 4927 + ); 4258 4928 self.inner.unary(req, path, codec).await 4259 4929 } 4260 4930 pub async fn amount( 4261 4931 &mut self, 4262 4932 request: impl tonic::IntoRequest<super::AmountRequest>, 4263 4933 ) -> std::result::Result<tonic::Response<super::AmountResponse>, tonic::Status> { 4264 - self.inner.ready().await.map_err(|e| { 4265 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4266 - })?; 4934 + self.inner 4935 + .ready() 4936 + .await 4937 + .map_err(|e| { 4938 + tonic::Status::unknown( 4939 + format!("Service was not ready: {}", e.into()), 4940 + ) 4941 + })?; 4267 4942 let codec = tonic::codec::ProstCodec::default(); 4268 - let path = 4269 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaylistService/Amount"); 4943 + let path = http::uri::PathAndQuery::from_static( 4944 + "/rockbox.v1alpha1.PlaylistService/Amount", 4945 + ); 4270 4946 let mut req = request.into_request(); 4271 - req.extensions_mut().insert(GrpcMethod::new( 4272 - "rockbox.v1alpha1.PlaylistService", 4273 - "Amount", 4274 - )); 4947 + req.extensions_mut() 4948 + .insert(GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "Amount")); 4275 4949 self.inner.unary(req, path, codec).await 4276 4950 } 4277 4951 pub async fn playlist_resume( 4278 4952 &mut self, 4279 4953 request: impl tonic::IntoRequest<super::PlaylistResumeRequest>, 4280 - ) -> std::result::Result<tonic::Response<super::PlaylistResumeResponse>, tonic::Status> 4281 - { 4282 - self.inner.ready().await.map_err(|e| { 4283 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4284 - })?; 4954 + ) -> std::result::Result< 4955 + tonic::Response<super::PlaylistResumeResponse>, 4956 + tonic::Status, 4957 + > { 4958 + self.inner 4959 + .ready() 4960 + .await 4961 + .map_err(|e| { 4962 + tonic::Status::unknown( 4963 + format!("Service was not ready: {}", e.into()), 4964 + ) 4965 + })?; 4285 4966 let codec = tonic::codec::ProstCodec::default(); 4286 4967 let path = http::uri::PathAndQuery::from_static( 4287 4968 "/rockbox.v1alpha1.PlaylistService/PlaylistResume", 4288 4969 ); 4289 4970 let mut req = request.into_request(); 4290 - req.extensions_mut().insert(GrpcMethod::new( 4291 - "rockbox.v1alpha1.PlaylistService", 4292 - "PlaylistResume", 4293 - )); 4971 + req.extensions_mut() 4972 + .insert( 4973 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "PlaylistResume"), 4974 + ); 4294 4975 self.inner.unary(req, path, codec).await 4295 4976 } 4296 4977 pub async fn resume_track( 4297 4978 &mut self, 4298 4979 request: impl tonic::IntoRequest<super::ResumeTrackRequest>, 4299 - ) -> std::result::Result<tonic::Response<super::ResumeTrackResponse>, tonic::Status> 4300 - { 4301 - self.inner.ready().await.map_err(|e| { 4302 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4303 - })?; 4980 + ) -> std::result::Result< 4981 + tonic::Response<super::ResumeTrackResponse>, 4982 + tonic::Status, 4983 + > { 4984 + self.inner 4985 + .ready() 4986 + .await 4987 + .map_err(|e| { 4988 + tonic::Status::unknown( 4989 + format!("Service was not ready: {}", e.into()), 4990 + ) 4991 + })?; 4304 4992 let codec = tonic::codec::ProstCodec::default(); 4305 4993 let path = http::uri::PathAndQuery::from_static( 4306 4994 "/rockbox.v1alpha1.PlaylistService/ResumeTrack", 4307 4995 ); 4308 4996 let mut req = request.into_request(); 4309 - req.extensions_mut().insert(GrpcMethod::new( 4310 - "rockbox.v1alpha1.PlaylistService", 4311 - "ResumeTrack", 4312 - )); 4997 + req.extensions_mut() 4998 + .insert( 4999 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "ResumeTrack"), 5000 + ); 4313 5001 self.inner.unary(req, path, codec).await 4314 5002 } 4315 5003 pub async fn set_modified( 4316 5004 &mut self, 4317 5005 request: impl tonic::IntoRequest<super::SetModifiedRequest>, 4318 - ) -> std::result::Result<tonic::Response<super::SetModifiedResponse>, tonic::Status> 4319 - { 4320 - self.inner.ready().await.map_err(|e| { 4321 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4322 - })?; 5006 + ) -> std::result::Result< 5007 + tonic::Response<super::SetModifiedResponse>, 5008 + tonic::Status, 5009 + > { 5010 + self.inner 5011 + .ready() 5012 + .await 5013 + .map_err(|e| { 5014 + tonic::Status::unknown( 5015 + format!("Service was not ready: {}", e.into()), 5016 + ) 5017 + })?; 4323 5018 let codec = tonic::codec::ProstCodec::default(); 4324 5019 let path = http::uri::PathAndQuery::from_static( 4325 5020 "/rockbox.v1alpha1.PlaylistService/SetModified", 4326 5021 ); 4327 5022 let mut req = request.into_request(); 4328 - req.extensions_mut().insert(GrpcMethod::new( 4329 - "rockbox.v1alpha1.PlaylistService", 4330 - "SetModified", 4331 - )); 5023 + req.extensions_mut() 5024 + .insert( 5025 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "SetModified"), 5026 + ); 4332 5027 self.inner.unary(req, path, codec).await 4333 5028 } 4334 5029 pub async fn start( 4335 5030 &mut self, 4336 5031 request: impl tonic::IntoRequest<super::StartRequest>, 4337 5032 ) -> std::result::Result<tonic::Response<super::StartResponse>, tonic::Status> { 4338 - self.inner.ready().await.map_err(|e| { 4339 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4340 - })?; 5033 + self.inner 5034 + .ready() 5035 + .await 5036 + .map_err(|e| { 5037 + tonic::Status::unknown( 5038 + format!("Service was not ready: {}", e.into()), 5039 + ) 5040 + })?; 4341 5041 let codec = tonic::codec::ProstCodec::default(); 4342 - let path = 4343 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaylistService/Start"); 5042 + let path = http::uri::PathAndQuery::from_static( 5043 + "/rockbox.v1alpha1.PlaylistService/Start", 5044 + ); 4344 5045 let mut req = request.into_request(); 4345 5046 req.extensions_mut() 4346 5047 .insert(GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "Start")); ··· 4350 5051 &mut self, 4351 5052 request: impl tonic::IntoRequest<super::SyncRequest>, 4352 5053 ) -> std::result::Result<tonic::Response<super::SyncResponse>, tonic::Status> { 4353 - self.inner.ready().await.map_err(|e| { 4354 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4355 - })?; 5054 + self.inner 5055 + .ready() 5056 + .await 5057 + .map_err(|e| { 5058 + tonic::Status::unknown( 5059 + format!("Service was not ready: {}", e.into()), 5060 + ) 5061 + })?; 4356 5062 let codec = tonic::codec::ProstCodec::default(); 4357 - let path = 4358 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.PlaylistService/Sync"); 5063 + let path = http::uri::PathAndQuery::from_static( 5064 + "/rockbox.v1alpha1.PlaylistService/Sync", 5065 + ); 4359 5066 let mut req = request.into_request(); 4360 5067 req.extensions_mut() 4361 5068 .insert(GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "Sync")); ··· 4364 5071 pub async fn remove_all_tracks( 4365 5072 &mut self, 4366 5073 request: impl tonic::IntoRequest<super::RemoveAllTracksRequest>, 4367 - ) -> std::result::Result<tonic::Response<super::RemoveAllTracksResponse>, tonic::Status> 4368 - { 4369 - self.inner.ready().await.map_err(|e| { 4370 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4371 - })?; 5074 + ) -> std::result::Result< 5075 + tonic::Response<super::RemoveAllTracksResponse>, 5076 + tonic::Status, 5077 + > { 5078 + self.inner 5079 + .ready() 5080 + .await 5081 + .map_err(|e| { 5082 + tonic::Status::unknown( 5083 + format!("Service was not ready: {}", e.into()), 5084 + ) 5085 + })?; 4372 5086 let codec = tonic::codec::ProstCodec::default(); 4373 5087 let path = http::uri::PathAndQuery::from_static( 4374 5088 "/rockbox.v1alpha1.PlaylistService/RemoveAllTracks", 4375 5089 ); 4376 5090 let mut req = request.into_request(); 4377 - req.extensions_mut().insert(GrpcMethod::new( 4378 - "rockbox.v1alpha1.PlaylistService", 4379 - "RemoveAllTracks", 4380 - )); 5091 + req.extensions_mut() 5092 + .insert( 5093 + GrpcMethod::new( 5094 + "rockbox.v1alpha1.PlaylistService", 5095 + "RemoveAllTracks", 5096 + ), 5097 + ); 4381 5098 self.inner.unary(req, path, codec).await 4382 5099 } 4383 5100 pub async fn remove_tracks( 4384 5101 &mut self, 4385 5102 request: impl tonic::IntoRequest<super::RemoveTracksRequest>, 4386 - ) -> std::result::Result<tonic::Response<super::RemoveTracksResponse>, tonic::Status> 4387 - { 4388 - self.inner.ready().await.map_err(|e| { 4389 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4390 - })?; 5103 + ) -> std::result::Result< 5104 + tonic::Response<super::RemoveTracksResponse>, 5105 + tonic::Status, 5106 + > { 5107 + self.inner 5108 + .ready() 5109 + .await 5110 + .map_err(|e| { 5111 + tonic::Status::unknown( 5112 + format!("Service was not ready: {}", e.into()), 5113 + ) 5114 + })?; 4391 5115 let codec = tonic::codec::ProstCodec::default(); 4392 5116 let path = http::uri::PathAndQuery::from_static( 4393 5117 "/rockbox.v1alpha1.PlaylistService/RemoveTracks", 4394 5118 ); 4395 5119 let mut req = request.into_request(); 4396 - req.extensions_mut().insert(GrpcMethod::new( 4397 - "rockbox.v1alpha1.PlaylistService", 4398 - "RemoveTracks", 4399 - )); 5120 + req.extensions_mut() 5121 + .insert( 5122 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "RemoveTracks"), 5123 + ); 4400 5124 self.inner.unary(req, path, codec).await 4401 5125 } 4402 5126 pub async fn create_playlist( 4403 5127 &mut self, 4404 5128 request: impl tonic::IntoRequest<super::CreatePlaylistRequest>, 4405 - ) -> std::result::Result<tonic::Response<super::CreatePlaylistResponse>, tonic::Status> 4406 - { 4407 - self.inner.ready().await.map_err(|e| { 4408 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4409 - })?; 5129 + ) -> std::result::Result< 5130 + tonic::Response<super::CreatePlaylistResponse>, 5131 + tonic::Status, 5132 + > { 5133 + self.inner 5134 + .ready() 5135 + .await 5136 + .map_err(|e| { 5137 + tonic::Status::unknown( 5138 + format!("Service was not ready: {}", e.into()), 5139 + ) 5140 + })?; 4410 5141 let codec = tonic::codec::ProstCodec::default(); 4411 5142 let path = http::uri::PathAndQuery::from_static( 4412 5143 "/rockbox.v1alpha1.PlaylistService/CreatePlaylist", 4413 5144 ); 4414 5145 let mut req = request.into_request(); 4415 - req.extensions_mut().insert(GrpcMethod::new( 4416 - "rockbox.v1alpha1.PlaylistService", 4417 - "CreatePlaylist", 4418 - )); 5146 + req.extensions_mut() 5147 + .insert( 5148 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "CreatePlaylist"), 5149 + ); 4419 5150 self.inner.unary(req, path, codec).await 4420 5151 } 4421 5152 pub async fn insert_tracks( 4422 5153 &mut self, 4423 5154 request: impl tonic::IntoRequest<super::InsertTracksRequest>, 4424 - ) -> std::result::Result<tonic::Response<super::InsertTracksResponse>, tonic::Status> 4425 - { 4426 - self.inner.ready().await.map_err(|e| { 4427 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4428 - })?; 5155 + ) -> std::result::Result< 5156 + tonic::Response<super::InsertTracksResponse>, 5157 + tonic::Status, 5158 + > { 5159 + self.inner 5160 + .ready() 5161 + .await 5162 + .map_err(|e| { 5163 + tonic::Status::unknown( 5164 + format!("Service was not ready: {}", e.into()), 5165 + ) 5166 + })?; 4429 5167 let codec = tonic::codec::ProstCodec::default(); 4430 5168 let path = http::uri::PathAndQuery::from_static( 4431 5169 "/rockbox.v1alpha1.PlaylistService/InsertTracks", 4432 5170 ); 4433 5171 let mut req = request.into_request(); 4434 - req.extensions_mut().insert(GrpcMethod::new( 4435 - "rockbox.v1alpha1.PlaylistService", 4436 - "InsertTracks", 4437 - )); 5172 + req.extensions_mut() 5173 + .insert( 5174 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "InsertTracks"), 5175 + ); 4438 5176 self.inner.unary(req, path, codec).await 4439 5177 } 4440 5178 pub async fn insert_directory( 4441 5179 &mut self, 4442 5180 request: impl tonic::IntoRequest<super::InsertDirectoryRequest>, 4443 - ) -> std::result::Result<tonic::Response<super::InsertDirectoryResponse>, tonic::Status> 4444 - { 4445 - self.inner.ready().await.map_err(|e| { 4446 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4447 - })?; 5181 + ) -> std::result::Result< 5182 + tonic::Response<super::InsertDirectoryResponse>, 5183 + tonic::Status, 5184 + > { 5185 + self.inner 5186 + .ready() 5187 + .await 5188 + .map_err(|e| { 5189 + tonic::Status::unknown( 5190 + format!("Service was not ready: {}", e.into()), 5191 + ) 5192 + })?; 4448 5193 let codec = tonic::codec::ProstCodec::default(); 4449 5194 let path = http::uri::PathAndQuery::from_static( 4450 5195 "/rockbox.v1alpha1.PlaylistService/InsertDirectory", 4451 5196 ); 4452 5197 let mut req = request.into_request(); 4453 - req.extensions_mut().insert(GrpcMethod::new( 4454 - "rockbox.v1alpha1.PlaylistService", 4455 - "InsertDirectory", 4456 - )); 5198 + req.extensions_mut() 5199 + .insert( 5200 + GrpcMethod::new( 5201 + "rockbox.v1alpha1.PlaylistService", 5202 + "InsertDirectory", 5203 + ), 5204 + ); 4457 5205 self.inner.unary(req, path, codec).await 4458 5206 } 4459 5207 pub async fn insert_playlist( 4460 5208 &mut self, 4461 5209 request: impl tonic::IntoRequest<super::InsertPlaylistRequest>, 4462 - ) -> std::result::Result<tonic::Response<super::InsertPlaylistResponse>, tonic::Status> 4463 - { 4464 - self.inner.ready().await.map_err(|e| { 4465 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4466 - })?; 5210 + ) -> std::result::Result< 5211 + tonic::Response<super::InsertPlaylistResponse>, 5212 + tonic::Status, 5213 + > { 5214 + self.inner 5215 + .ready() 5216 + .await 5217 + .map_err(|e| { 5218 + tonic::Status::unknown( 5219 + format!("Service was not ready: {}", e.into()), 5220 + ) 5221 + })?; 4467 5222 let codec = tonic::codec::ProstCodec::default(); 4468 5223 let path = http::uri::PathAndQuery::from_static( 4469 5224 "/rockbox.v1alpha1.PlaylistService/InsertPlaylist", 4470 5225 ); 4471 5226 let mut req = request.into_request(); 4472 - req.extensions_mut().insert(GrpcMethod::new( 4473 - "rockbox.v1alpha1.PlaylistService", 4474 - "InsertPlaylist", 4475 - )); 5227 + req.extensions_mut() 5228 + .insert( 5229 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "InsertPlaylist"), 5230 + ); 4476 5231 self.inner.unary(req, path, codec).await 4477 5232 } 4478 5233 pub async fn insert_album( 4479 5234 &mut self, 4480 5235 request: impl tonic::IntoRequest<super::InsertAlbumRequest>, 4481 - ) -> std::result::Result<tonic::Response<super::InsertAlbumResponse>, tonic::Status> 4482 - { 4483 - self.inner.ready().await.map_err(|e| { 4484 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4485 - })?; 5236 + ) -> std::result::Result< 5237 + tonic::Response<super::InsertAlbumResponse>, 5238 + tonic::Status, 5239 + > { 5240 + self.inner 5241 + .ready() 5242 + .await 5243 + .map_err(|e| { 5244 + tonic::Status::unknown( 5245 + format!("Service was not ready: {}", e.into()), 5246 + ) 5247 + })?; 4486 5248 let codec = tonic::codec::ProstCodec::default(); 4487 5249 let path = http::uri::PathAndQuery::from_static( 4488 5250 "/rockbox.v1alpha1.PlaylistService/InsertAlbum", 4489 5251 ); 4490 5252 let mut req = request.into_request(); 4491 - req.extensions_mut().insert(GrpcMethod::new( 4492 - "rockbox.v1alpha1.PlaylistService", 4493 - "InsertAlbum", 4494 - )); 5253 + req.extensions_mut() 5254 + .insert( 5255 + GrpcMethod::new("rockbox.v1alpha1.PlaylistService", "InsertAlbum"), 5256 + ); 4495 5257 self.inner.unary(req, path, codec).await 4496 5258 } 4497 5259 pub async fn insert_artist_tracks( 4498 5260 &mut self, 4499 5261 request: impl tonic::IntoRequest<super::InsertArtistTracksRequest>, 4500 - ) -> std::result::Result<tonic::Response<super::InsertArtistTracksResponse>, tonic::Status> 4501 - { 4502 - self.inner.ready().await.map_err(|e| { 4503 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4504 - })?; 5262 + ) -> std::result::Result< 5263 + tonic::Response<super::InsertArtistTracksResponse>, 5264 + tonic::Status, 5265 + > { 5266 + self.inner 5267 + .ready() 5268 + .await 5269 + .map_err(|e| { 5270 + tonic::Status::unknown( 5271 + format!("Service was not ready: {}", e.into()), 5272 + ) 5273 + })?; 4505 5274 let codec = tonic::codec::ProstCodec::default(); 4506 5275 let path = http::uri::PathAndQuery::from_static( 4507 5276 "/rockbox.v1alpha1.PlaylistService/InsertArtistTracks", 4508 5277 ); 4509 5278 let mut req = request.into_request(); 4510 - req.extensions_mut().insert(GrpcMethod::new( 4511 - "rockbox.v1alpha1.PlaylistService", 4512 - "InsertArtistTracks", 4513 - )); 5279 + req.extensions_mut() 5280 + .insert( 5281 + GrpcMethod::new( 5282 + "rockbox.v1alpha1.PlaylistService", 5283 + "InsertArtistTracks", 5284 + ), 5285 + ); 4514 5286 self.inner.unary(req, path, codec).await 4515 5287 } 4516 5288 pub async fn shuffle_playlist( 4517 5289 &mut self, 4518 5290 request: impl tonic::IntoRequest<super::ShufflePlaylistRequest>, 4519 - ) -> std::result::Result<tonic::Response<super::ShufflePlaylistResponse>, tonic::Status> 4520 - { 4521 - self.inner.ready().await.map_err(|e| { 4522 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 4523 - })?; 5291 + ) -> std::result::Result< 5292 + tonic::Response<super::ShufflePlaylistResponse>, 5293 + tonic::Status, 5294 + > { 5295 + self.inner 5296 + .ready() 5297 + .await 5298 + .map_err(|e| { 5299 + tonic::Status::unknown( 5300 + format!("Service was not ready: {}", e.into()), 5301 + ) 5302 + })?; 4524 5303 let codec = tonic::codec::ProstCodec::default(); 4525 5304 let path = http::uri::PathAndQuery::from_static( 4526 5305 "/rockbox.v1alpha1.PlaylistService/ShufflePlaylist", 4527 5306 ); 4528 5307 let mut req = request.into_request(); 4529 - req.extensions_mut().insert(GrpcMethod::new( 4530 - "rockbox.v1alpha1.PlaylistService", 4531 - "ShufflePlaylist", 4532 - )); 5308 + req.extensions_mut() 5309 + .insert( 5310 + GrpcMethod::new( 5311 + "rockbox.v1alpha1.PlaylistService", 5312 + "ShufflePlaylist", 5313 + ), 5314 + ); 4533 5315 self.inner.unary(req, path, codec).await 4534 5316 } 4535 5317 } ··· 4541 5323 dead_code, 4542 5324 missing_docs, 4543 5325 clippy::wildcard_imports, 4544 - clippy::let_unit_value 5326 + clippy::let_unit_value, 4545 5327 )] 4546 5328 use tonic::codegen::*; 4547 5329 /// Generated trait containing gRPC methods that should be implemented for use with PlaylistServiceServer. ··· 4550 5332 async fn get_current( 4551 5333 &self, 4552 5334 request: tonic::Request<super::GetCurrentRequest>, 4553 - ) -> std::result::Result<tonic::Response<super::GetCurrentResponse>, tonic::Status>; 5335 + ) -> std::result::Result< 5336 + tonic::Response<super::GetCurrentResponse>, 5337 + tonic::Status, 5338 + >; 4554 5339 async fn get_resume_info( 4555 5340 &self, 4556 5341 request: tonic::Request<super::GetResumeInfoRequest>, 4557 - ) -> std::result::Result<tonic::Response<super::GetResumeInfoResponse>, tonic::Status>; 5342 + ) -> std::result::Result< 5343 + tonic::Response<super::GetResumeInfoResponse>, 5344 + tonic::Status, 5345 + >; 4558 5346 async fn get_track_info( 4559 5347 &self, 4560 5348 request: tonic::Request<super::GetTrackInfoRequest>, 4561 - ) -> std::result::Result<tonic::Response<super::GetTrackInfoResponse>, tonic::Status>; 5349 + ) -> std::result::Result< 5350 + tonic::Response<super::GetTrackInfoResponse>, 5351 + tonic::Status, 5352 + >; 4562 5353 async fn get_first_index( 4563 5354 &self, 4564 5355 request: tonic::Request<super::GetFirstIndexRequest>, 4565 - ) -> std::result::Result<tonic::Response<super::GetFirstIndexResponse>, tonic::Status>; 5356 + ) -> std::result::Result< 5357 + tonic::Response<super::GetFirstIndexResponse>, 5358 + tonic::Status, 5359 + >; 4566 5360 async fn get_display_index( 4567 5361 &self, 4568 5362 request: tonic::Request<super::GetDisplayIndexRequest>, 4569 - ) -> std::result::Result<tonic::Response<super::GetDisplayIndexResponse>, tonic::Status>; 5363 + ) -> std::result::Result< 5364 + tonic::Response<super::GetDisplayIndexResponse>, 5365 + tonic::Status, 5366 + >; 4570 5367 async fn amount( 4571 5368 &self, 4572 5369 request: tonic::Request<super::AmountRequest>, ··· 4574 5371 async fn playlist_resume( 4575 5372 &self, 4576 5373 request: tonic::Request<super::PlaylistResumeRequest>, 4577 - ) -> std::result::Result<tonic::Response<super::PlaylistResumeResponse>, tonic::Status>; 5374 + ) -> std::result::Result< 5375 + tonic::Response<super::PlaylistResumeResponse>, 5376 + tonic::Status, 5377 + >; 4578 5378 async fn resume_track( 4579 5379 &self, 4580 5380 request: tonic::Request<super::ResumeTrackRequest>, 4581 - ) -> std::result::Result<tonic::Response<super::ResumeTrackResponse>, tonic::Status>; 5381 + ) -> std::result::Result< 5382 + tonic::Response<super::ResumeTrackResponse>, 5383 + tonic::Status, 5384 + >; 4582 5385 async fn set_modified( 4583 5386 &self, 4584 5387 request: tonic::Request<super::SetModifiedRequest>, 4585 - ) -> std::result::Result<tonic::Response<super::SetModifiedResponse>, tonic::Status>; 5388 + ) -> std::result::Result< 5389 + tonic::Response<super::SetModifiedResponse>, 5390 + tonic::Status, 5391 + >; 4586 5392 async fn start( 4587 5393 &self, 4588 5394 request: tonic::Request<super::StartRequest>, ··· 4594 5400 async fn remove_all_tracks( 4595 5401 &self, 4596 5402 request: tonic::Request<super::RemoveAllTracksRequest>, 4597 - ) -> std::result::Result<tonic::Response<super::RemoveAllTracksResponse>, tonic::Status>; 5403 + ) -> std::result::Result< 5404 + tonic::Response<super::RemoveAllTracksResponse>, 5405 + tonic::Status, 5406 + >; 4598 5407 async fn remove_tracks( 4599 5408 &self, 4600 5409 request: tonic::Request<super::RemoveTracksRequest>, 4601 - ) -> std::result::Result<tonic::Response<super::RemoveTracksResponse>, tonic::Status>; 5410 + ) -> std::result::Result< 5411 + tonic::Response<super::RemoveTracksResponse>, 5412 + tonic::Status, 5413 + >; 4602 5414 async fn create_playlist( 4603 5415 &self, 4604 5416 request: tonic::Request<super::CreatePlaylistRequest>, 4605 - ) -> std::result::Result<tonic::Response<super::CreatePlaylistResponse>, tonic::Status>; 5417 + ) -> std::result::Result< 5418 + tonic::Response<super::CreatePlaylistResponse>, 5419 + tonic::Status, 5420 + >; 4606 5421 async fn insert_tracks( 4607 5422 &self, 4608 5423 request: tonic::Request<super::InsertTracksRequest>, 4609 - ) -> std::result::Result<tonic::Response<super::InsertTracksResponse>, tonic::Status>; 5424 + ) -> std::result::Result< 5425 + tonic::Response<super::InsertTracksResponse>, 5426 + tonic::Status, 5427 + >; 4610 5428 async fn insert_directory( 4611 5429 &self, 4612 5430 request: tonic::Request<super::InsertDirectoryRequest>, 4613 - ) -> std::result::Result<tonic::Response<super::InsertDirectoryResponse>, tonic::Status>; 5431 + ) -> std::result::Result< 5432 + tonic::Response<super::InsertDirectoryResponse>, 5433 + tonic::Status, 5434 + >; 4614 5435 async fn insert_playlist( 4615 5436 &self, 4616 5437 request: tonic::Request<super::InsertPlaylistRequest>, 4617 - ) -> std::result::Result<tonic::Response<super::InsertPlaylistResponse>, tonic::Status>; 5438 + ) -> std::result::Result< 5439 + tonic::Response<super::InsertPlaylistResponse>, 5440 + tonic::Status, 5441 + >; 4618 5442 async fn insert_album( 4619 5443 &self, 4620 5444 request: tonic::Request<super::InsertAlbumRequest>, 4621 - ) -> std::result::Result<tonic::Response<super::InsertAlbumResponse>, tonic::Status>; 5445 + ) -> std::result::Result< 5446 + tonic::Response<super::InsertAlbumResponse>, 5447 + tonic::Status, 5448 + >; 4622 5449 async fn insert_artist_tracks( 4623 5450 &self, 4624 5451 request: tonic::Request<super::InsertArtistTracksRequest>, 4625 - ) -> std::result::Result<tonic::Response<super::InsertArtistTracksResponse>, tonic::Status>; 5452 + ) -> std::result::Result< 5453 + tonic::Response<super::InsertArtistTracksResponse>, 5454 + tonic::Status, 5455 + >; 4626 5456 async fn shuffle_playlist( 4627 5457 &self, 4628 5458 request: tonic::Request<super::ShufflePlaylistRequest>, 4629 - ) -> std::result::Result<tonic::Response<super::ShufflePlaylistResponse>, tonic::Status>; 5459 + ) -> std::result::Result< 5460 + tonic::Response<super::ShufflePlaylistResponse>, 5461 + tonic::Status, 5462 + >; 4630 5463 } 4631 5464 #[derive(Debug)] 4632 5465 pub struct PlaylistServiceServer<T> { ··· 4649 5482 max_encoding_message_size: None, 4650 5483 } 4651 5484 } 4652 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 5485 + pub fn with_interceptor<F>( 5486 + inner: T, 5487 + interceptor: F, 5488 + ) -> InterceptedService<Self, F> 4653 5489 where 4654 5490 F: tonic::service::Interceptor, 4655 5491 { ··· 4704 5540 "/rockbox.v1alpha1.PlaylistService/GetCurrent" => { 4705 5541 #[allow(non_camel_case_types)] 4706 5542 struct GetCurrentSvc<T: PlaylistService>(pub Arc<T>); 4707 - impl<T: PlaylistService> tonic::server::UnaryService<super::GetCurrentRequest> 4708 - for GetCurrentSvc<T> 4709 - { 5543 + impl< 5544 + T: PlaylistService, 5545 + > tonic::server::UnaryService<super::GetCurrentRequest> 5546 + for GetCurrentSvc<T> { 4710 5547 type Response = super::GetCurrentResponse; 4711 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5548 + type Future = BoxFuture< 5549 + tonic::Response<Self::Response>, 5550 + tonic::Status, 5551 + >; 4712 5552 fn call( 4713 5553 &mut self, 4714 5554 request: tonic::Request<super::GetCurrentRequest>, ··· 4745 5585 "/rockbox.v1alpha1.PlaylistService/GetResumeInfo" => { 4746 5586 #[allow(non_camel_case_types)] 4747 5587 struct GetResumeInfoSvc<T: PlaylistService>(pub Arc<T>); 4748 - impl<T: PlaylistService> 4749 - tonic::server::UnaryService<super::GetResumeInfoRequest> 4750 - for GetResumeInfoSvc<T> 4751 - { 5588 + impl< 5589 + T: PlaylistService, 5590 + > tonic::server::UnaryService<super::GetResumeInfoRequest> 5591 + for GetResumeInfoSvc<T> { 4752 5592 type Response = super::GetResumeInfoResponse; 4753 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5593 + type Future = BoxFuture< 5594 + tonic::Response<Self::Response>, 5595 + tonic::Status, 5596 + >; 4754 5597 fn call( 4755 5598 &mut self, 4756 5599 request: tonic::Request<super::GetResumeInfoRequest>, 4757 5600 ) -> Self::Future { 4758 5601 let inner = Arc::clone(&self.0); 4759 5602 let fut = async move { 4760 - <T as PlaylistService>::get_resume_info(&inner, request).await 5603 + <T as PlaylistService>::get_resume_info(&inner, request) 5604 + .await 4761 5605 }; 4762 5606 Box::pin(fut) 4763 5607 } ··· 4787 5631 "/rockbox.v1alpha1.PlaylistService/GetTrackInfo" => { 4788 5632 #[allow(non_camel_case_types)] 4789 5633 struct GetTrackInfoSvc<T: PlaylistService>(pub Arc<T>); 4790 - impl<T: PlaylistService> tonic::server::UnaryService<super::GetTrackInfoRequest> 4791 - for GetTrackInfoSvc<T> 4792 - { 5634 + impl< 5635 + T: PlaylistService, 5636 + > tonic::server::UnaryService<super::GetTrackInfoRequest> 5637 + for GetTrackInfoSvc<T> { 4793 5638 type Response = super::GetTrackInfoResponse; 4794 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5639 + type Future = BoxFuture< 5640 + tonic::Response<Self::Response>, 5641 + tonic::Status, 5642 + >; 4795 5643 fn call( 4796 5644 &mut self, 4797 5645 request: tonic::Request<super::GetTrackInfoRequest>, 4798 5646 ) -> Self::Future { 4799 5647 let inner = Arc::clone(&self.0); 4800 5648 let fut = async move { 4801 - <T as PlaylistService>::get_track_info(&inner, request).await 5649 + <T as PlaylistService>::get_track_info(&inner, request) 5650 + .await 4802 5651 }; 4803 5652 Box::pin(fut) 4804 5653 } ··· 4828 5677 "/rockbox.v1alpha1.PlaylistService/GetFirstIndex" => { 4829 5678 #[allow(non_camel_case_types)] 4830 5679 struct GetFirstIndexSvc<T: PlaylistService>(pub Arc<T>); 4831 - impl<T: PlaylistService> 4832 - tonic::server::UnaryService<super::GetFirstIndexRequest> 4833 - for GetFirstIndexSvc<T> 4834 - { 5680 + impl< 5681 + T: PlaylistService, 5682 + > tonic::server::UnaryService<super::GetFirstIndexRequest> 5683 + for GetFirstIndexSvc<T> { 4835 5684 type Response = super::GetFirstIndexResponse; 4836 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5685 + type Future = BoxFuture< 5686 + tonic::Response<Self::Response>, 5687 + tonic::Status, 5688 + >; 4837 5689 fn call( 4838 5690 &mut self, 4839 5691 request: tonic::Request<super::GetFirstIndexRequest>, 4840 5692 ) -> Self::Future { 4841 5693 let inner = Arc::clone(&self.0); 4842 5694 let fut = async move { 4843 - <T as PlaylistService>::get_first_index(&inner, request).await 5695 + <T as PlaylistService>::get_first_index(&inner, request) 5696 + .await 4844 5697 }; 4845 5698 Box::pin(fut) 4846 5699 } ··· 4870 5723 "/rockbox.v1alpha1.PlaylistService/GetDisplayIndex" => { 4871 5724 #[allow(non_camel_case_types)] 4872 5725 struct GetDisplayIndexSvc<T: PlaylistService>(pub Arc<T>); 4873 - impl<T: PlaylistService> 4874 - tonic::server::UnaryService<super::GetDisplayIndexRequest> 4875 - for GetDisplayIndexSvc<T> 4876 - { 5726 + impl< 5727 + T: PlaylistService, 5728 + > tonic::server::UnaryService<super::GetDisplayIndexRequest> 5729 + for GetDisplayIndexSvc<T> { 4877 5730 type Response = super::GetDisplayIndexResponse; 4878 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5731 + type Future = BoxFuture< 5732 + tonic::Response<Self::Response>, 5733 + tonic::Status, 5734 + >; 4879 5735 fn call( 4880 5736 &mut self, 4881 5737 request: tonic::Request<super::GetDisplayIndexRequest>, 4882 5738 ) -> Self::Future { 4883 5739 let inner = Arc::clone(&self.0); 4884 5740 let fut = async move { 4885 - <T as PlaylistService>::get_display_index(&inner, request).await 5741 + <T as PlaylistService>::get_display_index(&inner, request) 5742 + .await 4886 5743 }; 4887 5744 Box::pin(fut) 4888 5745 } ··· 4912 5769 "/rockbox.v1alpha1.PlaylistService/Amount" => { 4913 5770 #[allow(non_camel_case_types)] 4914 5771 struct AmountSvc<T: PlaylistService>(pub Arc<T>); 4915 - impl<T: PlaylistService> tonic::server::UnaryService<super::AmountRequest> for AmountSvc<T> { 5772 + impl< 5773 + T: PlaylistService, 5774 + > tonic::server::UnaryService<super::AmountRequest> 5775 + for AmountSvc<T> { 4916 5776 type Response = super::AmountResponse; 4917 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5777 + type Future = BoxFuture< 5778 + tonic::Response<Self::Response>, 5779 + tonic::Status, 5780 + >; 4918 5781 fn call( 4919 5782 &mut self, 4920 5783 request: tonic::Request<super::AmountRequest>, ··· 4951 5814 "/rockbox.v1alpha1.PlaylistService/PlaylistResume" => { 4952 5815 #[allow(non_camel_case_types)] 4953 5816 struct PlaylistResumeSvc<T: PlaylistService>(pub Arc<T>); 4954 - impl<T: PlaylistService> 4955 - tonic::server::UnaryService<super::PlaylistResumeRequest> 4956 - for PlaylistResumeSvc<T> 4957 - { 5817 + impl< 5818 + T: PlaylistService, 5819 + > tonic::server::UnaryService<super::PlaylistResumeRequest> 5820 + for PlaylistResumeSvc<T> { 4958 5821 type Response = super::PlaylistResumeResponse; 4959 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5822 + type Future = BoxFuture< 5823 + tonic::Response<Self::Response>, 5824 + tonic::Status, 5825 + >; 4960 5826 fn call( 4961 5827 &mut self, 4962 5828 request: tonic::Request<super::PlaylistResumeRequest>, 4963 5829 ) -> Self::Future { 4964 5830 let inner = Arc::clone(&self.0); 4965 5831 let fut = async move { 4966 - <T as PlaylistService>::playlist_resume(&inner, request).await 5832 + <T as PlaylistService>::playlist_resume(&inner, request) 5833 + .await 4967 5834 }; 4968 5835 Box::pin(fut) 4969 5836 } ··· 4993 5860 "/rockbox.v1alpha1.PlaylistService/ResumeTrack" => { 4994 5861 #[allow(non_camel_case_types)] 4995 5862 struct ResumeTrackSvc<T: PlaylistService>(pub Arc<T>); 4996 - impl<T: PlaylistService> tonic::server::UnaryService<super::ResumeTrackRequest> 4997 - for ResumeTrackSvc<T> 4998 - { 5863 + impl< 5864 + T: PlaylistService, 5865 + > tonic::server::UnaryService<super::ResumeTrackRequest> 5866 + for ResumeTrackSvc<T> { 4999 5867 type Response = super::ResumeTrackResponse; 5000 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5868 + type Future = BoxFuture< 5869 + tonic::Response<Self::Response>, 5870 + tonic::Status, 5871 + >; 5001 5872 fn call( 5002 5873 &mut self, 5003 5874 request: tonic::Request<super::ResumeTrackRequest>, ··· 5034 5905 "/rockbox.v1alpha1.PlaylistService/SetModified" => { 5035 5906 #[allow(non_camel_case_types)] 5036 5907 struct SetModifiedSvc<T: PlaylistService>(pub Arc<T>); 5037 - impl<T: PlaylistService> tonic::server::UnaryService<super::SetModifiedRequest> 5038 - for SetModifiedSvc<T> 5039 - { 5908 + impl< 5909 + T: PlaylistService, 5910 + > tonic::server::UnaryService<super::SetModifiedRequest> 5911 + for SetModifiedSvc<T> { 5040 5912 type Response = super::SetModifiedResponse; 5041 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5913 + type Future = BoxFuture< 5914 + tonic::Response<Self::Response>, 5915 + tonic::Status, 5916 + >; 5042 5917 fn call( 5043 5918 &mut self, 5044 5919 request: tonic::Request<super::SetModifiedRequest>, ··· 5075 5950 "/rockbox.v1alpha1.PlaylistService/Start" => { 5076 5951 #[allow(non_camel_case_types)] 5077 5952 struct StartSvc<T: PlaylistService>(pub Arc<T>); 5078 - impl<T: PlaylistService> tonic::server::UnaryService<super::StartRequest> for StartSvc<T> { 5953 + impl< 5954 + T: PlaylistService, 5955 + > tonic::server::UnaryService<super::StartRequest> for StartSvc<T> { 5079 5956 type Response = super::StartResponse; 5080 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 5957 + type Future = BoxFuture< 5958 + tonic::Response<Self::Response>, 5959 + tonic::Status, 5960 + >; 5081 5961 fn call( 5082 5962 &mut self, 5083 5963 request: tonic::Request<super::StartRequest>, 5084 5964 ) -> Self::Future { 5085 5965 let inner = Arc::clone(&self.0); 5086 - let fut = 5087 - async move { <T as PlaylistService>::start(&inner, request).await }; 5966 + let fut = async move { 5967 + <T as PlaylistService>::start(&inner, request).await 5968 + }; 5088 5969 Box::pin(fut) 5089 5970 } 5090 5971 } ··· 5113 5994 "/rockbox.v1alpha1.PlaylistService/Sync" => { 5114 5995 #[allow(non_camel_case_types)] 5115 5996 struct SyncSvc<T: PlaylistService>(pub Arc<T>); 5116 - impl<T: PlaylistService> tonic::server::UnaryService<super::SyncRequest> for SyncSvc<T> { 5997 + impl< 5998 + T: PlaylistService, 5999 + > tonic::server::UnaryService<super::SyncRequest> for SyncSvc<T> { 5117 6000 type Response = super::SyncResponse; 5118 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6001 + type Future = BoxFuture< 6002 + tonic::Response<Self::Response>, 6003 + tonic::Status, 6004 + >; 5119 6005 fn call( 5120 6006 &mut self, 5121 6007 request: tonic::Request<super::SyncRequest>, 5122 6008 ) -> Self::Future { 5123 6009 let inner = Arc::clone(&self.0); 5124 - let fut = 5125 - async move { <T as PlaylistService>::sync(&inner, request).await }; 6010 + let fut = async move { 6011 + <T as PlaylistService>::sync(&inner, request).await 6012 + }; 5126 6013 Box::pin(fut) 5127 6014 } 5128 6015 } ··· 5151 6038 "/rockbox.v1alpha1.PlaylistService/RemoveAllTracks" => { 5152 6039 #[allow(non_camel_case_types)] 5153 6040 struct RemoveAllTracksSvc<T: PlaylistService>(pub Arc<T>); 5154 - impl<T: PlaylistService> 5155 - tonic::server::UnaryService<super::RemoveAllTracksRequest> 5156 - for RemoveAllTracksSvc<T> 5157 - { 6041 + impl< 6042 + T: PlaylistService, 6043 + > tonic::server::UnaryService<super::RemoveAllTracksRequest> 6044 + for RemoveAllTracksSvc<T> { 5158 6045 type Response = super::RemoveAllTracksResponse; 5159 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6046 + type Future = BoxFuture< 6047 + tonic::Response<Self::Response>, 6048 + tonic::Status, 6049 + >; 5160 6050 fn call( 5161 6051 &mut self, 5162 6052 request: tonic::Request<super::RemoveAllTracksRequest>, 5163 6053 ) -> Self::Future { 5164 6054 let inner = Arc::clone(&self.0); 5165 6055 let fut = async move { 5166 - <T as PlaylistService>::remove_all_tracks(&inner, request).await 6056 + <T as PlaylistService>::remove_all_tracks(&inner, request) 6057 + .await 5167 6058 }; 5168 6059 Box::pin(fut) 5169 6060 } ··· 5193 6084 "/rockbox.v1alpha1.PlaylistService/RemoveTracks" => { 5194 6085 #[allow(non_camel_case_types)] 5195 6086 struct RemoveTracksSvc<T: PlaylistService>(pub Arc<T>); 5196 - impl<T: PlaylistService> tonic::server::UnaryService<super::RemoveTracksRequest> 5197 - for RemoveTracksSvc<T> 5198 - { 6087 + impl< 6088 + T: PlaylistService, 6089 + > tonic::server::UnaryService<super::RemoveTracksRequest> 6090 + for RemoveTracksSvc<T> { 5199 6091 type Response = super::RemoveTracksResponse; 5200 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6092 + type Future = BoxFuture< 6093 + tonic::Response<Self::Response>, 6094 + tonic::Status, 6095 + >; 5201 6096 fn call( 5202 6097 &mut self, 5203 6098 request: tonic::Request<super::RemoveTracksRequest>, ··· 5234 6129 "/rockbox.v1alpha1.PlaylistService/CreatePlaylist" => { 5235 6130 #[allow(non_camel_case_types)] 5236 6131 struct CreatePlaylistSvc<T: PlaylistService>(pub Arc<T>); 5237 - impl<T: PlaylistService> 5238 - tonic::server::UnaryService<super::CreatePlaylistRequest> 5239 - for CreatePlaylistSvc<T> 5240 - { 6132 + impl< 6133 + T: PlaylistService, 6134 + > tonic::server::UnaryService<super::CreatePlaylistRequest> 6135 + for CreatePlaylistSvc<T> { 5241 6136 type Response = super::CreatePlaylistResponse; 5242 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6137 + type Future = BoxFuture< 6138 + tonic::Response<Self::Response>, 6139 + tonic::Status, 6140 + >; 5243 6141 fn call( 5244 6142 &mut self, 5245 6143 request: tonic::Request<super::CreatePlaylistRequest>, 5246 6144 ) -> Self::Future { 5247 6145 let inner = Arc::clone(&self.0); 5248 6146 let fut = async move { 5249 - <T as PlaylistService>::create_playlist(&inner, request).await 6147 + <T as PlaylistService>::create_playlist(&inner, request) 6148 + .await 5250 6149 }; 5251 6150 Box::pin(fut) 5252 6151 } ··· 5276 6175 "/rockbox.v1alpha1.PlaylistService/InsertTracks" => { 5277 6176 #[allow(non_camel_case_types)] 5278 6177 struct InsertTracksSvc<T: PlaylistService>(pub Arc<T>); 5279 - impl<T: PlaylistService> tonic::server::UnaryService<super::InsertTracksRequest> 5280 - for InsertTracksSvc<T> 5281 - { 6178 + impl< 6179 + T: PlaylistService, 6180 + > tonic::server::UnaryService<super::InsertTracksRequest> 6181 + for InsertTracksSvc<T> { 5282 6182 type Response = super::InsertTracksResponse; 5283 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6183 + type Future = BoxFuture< 6184 + tonic::Response<Self::Response>, 6185 + tonic::Status, 6186 + >; 5284 6187 fn call( 5285 6188 &mut self, 5286 6189 request: tonic::Request<super::InsertTracksRequest>, ··· 5317 6220 "/rockbox.v1alpha1.PlaylistService/InsertDirectory" => { 5318 6221 #[allow(non_camel_case_types)] 5319 6222 struct InsertDirectorySvc<T: PlaylistService>(pub Arc<T>); 5320 - impl<T: PlaylistService> 5321 - tonic::server::UnaryService<super::InsertDirectoryRequest> 5322 - for InsertDirectorySvc<T> 5323 - { 6223 + impl< 6224 + T: PlaylistService, 6225 + > tonic::server::UnaryService<super::InsertDirectoryRequest> 6226 + for InsertDirectorySvc<T> { 5324 6227 type Response = super::InsertDirectoryResponse; 5325 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6228 + type Future = BoxFuture< 6229 + tonic::Response<Self::Response>, 6230 + tonic::Status, 6231 + >; 5326 6232 fn call( 5327 6233 &mut self, 5328 6234 request: tonic::Request<super::InsertDirectoryRequest>, 5329 6235 ) -> Self::Future { 5330 6236 let inner = Arc::clone(&self.0); 5331 6237 let fut = async move { 5332 - <T as PlaylistService>::insert_directory(&inner, request).await 6238 + <T as PlaylistService>::insert_directory(&inner, request) 6239 + .await 5333 6240 }; 5334 6241 Box::pin(fut) 5335 6242 } ··· 5359 6266 "/rockbox.v1alpha1.PlaylistService/InsertPlaylist" => { 5360 6267 #[allow(non_camel_case_types)] 5361 6268 struct InsertPlaylistSvc<T: PlaylistService>(pub Arc<T>); 5362 - impl<T: PlaylistService> 5363 - tonic::server::UnaryService<super::InsertPlaylistRequest> 5364 - for InsertPlaylistSvc<T> 5365 - { 6269 + impl< 6270 + T: PlaylistService, 6271 + > tonic::server::UnaryService<super::InsertPlaylistRequest> 6272 + for InsertPlaylistSvc<T> { 5366 6273 type Response = super::InsertPlaylistResponse; 5367 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6274 + type Future = BoxFuture< 6275 + tonic::Response<Self::Response>, 6276 + tonic::Status, 6277 + >; 5368 6278 fn call( 5369 6279 &mut self, 5370 6280 request: tonic::Request<super::InsertPlaylistRequest>, 5371 6281 ) -> Self::Future { 5372 6282 let inner = Arc::clone(&self.0); 5373 6283 let fut = async move { 5374 - <T as PlaylistService>::insert_playlist(&inner, request).await 6284 + <T as PlaylistService>::insert_playlist(&inner, request) 6285 + .await 5375 6286 }; 5376 6287 Box::pin(fut) 5377 6288 } ··· 5401 6312 "/rockbox.v1alpha1.PlaylistService/InsertAlbum" => { 5402 6313 #[allow(non_camel_case_types)] 5403 6314 struct InsertAlbumSvc<T: PlaylistService>(pub Arc<T>); 5404 - impl<T: PlaylistService> tonic::server::UnaryService<super::InsertAlbumRequest> 5405 - for InsertAlbumSvc<T> 5406 - { 6315 + impl< 6316 + T: PlaylistService, 6317 + > tonic::server::UnaryService<super::InsertAlbumRequest> 6318 + for InsertAlbumSvc<T> { 5407 6319 type Response = super::InsertAlbumResponse; 5408 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6320 + type Future = BoxFuture< 6321 + tonic::Response<Self::Response>, 6322 + tonic::Status, 6323 + >; 5409 6324 fn call( 5410 6325 &mut self, 5411 6326 request: tonic::Request<super::InsertAlbumRequest>, ··· 5442 6357 "/rockbox.v1alpha1.PlaylistService/InsertArtistTracks" => { 5443 6358 #[allow(non_camel_case_types)] 5444 6359 struct InsertArtistTracksSvc<T: PlaylistService>(pub Arc<T>); 5445 - impl<T: PlaylistService> 5446 - tonic::server::UnaryService<super::InsertArtistTracksRequest> 5447 - for InsertArtistTracksSvc<T> 5448 - { 6360 + impl< 6361 + T: PlaylistService, 6362 + > tonic::server::UnaryService<super::InsertArtistTracksRequest> 6363 + for InsertArtistTracksSvc<T> { 5449 6364 type Response = super::InsertArtistTracksResponse; 5450 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6365 + type Future = BoxFuture< 6366 + tonic::Response<Self::Response>, 6367 + tonic::Status, 6368 + >; 5451 6369 fn call( 5452 6370 &mut self, 5453 6371 request: tonic::Request<super::InsertArtistTracksRequest>, 5454 6372 ) -> Self::Future { 5455 6373 let inner = Arc::clone(&self.0); 5456 6374 let fut = async move { 5457 - <T as PlaylistService>::insert_artist_tracks(&inner, request).await 6375 + <T as PlaylistService>::insert_artist_tracks( 6376 + &inner, 6377 + request, 6378 + ) 6379 + .await 5458 6380 }; 5459 6381 Box::pin(fut) 5460 6382 } ··· 5484 6406 "/rockbox.v1alpha1.PlaylistService/ShufflePlaylist" => { 5485 6407 #[allow(non_camel_case_types)] 5486 6408 struct ShufflePlaylistSvc<T: PlaylistService>(pub Arc<T>); 5487 - impl<T: PlaylistService> 5488 - tonic::server::UnaryService<super::ShufflePlaylistRequest> 5489 - for ShufflePlaylistSvc<T> 5490 - { 6409 + impl< 6410 + T: PlaylistService, 6411 + > tonic::server::UnaryService<super::ShufflePlaylistRequest> 6412 + for ShufflePlaylistSvc<T> { 5491 6413 type Response = super::ShufflePlaylistResponse; 5492 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 6414 + type Future = BoxFuture< 6415 + tonic::Response<Self::Response>, 6416 + tonic::Status, 6417 + >; 5493 6418 fn call( 5494 6419 &mut self, 5495 6420 request: tonic::Request<super::ShufflePlaylistRequest>, 5496 6421 ) -> Self::Future { 5497 6422 let inner = Arc::clone(&self.0); 5498 6423 let fut = async move { 5499 - <T as PlaylistService>::shuffle_playlist(&inner, request).await 6424 + <T as PlaylistService>::shuffle_playlist(&inner, request) 6425 + .await 5500 6426 }; 5501 6427 Box::pin(fut) 5502 6428 } ··· 5523 6449 }; 5524 6450 Box::pin(fut) 5525 6451 } 5526 - _ => Box::pin(async move { 5527 - let mut response = http::Response::new(empty_body()); 5528 - let headers = response.headers_mut(); 5529 - headers.insert( 5530 - tonic::Status::GRPC_STATUS, 5531 - (tonic::Code::Unimplemented as i32).into(), 5532 - ); 5533 - headers.insert( 5534 - http::header::CONTENT_TYPE, 5535 - tonic::metadata::GRPC_CONTENT_TYPE, 5536 - ); 5537 - Ok(response) 5538 - }), 6452 + _ => { 6453 + Box::pin(async move { 6454 + let mut response = http::Response::new(empty_body()); 6455 + let headers = response.headers_mut(); 6456 + headers 6457 + .insert( 6458 + tonic::Status::GRPC_STATUS, 6459 + (tonic::Code::Unimplemented as i32).into(), 6460 + ); 6461 + headers 6462 + .insert( 6463 + http::header::CONTENT_TYPE, 6464 + tonic::metadata::GRPC_CONTENT_TYPE, 6465 + ); 6466 + Ok(response) 6467 + }) 6468 + } 5539 6469 } 5540 6470 } 5541 6471 } ··· 6045 6975 dead_code, 6046 6976 missing_docs, 6047 6977 clippy::wildcard_imports, 6048 - clippy::let_unit_value 6978 + clippy::let_unit_value, 6049 6979 )] 6050 - use tonic::codegen::http::Uri; 6051 6980 use tonic::codegen::*; 6981 + use tonic::codegen::http::Uri; 6052 6982 #[derive(Debug, Clone)] 6053 6983 pub struct SettingsServiceClient<T> { 6054 6984 inner: tonic::client::Grpc<T>, ··· 6092 7022 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 6093 7023 >, 6094 7024 >, 6095 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 6096 - Into<StdError> + std::marker::Send + std::marker::Sync, 7025 + <T as tonic::codegen::Service< 7026 + http::Request<tonic::body::BoxBody>, 7027 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 6097 7028 { 6098 7029 SettingsServiceClient::new(InterceptedService::new(inner, interceptor)) 6099 7030 } ··· 6131 7062 pub async fn get_settings_list( 6132 7063 &mut self, 6133 7064 request: impl tonic::IntoRequest<super::GetSettingsListRequest>, 6134 - ) -> std::result::Result<tonic::Response<super::GetSettingsListResponse>, tonic::Status> 6135 - { 6136 - self.inner.ready().await.map_err(|e| { 6137 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6138 - })?; 7065 + ) -> std::result::Result< 7066 + tonic::Response<super::GetSettingsListResponse>, 7067 + tonic::Status, 7068 + > { 7069 + self.inner 7070 + .ready() 7071 + .await 7072 + .map_err(|e| { 7073 + tonic::Status::unknown( 7074 + format!("Service was not ready: {}", e.into()), 7075 + ) 7076 + })?; 6139 7077 let codec = tonic::codec::ProstCodec::default(); 6140 7078 let path = http::uri::PathAndQuery::from_static( 6141 7079 "/rockbox.v1alpha1.SettingsService/GetSettingsList", 6142 7080 ); 6143 7081 let mut req = request.into_request(); 6144 - req.extensions_mut().insert(GrpcMethod::new( 6145 - "rockbox.v1alpha1.SettingsService", 6146 - "GetSettingsList", 6147 - )); 7082 + req.extensions_mut() 7083 + .insert( 7084 + GrpcMethod::new( 7085 + "rockbox.v1alpha1.SettingsService", 7086 + "GetSettingsList", 7087 + ), 7088 + ); 6148 7089 self.inner.unary(req, path, codec).await 6149 7090 } 6150 7091 pub async fn get_global_settings( 6151 7092 &mut self, 6152 7093 request: impl tonic::IntoRequest<super::GetGlobalSettingsRequest>, 6153 - ) -> std::result::Result<tonic::Response<super::GetGlobalSettingsResponse>, tonic::Status> 6154 - { 6155 - self.inner.ready().await.map_err(|e| { 6156 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6157 - })?; 7094 + ) -> std::result::Result< 7095 + tonic::Response<super::GetGlobalSettingsResponse>, 7096 + tonic::Status, 7097 + > { 7098 + self.inner 7099 + .ready() 7100 + .await 7101 + .map_err(|e| { 7102 + tonic::Status::unknown( 7103 + format!("Service was not ready: {}", e.into()), 7104 + ) 7105 + })?; 6158 7106 let codec = tonic::codec::ProstCodec::default(); 6159 7107 let path = http::uri::PathAndQuery::from_static( 6160 7108 "/rockbox.v1alpha1.SettingsService/GetGlobalSettings", 6161 7109 ); 6162 7110 let mut req = request.into_request(); 6163 - req.extensions_mut().insert(GrpcMethod::new( 6164 - "rockbox.v1alpha1.SettingsService", 6165 - "GetGlobalSettings", 6166 - )); 7111 + req.extensions_mut() 7112 + .insert( 7113 + GrpcMethod::new( 7114 + "rockbox.v1alpha1.SettingsService", 7115 + "GetGlobalSettings", 7116 + ), 7117 + ); 6167 7118 self.inner.unary(req, path, codec).await 6168 7119 } 6169 7120 pub async fn save_settings( 6170 7121 &mut self, 6171 7122 request: impl tonic::IntoRequest<super::SaveSettingsRequest>, 6172 - ) -> std::result::Result<tonic::Response<super::SaveSettingsResponse>, tonic::Status> 6173 - { 6174 - self.inner.ready().await.map_err(|e| { 6175 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6176 - })?; 7123 + ) -> std::result::Result< 7124 + tonic::Response<super::SaveSettingsResponse>, 7125 + tonic::Status, 7126 + > { 7127 + self.inner 7128 + .ready() 7129 + .await 7130 + .map_err(|e| { 7131 + tonic::Status::unknown( 7132 + format!("Service was not ready: {}", e.into()), 7133 + ) 7134 + })?; 6177 7135 let codec = tonic::codec::ProstCodec::default(); 6178 7136 let path = http::uri::PathAndQuery::from_static( 6179 7137 "/rockbox.v1alpha1.SettingsService/SaveSettings", 6180 7138 ); 6181 7139 let mut req = request.into_request(); 6182 - req.extensions_mut().insert(GrpcMethod::new( 6183 - "rockbox.v1alpha1.SettingsService", 6184 - "SaveSettings", 6185 - )); 7140 + req.extensions_mut() 7141 + .insert( 7142 + GrpcMethod::new("rockbox.v1alpha1.SettingsService", "SaveSettings"), 7143 + ); 6186 7144 self.inner.unary(req, path, codec).await 6187 7145 } 6188 7146 } ··· 6194 7152 dead_code, 6195 7153 missing_docs, 6196 7154 clippy::wildcard_imports, 6197 - clippy::let_unit_value 7155 + clippy::let_unit_value, 6198 7156 )] 6199 7157 use tonic::codegen::*; 6200 7158 /// Generated trait containing gRPC methods that should be implemented for use with SettingsServiceServer. ··· 6203 7161 async fn get_settings_list( 6204 7162 &self, 6205 7163 request: tonic::Request<super::GetSettingsListRequest>, 6206 - ) -> std::result::Result<tonic::Response<super::GetSettingsListResponse>, tonic::Status>; 7164 + ) -> std::result::Result< 7165 + tonic::Response<super::GetSettingsListResponse>, 7166 + tonic::Status, 7167 + >; 6207 7168 async fn get_global_settings( 6208 7169 &self, 6209 7170 request: tonic::Request<super::GetGlobalSettingsRequest>, 6210 - ) -> std::result::Result<tonic::Response<super::GetGlobalSettingsResponse>, tonic::Status>; 7171 + ) -> std::result::Result< 7172 + tonic::Response<super::GetGlobalSettingsResponse>, 7173 + tonic::Status, 7174 + >; 6211 7175 async fn save_settings( 6212 7176 &self, 6213 7177 request: tonic::Request<super::SaveSettingsRequest>, 6214 - ) -> std::result::Result<tonic::Response<super::SaveSettingsResponse>, tonic::Status>; 7178 + ) -> std::result::Result< 7179 + tonic::Response<super::SaveSettingsResponse>, 7180 + tonic::Status, 7181 + >; 6215 7182 } 6216 7183 #[derive(Debug)] 6217 7184 pub struct SettingsServiceServer<T> { ··· 6234 7201 max_encoding_message_size: None, 6235 7202 } 6236 7203 } 6237 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 7204 + pub fn with_interceptor<F>( 7205 + inner: T, 7206 + interceptor: F, 7207 + ) -> InterceptedService<Self, F> 6238 7208 where 6239 7209 F: tonic::service::Interceptor, 6240 7210 { ··· 6289 7259 "/rockbox.v1alpha1.SettingsService/GetSettingsList" => { 6290 7260 #[allow(non_camel_case_types)] 6291 7261 struct GetSettingsListSvc<T: SettingsService>(pub Arc<T>); 6292 - impl<T: SettingsService> 6293 - tonic::server::UnaryService<super::GetSettingsListRequest> 6294 - for GetSettingsListSvc<T> 6295 - { 7262 + impl< 7263 + T: SettingsService, 7264 + > tonic::server::UnaryService<super::GetSettingsListRequest> 7265 + for GetSettingsListSvc<T> { 6296 7266 type Response = super::GetSettingsListResponse; 6297 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 7267 + type Future = BoxFuture< 7268 + tonic::Response<Self::Response>, 7269 + tonic::Status, 7270 + >; 6298 7271 fn call( 6299 7272 &mut self, 6300 7273 request: tonic::Request<super::GetSettingsListRequest>, 6301 7274 ) -> Self::Future { 6302 7275 let inner = Arc::clone(&self.0); 6303 7276 let fut = async move { 6304 - <T as SettingsService>::get_settings_list(&inner, request).await 7277 + <T as SettingsService>::get_settings_list(&inner, request) 7278 + .await 6305 7279 }; 6306 7280 Box::pin(fut) 6307 7281 } ··· 6331 7305 "/rockbox.v1alpha1.SettingsService/GetGlobalSettings" => { 6332 7306 #[allow(non_camel_case_types)] 6333 7307 struct GetGlobalSettingsSvc<T: SettingsService>(pub Arc<T>); 6334 - impl<T: SettingsService> 6335 - tonic::server::UnaryService<super::GetGlobalSettingsRequest> 6336 - for GetGlobalSettingsSvc<T> 6337 - { 7308 + impl< 7309 + T: SettingsService, 7310 + > tonic::server::UnaryService<super::GetGlobalSettingsRequest> 7311 + for GetGlobalSettingsSvc<T> { 6338 7312 type Response = super::GetGlobalSettingsResponse; 6339 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 7313 + type Future = BoxFuture< 7314 + tonic::Response<Self::Response>, 7315 + tonic::Status, 7316 + >; 6340 7317 fn call( 6341 7318 &mut self, 6342 7319 request: tonic::Request<super::GetGlobalSettingsRequest>, 6343 7320 ) -> Self::Future { 6344 7321 let inner = Arc::clone(&self.0); 6345 7322 let fut = async move { 6346 - <T as SettingsService>::get_global_settings(&inner, request).await 7323 + <T as SettingsService>::get_global_settings(&inner, request) 7324 + .await 6347 7325 }; 6348 7326 Box::pin(fut) 6349 7327 } ··· 6373 7351 "/rockbox.v1alpha1.SettingsService/SaveSettings" => { 6374 7352 #[allow(non_camel_case_types)] 6375 7353 struct SaveSettingsSvc<T: SettingsService>(pub Arc<T>); 6376 - impl<T: SettingsService> tonic::server::UnaryService<super::SaveSettingsRequest> 6377 - for SaveSettingsSvc<T> 6378 - { 7354 + impl< 7355 + T: SettingsService, 7356 + > tonic::server::UnaryService<super::SaveSettingsRequest> 7357 + for SaveSettingsSvc<T> { 6379 7358 type Response = super::SaveSettingsResponse; 6380 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 7359 + type Future = BoxFuture< 7360 + tonic::Response<Self::Response>, 7361 + tonic::Status, 7362 + >; 6381 7363 fn call( 6382 7364 &mut self, 6383 7365 request: tonic::Request<super::SaveSettingsRequest>, ··· 6411 7393 }; 6412 7394 Box::pin(fut) 6413 7395 } 6414 - _ => Box::pin(async move { 6415 - let mut response = http::Response::new(empty_body()); 6416 - let headers = response.headers_mut(); 6417 - headers.insert( 6418 - tonic::Status::GRPC_STATUS, 6419 - (tonic::Code::Unimplemented as i32).into(), 6420 - ); 6421 - headers.insert( 6422 - http::header::CONTENT_TYPE, 6423 - tonic::metadata::GRPC_CONTENT_TYPE, 6424 - ); 6425 - Ok(response) 6426 - }), 7396 + _ => { 7397 + Box::pin(async move { 7398 + let mut response = http::Response::new(empty_body()); 7399 + let headers = response.headers_mut(); 7400 + headers 7401 + .insert( 7402 + tonic::Status::GRPC_STATUS, 7403 + (tonic::Code::Unimplemented as i32).into(), 7404 + ); 7405 + headers 7406 + .insert( 7407 + http::header::CONTENT_TYPE, 7408 + tonic::metadata::GRPC_CONTENT_TYPE, 7409 + ); 7410 + Ok(response) 7411 + }) 7412 + } 6427 7413 } 6428 7414 } 6429 7415 } ··· 6581 7567 dead_code, 6582 7568 missing_docs, 6583 7569 clippy::wildcard_imports, 6584 - clippy::let_unit_value 7570 + clippy::let_unit_value, 6585 7571 )] 6586 - use tonic::codegen::http::Uri; 6587 7572 use tonic::codegen::*; 7573 + use tonic::codegen::http::Uri; 6588 7574 #[derive(Debug, Clone)] 6589 7575 pub struct SoundServiceClient<T> { 6590 7576 inner: tonic::client::Grpc<T>, ··· 6628 7614 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 6629 7615 >, 6630 7616 >, 6631 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 6632 - Into<StdError> + std::marker::Send + std::marker::Sync, 7617 + <T as tonic::codegen::Service< 7618 + http::Request<tonic::body::BoxBody>, 7619 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 6633 7620 { 6634 7621 SoundServiceClient::new(InterceptedService::new(inner, interceptor)) 6635 7622 } ··· 6667 7654 pub async fn adjust_volume( 6668 7655 &mut self, 6669 7656 request: impl tonic::IntoRequest<super::AdjustVolumeRequest>, 6670 - ) -> std::result::Result<tonic::Response<super::AdjustVolumeResponse>, tonic::Status> 6671 - { 6672 - self.inner.ready().await.map_err(|e| { 6673 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6674 - })?; 7657 + ) -> std::result::Result< 7658 + tonic::Response<super::AdjustVolumeResponse>, 7659 + tonic::Status, 7660 + > { 7661 + self.inner 7662 + .ready() 7663 + .await 7664 + .map_err(|e| { 7665 + tonic::Status::unknown( 7666 + format!("Service was not ready: {}", e.into()), 7667 + ) 7668 + })?; 6675 7669 let codec = tonic::codec::ProstCodec::default(); 6676 - let path = 6677 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/AdjustVolume"); 7670 + let path = http::uri::PathAndQuery::from_static( 7671 + "/rockbox.v1alpha1.SoundService/AdjustVolume", 7672 + ); 6678 7673 let mut req = request.into_request(); 6679 - req.extensions_mut().insert(GrpcMethod::new( 6680 - "rockbox.v1alpha1.SoundService", 6681 - "AdjustVolume", 6682 - )); 7674 + req.extensions_mut() 7675 + .insert( 7676 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "AdjustVolume"), 7677 + ); 6683 7678 self.inner.unary(req, path, codec).await 6684 7679 } 6685 7680 pub async fn sound_set( 6686 7681 &mut self, 6687 7682 request: impl tonic::IntoRequest<super::SoundSetRequest>, 6688 - ) -> std::result::Result<tonic::Response<super::SoundSetResponse>, tonic::Status> { 6689 - self.inner.ready().await.map_err(|e| { 6690 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6691 - })?; 7683 + ) -> std::result::Result< 7684 + tonic::Response<super::SoundSetResponse>, 7685 + tonic::Status, 7686 + > { 7687 + self.inner 7688 + .ready() 7689 + .await 7690 + .map_err(|e| { 7691 + tonic::Status::unknown( 7692 + format!("Service was not ready: {}", e.into()), 7693 + ) 7694 + })?; 6692 7695 let codec = tonic::codec::ProstCodec::default(); 6693 - let path = 6694 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SoundSet"); 7696 + let path = http::uri::PathAndQuery::from_static( 7697 + "/rockbox.v1alpha1.SoundService/SoundSet", 7698 + ); 6695 7699 let mut req = request.into_request(); 6696 7700 req.extensions_mut() 6697 7701 .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundSet")); ··· 6700 7704 pub async fn sound_current( 6701 7705 &mut self, 6702 7706 request: impl tonic::IntoRequest<super::SoundCurrentRequest>, 6703 - ) -> std::result::Result<tonic::Response<super::SoundCurrentResponse>, tonic::Status> 6704 - { 6705 - self.inner.ready().await.map_err(|e| { 6706 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6707 - })?; 7707 + ) -> std::result::Result< 7708 + tonic::Response<super::SoundCurrentResponse>, 7709 + tonic::Status, 7710 + > { 7711 + self.inner 7712 + .ready() 7713 + .await 7714 + .map_err(|e| { 7715 + tonic::Status::unknown( 7716 + format!("Service was not ready: {}", e.into()), 7717 + ) 7718 + })?; 6708 7719 let codec = tonic::codec::ProstCodec::default(); 6709 - let path = 6710 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SoundCurrent"); 7720 + let path = http::uri::PathAndQuery::from_static( 7721 + "/rockbox.v1alpha1.SoundService/SoundCurrent", 7722 + ); 6711 7723 let mut req = request.into_request(); 6712 - req.extensions_mut().insert(GrpcMethod::new( 6713 - "rockbox.v1alpha1.SoundService", 6714 - "SoundCurrent", 6715 - )); 7724 + req.extensions_mut() 7725 + .insert( 7726 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundCurrent"), 7727 + ); 6716 7728 self.inner.unary(req, path, codec).await 6717 7729 } 6718 7730 pub async fn sound_default( 6719 7731 &mut self, 6720 7732 request: impl tonic::IntoRequest<super::SoundDefaultRequest>, 6721 - ) -> std::result::Result<tonic::Response<super::SoundDefaultResponse>, tonic::Status> 6722 - { 6723 - self.inner.ready().await.map_err(|e| { 6724 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6725 - })?; 7733 + ) -> std::result::Result< 7734 + tonic::Response<super::SoundDefaultResponse>, 7735 + tonic::Status, 7736 + > { 7737 + self.inner 7738 + .ready() 7739 + .await 7740 + .map_err(|e| { 7741 + tonic::Status::unknown( 7742 + format!("Service was not ready: {}", e.into()), 7743 + ) 7744 + })?; 6726 7745 let codec = tonic::codec::ProstCodec::default(); 6727 - let path = 6728 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SoundDefault"); 7746 + let path = http::uri::PathAndQuery::from_static( 7747 + "/rockbox.v1alpha1.SoundService/SoundDefault", 7748 + ); 6729 7749 let mut req = request.into_request(); 6730 - req.extensions_mut().insert(GrpcMethod::new( 6731 - "rockbox.v1alpha1.SoundService", 6732 - "SoundDefault", 6733 - )); 7750 + req.extensions_mut() 7751 + .insert( 7752 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundDefault"), 7753 + ); 6734 7754 self.inner.unary(req, path, codec).await 6735 7755 } 6736 7756 pub async fn sound_min( 6737 7757 &mut self, 6738 7758 request: impl tonic::IntoRequest<super::SoundMinRequest>, 6739 - ) -> std::result::Result<tonic::Response<super::SoundMinResponse>, tonic::Status> { 6740 - self.inner.ready().await.map_err(|e| { 6741 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6742 - })?; 7759 + ) -> std::result::Result< 7760 + tonic::Response<super::SoundMinResponse>, 7761 + tonic::Status, 7762 + > { 7763 + self.inner 7764 + .ready() 7765 + .await 7766 + .map_err(|e| { 7767 + tonic::Status::unknown( 7768 + format!("Service was not ready: {}", e.into()), 7769 + ) 7770 + })?; 6743 7771 let codec = tonic::codec::ProstCodec::default(); 6744 - let path = 6745 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SoundMin"); 7772 + let path = http::uri::PathAndQuery::from_static( 7773 + "/rockbox.v1alpha1.SoundService/SoundMin", 7774 + ); 6746 7775 let mut req = request.into_request(); 6747 7776 req.extensions_mut() 6748 7777 .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundMin")); ··· 6751 7780 pub async fn sound_max( 6752 7781 &mut self, 6753 7782 request: impl tonic::IntoRequest<super::SoundMaxRequest>, 6754 - ) -> std::result::Result<tonic::Response<super::SoundMaxResponse>, tonic::Status> { 6755 - self.inner.ready().await.map_err(|e| { 6756 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6757 - })?; 7783 + ) -> std::result::Result< 7784 + tonic::Response<super::SoundMaxResponse>, 7785 + tonic::Status, 7786 + > { 7787 + self.inner 7788 + .ready() 7789 + .await 7790 + .map_err(|e| { 7791 + tonic::Status::unknown( 7792 + format!("Service was not ready: {}", e.into()), 7793 + ) 7794 + })?; 6758 7795 let codec = tonic::codec::ProstCodec::default(); 6759 - let path = 6760 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SoundMax"); 7796 + let path = http::uri::PathAndQuery::from_static( 7797 + "/rockbox.v1alpha1.SoundService/SoundMax", 7798 + ); 6761 7799 let mut req = request.into_request(); 6762 7800 req.extensions_mut() 6763 7801 .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundMax")); ··· 6766 7804 pub async fn sound_unit( 6767 7805 &mut self, 6768 7806 request: impl tonic::IntoRequest<super::SoundUnitRequest>, 6769 - ) -> std::result::Result<tonic::Response<super::SoundUnitResponse>, tonic::Status> { 6770 - self.inner.ready().await.map_err(|e| { 6771 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6772 - })?; 7807 + ) -> std::result::Result< 7808 + tonic::Response<super::SoundUnitResponse>, 7809 + tonic::Status, 7810 + > { 7811 + self.inner 7812 + .ready() 7813 + .await 7814 + .map_err(|e| { 7815 + tonic::Status::unknown( 7816 + format!("Service was not ready: {}", e.into()), 7817 + ) 7818 + })?; 6773 7819 let codec = tonic::codec::ProstCodec::default(); 6774 - let path = 6775 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SoundUnit"); 7820 + let path = http::uri::PathAndQuery::from_static( 7821 + "/rockbox.v1alpha1.SoundService/SoundUnit", 7822 + ); 6776 7823 let mut req = request.into_request(); 6777 - req.extensions_mut().insert(GrpcMethod::new( 6778 - "rockbox.v1alpha1.SoundService", 6779 - "SoundUnit", 6780 - )); 7824 + req.extensions_mut() 7825 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundUnit")); 6781 7826 self.inner.unary(req, path, codec).await 6782 7827 } 6783 7828 pub async fn sound_val2_phys( 6784 7829 &mut self, 6785 7830 request: impl tonic::IntoRequest<super::SoundVal2PhysRequest>, 6786 - ) -> std::result::Result<tonic::Response<super::SoundVal2PhysResponse>, tonic::Status> 6787 - { 6788 - self.inner.ready().await.map_err(|e| { 6789 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6790 - })?; 7831 + ) -> std::result::Result< 7832 + tonic::Response<super::SoundVal2PhysResponse>, 7833 + tonic::Status, 7834 + > { 7835 + self.inner 7836 + .ready() 7837 + .await 7838 + .map_err(|e| { 7839 + tonic::Status::unknown( 7840 + format!("Service was not ready: {}", e.into()), 7841 + ) 7842 + })?; 6791 7843 let codec = tonic::codec::ProstCodec::default(); 6792 7844 let path = http::uri::PathAndQuery::from_static( 6793 7845 "/rockbox.v1alpha1.SoundService/SoundVal2Phys", 6794 7846 ); 6795 7847 let mut req = request.into_request(); 6796 - req.extensions_mut().insert(GrpcMethod::new( 6797 - "rockbox.v1alpha1.SoundService", 6798 - "SoundVal2Phys", 6799 - )); 7848 + req.extensions_mut() 7849 + .insert( 7850 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SoundVal2Phys"), 7851 + ); 6800 7852 self.inner.unary(req, path, codec).await 6801 7853 } 6802 7854 pub async fn get_pitch( 6803 7855 &mut self, 6804 7856 request: impl tonic::IntoRequest<super::GetPitchRequest>, 6805 - ) -> std::result::Result<tonic::Response<super::GetPitchResponse>, tonic::Status> { 6806 - self.inner.ready().await.map_err(|e| { 6807 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6808 - })?; 7857 + ) -> std::result::Result< 7858 + tonic::Response<super::GetPitchResponse>, 7859 + tonic::Status, 7860 + > { 7861 + self.inner 7862 + .ready() 7863 + .await 7864 + .map_err(|e| { 7865 + tonic::Status::unknown( 7866 + format!("Service was not ready: {}", e.into()), 7867 + ) 7868 + })?; 6809 7869 let codec = tonic::codec::ProstCodec::default(); 6810 - let path = 6811 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/GetPitch"); 7870 + let path = http::uri::PathAndQuery::from_static( 7871 + "/rockbox.v1alpha1.SoundService/GetPitch", 7872 + ); 6812 7873 let mut req = request.into_request(); 6813 7874 req.extensions_mut() 6814 7875 .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "GetPitch")); ··· 6817 7878 pub async fn set_pitch( 6818 7879 &mut self, 6819 7880 request: impl tonic::IntoRequest<super::SetPitchRequest>, 6820 - ) -> std::result::Result<tonic::Response<super::SetPitchResponse>, tonic::Status> { 6821 - self.inner.ready().await.map_err(|e| { 6822 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6823 - })?; 7881 + ) -> std::result::Result< 7882 + tonic::Response<super::SetPitchResponse>, 7883 + tonic::Status, 7884 + > { 7885 + self.inner 7886 + .ready() 7887 + .await 7888 + .map_err(|e| { 7889 + tonic::Status::unknown( 7890 + format!("Service was not ready: {}", e.into()), 7891 + ) 7892 + })?; 6824 7893 let codec = tonic::codec::ProstCodec::default(); 6825 - let path = 6826 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/SetPitch"); 7894 + let path = http::uri::PathAndQuery::from_static( 7895 + "/rockbox.v1alpha1.SoundService/SetPitch", 7896 + ); 6827 7897 let mut req = request.into_request(); 6828 7898 req.extensions_mut() 6829 7899 .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "SetPitch")); ··· 6832 7902 pub async fn beep_play( 6833 7903 &mut self, 6834 7904 request: impl tonic::IntoRequest<super::BeepPlayRequest>, 6835 - ) -> std::result::Result<tonic::Response<super::BeepPlayResponse>, tonic::Status> { 6836 - self.inner.ready().await.map_err(|e| { 6837 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6838 - })?; 7905 + ) -> std::result::Result< 7906 + tonic::Response<super::BeepPlayResponse>, 7907 + tonic::Status, 7908 + > { 7909 + self.inner 7910 + .ready() 7911 + .await 7912 + .map_err(|e| { 7913 + tonic::Status::unknown( 7914 + format!("Service was not ready: {}", e.into()), 7915 + ) 7916 + })?; 6839 7917 let codec = tonic::codec::ProstCodec::default(); 6840 - let path = 6841 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/BeepPlay"); 7918 + let path = http::uri::PathAndQuery::from_static( 7919 + "/rockbox.v1alpha1.SoundService/BeepPlay", 7920 + ); 6842 7921 let mut req = request.into_request(); 6843 7922 req.extensions_mut() 6844 7923 .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "BeepPlay")); ··· 6847 7926 pub async fn pcmbuf_fade( 6848 7927 &mut self, 6849 7928 request: impl tonic::IntoRequest<super::PcmbufFadeRequest>, 6850 - ) -> std::result::Result<tonic::Response<super::PcmbufFadeResponse>, tonic::Status> 6851 - { 6852 - self.inner.ready().await.map_err(|e| { 6853 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6854 - })?; 7929 + ) -> std::result::Result< 7930 + tonic::Response<super::PcmbufFadeResponse>, 7931 + tonic::Status, 7932 + > { 7933 + self.inner 7934 + .ready() 7935 + .await 7936 + .map_err(|e| { 7937 + tonic::Status::unknown( 7938 + format!("Service was not ready: {}", e.into()), 7939 + ) 7940 + })?; 6855 7941 let codec = tonic::codec::ProstCodec::default(); 6856 - let path = 6857 - http::uri::PathAndQuery::from_static("/rockbox.v1alpha1.SoundService/PcmbufFade"); 7942 + let path = http::uri::PathAndQuery::from_static( 7943 + "/rockbox.v1alpha1.SoundService/PcmbufFade", 7944 + ); 6858 7945 let mut req = request.into_request(); 6859 - req.extensions_mut().insert(GrpcMethod::new( 6860 - "rockbox.v1alpha1.SoundService", 6861 - "PcmbufFade", 6862 - )); 7946 + req.extensions_mut() 7947 + .insert(GrpcMethod::new("rockbox.v1alpha1.SoundService", "PcmbufFade")); 6863 7948 self.inner.unary(req, path, codec).await 6864 7949 } 6865 7950 pub async fn pcmbuf_set_low_latency( 6866 7951 &mut self, 6867 7952 request: impl tonic::IntoRequest<super::PcmbufSetLowLatencyRequest>, 6868 - ) -> std::result::Result<tonic::Response<super::PcmbufSetLowLatencyResponse>, tonic::Status> 6869 - { 6870 - self.inner.ready().await.map_err(|e| { 6871 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6872 - })?; 7953 + ) -> std::result::Result< 7954 + tonic::Response<super::PcmbufSetLowLatencyResponse>, 7955 + tonic::Status, 7956 + > { 7957 + self.inner 7958 + .ready() 7959 + .await 7960 + .map_err(|e| { 7961 + tonic::Status::unknown( 7962 + format!("Service was not ready: {}", e.into()), 7963 + ) 7964 + })?; 6873 7965 let codec = tonic::codec::ProstCodec::default(); 6874 7966 let path = http::uri::PathAndQuery::from_static( 6875 7967 "/rockbox.v1alpha1.SoundService/PcmbufSetLowLatency", 6876 7968 ); 6877 7969 let mut req = request.into_request(); 6878 - req.extensions_mut().insert(GrpcMethod::new( 6879 - "rockbox.v1alpha1.SoundService", 6880 - "PcmbufSetLowLatency", 6881 - )); 7970 + req.extensions_mut() 7971 + .insert( 7972 + GrpcMethod::new( 7973 + "rockbox.v1alpha1.SoundService", 7974 + "PcmbufSetLowLatency", 7975 + ), 7976 + ); 6882 7977 self.inner.unary(req, path, codec).await 6883 7978 } 6884 7979 pub async fn system_sound_play( 6885 7980 &mut self, 6886 7981 request: impl tonic::IntoRequest<super::SystemSoundPlayRequest>, 6887 - ) -> std::result::Result<tonic::Response<super::SystemSoundPlayResponse>, tonic::Status> 6888 - { 6889 - self.inner.ready().await.map_err(|e| { 6890 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6891 - })?; 7982 + ) -> std::result::Result< 7983 + tonic::Response<super::SystemSoundPlayResponse>, 7984 + tonic::Status, 7985 + > { 7986 + self.inner 7987 + .ready() 7988 + .await 7989 + .map_err(|e| { 7990 + tonic::Status::unknown( 7991 + format!("Service was not ready: {}", e.into()), 7992 + ) 7993 + })?; 6892 7994 let codec = tonic::codec::ProstCodec::default(); 6893 7995 let path = http::uri::PathAndQuery::from_static( 6894 7996 "/rockbox.v1alpha1.SoundService/SystemSoundPlay", 6895 7997 ); 6896 7998 let mut req = request.into_request(); 6897 - req.extensions_mut().insert(GrpcMethod::new( 6898 - "rockbox.v1alpha1.SoundService", 6899 - "SystemSoundPlay", 6900 - )); 7999 + req.extensions_mut() 8000 + .insert( 8001 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "SystemSoundPlay"), 8002 + ); 6901 8003 self.inner.unary(req, path, codec).await 6902 8004 } 6903 8005 pub async fn keyclick_click( 6904 8006 &mut self, 6905 8007 request: impl tonic::IntoRequest<super::KeyclickClickRequest>, 6906 - ) -> std::result::Result<tonic::Response<super::KeyclickClickResponse>, tonic::Status> 6907 - { 6908 - self.inner.ready().await.map_err(|e| { 6909 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 6910 - })?; 8008 + ) -> std::result::Result< 8009 + tonic::Response<super::KeyclickClickResponse>, 8010 + tonic::Status, 8011 + > { 8012 + self.inner 8013 + .ready() 8014 + .await 8015 + .map_err(|e| { 8016 + tonic::Status::unknown( 8017 + format!("Service was not ready: {}", e.into()), 8018 + ) 8019 + })?; 6911 8020 let codec = tonic::codec::ProstCodec::default(); 6912 8021 let path = http::uri::PathAndQuery::from_static( 6913 8022 "/rockbox.v1alpha1.SoundService/KeyclickClick", 6914 8023 ); 6915 8024 let mut req = request.into_request(); 6916 - req.extensions_mut().insert(GrpcMethod::new( 6917 - "rockbox.v1alpha1.SoundService", 6918 - "KeyclickClick", 6919 - )); 8025 + req.extensions_mut() 8026 + .insert( 8027 + GrpcMethod::new("rockbox.v1alpha1.SoundService", "KeyclickClick"), 8028 + ); 6920 8029 self.inner.unary(req, path, codec).await 6921 8030 } 6922 8031 } ··· 6928 8037 dead_code, 6929 8038 missing_docs, 6930 8039 clippy::wildcard_imports, 6931 - clippy::let_unit_value 8040 + clippy::let_unit_value, 6932 8041 )] 6933 8042 use tonic::codegen::*; 6934 8043 /// Generated trait containing gRPC methods that should be implemented for use with SoundServiceServer. ··· 6937 8046 async fn adjust_volume( 6938 8047 &self, 6939 8048 request: tonic::Request<super::AdjustVolumeRequest>, 6940 - ) -> std::result::Result<tonic::Response<super::AdjustVolumeResponse>, tonic::Status>; 8049 + ) -> std::result::Result< 8050 + tonic::Response<super::AdjustVolumeResponse>, 8051 + tonic::Status, 8052 + >; 6941 8053 async fn sound_set( 6942 8054 &self, 6943 8055 request: tonic::Request<super::SoundSetRequest>, 6944 - ) -> std::result::Result<tonic::Response<super::SoundSetResponse>, tonic::Status>; 8056 + ) -> std::result::Result< 8057 + tonic::Response<super::SoundSetResponse>, 8058 + tonic::Status, 8059 + >; 6945 8060 async fn sound_current( 6946 8061 &self, 6947 8062 request: tonic::Request<super::SoundCurrentRequest>, 6948 - ) -> std::result::Result<tonic::Response<super::SoundCurrentResponse>, tonic::Status>; 8063 + ) -> std::result::Result< 8064 + tonic::Response<super::SoundCurrentResponse>, 8065 + tonic::Status, 8066 + >; 6949 8067 async fn sound_default( 6950 8068 &self, 6951 8069 request: tonic::Request<super::SoundDefaultRequest>, 6952 - ) -> std::result::Result<tonic::Response<super::SoundDefaultResponse>, tonic::Status>; 8070 + ) -> std::result::Result< 8071 + tonic::Response<super::SoundDefaultResponse>, 8072 + tonic::Status, 8073 + >; 6953 8074 async fn sound_min( 6954 8075 &self, 6955 8076 request: tonic::Request<super::SoundMinRequest>, 6956 - ) -> std::result::Result<tonic::Response<super::SoundMinResponse>, tonic::Status>; 8077 + ) -> std::result::Result< 8078 + tonic::Response<super::SoundMinResponse>, 8079 + tonic::Status, 8080 + >; 6957 8081 async fn sound_max( 6958 8082 &self, 6959 8083 request: tonic::Request<super::SoundMaxRequest>, 6960 - ) -> std::result::Result<tonic::Response<super::SoundMaxResponse>, tonic::Status>; 8084 + ) -> std::result::Result< 8085 + tonic::Response<super::SoundMaxResponse>, 8086 + tonic::Status, 8087 + >; 6961 8088 async fn sound_unit( 6962 8089 &self, 6963 8090 request: tonic::Request<super::SoundUnitRequest>, 6964 - ) -> std::result::Result<tonic::Response<super::SoundUnitResponse>, tonic::Status>; 8091 + ) -> std::result::Result< 8092 + tonic::Response<super::SoundUnitResponse>, 8093 + tonic::Status, 8094 + >; 6965 8095 async fn sound_val2_phys( 6966 8096 &self, 6967 8097 request: tonic::Request<super::SoundVal2PhysRequest>, 6968 - ) -> std::result::Result<tonic::Response<super::SoundVal2PhysResponse>, tonic::Status>; 8098 + ) -> std::result::Result< 8099 + tonic::Response<super::SoundVal2PhysResponse>, 8100 + tonic::Status, 8101 + >; 6969 8102 async fn get_pitch( 6970 8103 &self, 6971 8104 request: tonic::Request<super::GetPitchRequest>, 6972 - ) -> std::result::Result<tonic::Response<super::GetPitchResponse>, tonic::Status>; 8105 + ) -> std::result::Result< 8106 + tonic::Response<super::GetPitchResponse>, 8107 + tonic::Status, 8108 + >; 6973 8109 async fn set_pitch( 6974 8110 &self, 6975 8111 request: tonic::Request<super::SetPitchRequest>, 6976 - ) -> std::result::Result<tonic::Response<super::SetPitchResponse>, tonic::Status>; 8112 + ) -> std::result::Result< 8113 + tonic::Response<super::SetPitchResponse>, 8114 + tonic::Status, 8115 + >; 6977 8116 async fn beep_play( 6978 8117 &self, 6979 8118 request: tonic::Request<super::BeepPlayRequest>, 6980 - ) -> std::result::Result<tonic::Response<super::BeepPlayResponse>, tonic::Status>; 8119 + ) -> std::result::Result< 8120 + tonic::Response<super::BeepPlayResponse>, 8121 + tonic::Status, 8122 + >; 6981 8123 async fn pcmbuf_fade( 6982 8124 &self, 6983 8125 request: tonic::Request<super::PcmbufFadeRequest>, 6984 - ) -> std::result::Result<tonic::Response<super::PcmbufFadeResponse>, tonic::Status>; 8126 + ) -> std::result::Result< 8127 + tonic::Response<super::PcmbufFadeResponse>, 8128 + tonic::Status, 8129 + >; 6985 8130 async fn pcmbuf_set_low_latency( 6986 8131 &self, 6987 8132 request: tonic::Request<super::PcmbufSetLowLatencyRequest>, 6988 - ) -> std::result::Result<tonic::Response<super::PcmbufSetLowLatencyResponse>, tonic::Status>; 8133 + ) -> std::result::Result< 8134 + tonic::Response<super::PcmbufSetLowLatencyResponse>, 8135 + tonic::Status, 8136 + >; 6989 8137 async fn system_sound_play( 6990 8138 &self, 6991 8139 request: tonic::Request<super::SystemSoundPlayRequest>, 6992 - ) -> std::result::Result<tonic::Response<super::SystemSoundPlayResponse>, tonic::Status>; 8140 + ) -> std::result::Result< 8141 + tonic::Response<super::SystemSoundPlayResponse>, 8142 + tonic::Status, 8143 + >; 6993 8144 async fn keyclick_click( 6994 8145 &self, 6995 8146 request: tonic::Request<super::KeyclickClickRequest>, 6996 - ) -> std::result::Result<tonic::Response<super::KeyclickClickResponse>, tonic::Status>; 8147 + ) -> std::result::Result< 8148 + tonic::Response<super::KeyclickClickResponse>, 8149 + tonic::Status, 8150 + >; 6997 8151 } 6998 8152 #[derive(Debug)] 6999 8153 pub struct SoundServiceServer<T> { ··· 7016 8170 max_encoding_message_size: None, 7017 8171 } 7018 8172 } 7019 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 8173 + pub fn with_interceptor<F>( 8174 + inner: T, 8175 + interceptor: F, 8176 + ) -> InterceptedService<Self, F> 7020 8177 where 7021 8178 F: tonic::service::Interceptor, 7022 8179 { ··· 7071 8228 "/rockbox.v1alpha1.SoundService/AdjustVolume" => { 7072 8229 #[allow(non_camel_case_types)] 7073 8230 struct AdjustVolumeSvc<T: SoundService>(pub Arc<T>); 7074 - impl<T: SoundService> tonic::server::UnaryService<super::AdjustVolumeRequest> 7075 - for AdjustVolumeSvc<T> 7076 - { 8231 + impl< 8232 + T: SoundService, 8233 + > tonic::server::UnaryService<super::AdjustVolumeRequest> 8234 + for AdjustVolumeSvc<T> { 7077 8235 type Response = super::AdjustVolumeResponse; 7078 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8236 + type Future = BoxFuture< 8237 + tonic::Response<Self::Response>, 8238 + tonic::Status, 8239 + >; 7079 8240 fn call( 7080 8241 &mut self, 7081 8242 request: tonic::Request<super::AdjustVolumeRequest>, ··· 7112 8273 "/rockbox.v1alpha1.SoundService/SoundSet" => { 7113 8274 #[allow(non_camel_case_types)] 7114 8275 struct SoundSetSvc<T: SoundService>(pub Arc<T>); 7115 - impl<T: SoundService> tonic::server::UnaryService<super::SoundSetRequest> for SoundSetSvc<T> { 8276 + impl< 8277 + T: SoundService, 8278 + > tonic::server::UnaryService<super::SoundSetRequest> 8279 + for SoundSetSvc<T> { 7116 8280 type Response = super::SoundSetResponse; 7117 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8281 + type Future = BoxFuture< 8282 + tonic::Response<Self::Response>, 8283 + tonic::Status, 8284 + >; 7118 8285 fn call( 7119 8286 &mut self, 7120 8287 request: tonic::Request<super::SoundSetRequest>, ··· 7151 8318 "/rockbox.v1alpha1.SoundService/SoundCurrent" => { 7152 8319 #[allow(non_camel_case_types)] 7153 8320 struct SoundCurrentSvc<T: SoundService>(pub Arc<T>); 7154 - impl<T: SoundService> tonic::server::UnaryService<super::SoundCurrentRequest> 7155 - for SoundCurrentSvc<T> 7156 - { 8321 + impl< 8322 + T: SoundService, 8323 + > tonic::server::UnaryService<super::SoundCurrentRequest> 8324 + for SoundCurrentSvc<T> { 7157 8325 type Response = super::SoundCurrentResponse; 7158 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8326 + type Future = BoxFuture< 8327 + tonic::Response<Self::Response>, 8328 + tonic::Status, 8329 + >; 7159 8330 fn call( 7160 8331 &mut self, 7161 8332 request: tonic::Request<super::SoundCurrentRequest>, ··· 7192 8363 "/rockbox.v1alpha1.SoundService/SoundDefault" => { 7193 8364 #[allow(non_camel_case_types)] 7194 8365 struct SoundDefaultSvc<T: SoundService>(pub Arc<T>); 7195 - impl<T: SoundService> tonic::server::UnaryService<super::SoundDefaultRequest> 7196 - for SoundDefaultSvc<T> 7197 - { 8366 + impl< 8367 + T: SoundService, 8368 + > tonic::server::UnaryService<super::SoundDefaultRequest> 8369 + for SoundDefaultSvc<T> { 7198 8370 type Response = super::SoundDefaultResponse; 7199 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8371 + type Future = BoxFuture< 8372 + tonic::Response<Self::Response>, 8373 + tonic::Status, 8374 + >; 7200 8375 fn call( 7201 8376 &mut self, 7202 8377 request: tonic::Request<super::SoundDefaultRequest>, ··· 7233 8408 "/rockbox.v1alpha1.SoundService/SoundMin" => { 7234 8409 #[allow(non_camel_case_types)] 7235 8410 struct SoundMinSvc<T: SoundService>(pub Arc<T>); 7236 - impl<T: SoundService> tonic::server::UnaryService<super::SoundMinRequest> for SoundMinSvc<T> { 8411 + impl< 8412 + T: SoundService, 8413 + > tonic::server::UnaryService<super::SoundMinRequest> 8414 + for SoundMinSvc<T> { 7237 8415 type Response = super::SoundMinResponse; 7238 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8416 + type Future = BoxFuture< 8417 + tonic::Response<Self::Response>, 8418 + tonic::Status, 8419 + >; 7239 8420 fn call( 7240 8421 &mut self, 7241 8422 request: tonic::Request<super::SoundMinRequest>, ··· 7272 8453 "/rockbox.v1alpha1.SoundService/SoundMax" => { 7273 8454 #[allow(non_camel_case_types)] 7274 8455 struct SoundMaxSvc<T: SoundService>(pub Arc<T>); 7275 - impl<T: SoundService> tonic::server::UnaryService<super::SoundMaxRequest> for SoundMaxSvc<T> { 8456 + impl< 8457 + T: SoundService, 8458 + > tonic::server::UnaryService<super::SoundMaxRequest> 8459 + for SoundMaxSvc<T> { 7276 8460 type Response = super::SoundMaxResponse; 7277 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8461 + type Future = BoxFuture< 8462 + tonic::Response<Self::Response>, 8463 + tonic::Status, 8464 + >; 7278 8465 fn call( 7279 8466 &mut self, 7280 8467 request: tonic::Request<super::SoundMaxRequest>, ··· 7311 8498 "/rockbox.v1alpha1.SoundService/SoundUnit" => { 7312 8499 #[allow(non_camel_case_types)] 7313 8500 struct SoundUnitSvc<T: SoundService>(pub Arc<T>); 7314 - impl<T: SoundService> tonic::server::UnaryService<super::SoundUnitRequest> for SoundUnitSvc<T> { 8501 + impl< 8502 + T: SoundService, 8503 + > tonic::server::UnaryService<super::SoundUnitRequest> 8504 + for SoundUnitSvc<T> { 7315 8505 type Response = super::SoundUnitResponse; 7316 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8506 + type Future = BoxFuture< 8507 + tonic::Response<Self::Response>, 8508 + tonic::Status, 8509 + >; 7317 8510 fn call( 7318 8511 &mut self, 7319 8512 request: tonic::Request<super::SoundUnitRequest>, ··· 7350 8543 "/rockbox.v1alpha1.SoundService/SoundVal2Phys" => { 7351 8544 #[allow(non_camel_case_types)] 7352 8545 struct SoundVal2PhysSvc<T: SoundService>(pub Arc<T>); 7353 - impl<T: SoundService> tonic::server::UnaryService<super::SoundVal2PhysRequest> 7354 - for SoundVal2PhysSvc<T> 7355 - { 8546 + impl< 8547 + T: SoundService, 8548 + > tonic::server::UnaryService<super::SoundVal2PhysRequest> 8549 + for SoundVal2PhysSvc<T> { 7356 8550 type Response = super::SoundVal2PhysResponse; 7357 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8551 + type Future = BoxFuture< 8552 + tonic::Response<Self::Response>, 8553 + tonic::Status, 8554 + >; 7358 8555 fn call( 7359 8556 &mut self, 7360 8557 request: tonic::Request<super::SoundVal2PhysRequest>, ··· 7391 8588 "/rockbox.v1alpha1.SoundService/GetPitch" => { 7392 8589 #[allow(non_camel_case_types)] 7393 8590 struct GetPitchSvc<T: SoundService>(pub Arc<T>); 7394 - impl<T: SoundService> tonic::server::UnaryService<super::GetPitchRequest> for GetPitchSvc<T> { 8591 + impl< 8592 + T: SoundService, 8593 + > tonic::server::UnaryService<super::GetPitchRequest> 8594 + for GetPitchSvc<T> { 7395 8595 type Response = super::GetPitchResponse; 7396 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8596 + type Future = BoxFuture< 8597 + tonic::Response<Self::Response>, 8598 + tonic::Status, 8599 + >; 7397 8600 fn call( 7398 8601 &mut self, 7399 8602 request: tonic::Request<super::GetPitchRequest>, ··· 7430 8633 "/rockbox.v1alpha1.SoundService/SetPitch" => { 7431 8634 #[allow(non_camel_case_types)] 7432 8635 struct SetPitchSvc<T: SoundService>(pub Arc<T>); 7433 - impl<T: SoundService> tonic::server::UnaryService<super::SetPitchRequest> for SetPitchSvc<T> { 8636 + impl< 8637 + T: SoundService, 8638 + > tonic::server::UnaryService<super::SetPitchRequest> 8639 + for SetPitchSvc<T> { 7434 8640 type Response = super::SetPitchResponse; 7435 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8641 + type Future = BoxFuture< 8642 + tonic::Response<Self::Response>, 8643 + tonic::Status, 8644 + >; 7436 8645 fn call( 7437 8646 &mut self, 7438 8647 request: tonic::Request<super::SetPitchRequest>, ··· 7469 8678 "/rockbox.v1alpha1.SoundService/BeepPlay" => { 7470 8679 #[allow(non_camel_case_types)] 7471 8680 struct BeepPlaySvc<T: SoundService>(pub Arc<T>); 7472 - impl<T: SoundService> tonic::server::UnaryService<super::BeepPlayRequest> for BeepPlaySvc<T> { 8681 + impl< 8682 + T: SoundService, 8683 + > tonic::server::UnaryService<super::BeepPlayRequest> 8684 + for BeepPlaySvc<T> { 7473 8685 type Response = super::BeepPlayResponse; 7474 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8686 + type Future = BoxFuture< 8687 + tonic::Response<Self::Response>, 8688 + tonic::Status, 8689 + >; 7475 8690 fn call( 7476 8691 &mut self, 7477 8692 request: tonic::Request<super::BeepPlayRequest>, ··· 7508 8723 "/rockbox.v1alpha1.SoundService/PcmbufFade" => { 7509 8724 #[allow(non_camel_case_types)] 7510 8725 struct PcmbufFadeSvc<T: SoundService>(pub Arc<T>); 7511 - impl<T: SoundService> tonic::server::UnaryService<super::PcmbufFadeRequest> for PcmbufFadeSvc<T> { 8726 + impl< 8727 + T: SoundService, 8728 + > tonic::server::UnaryService<super::PcmbufFadeRequest> 8729 + for PcmbufFadeSvc<T> { 7512 8730 type Response = super::PcmbufFadeResponse; 7513 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8731 + type Future = BoxFuture< 8732 + tonic::Response<Self::Response>, 8733 + tonic::Status, 8734 + >; 7514 8735 fn call( 7515 8736 &mut self, 7516 8737 request: tonic::Request<super::PcmbufFadeRequest>, ··· 7547 8768 "/rockbox.v1alpha1.SoundService/PcmbufSetLowLatency" => { 7548 8769 #[allow(non_camel_case_types)] 7549 8770 struct PcmbufSetLowLatencySvc<T: SoundService>(pub Arc<T>); 7550 - impl<T: SoundService> 7551 - tonic::server::UnaryService<super::PcmbufSetLowLatencyRequest> 7552 - for PcmbufSetLowLatencySvc<T> 7553 - { 8771 + impl< 8772 + T: SoundService, 8773 + > tonic::server::UnaryService<super::PcmbufSetLowLatencyRequest> 8774 + for PcmbufSetLowLatencySvc<T> { 7554 8775 type Response = super::PcmbufSetLowLatencyResponse; 7555 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8776 + type Future = BoxFuture< 8777 + tonic::Response<Self::Response>, 8778 + tonic::Status, 8779 + >; 7556 8780 fn call( 7557 8781 &mut self, 7558 8782 request: tonic::Request<super::PcmbufSetLowLatencyRequest>, 7559 8783 ) -> Self::Future { 7560 8784 let inner = Arc::clone(&self.0); 7561 8785 let fut = async move { 7562 - <T as SoundService>::pcmbuf_set_low_latency(&inner, request).await 8786 + <T as SoundService>::pcmbuf_set_low_latency(&inner, request) 8787 + .await 7563 8788 }; 7564 8789 Box::pin(fut) 7565 8790 } ··· 7589 8814 "/rockbox.v1alpha1.SoundService/SystemSoundPlay" => { 7590 8815 #[allow(non_camel_case_types)] 7591 8816 struct SystemSoundPlaySvc<T: SoundService>(pub Arc<T>); 7592 - impl<T: SoundService> tonic::server::UnaryService<super::SystemSoundPlayRequest> 7593 - for SystemSoundPlaySvc<T> 7594 - { 8817 + impl< 8818 + T: SoundService, 8819 + > tonic::server::UnaryService<super::SystemSoundPlayRequest> 8820 + for SystemSoundPlaySvc<T> { 7595 8821 type Response = super::SystemSoundPlayResponse; 7596 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8822 + type Future = BoxFuture< 8823 + tonic::Response<Self::Response>, 8824 + tonic::Status, 8825 + >; 7597 8826 fn call( 7598 8827 &mut self, 7599 8828 request: tonic::Request<super::SystemSoundPlayRequest>, 7600 8829 ) -> Self::Future { 7601 8830 let inner = Arc::clone(&self.0); 7602 8831 let fut = async move { 7603 - <T as SoundService>::system_sound_play(&inner, request).await 8832 + <T as SoundService>::system_sound_play(&inner, request) 8833 + .await 7604 8834 }; 7605 8835 Box::pin(fut) 7606 8836 } ··· 7630 8860 "/rockbox.v1alpha1.SoundService/KeyclickClick" => { 7631 8861 #[allow(non_camel_case_types)] 7632 8862 struct KeyclickClickSvc<T: SoundService>(pub Arc<T>); 7633 - impl<T: SoundService> tonic::server::UnaryService<super::KeyclickClickRequest> 7634 - for KeyclickClickSvc<T> 7635 - { 8863 + impl< 8864 + T: SoundService, 8865 + > tonic::server::UnaryService<super::KeyclickClickRequest> 8866 + for KeyclickClickSvc<T> { 7636 8867 type Response = super::KeyclickClickResponse; 7637 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 8868 + type Future = BoxFuture< 8869 + tonic::Response<Self::Response>, 8870 + tonic::Status, 8871 + >; 7638 8872 fn call( 7639 8873 &mut self, 7640 8874 request: tonic::Request<super::KeyclickClickRequest>, ··· 7668 8902 }; 7669 8903 Box::pin(fut) 7670 8904 } 7671 - _ => Box::pin(async move { 7672 - let mut response = http::Response::new(empty_body()); 7673 - let headers = response.headers_mut(); 7674 - headers.insert( 7675 - tonic::Status::GRPC_STATUS, 7676 - (tonic::Code::Unimplemented as i32).into(), 7677 - ); 7678 - headers.insert( 7679 - http::header::CONTENT_TYPE, 7680 - tonic::metadata::GRPC_CONTENT_TYPE, 7681 - ); 7682 - Ok(response) 7683 - }), 8905 + _ => { 8906 + Box::pin(async move { 8907 + let mut response = http::Response::new(empty_body()); 8908 + let headers = response.headers_mut(); 8909 + headers 8910 + .insert( 8911 + tonic::Status::GRPC_STATUS, 8912 + (tonic::Code::Unimplemented as i32).into(), 8913 + ); 8914 + headers 8915 + .insert( 8916 + http::header::CONTENT_TYPE, 8917 + tonic::metadata::GRPC_CONTENT_TYPE, 8918 + ); 8919 + Ok(response) 8920 + }) 8921 + } 7684 8922 } 7685 8923 } 7686 8924 } ··· 7741 8979 dead_code, 7742 8980 missing_docs, 7743 8981 clippy::wildcard_imports, 7744 - clippy::let_unit_value 8982 + clippy::let_unit_value, 7745 8983 )] 7746 - use tonic::codegen::http::Uri; 7747 8984 use tonic::codegen::*; 8985 + use tonic::codegen::http::Uri; 7748 8986 #[derive(Debug, Clone)] 7749 8987 pub struct SystemServiceClient<T> { 7750 8988 inner: tonic::client::Grpc<T>, ··· 7788 9026 <T as tonic::client::GrpcService<tonic::body::BoxBody>>::ResponseBody, 7789 9027 >, 7790 9028 >, 7791 - <T as tonic::codegen::Service<http::Request<tonic::body::BoxBody>>>::Error: 7792 - Into<StdError> + std::marker::Send + std::marker::Sync, 9029 + <T as tonic::codegen::Service< 9030 + http::Request<tonic::body::BoxBody>, 9031 + >>::Error: Into<StdError> + std::marker::Send + std::marker::Sync, 7793 9032 { 7794 9033 SystemServiceClient::new(InterceptedService::new(inner, interceptor)) 7795 9034 } ··· 7827 9066 pub async fn get_rockbox_version( 7828 9067 &mut self, 7829 9068 request: impl tonic::IntoRequest<super::GetRockboxVersionRequest>, 7830 - ) -> std::result::Result<tonic::Response<super::GetRockboxVersionResponse>, tonic::Status> 7831 - { 7832 - self.inner.ready().await.map_err(|e| { 7833 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 7834 - })?; 9069 + ) -> std::result::Result< 9070 + tonic::Response<super::GetRockboxVersionResponse>, 9071 + tonic::Status, 9072 + > { 9073 + self.inner 9074 + .ready() 9075 + .await 9076 + .map_err(|e| { 9077 + tonic::Status::unknown( 9078 + format!("Service was not ready: {}", e.into()), 9079 + ) 9080 + })?; 7835 9081 let codec = tonic::codec::ProstCodec::default(); 7836 9082 let path = http::uri::PathAndQuery::from_static( 7837 9083 "/rockbox.v1alpha1.SystemService/GetRockboxVersion", 7838 9084 ); 7839 9085 let mut req = request.into_request(); 7840 - req.extensions_mut().insert(GrpcMethod::new( 7841 - "rockbox.v1alpha1.SystemService", 7842 - "GetRockboxVersion", 7843 - )); 9086 + req.extensions_mut() 9087 + .insert( 9088 + GrpcMethod::new( 9089 + "rockbox.v1alpha1.SystemService", 9090 + "GetRockboxVersion", 9091 + ), 9092 + ); 7844 9093 self.inner.unary(req, path, codec).await 7845 9094 } 7846 9095 pub async fn get_global_status( 7847 9096 &mut self, 7848 9097 request: impl tonic::IntoRequest<super::GetGlobalStatusRequest>, 7849 - ) -> std::result::Result<tonic::Response<super::GetGlobalStatusResponse>, tonic::Status> 7850 - { 7851 - self.inner.ready().await.map_err(|e| { 7852 - tonic::Status::unknown(format!("Service was not ready: {}", e.into())) 7853 - })?; 9098 + ) -> std::result::Result< 9099 + tonic::Response<super::GetGlobalStatusResponse>, 9100 + tonic::Status, 9101 + > { 9102 + self.inner 9103 + .ready() 9104 + .await 9105 + .map_err(|e| { 9106 + tonic::Status::unknown( 9107 + format!("Service was not ready: {}", e.into()), 9108 + ) 9109 + })?; 7854 9110 let codec = tonic::codec::ProstCodec::default(); 7855 9111 let path = http::uri::PathAndQuery::from_static( 7856 9112 "/rockbox.v1alpha1.SystemService/GetGlobalStatus", 7857 9113 ); 7858 9114 let mut req = request.into_request(); 7859 - req.extensions_mut().insert(GrpcMethod::new( 7860 - "rockbox.v1alpha1.SystemService", 7861 - "GetGlobalStatus", 7862 - )); 9115 + req.extensions_mut() 9116 + .insert( 9117 + GrpcMethod::new("rockbox.v1alpha1.SystemService", "GetGlobalStatus"), 9118 + ); 7863 9119 self.inner.unary(req, path, codec).await 7864 9120 } 7865 9121 } ··· 7871 9127 dead_code, 7872 9128 missing_docs, 7873 9129 clippy::wildcard_imports, 7874 - clippy::let_unit_value 9130 + clippy::let_unit_value, 7875 9131 )] 7876 9132 use tonic::codegen::*; 7877 9133 /// Generated trait containing gRPC methods that should be implemented for use with SystemServiceServer. ··· 7880 9136 async fn get_rockbox_version( 7881 9137 &self, 7882 9138 request: tonic::Request<super::GetRockboxVersionRequest>, 7883 - ) -> std::result::Result<tonic::Response<super::GetRockboxVersionResponse>, tonic::Status>; 9139 + ) -> std::result::Result< 9140 + tonic::Response<super::GetRockboxVersionResponse>, 9141 + tonic::Status, 9142 + >; 7884 9143 async fn get_global_status( 7885 9144 &self, 7886 9145 request: tonic::Request<super::GetGlobalStatusRequest>, 7887 - ) -> std::result::Result<tonic::Response<super::GetGlobalStatusResponse>, tonic::Status>; 9146 + ) -> std::result::Result< 9147 + tonic::Response<super::GetGlobalStatusResponse>, 9148 + tonic::Status, 9149 + >; 7888 9150 } 7889 9151 #[derive(Debug)] 7890 9152 pub struct SystemServiceServer<T> { ··· 7907 9169 max_encoding_message_size: None, 7908 9170 } 7909 9171 } 7910 - pub fn with_interceptor<F>(inner: T, interceptor: F) -> InterceptedService<Self, F> 9172 + pub fn with_interceptor<F>( 9173 + inner: T, 9174 + interceptor: F, 9175 + ) -> InterceptedService<Self, F> 7911 9176 where 7912 9177 F: tonic::service::Interceptor, 7913 9178 { ··· 7962 9227 "/rockbox.v1alpha1.SystemService/GetRockboxVersion" => { 7963 9228 #[allow(non_camel_case_types)] 7964 9229 struct GetRockboxVersionSvc<T: SystemService>(pub Arc<T>); 7965 - impl<T: SystemService> 7966 - tonic::server::UnaryService<super::GetRockboxVersionRequest> 7967 - for GetRockboxVersionSvc<T> 7968 - { 9230 + impl< 9231 + T: SystemService, 9232 + > tonic::server::UnaryService<super::GetRockboxVersionRequest> 9233 + for GetRockboxVersionSvc<T> { 7969 9234 type Response = super::GetRockboxVersionResponse; 7970 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 9235 + type Future = BoxFuture< 9236 + tonic::Response<Self::Response>, 9237 + tonic::Status, 9238 + >; 7971 9239 fn call( 7972 9240 &mut self, 7973 9241 request: tonic::Request<super::GetRockboxVersionRequest>, 7974 9242 ) -> Self::Future { 7975 9243 let inner = Arc::clone(&self.0); 7976 9244 let fut = async move { 7977 - <T as SystemService>::get_rockbox_version(&inner, request).await 9245 + <T as SystemService>::get_rockbox_version(&inner, request) 9246 + .await 7978 9247 }; 7979 9248 Box::pin(fut) 7980 9249 } ··· 8004 9273 "/rockbox.v1alpha1.SystemService/GetGlobalStatus" => { 8005 9274 #[allow(non_camel_case_types)] 8006 9275 struct GetGlobalStatusSvc<T: SystemService>(pub Arc<T>); 8007 - impl<T: SystemService> 8008 - tonic::server::UnaryService<super::GetGlobalStatusRequest> 8009 - for GetGlobalStatusSvc<T> 8010 - { 9276 + impl< 9277 + T: SystemService, 9278 + > tonic::server::UnaryService<super::GetGlobalStatusRequest> 9279 + for GetGlobalStatusSvc<T> { 8011 9280 type Response = super::GetGlobalStatusResponse; 8012 - type Future = BoxFuture<tonic::Response<Self::Response>, tonic::Status>; 9281 + type Future = BoxFuture< 9282 + tonic::Response<Self::Response>, 9283 + tonic::Status, 9284 + >; 8013 9285 fn call( 8014 9286 &mut self, 8015 9287 request: tonic::Request<super::GetGlobalStatusRequest>, 8016 9288 ) -> Self::Future { 8017 9289 let inner = Arc::clone(&self.0); 8018 9290 let fut = async move { 8019 - <T as SystemService>::get_global_status(&inner, request).await 9291 + <T as SystemService>::get_global_status(&inner, request) 9292 + .await 8020 9293 }; 8021 9294 Box::pin(fut) 8022 9295 } ··· 8043 9316 }; 8044 9317 Box::pin(fut) 8045 9318 } 8046 - _ => Box::pin(async move { 8047 - let mut response = http::Response::new(empty_body()); 8048 - let headers = response.headers_mut(); 8049 - headers.insert( 8050 - tonic::Status::GRPC_STATUS, 8051 - (tonic::Code::Unimplemented as i32).into(), 8052 - ); 8053 - headers.insert( 8054 - http::header::CONTENT_TYPE, 8055 - tonic::metadata::GRPC_CONTENT_TYPE, 8056 - ); 8057 - Ok(response) 8058 - }), 9319 + _ => { 9320 + Box::pin(async move { 9321 + let mut response = http::Response::new(empty_body()); 9322 + let headers = response.headers_mut(); 9323 + headers 9324 + .insert( 9325 + tonic::Status::GRPC_STATUS, 9326 + (tonic::Code::Unimplemented as i32).into(), 9327 + ); 9328 + headers 9329 + .insert( 9330 + http::header::CONTENT_TYPE, 9331 + tonic::metadata::GRPC_CONTENT_TYPE, 9332 + ); 9333 + Ok(response) 9334 + }) 9335 + } 8059 9336 } 8060 9337 } 8061 9338 }
+64 -16
crates/upnp/src/lib.rs
··· 92 92 } 93 93 } 94 94 95 + /// Start a subscriber `n` chunks *behind* the live edge so the remote 96 + /// client can drain historical buffered data at network speed instead of 97 + /// waiting for new chunks to arrive in real time. Clamped to the oldest 98 + /// chunk still in the buffer. 99 + pub(crate) fn subscribe_from_behind(self: &Arc<Self>, n: u64) -> BroadcastReceiver { 100 + let g = self.inner.lock().unwrap(); 101 + let front_seq = g.chunks.front().map(|(s, _)| *s).unwrap_or(g.next_seq); 102 + let next_seq = g.next_seq.saturating_sub(n).max(front_seq); 103 + BroadcastReceiver { 104 + buf: Arc::clone(self), 105 + next_seq, 106 + } 107 + } 108 + 95 109 fn reset(&self) { 96 110 let mut g = self.inner.lock().unwrap(); 97 111 g.chunks.clear(); ··· 320 334 if let Some(ref t) = track { 321 335 *LAST_PCM_TRACK_PATH.lock().unwrap() = t.path.clone(); 322 336 } 323 - let album_art_url = if let Some(ref t) = track { 324 - get_album_art_url(&t.path, local_ip).await 325 - } else { 326 - None 327 - }; 328 - if let Err(e) = avtransport_play( 329 - &url, 330 - &stream_url, 331 - track.as_ref(), 332 - sample_rate, 333 - true, 334 - album_art_url.as_deref(), 335 - ) 336 - .await 337 + // Send SetAVTransportURI + Play immediately without waiting for the 338 + // album art DB lookup — this cuts 100–500 ms of startup latency. 339 + if let Err(e) = 340 + avtransport_play(&url, &stream_url, track.as_ref(), sample_rate, true, None) 341 + .await 337 342 { 338 343 tracing::warn!("UPnP AVTransport play failed: {}", e); 344 + return; 345 + } 346 + // Follow up with album art once the DB lookup completes (metadata- 347 + // only update, no second Play so the renderer stays connected). 348 + if let Some(ref t) = track { 349 + if let Some(art) = get_album_art_url(&t.path, local_ip).await { 350 + let _ = avtransport_play( 351 + &url, 352 + &stream_url, 353 + track.as_ref(), 354 + sample_rate, 355 + false, 356 + Some(&art), 357 + ) 358 + .await; 359 + } 339 360 } 340 361 }); 341 362 } else { ··· 357 378 } 358 379 }; 359 380 360 - if is_track_change { 381 + // If the "new track" is our own WAV stream the renderer is re-ingesting 382 + // (http://<ip>:<port>/stream.wav), skip SetAVTransportURI entirely. 383 + // Sending it would overwrite the correct DIDL metadata (duration, album 384 + // art) stored for the real file with stream.wav's codec values (duration 385 + // 0, no art), and would create an infinite feedback loop. 386 + let is_our_stream = 387 + current_path.starts_with("http://") && current_path.ends_with("/stream.wav"); 388 + 389 + if is_track_change && !is_our_stream { 361 390 // Fire SetAVTransportURI *without* Play at the exact PCM boundary. 362 391 // The renderer updates its metadata display and — if it supports 363 392 // metadata-only updates — stays connected to the live /stream.wav ··· 423 452 *rp = false; 424 453 } 425 454 455 + /// Reset the renderer-side state so the next `pcm_upnp_start()` always sends 456 + /// a fresh SetAVTransportURI + Play to the renderer. Call this whenever the 457 + /// UPnP sink is selected (e.g. the user connects to a UPnP device from the UI) 458 + /// to make output switch-in work without restarting the daemon. 459 + #[cfg(feature = "ffi")] 460 + #[no_mangle] 461 + pub extern "C" fn pcm_upnp_reset_renderer() { 462 + // Kill any running track-change monitor — a new one will start with pcm_upnp_start(). 463 + MONITOR_GEN.fetch_add(1, Ordering::SeqCst); 464 + // Clear the last-track hint so the next start is always treated as "first play". 465 + *LAST_PCM_TRACK_PATH.lock().unwrap() = String::new(); 466 + // Reset the "renderer already playing" flag so pcm_upnp_start() sends Play. 467 + *RENDERER_PLAYING.lock().unwrap() = false; 468 + tracing::debug!("UPnP PCM sink: renderer state reset"); 469 + } 470 + 426 471 // --------------------------------------------------------------------------- 427 472 // Album art DB lookup 428 473 // --------------------------------------------------------------------------- ··· 470 515 .map(|t| t.path.clone()) 471 516 .unwrap_or_default(); 472 517 473 - if !current_path.is_empty() && current_path != last_current_path { 518 + let is_our_stream = 519 + current_path.starts_with("http://") && current_path.ends_with("/stream.wav"); 520 + 521 + if !current_path.is_empty() && current_path != last_current_path && !is_our_stream { 474 522 let is_first = last_current_path.is_empty(); 475 523 last_current_path = current_path.clone(); 476 524
+5 -1
crates/upnp/src/pcm_server.rs
··· 361 361 if req.wants_icy { " (ICY)" } else { "" } 362 362 ); 363 363 364 - let mut rx = buf.subscribe(); 364 + // Start ~2 s behind the live edge so the renderer can drain historical 365 + // buffered chunks at network speed instead of filling at real-time rate. 366 + // Each chunk ≈ 8192 bytes ≈ 46 ms; 44 chunks ≈ 2 s. 367 + let mut rx = buf.subscribe_from_behind(44); 365 368 366 369 if req.wants_icy { 367 370 let art_url = art_base_url(local_ip, port); ··· 476 479 for stream in listener.incoming() { 477 480 match stream { 478 481 Ok(mut tcp) => { 482 + let _ = tcp.set_nodelay(true); 479 483 let buf = buf.clone(); 480 484 std::thread::spawn(move || { 481 485 let peer = tcp.peer_addr().map(|a| a.to_string()).unwrap_or_default();
+158 -27
crates/upnp/src/renderer.rs
··· 41 41 current_metadata: String, 42 42 transport_state: TransportState, 43 43 mute: bool, 44 + /// Value of `current_track().elapsed` when the current track started. 45 + /// Subtracted from the live elapsed so RelTime resets to 0 on each track 46 + /// change even though the underlying WAV stream is continuous. 47 + elapsed_offset: u64, 44 48 } 45 49 46 50 static RENDERER_STATE: Mutex<RendererState> = Mutex::new(RendererState { ··· 48 52 current_metadata: String::new(), 49 53 transport_state: TransportState::NoMediaPresent, 50 54 mute: false, 55 + elapsed_offset: 0, 51 56 }); 52 57 53 58 static RENDERER_UUID: OnceLock<String> = OnceLock::new(); ··· 369 374 tracing::info!("UPnP renderer: SetAVTransportURI = {uri}"); 370 375 { 371 376 let mut st = RENDERER_STATE.lock().unwrap(); 377 + // Track-change while playing: capture current elapsed so that 378 + // GetPositionInfo resets RelTime to 0 for the new track. 379 + if st.transport_state == TransportState::Playing { 380 + let elapsed = rockbox_sys::playback::current_track() 381 + .map(|t| t.elapsed) 382 + .unwrap_or(0); 383 + st.elapsed_offset = elapsed; 384 + } 372 385 st.current_uri = Some(uri); 373 386 st.current_metadata = metadata; 374 387 st.transport_state = TransportState::Stopped; ··· 381 394 } 382 395 383 396 Some("Play") => { 384 - let uri = { 397 + let (uri, metadata) = { 385 398 let st = RENDERER_STATE.lock().unwrap(); 386 - st.current_uri.clone() 399 + (st.current_uri.clone(), st.current_metadata.clone()) 387 400 }; 401 + tracing::info!("UPnP renderer: Play action received, uri={uri:?}"); 388 402 match uri { 389 403 None => soap_error(701, "Transition not available"), 390 404 Some(uri) => { 391 405 tracing::info!("UPnP renderer: Play {uri}"); 406 + 407 + // Guard against the self-referential loop: when the UPnP PCM 408 + // output sink sends Play(stream.wav) to the same rockboxd 409 + // instance's renderer, playing the stream back would create a 410 + // circular audio path (engine reads stream.wav → PCM output → 411 + // BroadcastBuffer → stream.wav → ...), overflowing the codec 412 + // thread stack and crashing. Detect this by matching our own 413 + // PCM HTTP port in the URI. Audio is already flowing via the 414 + // UPnP sink, so just acknowledge without re-routing. 415 + let own_pcm_port = crate::CONFIG.lock().unwrap().pcm_port; 416 + let is_own_stream = (uri.ends_with("/stream.wav")) 417 + && (uri.contains(&format!(":{own_pcm_port}/")) 418 + || uri.ends_with(&format!(":{own_pcm_port}"))); 419 + if is_own_stream { 420 + tracing::warn!( 421 + "UPnP renderer: Play for own PCM stream (port {own_pcm_port}) — \ 422 + acknowledging without re-routing to prevent feedback loop" 423 + ); 424 + RENDERER_STATE.lock().unwrap().transport_state = TransportState::Playing; 425 + return soap_ok("urn:schemas-upnp-org:service:AVTransport:1", "Play", ""); 426 + } 427 + 428 + let title = 429 + extract_didl_field(&metadata, "title").unwrap_or_else(|| uri.clone()); 430 + let artist = extract_didl_field(&metadata, "artist") 431 + .or_else(|| extract_didl_field(&metadata, "creator")) 432 + .unwrap_or_default(); 433 + let album = extract_didl_field(&metadata, "album").unwrap_or_default(); 434 + let duration_ms = parse_didl_duration_ms(&metadata).unwrap_or(0) as u64; 435 + let album_art_url = 436 + extract_didl_field(&metadata, "albumArtURI").unwrap_or_default(); 437 + rockbox_sys::playback::set_metadata_override( 438 + &uri, 439 + &title, 440 + &artist, 441 + &album, 442 + duration_ms, 443 + &album_art_url, 444 + ); 392 445 play_url(&uri).await; 393 - RENDERER_STATE.lock().unwrap().transport_state = TransportState::Playing; 446 + { 447 + let mut st = RENDERER_STATE.lock().unwrap(); 448 + st.transport_state = TransportState::Playing; 449 + st.elapsed_offset = 0; // stream restarts from 0 450 + } 394 451 soap_ok("urn:schemas-upnp-org:service:AVTransport:1", "Play", "") 395 452 } 396 453 } ··· 407 464 } 408 465 { 409 466 let mut st = RENDERER_STATE.lock().unwrap(); 467 + if let Some(ref uri) = st.current_uri { 468 + rockbox_sys::playback::clear_metadata_override(uri); 469 + } 410 470 st.transport_state = TransportState::Stopped; 411 471 st.current_metadata = String::new(); 412 472 } ··· 521 581 ) 522 582 } 523 583 524 - _ => soap_error(401, "Invalid Action"), 584 + other => { 585 + tracing::warn!("UPnP renderer: unknown AVTransport action: {other:?}"); 586 + soap_error(401, "Invalid Action") 587 + } 525 588 } 526 589 } 527 590 ··· 637 700 soap_error(401, "Invalid Action") 638 701 } 639 702 703 + /// Extract a DIDL-Lite field by its local name, trying common namespace prefixes. 704 + fn extract_didl_field(didl: &str, local_name: &str) -> Option<String> { 705 + for prefix in &["dc:", "upnp:", "r:", ""] { 706 + let tag = format!("{}{}", prefix, local_name); 707 + if let Some(v) = extract_tag(didl, &tag) { 708 + if !v.is_empty() { 709 + return Some(v); 710 + } 711 + } 712 + } 713 + None 714 + } 715 + 640 716 async fn play_url(uri: &str) { 641 - use crate::api::rockbox::v1alpha1::{ 642 - playback_service_client::PlaybackServiceClient, PlayTrackRequest, 643 - }; 644 - let port = std::env::var("ROCKBOX_PORT").unwrap_or_else(|_| "6061".to_string()); 645 - let url = format!("tcp://127.0.0.1:{}", port); 646 - match PlaybackServiceClient::connect(url).await { 647 - Ok(mut client) => { 648 - let req = PlayTrackRequest { 649 - path: uri.to_string(), 650 - }; 651 - if let Err(e) = client.play_track(req).await { 652 - tracing::error!("UPnP renderer: PlayTrack gRPC error: {e}"); 653 - } 717 + let tcp_port = std::env::var("ROCKBOX_TCP_PORT").unwrap_or_else(|_| "6063".to_string()); 718 + let base = format!("http://127.0.0.1:{tcp_port}"); 719 + // The internal HTTP server closes the TCP socket after each response. 720 + // pool_max_idle_per_host(0) disables connection pooling so each request 721 + // opens a fresh connection instead of reusing a server-closed socket. 722 + let client = reqwest::Client::builder() 723 + .pool_max_idle_per_host(0) 724 + .build() 725 + .unwrap_or_default(); 726 + 727 + let body = serde_json::json!({ "tracks": [uri] }); 728 + tracing::info!("UPnP renderer: POST {base}/playlists tracks=[{uri}]"); 729 + match client 730 + .post(format!("{base}/playlists")) 731 + .json(&body) 732 + .send() 733 + .await 734 + { 735 + Ok(r) if r.status().is_success() => { 736 + tracing::info!("UPnP renderer: playlist created, starting playback"); 654 737 } 655 - Err(e) => tracing::error!("UPnP renderer: gRPC connect error: {e}"), 738 + Ok(r) => { 739 + tracing::error!("UPnP renderer: POST /playlists failed: {}", r.status()); 740 + return; 741 + } 742 + Err(e) => { 743 + tracing::error!("UPnP renderer: POST /playlists error: {e}"); 744 + return; 745 + } 746 + } 747 + 748 + tracing::info!("UPnP renderer: PUT {base}/playlists/start"); 749 + match client.put(format!("{base}/playlists/start")).send().await { 750 + Ok(r) if r.status().is_success() => { 751 + tracing::info!("UPnP renderer: playback started"); 752 + } 753 + Ok(r) => tracing::error!("UPnP renderer: PUT /playlists/start failed: {}", r.status()), 754 + Err(e) => tracing::error!("UPnP renderer: PUT /playlists/start error: {e}"), 656 755 } 657 756 } 658 757 ··· 673 772 } 674 773 675 774 fn get_position_info() -> (String, i32, i32) { 676 - let uri = RENDERER_STATE 677 - .lock() 678 - .unwrap() 679 - .current_uri 680 - .clone() 681 - .unwrap_or_default(); 775 + let (uri, metadata, elapsed_offset) = { 776 + let st = RENDERER_STATE.lock().unwrap(); 777 + ( 778 + st.current_uri.clone().unwrap_or_default(), 779 + st.current_metadata.clone(), 780 + st.elapsed_offset, 781 + ) 782 + }; 682 783 683 - let (elapsed, duration) = match rockbox_sys::playback::current_track() { 684 - Some(track) => (track.elapsed as i32, track.length as i32), 685 - None => (0, 0), 784 + // Elapsed from the codec minus the offset captured at the last track 785 + // boundary, so RelTime resets to 0 on each track change even though the 786 + // underlying WAV stream is continuous. 787 + let elapsed = match rockbox_sys::playback::current_track() { 788 + Some(track) => (track.elapsed.saturating_sub(elapsed_offset)) as i32, 789 + None => 0, 686 790 }; 791 + 792 + // Duration from the DIDL-Lite sent by the source (accurate per-track). 793 + let duration = parse_didl_duration_ms(&metadata).unwrap_or(0); 794 + 687 795 (uri, elapsed, duration) 796 + } 797 + 798 + /// Parse `duration="H:MM:SS.mmm"` from a DIDL-Lite string. 799 + fn parse_didl_duration_ms(didl: &str) -> Option<i32> { 800 + let key = "duration=\""; 801 + let start = didl.find(key)? + key.len(); 802 + let end = didl[start..].find('"')? + start; 803 + parse_upnp_duration_ms(&didl[start..end]) 804 + } 805 + 806 + /// Parse a UPnP duration string `[H+]:MM:SS[.F+]` into milliseconds. 807 + fn parse_upnp_duration_ms(s: &str) -> Option<i32> { 808 + let mut parts = s.splitn(3, ':'); 809 + let h: i32 = parts.next()?.parse().ok()?; 810 + let m: i32 = parts.next()?.parse().ok()?; 811 + let sec_frac = parts.next()?; 812 + let mut sec_parts = sec_frac.splitn(2, '.'); 813 + let sec: i32 = sec_parts.next()?.parse().ok()?; 814 + let ms: i32 = sec_parts.next().map_or(0, |f| { 815 + let padded = format!("{:0<3}", &f[..f.len().min(3)]); 816 + padded.parse().unwrap_or(0) 817 + }); 818 + Some((h * 3600 + m * 60 + sec) * 1000 + ms) 688 819 } 689 820 690 821 // SOUND_VOLUME = 0 in Rockbox (first entry in the sound settings enum).
+1
firmware/SOURCES
··· 541 541 target/hosted/pcm-squeezelite.c 542 542 target/hosted/pcm-upnp.c 543 543 target/hosted/pcm-chromecast.c 544 + target/hosted/pcm-tcp.c 544 545 #endif 545 546 #ifdef HAVE_SW_VOLUME_CONTROL 546 547 pcm_sw_volume.c
+6
firmware/export/pcm_sink.h
··· 58 58 PCM_SINK_SQUEEZELITE, 59 59 PCM_SINK_UPNP, 60 60 PCM_SINK_CHROMECAST, 61 + PCM_SINK_SNAPCAST_TCP, 61 62 #endif 62 63 PCM_SINK_NUM 63 64 }; ··· 86 87 void pcm_chromecast_set_http_port(uint16_t port); 87 88 void pcm_chromecast_set_device_host(const char *host); 88 89 void pcm_chromecast_set_device_port(uint16_t port); 90 + 91 + /* Snapcast TCP sink — streams raw S16LE PCM to snapserver's tcp:// source */ 92 + extern struct pcm_sink tcp_pcm_sink; 93 + void pcm_tcp_set_host(const char *host); 94 + void pcm_tcp_set_port(uint16_t port); 89 95 #endif
+1
firmware/pcm.c
··· 86 86 [PCM_SINK_SQUEEZELITE] = &squeezelite_pcm_sink, 87 87 [PCM_SINK_UPNP] = &upnp_pcm_sink, 88 88 [PCM_SINK_CHROMECAST] = &chromecast_pcm_sink, 89 + [PCM_SINK_SNAPCAST_TCP] = &tcp_pcm_sink, 89 90 #endif 90 91 }; 91 92 static enum pcm_sink_ids cur_sink = PCM_SINK_BUILTIN;
+260
firmware/target/hosted/pcm-tcp.c
··· 1 + /*************************************************************************** 2 + * __________ __ ___. 3 + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ 4 + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / 5 + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < 6 + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ 7 + * \/ \/ \/ \/ \/ 8 + * 9 + * PCM sink that writes raw S16LE stereo PCM over a TCP socket. 10 + * Intended for use with Snapcast (tcp:// source) or similar consumers. 11 + * 12 + * Usage: 13 + * pcm_tcp_set_host("192.168.1.x"); // snapserver host 14 + * pcm_tcp_set_port(4953); // snapserver tcp source port (default) 15 + * pcm_switch_sink(PCM_SINK_SNAPCAST_TCP); 16 + * 17 + * Snapserver config: 18 + * source = tcp://0.0.0.0:4953?name=default&sampleformat=44100:16:2 19 + * 20 + * Copyright (C) 2026 Rockbox contributors 21 + * 22 + * This program is free software; you can redistribute it and/or 23 + * modify it under the terms of the GNU General Public License 24 + * as published by the Free Software Foundation; either version 2 25 + * of the License, or (at your option) any later version. 26 + * 27 + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 28 + * KIND, either express or implied. 29 + * 30 + ****************************************************************************/ 31 + 32 + #include "autoconf.h" 33 + #include "config.h" 34 + 35 + #include <arpa/inet.h> 36 + #include <errno.h> 37 + #include <netdb.h> 38 + #include <pthread.h> 39 + #include <stdbool.h> 40 + #include <stddef.h> 41 + #include <stdint.h> 42 + #include <stdio.h> 43 + #include <stdlib.h> 44 + #include <string.h> 45 + #include <sys/socket.h> 46 + #include <sys/types.h> 47 + #include <unistd.h> 48 + 49 + #include "pcm.h" 50 + #include "pcm-internal.h" 51 + #include "pcm_mixer.h" 52 + #include "pcm_sampr.h" 53 + #include "pcm_sink.h" 54 + 55 + #define LOGF_ENABLE 56 + #include "logf.h" 57 + 58 + #define DEFAULT_TCP_HOST "127.0.0.1" 59 + #define DEFAULT_TCP_PORT 4953 60 + 61 + static char tcp_host[256] = DEFAULT_TCP_HOST; 62 + static uint16_t tcp_port = DEFAULT_TCP_PORT; 63 + static int tcp_fd = -1; 64 + 65 + static const void *pcm_data = NULL; 66 + static size_t pcm_size = 0; 67 + 68 + static pthread_mutex_t tcp_mtx; 69 + static pthread_t tcp_tid; 70 + static volatile bool tcp_running = false; 71 + static volatile bool tcp_stop = false; 72 + 73 + void pcm_tcp_set_host(const char *host) 74 + { 75 + strncpy(tcp_host, host, sizeof(tcp_host) - 1); 76 + tcp_host[sizeof(tcp_host) - 1] = '\0'; 77 + } 78 + 79 + void pcm_tcp_set_port(uint16_t port) 80 + { 81 + tcp_port = port; 82 + } 83 + 84 + static int tcp_connect_once(void) 85 + { 86 + struct addrinfo hints, *res, *rp; 87 + char portstr[8]; 88 + int fd = -1; 89 + 90 + memset(&hints, 0, sizeof(hints)); 91 + hints.ai_family = AF_UNSPEC; 92 + hints.ai_socktype = SOCK_STREAM; 93 + 94 + snprintf(portstr, sizeof(portstr), "%u", (unsigned)tcp_port); 95 + if (getaddrinfo(tcp_host, portstr, &hints, &res) != 0) { 96 + logf("pcm-tcp: getaddrinfo(%s:%s) failed: %s", 97 + tcp_host, portstr, strerror(errno)); 98 + return -1; 99 + } 100 + 101 + for (rp = res; rp != NULL; rp = rp->ai_next) { 102 + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); 103 + if (fd < 0) 104 + continue; 105 + if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0) 106 + break; 107 + close(fd); 108 + fd = -1; 109 + } 110 + freeaddrinfo(res); 111 + 112 + if (fd < 0) 113 + logf("pcm-tcp: connect to %s:%u failed: %s", 114 + tcp_host, (unsigned)tcp_port, strerror(errno)); 115 + else 116 + logf("pcm-tcp: connected to %s:%u fd=%d", 117 + tcp_host, (unsigned)tcp_port, fd); 118 + 119 + return fd; 120 + } 121 + 122 + static void *tcp_thread(void *arg) 123 + { 124 + (void)arg; 125 + 126 + while (!tcp_stop) { 127 + pthread_mutex_lock(&tcp_mtx); 128 + const void *data = pcm_data; 129 + size_t size = pcm_size; 130 + pcm_data = NULL; 131 + pcm_size = 0; 132 + pthread_mutex_unlock(&tcp_mtx); 133 + 134 + /* Write current chunk in pieces so stop() can interrupt promptly */ 135 + while (size > 0 && !tcp_stop) { 136 + ssize_t n = write(tcp_fd, data, size); 137 + if (n < 0) { 138 + if (errno == EINTR || errno == EAGAIN) 139 + continue; 140 + logf("pcm-tcp: write error: %s", strerror(errno)); 141 + /* Mark connection dead; reconnect on next sink_dma_start */ 142 + close(tcp_fd); 143 + tcp_fd = -1; 144 + tcp_stop = true; 145 + break; 146 + } 147 + data = (const char *)data + n; 148 + size -= n; 149 + } 150 + 151 + if (tcp_stop) 152 + break; 153 + 154 + /* Request next buffer */ 155 + pthread_mutex_lock(&tcp_mtx); 156 + bool got_more = pcm_play_dma_complete_callback(PCM_DMAST_OK, 157 + &pcm_data, &pcm_size); 158 + pthread_mutex_unlock(&tcp_mtx); 159 + 160 + if (!got_more) { 161 + logf("pcm-tcp: no more PCM data"); 162 + break; 163 + } 164 + 165 + pcm_play_dma_status_callback(PCM_DMAST_STARTED); 166 + } 167 + 168 + tcp_running = false; 169 + return NULL; 170 + } 171 + 172 + static void sink_dma_init(void) 173 + { 174 + pthread_mutexattr_t attr; 175 + pthread_mutexattr_init(&attr); 176 + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); 177 + pthread_mutex_init(&tcp_mtx, &attr); 178 + pthread_mutexattr_destroy(&attr); 179 + } 180 + 181 + static void sink_dma_postinit(void) 182 + { 183 + } 184 + 185 + static void sink_set_freq(uint16_t freq) 186 + { 187 + (void)freq; 188 + } 189 + 190 + static void sink_lock(void) 191 + { 192 + pthread_mutex_lock(&tcp_mtx); 193 + } 194 + 195 + static void sink_unlock(void) 196 + { 197 + pthread_mutex_unlock(&tcp_mtx); 198 + } 199 + 200 + static void sink_dma_start(const void *addr, size_t size) 201 + { 202 + logf("pcm-tcp: start (%p, %zu) fd=%d", addr, size, tcp_fd); 203 + 204 + /* Connect on first call or after a write error closed the socket */ 205 + if (tcp_fd < 0) { 206 + tcp_fd = tcp_connect_once(); 207 + if (tcp_fd < 0) { 208 + logf("pcm-tcp: dropping audio (no connection to %s:%u)", 209 + tcp_host, (unsigned)tcp_port); 210 + return; 211 + } 212 + } 213 + 214 + pthread_mutex_lock(&tcp_mtx); 215 + pcm_data = addr; 216 + pcm_size = size; 217 + pthread_mutex_unlock(&tcp_mtx); 218 + 219 + tcp_stop = false; 220 + tcp_running = true; 221 + pthread_create(&tcp_tid, NULL, tcp_thread, NULL); 222 + } 223 + 224 + static void sink_dma_stop(void) 225 + { 226 + logf("pcm-tcp: stop"); 227 + 228 + tcp_stop = true; 229 + 230 + if (tcp_running) { 231 + pthread_join(tcp_tid, NULL); 232 + tcp_running = false; 233 + } 234 + 235 + pthread_mutex_lock(&tcp_mtx); 236 + pcm_data = NULL; 237 + pcm_size = 0; 238 + pthread_mutex_unlock(&tcp_mtx); 239 + 240 + /* Keep tcp_fd open between tracks so snapserver doesn't see a disconnect. 241 + * If the write loop closed it on error, tcp_fd is already -1 and the 242 + * next sink_dma_start will reconnect automatically. */ 243 + } 244 + 245 + struct pcm_sink tcp_pcm_sink = { 246 + .caps = { 247 + .samprs = hw_freq_sampr, 248 + .num_samprs = HW_NUM_FREQ, 249 + .default_freq = HW_FREQ_DEFAULT, 250 + }, 251 + .ops = { 252 + .init = sink_dma_init, 253 + .postinit = sink_dma_postinit, 254 + .set_freq = sink_set_freq, 255 + .lock = sink_lock, 256 + .unlock = sink_unlock, 257 + .play = sink_dma_start, 258 + .stop = sink_dma_stop, 259 + }, 260 + };
+1
gpui/src/ui/components/device_picker.rs
··· 12 12 match device.service.as_str() { 13 13 "chromecast" => Icons::Chromecast, 14 14 "airplay" => Icons::Airplay, 15 + "snapcast" => Icons::Speaker, 15 16 _ => { 16 17 if device.is_current_device { 17 18 Icons::Device
+4
lib/rbcodec/metadata/wave.c
··· 364 364 fmt.numbytes = chunksize; 365 365 if (fmt.formattag == WAVE_FORMAT_ATRAC3) 366 366 id3->first_frame_offset = offset; 367 + /* 'data' is always the last meaningful chunk. Stop here so the 368 + * parser never tries to seek past an infinite-size data chunk 369 + * (e.g. live WAV streams use 0xFFFFFFFF as a sentinel size). */ 370 + break; 367 371 } 368 372 else if (memcmp(buf, chunknames + LIST_CHUNK * namelen, namelen) == 0) 369 373 {