use crate::model::*;
use serde::{Serializer, ser::SerializeStruct};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Device {
pub id: Option<String>,
pub is_active: bool,
pub is_private_session: bool,
pub is_restricted: bool,
pub name: String,
#[serde(rename = "type")]
pub device_type: DeviceType,
pub volume_percent: Option<u32>,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
pub enum DeviceType {
Computer,
Tablet,
Smartphone,
Speaker,
TV,
AVR,
STB,
AudioDongle,
GameConsole,
CastVideo,
CastAudio,
Automobile,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CurrentlyPlaying {
pub context: Option<Context>,
#[serde(
rename = "progress_ms",
with = "serde_duration_millis_option"
)]
pub progress: Option<Duration>,
pub is_playing: bool,
pub item: Option<Track>,
pub currently_playing_type: TrackType,
pub actions: Actions,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct CurrentPlayback {
pub device: Device,
pub repeat_state: RepeatState,
pub shuffle_state: bool,
#[serde(flatten)]
pub currently_playing: CurrentlyPlaying,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct Actions {
#[serde(with = "serde_disallows")]
pub disallows: Vec<Disallow>,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Disallow {
InterruptingPlayback,
Pausing,
Resuming,
Seeking,
SkippingNext,
SkippingPrev,
TogglingRepeatContext,
TogglingShuffle,
TogglingRepeatTrack,
TransferringPlayback,
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TrackType {
Track,
Episode,
Ad,
Unknown,
}
#[derive(Debug, Clone, PartialEq, Eq, Deserialize)]
pub struct Context {
#[serde(rename = "type")]
pub context_type: ItemType,
pub external_urls: HashMap<String, String>,
#[serde(rename = "uri", deserialize_with = "de_any_uri")]
pub id: String,
}
impl Serialize for Context {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
let mut context = serializer.serialize_struct("Context", 3)?;
context.serialize_field("type", &self.context_type)?;
context.serialize_field("external_urls", &self.external_urls)?;
context.serialize_field("uri", {
struct UriSerialize<'a> {
context_type: ItemType,
id: &'a str,
}
impl Serialize for UriSerialize<'_> {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
serializer.serialize_str(&format!("spotify:{}:{}", self.context_type.as_str(), self.id))
}
}
&UriSerialize {
context_type: self.context_type,
id: &self.id
}
})?;
context.end()
}
}
#[derive(Debug, Clone, PartialEq, Eq, Copy, Hash, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum RepeatState {
Off,
Track,
Context,
}
impl RepeatState {
pub fn as_str(self) -> &'static str {
match self {
Self::Off => "off",
Self::Track => "track",
Self::Context => "context",
}
}
}