use chrono::serde::ts_milliseconds;
use chrono::{DateTime, Duration, Utc};
use serde::{Deserialize, Deserializer, Serialize};
use std::collections::HashMap;
use crate::{
custom_serde::option_duration_ms, CurrentlyPlayingType, Device, DisallowKey, PlayableItem,
RepeatState, Type,
};
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct Context {
pub uri: String,
pub href: String,
pub external_urls: HashMap<String, String>,
#[serde(rename = "type")]
pub _type: Type,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct CurrentlyPlayingContext {
pub context: Option<Context>,
#[serde(with = "ts_milliseconds")]
pub timestamp: DateTime<Utc>,
#[serde(default)]
#[serde(with = "option_duration_ms", rename = "progress_ms")]
pub progress: Option<Duration>,
pub is_playing: bool,
pub item: Option<PlayableItem>,
pub currently_playing_type: CurrentlyPlayingType,
pub actions: Actions,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct CurrentPlaybackContext {
pub device: Device,
pub repeat_state: RepeatState,
pub shuffle_state: bool,
pub context: Option<Context>,
#[serde(with = "ts_milliseconds")]
pub timestamp: DateTime<Utc>,
#[serde(default)]
#[serde(with = "option_duration_ms", rename = "progress_ms")]
pub progress: Option<Duration>,
pub is_playing: bool,
pub item: Option<PlayableItem>,
pub currently_playing_type: CurrentlyPlayingType,
pub actions: Actions,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)]
pub struct CurrentUserQueue {
pub currently_playing: Option<PlayableItem>,
pub queue: Vec<PlayableItem>,
}
#[derive(Clone, Debug, PartialEq, Eq, Default)]
pub struct Actions {
pub disallows: Vec<DisallowKey>,
}
impl Serialize for Actions {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
#[derive(Serialize)]
struct OriginalActions {
pub disallows: HashMap<DisallowKey, bool>,
}
let original_actions = OriginalActions {
disallows: self.disallows.iter().map(|&key| (key, true)).collect(),
};
original_actions.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for Actions {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
#[derive(Deserialize)]
struct OriginalActions {
pub disallows: HashMap<DisallowKey, bool>,
}
let orignal_actions = OriginalActions::deserialize(deserializer)?;
Ok(Self {
disallows: orignal_actions
.disallows
.into_iter()
.filter(|(_, value)| *value)
.map(|(key, _)| key)
.collect(),
})
}
}