use chrono::{DateTime, Utc};
use serde::de::{self, Unexpected};
use serde::{Deserialize, Deserializer, Serialize};
use std::fmt::Debug;
use std::time::Duration;
#[cfg(feature = "client")]
mod client;
#[cfg(feature = "client")]
pub use client::MpdClient;
#[cfg(feature = "client")]
mod response;
#[cfg(feature = "client")]
pub use crate::response::Mixed;
mod filter;
pub use filter::{Filter, FilterExpr, ToFilterExpr};
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct Playlist {
pub path: String,
}
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct Directory {
pub path: String,
pub last_modified: Option<DateTime<Utc>>,
}
#[serde_with::skip_serializing_none]
#[derive(Deserialize, Serialize, Debug, Default)]
pub struct Status {
pub partition: Option<String>,
pub volume: Option<u8>,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_bint")]
pub repeat: bool,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_bint")]
pub random: bool,
pub single: String,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_bint")]
pub consume: bool,
pub playlist: u32,
pub playlistlength: u32,
pub song: Option<u32>,
pub songid: Option<u32>,
pub nextsong: Option<u32>,
pub nextsongid: Option<u32>,
pub time: Option<String>,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_time_float")]
#[serde(default)]
pub elapsed: Option<Duration>,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_time_float")]
#[serde(default)]
pub duration: Option<Duration>,
pub mixrampdb: f32,
pub mixrampdelay: Option<u32>,
pub state: String,
pub bitrate: Option<u16>,
pub xfade: Option<u32>,
pub audio: Option<String>,
pub updating_db: Option<u32>,
pub error: Option<String>,
}
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
pub struct Stats {
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_time_int")]
pub uptime: Duration,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_time_int")]
pub playtime: Duration,
pub artists: u32,
pub albums: u32,
pub songs: u32,
#[cfg(feature = "client")]
#[serde(deserialize_with = "de_time_int")]
pub db_playtime: Duration,
pub db_update: i32,
}
#[serde_with::skip_serializing_none]
#[derive(Deserialize, Serialize, Clone, Debug, Default)]
pub struct Track {
pub file: String,
pub artist_sort: Option<String>,
pub album_artist: Option<String>,
pub album_sort: Option<String>,
pub album_artist_sort: Option<String>,
pub performer: Vec<String>,
pub genre: Option<String>,
pub title: Option<String>,
pub track: Option<u32>,
pub album: Option<String>,
pub artist: Option<String>,
pub pos: Option<u32>,
pub id: Option<u32>,
pub last_modified: Option<DateTime<Utc>>,
pub original_date: Option<String>,
pub time: Option<String>,
pub format: Option<String>,
pub duration: Duration,
pub label: Option<String>,
pub date: Option<String>,
pub disc: Option<u32>,
pub musicbraiz_trackid: Option<String>,
pub musicbrainz_albumid: Option<String>,
pub musicbrainz_albumartistid: Option<String>,
pub musicbrainz_artistid: Option<String>,
pub musicbraiz_releasetrackid: Option<String>,
pub composer: Option<String>,
}
#[derive(Copy, Clone, Debug)]
pub enum Tag {
Artist,
ArtistSort,
Album,
AlbumSort,
AlbumArtist,
AlbumSortOrder,
Title,
Track,
Name,
Genre,
Date,
Composer,
Performer,
Conductor,
Work,
Grouping,
Comment,
Disc,
Label,
MusicbrainzArtistId,
MusicbrainzAlbumId,
MusicbrainzAlbumArtistId,
MusicbrainzTrackId,
MusicbrainzReleaseTrackId,
MusicbrainzWorkId,
Any,
}
#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "lowercase")]
pub enum Subsystem {
Database,
Player,
Mixer,
Options,
Update,
#[serde(rename = "stored_playlist")]
StoredPlaylist,
Playlist,
Output,
Partitions,
Sticker,
Subscription,
Message,
}
#[cfg(feature = "client")]
fn de_time_int<'de, D>(deserializer: D) -> Result<Duration, D::Error>
where
D: Deserializer<'de>,
{
u64::deserialize(deserializer).map(Duration::from_secs)
}
#[cfg(feature = "client")]
fn de_time_float<'de, D>(deserializer: D) -> Result<Option<Duration>, D::Error>
where
D: Deserializer<'de>,
{
f64::deserialize(deserializer)
.map(Duration::from_secs_f64)
.map(Some)
}
#[cfg(feature = "client")]
fn de_bint<'de, D>(deserializer: D) -> Result<bool, D::Error>
where
D: Deserializer<'de>,
{
match u8::deserialize(deserializer)? {
0 => Ok(false),
1 => Ok(true),
n => Err(de::Error::invalid_value(
Unexpected::Unsigned(n as u64),
&"zero or one",
)),
}
}