Skip to main content

doobs_mpris/
track_list.rs

1// SPDX-License-Identifier: MPL-2.0
2use std::collections::BTreeMap;
3use std::ops::Deref;
4
5use zbus::Connection;
6use zbus::names::OwnedBusName;
7
8use crate::binding::TrackListProxy;
9use crate::types::{Metadata, TrackId};
10use crate::{Error, Result};
11
12/// Simplified access to the track list of an MPRIS media player.
13#[derive(Debug, Clone)]
14pub struct TrackList {
15    proxy: TrackListProxy<'static>,
16}
17
18impl TrackList {
19    /// Creates a new instance of the `org.mpris.MediaPlayer2.TrackList` interface.
20    // TODO this being an OwnedBusName makes it really annoying to create a player
21    // (although not as bad since TrackList can be created from the MediaPlayer)
22    pub async fn new(connection: &Connection, name: OwnedBusName) -> Result<Self> {
23        TrackListProxy::builder(connection)
24            .destination(name)?
25            .build()
26            .await
27            .map(Self::from)
28            .map_err(Error::from)
29    }
30
31    /// Adds a new track to this track list.
32    pub async fn add_track<S: ToString>(
33        &self,
34        uri: S,
35        after: TrackId,
36        set_as_current: bool,
37    ) -> Result<()> {
38        let uri = uri.to_string();
39        self.proxy
40            .add_track(&uri, after, set_as_current)
41            .await
42            .map_err(Error::from)
43    }
44
45    /// Gets the metadata of the given tracks.
46    pub async fn get_tracks_metadata<T: AsRef<[TrackId]>>(
47        &self,
48        tracks: T,
49    ) -> Result<Vec<Metadata>> {
50        self.proxy
51            .get_tracks_metadata(tracks.as_ref().to_vec())
52            .await
53            .map_err(Error::from)
54    }
55
56    /// Goes to the specified track.
57    pub async fn go_to(&self, track: TrackId) -> Result<()> {
58        self.proxy.go_to(track).await.map_err(Error::from)
59    }
60
61    /// Removes the specified track.
62    pub async fn remove(&self, track: TrackId) -> Result<()> {
63        self.proxy.remove_track(track).await.map_err(Error::from)
64    }
65
66    /// Returns a list of all available [TrackId]s.
67    pub async fn tracks(&self) -> Result<Vec<TrackId>> {
68        self.proxy
69            .tracks()
70            .await
71            .map(|x| x.into_iter().collect())
72            .map_err(Error::from)
73    }
74
75    /// Returns a list of all available [TrackId]s and their associated metadata,
76    /// in order.
77    pub async fn detailed_tracks(&self) -> Result<BTreeMap<TrackId, Metadata>> {
78        let tracks = self.tracks().await?;
79        let metadata = self.get_tracks_metadata(&tracks).await?;
80        Ok(tracks.into_iter().zip(metadata.into_iter()).collect())
81    }
82}
83
84impl Deref for TrackList {
85    type Target = TrackListProxy<'static>;
86
87    fn deref(&self) -> &Self::Target {
88        &self.proxy
89    }
90}
91
92impl From<TrackListProxy<'static>> for TrackList {
93    fn from(proxy: TrackListProxy<'static>) -> Self {
94        Self { proxy }
95    }
96}