azalea_shell/service/dbus/mpris/
proxy.rs1use 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
72impl 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}