use serde::{Deserialize, Serialize};
use crate::models::{
album::Image, deserialization::deserialize_flexible_string_id, search::ItemSearchResult,
subscription::User, track::Track,
};
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
pub struct Playlist {
#[serde(default, deserialize_with = "deserialize_flexible_string_id")]
pub id: Option<String>,
pub name: Option<String>,
pub description: Option<String>,
pub tracks_count: Option<i32>,
pub duration: Option<i32>,
pub is_public: Option<bool>,
pub creator: Option<User>,
pub owner: Option<PlaylistOwner>,
pub image: Option<Image>,
pub image_rectangle: Option<Vec<String>>,
pub image_rectangle_mini: Option<Vec<String>>,
pub images: Option<Vec<String>>,
pub images150: Option<Vec<String>>,
pub images300: Option<Vec<String>>,
pub tracks: Option<ItemSearchResult<Box<Track>>>,
pub created_at: Option<i64>,
pub updated_at: Option<i64>,
}
impl Playlist {
#[must_use]
pub fn creator_name(&self) -> Option<&str> {
self.creator
.as_ref()
.and_then(|c| c.display_name.as_deref())
.or_else(|| {
let o = self.owner.as_ref()?;
o.name.as_deref()
})
}
#[must_use]
pub fn best_image_url(&self, large: bool) -> Option<String> {
if large {
first_img_url(self.image_rectangle.as_ref())
.or_else(|| first_img_url(self.images300.as_ref()))
.or_else(|| first_img_url(self.images150.as_ref()))
.or_else(|| first_img_url(self.images.as_ref()))
} else {
first_img_url(self.image_rectangle_mini.as_ref())
.or_else(|| first_img_url(self.image_rectangle.as_ref()))
.or_else(|| first_img_url(self.images150.as_ref()))
.or_else(|| first_img_url(self.images.as_ref()))
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)]
pub struct PlaylistOwner {
pub id: Option<i32>,
pub name: Option<String>,
}
fn first_img_url(v: Option<&Vec<String>>) -> Option<String> {
v?.first().cloned()
}