i3status_rs/blocks/music/
zbus_mpris.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
//! # DBus interface proxies for: `org.mpris.MediaPlayer2.Player`
//!
//! This code was generated by `zbus-xmlgen` `1.0.0` from DBus introspection data.
//! Source: `11`.
//!
//! You may prefer to adapt it, instead of using it verbatim.
//!
//! More information can be found in the
//! [Writing a client proxy](https://zeenix.pages.freedesktop.org/zbus/client.html)
//! section of the zbus documentation.
//!
//! This DBus object implements
//! [standard DBus interfaces](https://dbus.freedesktop.org/doc/dbus-specification.html),
//! (`org.freedesktop.DBus.*`) for which the following zbus proxies can be used:
//!
//! * [`zbus::fdo::PropertiesProxy`]
//! * [`zbus::fdo::IntrospectableProxy`]
//! * [`zbus::fdo::PeerProxy`]
//!
//! …consequently `zbus-xmlgen` did not generate code for the above interfaces.

use std::collections::HashMap;
use zbus::zvariant::{self, ObjectPath, OwnedValue, Value};

#[derive(Debug, Clone)]
pub struct PlayerMetadata {
    pub title: Option<String>,
    pub artist: Option<String>,
    pub url: Option<String>,
}

impl TryFrom<OwnedValue> for PlayerMetadata {
    type Error = <HashMap<String, OwnedValue> as TryFrom<OwnedValue>>::Error;

    fn try_from(value: OwnedValue) -> Result<Self, Self::Error> {
        let map = HashMap::<String, OwnedValue>::try_from(value)?;

        let val_to_string = |val: &Value| {
            val.downcast_ref::<&str>()
                .ok()
                .and_then(|val| (!val.is_empty()).then(|| val.to_string()))
        };

        let title = map.get("xesam:title").and_then(|val| val_to_string(val));

        let artists = map
            .get("xesam:artist")
            .and_then(|val| val.downcast_ref::<&zvariant::Array>().ok())
            .map(|val| val.inner());
        let artist = artists.and_then(|val| val.first()).and_then(val_to_string);

        let url = map.get("xesam:url").and_then(|val| val_to_string(val));

        Ok(Self { title, artist, url })
    }
}

#[zbus::proxy(
    interface = "org.mpris.MediaPlayer2.Player",
    default_path = "/org/mpris/MediaPlayer2"
)]
pub(super) trait Player {
    /// Next method
    fn next(&self) -> zbus::Result<()>;

    /// OpenUri method
    fn open_uri(&self, uri: &str) -> zbus::Result<()>;

    /// Pause method
    fn pause(&self) -> zbus::Result<()>;

    /// Play method
    fn play(&self) -> zbus::Result<()>;

    /// PlayPause method
    fn play_pause(&self) -> zbus::Result<()>;

    /// Previous method
    fn previous(&self) -> zbus::Result<()>;

    /// Seek method
    fn seek(&self, offset: i64) -> zbus::Result<()>;

    /// SetPosition method
    fn set_position(&self, track_id: &ObjectPath<'_>, position: i64) -> zbus::Result<()>;

    /// Stop method
    fn stop(&self) -> zbus::Result<()>;

    /// Seeked signal
    #[zbus(signal)]
    fn seeked(&self, position: i64) -> zbus::Result<()>;

    /// CanControl property
    #[zbus(property)]
    fn can_control(&self) -> zbus::Result<bool>;

    /// CanGoNext property
    #[zbus(property)]
    fn can_go_next(&self) -> zbus::Result<bool>;

    /// CanGoPrevious property
    #[zbus(property)]
    fn can_go_previous(&self) -> zbus::Result<bool>;

    /// CanPause property
    #[zbus(property)]
    fn can_pause(&self) -> zbus::Result<bool>;

    /// CanPlay property
    #[zbus(property)]
    fn can_play(&self) -> zbus::Result<bool>;

    /// CanSeek property
    #[zbus(property)]
    fn can_seek(&self) -> zbus::Result<bool>;

    /// MaximumRate property
    #[zbus(property)]
    fn maximum_rate(&self) -> zbus::Result<f64>;

    /// Metadata property
    #[zbus(property)]
    fn metadata(&self) -> zbus::Result<PlayerMetadata>;

    /// MinimumRate property
    #[zbus(property)]
    fn minimum_rate(&self) -> zbus::Result<f64>;

    /// PlaybackStatus property
    #[zbus(property)]
    fn playback_status(&self) -> zbus::Result<String>;

    /// Position property
    #[zbus(property)]
    fn position(&self) -> zbus::Result<i64>;

    /// Rate property
    #[zbus(property)]
    fn rate(&self) -> zbus::Result<f64>;
    #[zbus(property)]
    fn set_rate(&self, value: f64) -> zbus::Result<()>;

    /// Volume property
    #[zbus(property)]
    fn volume(&self) -> zbus::Result<f64>;
    #[zbus(property)]
    fn set_volume(&self, value: f64) -> zbus::Result<()>;
}