1use std::ops::Deref;
3
4use zbus::Connection;
5use zbus::names::OwnedBusName;
6
7use crate::binding::{MediaPlayer2Proxy, PlayerProxy};
8use crate::types::{LoopStatus, Metadata, MprisDuration, PlaybackStatus, TrackId};
9use crate::{Error, MediaPlayer, Result, handle_optional};
10
11#[derive(Debug, Clone)]
13pub struct Player {
14 proxy: PlayerProxy<'static>,
15}
16
17impl Player {
18 pub async fn new(connection: &Connection, name: OwnedBusName) -> Result<Self> {
21 PlayerProxy::builder(connection)
22 .destination(name)?
23 .build()
24 .await
25 .map(Self::from)
26 .map_err(Error::from)
27 }
28
29 pub async fn media_player(&self) -> Result<MediaPlayer> {
31 let proxy = MediaPlayer2Proxy::builder(self.proxy.inner().connection())
32 .destination(self.proxy.inner().destination().to_owned())?
33 .build()
34 .await?;
35 Ok(proxy.into())
36 }
37
38 pub async fn seek<D>(&self, duration: D) -> Result<bool>
40 where
41 D: Into<MprisDuration>,
42 {
43 if self.proxy.can_seek().await? {
44 self.proxy.seek(duration.into()).await?;
45 Ok(true)
46 } else {
47 Ok(false)
48 }
49 }
50
51 pub async fn set_position<D>(&self, track: TrackId, position: D) -> Result<()>
55 where
56 D: Into<MprisDuration>,
57 {
58 self.proxy
59 .set_position(track, position.into())
60 .await
61 .map_err(Error::from)
62 }
63
64 pub async fn position(&self) -> Result<Option<MprisDuration>> {
68 handle_optional(self.proxy.position().await)
69 }
70
71 pub async fn playback_status(&self) -> Result<PlaybackStatus> {
73 self.proxy.playback_status().await.map_err(Error::from)
74 }
75
76 pub async fn rate(&self) -> Result<Option<f64>> {
80 handle_optional(self.proxy.rate().await)
81 }
82
83 pub async fn set_rate(&self, value: f64) -> Result<()> {
85 handle_optional(self.proxy.set_rate(value).await).map(|_| ())
86 }
87
88 pub async fn minimum_rate(&self) -> Result<Option<f64>> {
92 handle_optional(self.proxy.minimum_rate().await)
93 }
94
95 pub async fn maximum_rate(&self) -> Result<Option<f64>> {
99 handle_optional(self.proxy.maximum_rate().await)
100 }
101
102 pub async fn available_rates(&self) -> Result<Option<std::ops::RangeInclusive<f64>>> {
106 let minimum = match self.minimum_rate().await? {
107 Some(min) => min,
108 None => return Ok(None),
109 };
110 let maximum = match self.maximum_rate().await? {
111 Some(max) => max,
112 None => return Ok(None),
113 };
114 Ok(Some(minimum..=maximum))
115 }
116
117 pub async fn metadata(&self) -> Result<Metadata> {
119 self.proxy.metadata().await.map_err(Error::from)
120 }
121
122 pub async fn shuffle(&self) -> Result<Option<bool>> {
127 if self.can_control().await? {
128 handle_optional(self.proxy.shuffle().await)
129 } else {
130 Ok(None)
131 }
132 }
133
134 pub async fn set_shuffle(&self, value: bool) -> Result<()> {
139 if self.proxy.can_control().await? {
140 self.proxy.set_shuffle(value).await.map_err(Error::from)
141 } else {
142 Ok(())
143 }
144 }
145
146 pub async fn loop_status(&self) -> Result<Option<LoopStatus>> {
148 if self.proxy.can_control().await? {
149 handle_optional(self.proxy.loop_status().await)
150 } else {
151 Ok(None)
152 }
153 }
154
155 pub async fn set_loop_status(&self, value: LoopStatus) -> Result<()> {
157 if self.proxy.can_control().await? {
158 handle_optional(self.proxy.set_loop_status(value).await).map(|_| ())
159 } else {
160 Ok(())
161 }
162 }
163}
164
165impl Deref for Player {
166 type Target = PlayerProxy<'static>;
167
168 fn deref(&self) -> &Self::Target {
169 &self.proxy
170 }
171}
172
173impl From<PlayerProxy<'static>> for Player {
174 fn from(proxy: PlayerProxy<'static>) -> Self {
175 Self { proxy }
176 }
177}