azalea_shell/service/dbus/mpris/
proxy.rs

1use std::collections::HashMap;
2
3use zbus::proxy;
4use zbus::zvariant::OwnedValue;
5use zbus::zvariant::as_value::optional;
6
7#[proxy(
8    interface = "org.mpris.MediaPlayer2.Player",
9    default_path = "/org/mpris/MediaPlayer2"
10)]
11pub trait Player {
12    fn next(&self) -> zbus::Result<()>;
13    fn previous(&self) -> zbus::Result<()>;
14    fn pause(&self) -> zbus::Result<()>;
15    fn play_pause(&self) -> zbus::Result<()>;
16    fn stop(&self) -> zbus::Result<()>;
17    fn play(&self) -> zbus::Result<()>;
18    fn seek(&self, offset: i64) -> zbus::Result<()>;
19    fn set_position(&self, offset: i64) -> zbus::Result<()>;
20    fn open_uri(&self, uri: &str) -> zbus::Result<()>;
21
22    #[zbus(property)]
23    fn playback_status(&self) -> zbus::fdo::Result<PlaybackStatus>;
24
25    #[zbus(property)]
26    fn rate(&self) -> zbus::fdo::Result<PlaybackRate>;
27
28    #[zbus(property)]
29    fn metadata(&self) -> zbus::Result<Metadata>;
30
31    #[zbus(property)]
32    fn volume(&self) -> zbus::Result<f64>;
33
34    #[zbus(property(emits_changed_signal = "false"))]
35    fn position(&self) -> zbus::Result<i64>;
36
37    #[zbus(signal)]
38    fn seeked(&self, position: i64) -> zbus::Result<()>;
39}
40
41#[derive(Clone, Debug, Default, serde::Serialize, serde::Deserialize, OwnedValue)]
42#[zvariant(signature = "s")]
43pub enum PlaybackStatus {
44    Playing,
45    Paused,
46    #[default]
47    Stopped,
48}
49
50pub type PlaybackRate = f64;
51
52#[derive(Clone, Debug, serde::Serialize, serde::Deserialize, zbus::zvariant::Type)]
53#[zvariant(signature = "dict")]
54pub struct Metadata {
55    #[serde(rename = "mpris:trackid", with = "optional")]
56    pub trackid: Option<String>,
57    #[serde(rename = "mpris:length", with = "optional")]
58    pub length: Option<i64>,
59    #[serde(rename = "mpris:artUrl", with = "optional")]
60    pub art_url: Option<String>,
61
62    #[serde(rename = "xesam:title", with = "optional")]
63    pub title: Option<String>,
64    #[serde(rename = "xesam:url", with = "optional")]
65    pub url: Option<String>,
66    #[serde(rename = "xesam:artist", with = "optional")]
67    pub artist: Option<Vec<String>>,
68    #[serde(rename = "xesam:album", with = "optional")]
69    pub album: Option<String>,
70}
71
72// FIXME: OwnedValue macro did not work
73impl TryFrom<zbus::zvariant::OwnedValue> for Metadata {
74    type Error = zbus::zvariant::Error;
75    #[inline]
76    fn try_from(value: zbus::zvariant::OwnedValue) -> zbus::zvariant::Result<Self> {
77        let mut fields = <HashMap<String, zbus::zvariant::Value>>::try_from(value)?;
78        Ok(Self {
79            length: fields
80                .get("mpris:length")
81                .map(|v| v.try_into())
82                .transpose()
83                .unwrap_or(None),
84            art_url: fields
85                .get("mpris:artUrl")
86                .map(|v| v.try_into())
87                .transpose()
88                .unwrap_or(None),
89            title: fields
90                .get("xesam:title")
91                .map(|v| v.try_into())
92                .transpose()
93                .unwrap_or(None),
94            url: fields
95                .get("xesam:url")
96                .map(|v| v.try_into())
97                .transpose()
98                .unwrap_or(None),
99            artist: fields
100                .remove("xesam:artist")
101                .map(|v| v.try_into())
102                .transpose()
103                .unwrap_or(None),
104            album: fields
105                .get("xesam:album")
106                .map(|v| v.try_into())
107                .transpose()
108                .unwrap_or(None),
109            trackid: Some(
110                TryInto::<zbus::zvariant::ObjectPath>::try_into(
111                    fields
112                        .remove("mpris:trackid")
113                        .ok_or_else(|| zbus::zvariant::Error::IncorrectType)?,
114                )?
115                .as_str()
116                .to_string(),
117            ),
118        })
119    }
120}