use std::{collections::HashMap, fmt};
use serde::Serialize;
use zbus::zvariant::{self, OwnedObjectPath, Type, Value};
use crate::TimeInUs;
pub type DateTime = String;
pub type Uri = String;
#[derive(Clone, PartialEq, Serialize, Type)]
#[zvariant(signature = "a{sv}")]
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: OwnedObjectPath) {
self.insert("mpris:trackid", trackid);
}
pub fn set_length(&mut self, length: TimeInUs) {
self.insert("mpris:length", length);
}
pub fn set_art_url(&mut self, art_url: Uri) {
self.insert("mpris:artUrl", art_url);
}
pub fn set_album(&mut self, album: String) {
self.insert("xesam:album", album);
}
pub fn set_album_artist(&mut self, album_artist: Vec<String>) {
self.insert("xesam:albumArtist", album_artist);
}
pub fn set_artist(&mut self, artist: Vec<String>) {
self.insert("xesam:artist", artist);
}
pub fn set_lyrics(&mut self, lyrics: String) {
self.insert("xesam:asText", lyrics);
}
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: Vec<String>) {
self.insert("xesam:comment", comment);
}
pub fn set_composer(&mut self, composer: Vec<String>) {
self.insert("xesam:composer", composer);
}
pub fn set_content_created(&mut self, content_created: DateTime) {
self.insert("xesam:contentCreated", content_created);
}
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: DateTime) {
self.insert("xesam:firstUsed", first_used);
}
pub fn set_genre(&mut self, genre: Vec<String>) {
self.insert("xesam:genre", genre);
}
pub fn set_last_used(&mut self, last_used: DateTime) {
self.insert("xesam:lastUsed", last_used);
}
pub fn set_lyricist(&mut self, lyricist: Vec<String>) {
self.insert("xesam:lyricist", lyricist);
}
pub fn set_title(&mut self, title: String) {
self.insert("xesam:title", title);
}
pub fn set_track_number(&mut self, track_number: i32) {
self.insert("xesam:trackNumber", track_number);
}
pub fn set_url(&mut self, url: Uri) {
self.insert("xesam:url", url);
}
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 trackid(mut self, trackid: OwnedObjectPath) -> Self {
self.m.set_trackid(trackid);
self
}
pub fn length(mut self, length: TimeInUs) -> Self {
self.m.set_length(length);
self
}
pub fn art_url(mut self, art_url: Uri) -> Self {
self.m.set_art_url(art_url);
self
}
pub fn album(mut self, album: String) -> Self {
self.m.set_album(album);
self
}
pub fn album_artist(mut self, album_artist: Vec<String>) -> Self {
self.m.set_album_artist(album_artist);
self
}
pub fn artist(mut self, artist: Vec<String>) -> Self {
self.m.set_artist(artist);
self
}
pub fn lyrics(mut self, lyrics: 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: Vec<String>) -> Self {
self.m.set_comment(comment);
self
}
pub fn composer(mut self, composer: Vec<String>) -> Self {
self.m.set_composer(composer);
self
}
pub fn content_created(mut self, content_created: 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: DateTime) -> Self {
self.m.set_first_used(first_used);
self
}
pub fn genre(mut self, genre: Vec<String>) -> Self {
self.m.set_genre(genre);
self
}
pub fn last_used(mut self, last_used: DateTime) -> Self {
self.m.set_last_used(last_used);
self
}
pub fn lyricist(mut self, lyricist: Vec<String>) -> Self {
self.m.set_lyricist(lyricist);
self
}
pub fn title(mut self, title: String) -> Self {
self.m.set_title(title);
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: Uri) -> Self {
self.m.set_url(url);
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)
}
}