Krolyxon
Commit ad32349

rmptuiad32349

refactor: consolidate MPD TCP connection

Keep the TCP stream and parsed player state in one Connection, and route app commands directly through it. Preserve MPD directory URIs in browser entries and use recursive directory adds for queue actions.
Author
krolyxon
Date
2026-10-15 23:01 +0530
Parent
fbd9aa5
Commit
ad32349dea9067610c20eccbd7de6aa503982cc2

+151 −147

5 files changed

  1. M src/app.rs +46 −51
  2. M src/browser.rs +53 −3
  3. M src/connection.rs +42 −76
  4. M src/event_handler/handler.rs +8 −15
  5. M src/main.rs +2 −2
M src/app.rs View
@@ -60,9 +60,9 @@ impl App {
6060 pub async fn new(address: &str, password: Option<&str>, config: Config) -> AppResult<Self> {
6161 let mut conn = Connection::connect(address, password).await?;
6262 let mut queue_list = ContentList::new();
63− queue_list.list = conn.client.queue().await?;
63+ queue_list.list = conn.queue().await?;
6464 let mut pl_list = ContentList::new();
65− pl_list.list = conn.client.playlists().await?;
65+ pl_list.list = conn.playlists().await?;
6666 pl_list.list.sort();
6767 let append_list = Self::get_append_list(&mut conn).await?;
6868 let mut browser = FileBrowser::new();
@@ -133,7 +133,7 @@ impl App {
133133 }
134134
135135 pub async fn update_queue(&mut self) -> AppResult<()> {
136− self.queue_list.list = self.conn.client.queue().await?;
136+ self.queue_list.list = self.conn.queue().await?;
137137 if self.queue_list.list.is_empty() {
138138 self.queue_list.index = 0;
139139 } else {
@@ -143,7 +143,7 @@ impl App {
143143 }
144144
145145 pub async fn refresh_playlists(&mut self) -> AppResult<()> {
146− self.pl_list.list = self.conn.client.playlists().await?;
146+ self.pl_list.list = self.conn.playlists().await?;
147147 self.pl_list.list.sort();
148148 self.pl_list.index = self
149149 .pl_list
@@ -155,7 +155,7 @@ impl App {
155155
156156 pub async fn refresh_playlist_view(&mut self) -> AppResult<()> {
157157 self.playlist_contents = match self.pl_list.list.get(self.pl_list.index) {
158− Some(name) => self.conn.client.playlist(name).await?,
158+ Some(name) => self.conn.playlist(name).await?,
159159 None => Vec::new(),
160160 };
161161 self.playlist_song_index = self
@@ -172,7 +172,6 @@ impl App {
172172 return Ok(());
173173 }
174174 self.conn
175− .client
176175 .delete_playlist_song(playlist, self.playlist_song_index)
177176 .await?;
178177 self.refresh_playlist_view().await
@@ -191,7 +190,6 @@ impl App {
191190 return Ok(());
192191 };
193192 self.conn
194− .client
195193 .move_playlist_song(playlist, self.playlist_song_index, target)
196194 .await?;
197195 self.playlist_song_index = target;
@@ -202,7 +200,7 @@ impl App {
202200 let Some(playlist) = self.pl_list.list.get(self.pl_list.index) else {
203201 return Ok(());
204202 };
205− self.conn.client.delete_playlist(playlist).await?;
203+ self.conn.delete_playlist(playlist).await?;
206204 self.refresh_playlists().await?;
207205 Ok(())
208206 }
@@ -214,10 +212,9 @@ impl App {
214212 if self.playlist_song_index >= self.playlist_contents.len() {
215213 return Ok(());
216214 }
217− let queue_position = self.conn.client.queue().await?.len();
218− self.conn.client.append_playlist(playlist).await?;
215+ let queue_position = self.conn.queue().await?.len();
216+ self.conn.append_playlist(playlist).await?;
219217 self.conn
220− .client
221218 .play(Some((queue_position + self.playlist_song_index) as u32))
222219 .await?;
223220 self.update_queue().await?;
@@ -228,7 +225,7 @@ impl App {
228225 let mut list = ContentList::new();
229226 list.list.push("Current Playlist".to_string());
230227 list.list.push("New Playlist".to_string());
231− list.list.extend(conn.client.playlists().await?);
228+ list.list.extend(conn.playlists().await?);
232229 Ok(list)
233230 }
234231
@@ -240,12 +237,7 @@ impl App {
240237 };
241238 match entry {
242239 BrowserEntry::Directory(name) => {
243− let path = join_library_path(&self.browser.path, &name);
244− for (entry_type, file) in self.conn.client.list_files(&path).await? {
245− if entry_type == "file" && is_audio_file(&file) {
246− self.conn.client.add(&file).await?;
247− }
248− }
240+ self.conn.add(&name).await?;
249241 }
250242 BrowserEntry::Song(song) => {
251243 let positions: Vec<u32> = self
@@ -258,10 +250,10 @@ impl App {
258250 })
259251 .collect();
260252 if positions.is_empty() {
261− self.conn.client.add(&song.file).await?;
253+ self.conn.add(&song.file).await?;
262254 } else {
263255 for position in positions.into_iter().rev() {
264− self.conn.client.delete(position).await?;
256+ self.conn.delete(position).await?;
265257 }
266258 }
267259 }
@@ -272,10 +264,7 @@ impl App {
272264 }
273265 SelectedTab::Queue => {
274266 if !self.queue_list.list.is_empty() {
275− self.conn
276− .client
277− .delete(self.queue_list.index as u32)
278− .await?;
267+ self.conn.delete(self.queue_list.index as u32).await?;
279268 }
280269 }
281270 SelectedTab::Playlists => {}
@@ -300,7 +289,7 @@ impl App {
300289 match entry {
301290 BrowserEntry::Directory(name) => {
302291 self.browser.prev_selected = self.browser.selected;
303− self.browser.path = join_library_path(&self.browser.path, &name);
292+ self.browser.path = name;
304293 self.browser.selected = 0;
305294 self.browser.update_directory(&mut self.conn).await?;
306295 }
@@ -311,7 +300,7 @@ impl App {
311300 .iter()
312301 .position(|queued| queued.file == song.file)
313302 {
314− self.conn.client.play(Some(index as u32)).await?;
303+ self.conn.play(Some(index as u32)).await?;
315304 } else {
316305 self.conn.push(&song).await?;
317306 self.update_queue().await?;
@@ -340,26 +329,23 @@ impl App {
340329 };
341330 match entry {
342331 BrowserEntry::Song(song) => vec![song],
343− BrowserEntry::Directory(name) => {
344− let path = join_library_path(&self.browser.path, &name);
345− self.conn
346− .client
347− .list_files(&path)
348− .await?
349− .into_iter()
350− .filter_map(|(kind, file)| {
351− (kind == "file" && is_audio_file(&file))
352− .then(|| Connection::song_from_file(&file))
353− })
354− .collect()
355− }
332+ BrowserEntry::Directory(name) => self
333+ .conn
334+ .list_files(&name)
335+ .await?
336+ .into_iter()
337+ .filter_map(|(kind, file)| {
338+ (kind == "file" && is_audio_file(&file))
339+ .then(|| Connection::song_from_file(&file))
340+ })
341+ .collect(),
356342 }
357343 }
358344 SelectedTab::Playlists => {
359345 let Some(name) = self.pl_list.list.get(self.pl_list.index) else {
360346 return Ok(());
361347 };
362− self.conn.client.playlist(name).await?
348+ self.conn.playlist(name).await?
363349 }
364350 };
365351
@@ -370,8 +356,26 @@ impl App {
370356 self.update_queue().await?;
371357 }
372358 } else {
373− for song in songs {
374− self.conn.client.add(&song.file).await?;
359+ let selected_directory = if self.selected_tab == SelectedTab::DirectoryBrowser {
360+ self.browser
361+ .entries
362+ .get(self.browser.selected)
363+ .and_then(|entry| {
364+ if let BrowserEntry::Directory(path) = entry {
365+ Some(path.as_str())
366+ } else {
367+ None
368+ }
369+ })
370+ } else {
371+ None
372+ };
373+ if let Some(path) = selected_directory {
374+ self.conn.add(path).await?;
375+ } else {
376+ for song in songs {
377+ self.conn.add(&song.file).await?;
378+ }
375379 }
376380 self.update_queue().await?;
377381 }
@@ -495,12 +499,3 @@ impl App {
495499 }
496500 }
497501 }
498−
499−pub fn join_library_path(parent: &str, child: &str) -> String {
500− let parent = parent.trim_matches('/').trim_start_matches("./");
501− if parent.is_empty() || parent == "." {
502− child.trim_start_matches("./").to_string()
503− } else {
504− format!("{parent}/{}", child.trim_start_matches("./"))
505− }
506−}
M src/browser.rs View
@@ -23,7 +23,10 @@ pub enum BrowserEntry {
2323 impl BrowserEntry {
2424 pub fn name(&self) -> &str {
2525 match self {
26− Self::Directory(name) => name,
26+ Self::Directory(path) => Path::new(path)
27+ .file_name()
28+ .and_then(|name| name.to_str())
29+ .unwrap_or(path),
2730 Self::Song(song) => Path::new(&song.file)
2831 .file_name()
2932 .and_then(|name| name.to_str())
@@ -42,7 +45,7 @@ impl FileBrowser {
4245
4346 pub async fn update_directory(&mut self, conn: &mut Connection) -> AppResult<()> {
4447 let query_path = self.path.trim_start_matches("./").trim_matches('/');
45− let (directories, songs) = conn.client.ls_info(query_path).await?;
48+ let (directories, songs) = conn.ls_info(query_path).await?;
4649 let mut entries = Vec::new();
4750 for directory in directories {
4851 if let Some(name) = Path::new(&directory)
@@ -50,7 +53,7 @@ impl FileBrowser {
5053 .and_then(|name| name.to_str())
5154 {
5255 if !name.starts_with('.') {
53− entries.push(BrowserEntry::Directory(name.to_string()));
56+ entries.push(BrowserEntry::Directory(directory));
5457 }
5558 }
5659 }
@@ -112,3 +115,50 @@ impl FileBrowser {
112115 Ok(())
113116 }
114117 }
118+
119+#[cfg(test)]
120+mod tests {
121+ use super::*;
122+ use tokio::{
123+ io::{AsyncBufReadExt, AsyncWriteExt, BufReader},
124+ net::TcpListener,
125+ };
126+
127+ #[tokio::test]
128+ async fn preserves_mpd_directory_uris_and_displays_their_basename() {
129+ let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
130+ let address = listener.local_addr().unwrap();
131+ let server = tokio::spawn(async move {
132+ let (stream, _) = listener.accept().await.unwrap();
133+ let mut stream = BufReader::new(stream);
134+ stream
135+ .get_mut()
136+ .write_all(b"OK MPD 0.23.0\n")
137+ .await
138+ .unwrap();
139+
140+ for response in ["OK\n", "OK\n", "OK\n", "directory: library/Artist\nOK\n"] {
141+ let mut command = String::new();
142+ stream.read_line(&mut command).await.unwrap();
143+ stream
144+ .get_mut()
145+ .write_all(response.as_bytes())
146+ .await
147+ .unwrap();
148+ }
149+ });
150+
151+ let mut conn = Connection::connect(&address.to_string(), None)
152+ .await
153+ .unwrap();
154+ let mut browser = FileBrowser::new();
155+ browser.update_directory(&mut conn).await.unwrap();
156+
157+ assert_eq!(
158+ browser.entries,
159+ vec![BrowserEntry::Directory("library/Artist".to_string())]
160+ );
161+ assert_eq!(browser.entries[0].name(), "Artist");
162+ server.await.unwrap();
163+ }
164+}
M src/connection.rs View
@@ -78,15 +78,25 @@ impl fmt::Display for MpdError {
7878 impl Error for MpdError {}
7979
8080 #[derive(Debug)]
81−pub struct MpdClient {
81+pub struct Connection {
8282 stream: BufReader<TcpStream>,
83+ pub current_song: Song,
84+ pub stats: Stats,
85+ pub status: Status,
86+ pub volume_status: VolumeStatus,
87+ last_status_update: Instant,
8388 }
8489
85−impl MpdClient {
86− pub async fn connect(address: &str, password: Option<&str>) -> AppResult<Self> {
90+impl Connection {
91+ async fn open(address: &str, password: Option<&str>) -> AppResult<Self> {
8792 let stream = TcpStream::connect(address).await?;
8893 let mut client = Self {
8994 stream: BufReader::new(stream),
95+ current_song: Song::default(),
96+ stats: Stats::default(),
97+ status: Status::default(),
98+ volume_status: VolumeStatus::Unmuted,
99+ last_status_update: Instant::now(),
90100 };
91101 let mut greeting = String::new();
92102 client.stream.read_line(&mut greeting).await?;
@@ -132,7 +142,7 @@ impl MpdClient {
132142 }
133143 }
134144
135− pub async fn status(&mut self) -> AppResult<Status> {
145+ async fn read_status(&mut self) -> AppResult<Status> {
136146 let fields = fields(self.command("status", &[]).await?);
137147 let time = fields.get("time").and_then(|s| {
138148 let (elapsed, total) = s.split_once(':')?;
@@ -171,7 +181,7 @@ impl MpdClient {
171181 })
172182 }
173183
174− pub async fn stats(&mut self) -> AppResult<Stats> {
184+ async fn read_stats(&mut self) -> AppResult<Stats> {
175185 let fields = fields(self.command("stats", &[]).await?);
176186 Ok(Stats {
177187 songs: fields
@@ -181,7 +191,7 @@ impl MpdClient {
181191 })
182192 }
183193
184− pub async fn current_song(&mut self) -> AppResult<Song> {
194+ async fn read_current_song(&mut self) -> AppResult<Song> {
185195 Ok(parse_songs(self.command("currentsong", &[]).await?)
186196 .into_iter()
187197 .next()
@@ -193,9 +203,9 @@ impl MpdClient {
193203 }
194204
195205 pub async fn snapshot(&mut self) -> AppResult<MpdSnapshot> {
196− let status = self.status().await?;
197− let stats = self.stats().await?;
198− let current_song = self.current_song().await?;
206+ let status = self.read_status().await?;
207+ let stats = self.read_stats().await?;
208+ let current_song = self.read_current_song().await?;
199209 let queue = self.queue().await?;
200210 Ok(MpdSnapshot {
201211 status,
@@ -287,17 +297,6 @@ impl MpdClient {
287297 Ok(())
288298 }
289299
290− pub async fn pause(&mut self, paused: bool) -> AppResult<()> {
291− self.command("pause", &[if paused { "1" } else { "0" }])
292− .await?;
293− Ok(())
294− }
295−
296− pub async fn toggle_pause(&mut self) -> AppResult<()> {
297− self.command("pause", &[]).await?;
298− Ok(())
299− }
300−
301300 pub async fn set_repeat(&mut self, enabled: bool) -> AppResult<()> {
302301 self.command("repeat", &[if enabled { "1" } else { "0" }])
303302 .await?;
@@ -351,21 +350,11 @@ impl MpdClient {
351350 Ok(())
352351 }
353352
354− pub async fn load_playlist(&mut self, name: &str) -> AppResult<()> {
355− self.append_playlist(name).await?;
356− self.play(None).await
357− }
358−
359353 pub async fn append_playlist(&mut self, name: &str) -> AppResult<()> {
360354 self.command("load", &[name]).await?;
361355 Ok(())
362356 }
363357
364− pub async fn add_to_playlist(&mut self, playlist: &str, file: &str) -> AppResult<()> {
365− self.command("playlistadd", &[playlist, file]).await?;
366− Ok(())
367− }
368−
369358 pub async fn delete_playlist_song(&mut self, playlist: &str, position: usize) -> AppResult<()> {
370359 self.command("playlistdelete", &[playlist, &position.to_string()])
371360 .await?;
@@ -418,30 +407,11 @@ impl MpdClient {
418407 }
419408 }
420409
421−#[derive(Debug)]
422−pub struct Connection {
423− pub client: MpdClient,
424− pub current_song: Song,
425− pub stats: Stats,
426− pub status: Status,
427− pub volume_status: VolumeStatus,
428− last_status_update: Instant,
429−}
430−
431410 impl Connection {
432411 pub async fn connect(address: &str, password: Option<&str>) -> AppResult<Self> {
433− let mut client = MpdClient::connect(address, password).await?;
434− let status = client.status().await?;
435− let stats = client.stats().await?;
436− let current_song = client.current_song().await?;
437− Ok(Self {
438− client,
439− current_song,
440− stats,
441− status,
442− volume_status: VolumeStatus::Unmuted,
443− last_status_update: Instant::now(),
444− })
412+ let mut connection = Self::open(address, password).await?;
413+ connection.update_status().await?;
414+ Ok(connection)
445415 }
446416
447417 pub fn apply_snapshot(&mut self, status: Status, stats: Stats, current_song: Song) {
@@ -452,9 +422,9 @@ impl Connection {
452422 }
453423
454424 pub async fn update_status(&mut self) -> AppResult<()> {
455− self.status = self.client.status().await?;
456− self.stats = self.client.stats().await?;
457− self.current_song = self.client.current_song().await?;
425+ self.status = self.read_status().await?;
426+ self.stats = self.read_stats().await?;
427+ self.current_song = self.read_current_song().await?;
458428 self.last_status_update = Instant::now();
459429 Ok(())
460430 }
@@ -484,21 +454,23 @@ impl Connection {
484454 }
485455
486456 pub async fn push(&mut self, song: &Song) -> AppResult<()> {
487− self.client.add(&song.file).await?;
488− let queue = self.client.queue().await?;
457+ self.add(&song.file).await?;
458+ let queue = self.queue().await?;
489459 if !queue.is_empty() {
490− self.client.play(Some(queue.len() as u32 - 1)).await?;
460+ self.play(Some(queue.len() as u32 - 1)).await?;
491461 }
492462 self.update_status().await
493463 }
494464
495465 pub async fn load_playlist(&mut self, playlist: &str) -> AppResult<()> {
496− self.client.load_playlist(playlist).await?;
466+ self.append_playlist(playlist).await?;
467+ self.play(None).await?;
497468 self.update_status().await
498469 }
499470
500471 pub async fn add_to_playlist(&mut self, playlist: &str, song: &Song) -> AppResult<()> {
501− self.client.add_to_playlist(playlist, &song.file).await
472+ self.command("playlistadd", &[playlist, &song.file]).await?;
473+ Ok(())
502474 }
503475
504476 pub fn song_from_file(filename: &str) -> Song {
@@ -518,41 +490,41 @@ impl Connection {
518490 }
519491
520492 pub async fn toggle_pause(&mut self) -> AppResult<()> {
521− self.client.toggle_pause().await?;
493+ self.command("pause", &[]).await?;
522494 self.update_status().await
523495 }
524496
525497 pub async fn pause(&mut self) -> AppResult<()> {
526− self.client.pause(true).await?;
498+ self.command("pause", &["1"]).await?;
527499 self.update_status().await
528500 }
529501
530502 pub async fn toggle_repeat(&mut self) -> AppResult<()> {
531− self.client.set_repeat(!self.status.repeat).await?;
503+ self.set_repeat(!self.status.repeat).await?;
532504 self.update_status().await
533505 }
534506
535507 pub async fn toggle_random(&mut self) -> AppResult<()> {
536− self.client.set_random(!self.status.random).await?;
508+ self.set_random(!self.status.random).await?;
537509 self.update_status().await
538510 }
539511
540512 pub async fn inc_volume(&mut self, amount: i8) -> AppResult<()> {
541513 let volume = self.status.volume.saturating_add(amount).min(100);
542514 self.volume_status = VolumeStatus::Unmuted;
543− self.client.set_volume(volume).await?;
515+ self.set_volume(volume).await?;
544516 self.update_status().await
545517 }
546518
547519 pub async fn dec_volume(&mut self, amount: i8) -> AppResult<()> {
548520 let volume = self.status.volume.saturating_sub(amount).max(0);
549521 self.volume_status = VolumeStatus::Unmuted;
550− self.client.set_volume(volume).await?;
522+ self.set_volume(volume).await?;
551523 self.update_status().await
552524 }
553525
554526 pub async fn refresh_song_list(&mut self) -> AppResult<()> {
555− self.stats = self.client.stats().await?;
527+ self.stats = self.read_stats().await?;
556528 Ok(())
557529 }
558530 }
@@ -702,9 +674,7 @@ mod tests {
702674 stream.get_mut().write_all(b"OK\n").await.unwrap();
703675 });
704676
705− let mut client = MpdClient::connect(&address.to_string(), None)
706− .await
707− .unwrap();
677+ let mut client = Connection::open(&address.to_string(), None).await.unwrap();
708678 client.command("play", &["0"]).await.unwrap();
709679 server.await.unwrap();
710680 }
@@ -729,9 +699,7 @@ mod tests {
729699 }
730700 });
731701
732− let mut client = MpdClient::connect(&address.to_string(), None)
733− .await
734− .unwrap();
702+ let mut client = Connection::open(&address.to_string(), None).await.unwrap();
735703 client.ls_info("").await.unwrap();
736704 client.list_files("").await.unwrap();
737705 server.await.unwrap();
@@ -761,9 +729,7 @@ mod tests {
761729 }
762730 });
763731
764− let mut client = MpdClient::connect(&address.to_string(), None)
765− .await
766− .unwrap();
732+ let mut client = Connection::open(&address.to_string(), None).await.unwrap();
767733 client.delete_playlist_song("mix \"one\"", 2).await.unwrap();
768734 client
769735 .move_playlist_song("mix \"one\"", 1, 2)
M src/event_handler/handler.rs View
@@ -45,7 +45,7 @@ pub async fn handle_key_events(key: KeyEvent, app: &mut App) -> AppResult<()> {
4545 if is_bound(app, "quit", key) {
4646 app.quit();
4747 } else if is_bound(app, "clear_queue", key) {
48− app.conn.client.clear().await?;
48+ app.conn.clear().await?;
4949 app.update_queue().await?;
5050 app.conn.update_status().await?;
5151 } else if is_bound(app, "toggle_pause", key) {
@@ -67,7 +67,6 @@ pub async fn handle_key_events(key: KeyEvent, app: &mut App) -> AppResult<()> {
6767 current.saturating_sub(app.config.playback.seek_seconds)
6868 };
6969 app.conn
70− .client
7170 .seek(position.pos, std::time::Duration::from_secs(target))
7271 .await?;
7372 app.conn.update_status().await?;
@@ -86,13 +85,13 @@ pub async fn handle_key_events(key: KeyEvent, app: &mut App) -> AppResult<()> {
8685 app.refresh_playlist_view().await?;
8786 } else if is_bound(app, "next_track", key) {
8887 if !app.queue_list.list.is_empty() {
89− app.conn.client.next().await?;
88+ app.conn.next().await?;
9089 app.update_queue().await?;
9190 app.conn.update_status().await?;
9291 }
9392 } else if is_bound(app, "previous_track", key) {
9493 if !app.queue_list.list.is_empty() {
95− app.conn.client.previous().await?;
94+ app.conn.previous().await?;
9695 app.update_queue().await?;
9796 app.conn.update_status().await?;
9897 }
@@ -107,17 +106,17 @@ pub async fn handle_key_events(key: KeyEvent, app: &mut App) -> AppResult<()> {
107106 } else if is_bound(app, "toggle_mute", key) {
108107 match app.conn.volume_status {
109108 VolumeStatus::Muted(volume) => {
110− app.conn.client.set_volume(volume).await?;
109+ app.conn.set_volume(volume).await?;
111110 app.conn.volume_status = VolumeStatus::Unmuted;
112111 }
113112 VolumeStatus::Unmuted => {
114− app.conn.client.set_volume(0).await?;
113+ app.conn.set_volume(0).await?;
115114 app.conn.volume_status = VolumeStatus::Muted(app.conn.status.volume);
116115 }
117116 }
118117 app.conn.update_status().await?;
119118 } else if is_bound(app, "update_database", key) {
120− app.conn.client.update_database().await?;
119+ app.conn.update_database().await?;
121120 app.should_update_song_list = true;
122121 app.conn.update_status().await?;
123122 } else if is_bound(app, "search", key) {
@@ -149,15 +148,12 @@ async fn handle_queue_key(key: KeyEvent, app: &mut App) -> AppResult<()> {
149148 app.queue_list.prev();
150149 } else if is_bound(app, "activate", key) {
151150 if app.queue_list.index < app.queue_list.list.len() {
152− app.conn
153− .client
154− .play(Some(app.queue_list.index as u32))
155− .await?;
151+ app.conn.play(Some(app.queue_list.index as u32)).await?;
156152 app.conn.update_status().await?;
157153 }
158154 } else if is_bound(app, "queue_delete", key) {
159155 if app.queue_list.index < app.queue_list.list.len() {
160− app.conn.client.delete(app.queue_list.index as u32).await?;
156+ app.conn.delete(app.queue_list.index as u32).await?;
161157 app.update_queue().await?;
162158 app.conn.update_status().await?;
163159 }
@@ -165,7 +161,6 @@ async fn handle_queue_key(key: KeyEvent, app: &mut App) -> AppResult<()> {
165161 let position = app.queue_list.index;
166162 if position + 1 < app.queue_list.list.len() {
167163 app.conn
168− .client
169164 .swap(position as u32, (position + 1) as u32)
170165 .await?;
171166 app.queue_list.index += 1;
@@ -175,7 +170,6 @@ async fn handle_queue_key(key: KeyEvent, app: &mut App) -> AppResult<()> {
175170 let position = app.queue_list.index;
176171 if position > 0 && position < app.queue_list.list.len() {
177172 app.conn
178− .client
179173 .swap(position as u32, (position - 1) as u32)
180174 .await?;
181175 app.queue_list.index -= 1;
@@ -322,7 +316,6 @@ async fn handle_input_key(key: KeyEvent, app: &mut App) -> AppResult<()> {
322316 if let Some(old_name) = app.pl_list.list.get(app.pl_list.index).cloned() {
323317 if !app.pl_newname_input.trim().is_empty() {
324318 app.conn
325− .client
326319 .rename_playlist(&old_name, &app.pl_newname_input)
327320 .await?;
328321 app.refresh_playlists().await?;
M src/main.rs View
@@ -6,7 +6,7 @@ use ratatui::prelude::*;
66 use rmptui::{
77 app::App,
88 config::Config,
9− connection::{MpdClient, MpdSnapshot},
9+ connection::{Connection, MpdSnapshot},
1010 event_handler::handler,
1111 tui, AppResult,
1212 };
@@ -121,7 +121,7 @@ async fn watch_mpd(
121121 password: Option<String>,
122122 updates: mpsc::Sender<MpdSnapshot>,
123123 ) -> AppResult<()> {
124− let mut client = MpdClient::connect(&address, password.as_deref()).await?;
124+ let mut client = Connection::connect(&address, password.as_deref()).await?;
125125 loop {
126126 client.idle().await?;
127127 let snapshot = client.snapshot().await?;