use std::{collections::HashMap, fmt};
use serde::Serialize;
use zbus::zvariant::{self, OwnedObjectPath, Type, Value};
use crate::{Time, Uri};
pub type DateTime = String;
#[derive(Clone, PartialEq, Serialize, Type)]
#[serde(transparent)]
#[zvariant(signature = "a{sv}")]
#[doc(alias = "Metadata_Map")]
pub struct Metadata(HashMap<String, Value<'static>>);
impl fmt::Debug for Metadata {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Debug::fmt(&self.0, f)
}
}
impl Default for Metadata {
fn default() -> Self {
Self::new()
}
}
impl Metadata {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn builder() -> MetadataBuilder {
MetadataBuilder { m: Metadata::new() }
}
pub fn insert(
&mut self,
key: impl Into<String>,
value: impl Into<Value<'static>>,
) -> Option<Value<'static>> {
self.0.insert(key.into(), value.into())
}
pub fn get<'v, V>(&'v self, key: &str) -> Option<zvariant::Result<&'v V>>
where
&'v V: TryFrom<&'v Value<'v>>,
{
self.get_value(key)
.map(|v| v.downcast_ref().ok_or(zvariant::Error::IncorrectType))
}
pub fn get_value(&self, key: &str) -> Option<&Value<'_>> {
self.0.get(key)
}
pub fn set_trackid(&mut self, trackid: impl Into<OwnedObjectPath>) {
self.insert("mpris:trackid", trackid.into());
}
pub fn set_length(&mut self, length: Time) {
self.insert("mpris:length", length);
}
pub fn set_art_url(&mut self, art_url: impl Into<Uri>) {
self.insert("mpris:artUrl", art_url.into());
}
pub fn set_album(&mut self, album: impl Into<String>) {
self.insert("xesam:album", album.into());
}
pub fn set_album_artist(&mut self, album_artist: impl IntoIterator<Item = impl Into<String>>) {
self.insert(
"xesam:albumArtist",
album_artist
.into_iter()
.map(|i| i.into())
.collect::<Vec<_>>(),
);
}
pub fn set_artist(&mut self, artist: impl IntoIterator<Item = impl Into<String>>) {
self.insert(
"xesam:artist",
artist.into_iter().map(|i| i.into()).collect::<Vec<_>>(),
);
}
pub fn set_lyrics(&mut self, lyrics: impl Into<String>) {
self.insert("xesam:asText", lyrics.into());
}
pub fn set_audio_bpm(&mut self, audio_bpm: i32) {
self.insert("xesam:audioBPM", audio_bpm);
}
pub fn set_auto_rating(&mut self, auto_rating: f64) {
self.insert("xesam:autoRating", auto_rating);
}
pub fn set_comment(&mut self, comment: impl IntoIterator<Item = impl Into<String>>) {
self.insert(
"xesam:comment",
comment.into_iter().map(|i| i.into()).collect::<Vec<_>>(),
);
}
pub fn set_composer(&mut self, composer: impl IntoIterator<Item = impl Into<String>>) {
self.insert(
"xesam:composer",
composer.into_iter().map(|i| i.into()).collect::<Vec<_>>(),
);
}
pub fn set_content_created(&mut self, content_created: impl Into<DateTime>) {
self.insert("xesam:contentCreated", content_created.into());
}
pub fn set_disc_number(&mut self, disc_number: i32) {
self.insert("xesam:discNumber", disc_number);
}
pub fn set_first_used(&mut self, first_used: impl Into<DateTime>) {
self.insert("xesam:firstUsed", first_used.into());
}
pub fn set_genre(&mut self, genre: impl IntoIterator<Item = impl Into<String>>) {
self.insert(
"xesam:genre",
genre.into_iter().map(|i| i.into()).collect::<Vec<_>>(),
);
}
pub fn set_last_used(&mut self, last_used: impl Into<DateTime>) {
self.insert("xesam:lastUsed", last_used.into());
}
pub fn set_lyricist(&mut self, lyricist: impl IntoIterator<Item = impl Into<String>>) {
self.insert(
"xesam:lyricist",
lyricist.into_iter().map(|i| i.into()).collect::<Vec<_>>(),
);
}
pub fn set_title(&mut self, title: impl Into<String>) {
self.insert("xesam:title", title.into());
}
pub fn set_track_number(&mut self, track_number: i32) {
self.insert("xesam:trackNumber", track_number);
}
pub fn set_url(&mut self, url: impl Into<Uri>) {
self.insert("xesam:url", url.into());
}
pub fn set_use_count(&mut self, use_count: i32) {
self.insert("xesam:useCount", use_count);
}
pub fn set_user_rating(&mut self, user_rating: f64) {
self.insert("xesam:userRating", user_rating);
}
}
#[derive(Debug, Default, Clone)]
pub struct MetadataBuilder {
m: Metadata,
}
impl MetadataBuilder {
pub fn other(mut self, key: impl Into<String>, value: impl Into<Value<'static>>) -> Self {
self.m.insert(key, value);
self
}
pub fn trackid(mut self, trackid: impl Into<OwnedObjectPath>) -> Self {
self.m.set_trackid(trackid);
self
}
pub fn length(mut self, length: Time) -> Self {
self.m.set_length(length);
self
}
pub fn art_url(mut self, art_url: impl Into<Uri>) -> Self {
self.m.set_art_url(art_url);
self
}
pub fn album(mut self, album: impl Into<String>) -> Self {
self.m.set_album(album);
self
}
pub fn album_artist(
mut self,
album_artist: impl IntoIterator<Item = impl Into<String>>,
) -> Self {
self.m.set_album_artist(album_artist);
self
}
pub fn artist(mut self, artist: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.m.set_artist(artist);
self
}
pub fn lyrics(mut self, lyrics: impl Into<String>) -> Self {
self.m.set_lyrics(lyrics);
self
}
pub fn audio_bpm(mut self, audio_bpm: i32) -> Self {
self.m.set_audio_bpm(audio_bpm);
self
}
pub fn auto_rating(mut self, auto_rating: f64) -> Self {
self.m.set_auto_rating(auto_rating);
self
}
pub fn comment(mut self, comment: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.m.set_comment(comment);
self
}
pub fn composer(mut self, composer: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.m.set_composer(composer);
self
}
pub fn content_created(mut self, content_created: impl Into<DateTime>) -> Self {
self.m.set_content_created(content_created);
self
}
pub fn disc_number(mut self, disc_number: i32) -> Self {
self.m.set_disc_number(disc_number);
self
}
pub fn first_used(mut self, first_used: impl Into<DateTime>) -> Self {
self.m.set_first_used(first_used);
self
}
pub fn genre(mut self, genre: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.m.set_genre(genre);
self
}
pub fn last_used(mut self, last_used: impl Into<DateTime>) -> Self {
self.m.set_last_used(last_used);
self
}
pub fn lyricist(mut self, lyricist: impl IntoIterator<Item = impl Into<String>>) -> Self {
self.m.set_lyricist(lyricist);
self
}
pub fn title(mut self, title: impl Into<String>) -> Self {
self.m.set_title(title.into());
self
}
pub fn track_number(mut self, track_number: i32) -> Self {
self.m.set_track_number(track_number);
self
}
pub fn url(mut self, url: impl Into<Uri>) -> Self {
self.m.set_url(url.into());
self
}
pub fn use_count(mut self, use_count: i32) -> Self {
self.m.set_use_count(use_count);
self
}
pub fn user_rating(mut self, user_rating: f64) -> Self {
self.m.set_user_rating(user_rating);
self
}
pub fn build(self) -> Metadata {
self.m
}
}
impl<'a> From<Metadata> for Value<'a> {
fn from(metainfo: Metadata) -> Self {
Value::new(metainfo.0)
}
}