mpris_server/playlist.rs
1use serde::Serialize;
2use zbus::zvariant::{ObjectPath, Type, Value};
3
4use crate::{PlaylistId, Uri};
5
6/// A data structure describing a playlist.
7#[derive(Debug, Clone, PartialEq, Eq, Serialize, Type)]
8pub struct Playlist {
9 /// A unique identifier for the playlist.
10 ///
11 /// This should remain the same if the playlist is renamed.
12 pub id: PlaylistId,
13 /// The name of the playlist, typically given by the user.
14 pub name: String,
15 /// The URI of an (optional) icon.
16 pub icon: Uri,
17}
18
19impl From<Playlist> for Value<'_> {
20 fn from(p: Playlist) -> Self {
21 Value::from((p.id, p.name, p.icon))
22 }
23}
24
25/// A data structure describing a playlist, or nothing.
26///
27/// <details><summary>Rationale</summary>
28///
29/// D-Bus does not (at the time of writing) support a MAYBE type, so we are
30/// forced to invent our own.
31///
32/// </details>
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Type)]
34#[doc(alias = "Maybe_Playlist")]
35pub(crate) struct MaybePlaylist {
36 /// Whether this structure refers to a valid playlist.
37 valid: bool,
38 /// The playlist, providing `valid` is true, otherwise undefined.
39 ///
40 /// When constructing this type, it should be noted that the playlist ID
41 /// must be a valid object path, or D-Bus implementations may reject it.
42 /// This is true even when Valid is false. It is suggested that "/" is
43 /// used as the playlist ID in this case.
44 playlist: Playlist,
45}
46
47impl From<Option<Playlist>> for MaybePlaylist {
48 fn from(playlist: Option<Playlist>) -> Self {
49 match playlist {
50 Some(playlist) => Self {
51 valid: true,
52 playlist,
53 },
54 None => Self {
55 valid: false,
56 playlist: Playlist {
57 id: ObjectPath::from_static_str_unchecked("/").into(),
58 name: String::new(),
59 icon: Uri::new(),
60 },
61 },
62 }
63 }
64}
65
66impl From<MaybePlaylist> for Value<'_> {
67 fn from(mp: MaybePlaylist) -> Self {
68 Value::from((mp.valid, mp.playlist))
69 }
70}
71
72#[cfg(test)]
73mod tests {
74 use super::*;
75
76 #[test]
77 fn valid_signatures() {
78 assert_eq!(Playlist::SIGNATURE, "(oss)");
79 assert_eq!(MaybePlaylist::SIGNATURE, "(b(oss))");
80 }
81}