use super::{
ExternalUrls, Image, ItemType, ReleaseDatePrecision, Restrictions, ResumePoint, SimplifiedShow,
};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Episode {
pub description: String,
pub html_description: String,
pub duration_ms: u32,
pub explicit: bool,
pub external_urls: ExternalUrls,
pub href: String,
pub id: String,
pub images: Vec<Image>,
pub is_externally_hosted: bool,
pub is_playable: bool,
pub languages: Vec<String>,
pub name: String,
pub release_date: String,
pub release_date_precision: ReleaseDatePrecision,
pub resume_point: Option<ResumePoint>,
#[serde(rename = "type")]
pub type_: ItemType,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub restrictions: Option<Restrictions>,
pub show: SimplifiedShow,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SimplifiedEpisode {
pub description: String,
pub html_description: String,
pub duration_ms: u32,
pub explicit: bool,
pub external_urls: ExternalUrls,
pub href: String,
pub id: String,
pub images: Vec<Image>,
pub is_externally_hosted: bool,
pub is_playable: bool,
pub languages: Vec<String>,
pub name: String,
pub release_date: String,
pub release_date_precision: ReleaseDatePrecision,
pub resume_point: Option<ResumePoint>,
#[serde(rename = "type")]
pub type_: ItemType,
pub uri: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub restrictions: Option<Restrictions>,
}
impl From<Episode> for SimplifiedEpisode {
fn from(episode: Episode) -> Self {
Self {
description: episode.description,
html_description: episode.html_description,
duration_ms: episode.duration_ms,
explicit: episode.explicit,
external_urls: episode.external_urls,
href: episode.href,
id: episode.id,
images: episode.images,
is_externally_hosted: episode.is_externally_hosted,
is_playable: episode.is_playable,
languages: episode.languages,
name: episode.name,
release_date: episode.release_date,
release_date_precision: episode.release_date_precision,
resume_point: episode.resume_point,
type_: episode.type_,
uri: episode.uri,
restrictions: episode.restrictions,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct Episodes {
pub episodes: Vec<Option<Episode>>,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub struct SavedEpisode {
pub added_at: String,
pub episode: Episode,
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn episode() {
let json = r#"
{
"audio_preview_url": "https://p.scdn.co/mp3-preview/2f37da1d4221f40b9d1a98cd191f4d6f1646ad17",
"description": "A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.",
"html_description": "<p>A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.</p>",
"duration_ms": 1686230,
"explicit": false,
"external_urls": {
"spotify": "string"
},
"href": "https://api.spotify.com/v1/episodes/5Xt5DXGzch68nYYamXrNxZ",
"id": "5Xt5DXGzch68nYYamXrNxZ",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"height": 300,
"width": 300
}
],
"is_externally_hosted": false,
"is_playable": false,
"language": "en",
"languages": ["fr", "en"],
"name": "Starting Your Own Podcast: Tips, Tricks, and Advice From Anchor Creators",
"release_date": "1981-12-15",
"release_date_precision": "day",
"resume_point": {
"fully_played": false,
"resume_position_ms": 0
},
"type": "episode",
"uri": "spotify:episode:0zLhl3WsOCQHbe1BPTiHgr",
"restrictions": {
"reason": "string"
},
"show": {
"available_markets": ["US"],
"copyrights": [
{
"text": "string",
"type": "C"
}
],
"description": "string",
"html_description": "string",
"explicit": false,
"external_urls": {
"spotify": "string"
},
"href": "string",
"id": "string",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"height": 300,
"width": 300
}
],
"is_externally_hosted": false,
"languages": ["string"],
"media_type": "string",
"name": "string",
"publisher": "string",
"type": "show",
"uri": "string",
"total_episodes": 0
}
}
"#;
crate::test::assert_deserialized!(Episode, json);
}
#[test]
fn simplified_episode() {
let json = r#"
{
"audio_preview_url": "https://p.scdn.co/mp3-preview/2f37da1d4221f40b9d1a98cd191f4d6f1646ad17",
"description": "A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.",
"html_description": "<p>A Spotify podcast sharing fresh insights on important topics of the moment—in a way only Spotify can. You’ll hear from experts in the music, podcast and tech industries as we discover and uncover stories about our work and the world around us.</p>",
"duration_ms": 1686230,
"explicit": false,
"external_urls": {
"spotify": "string"
},
"href": "https://api.spotify.com/v1/episodes/5Xt5DXGzch68nYYamXrNxZ",
"id": "5Xt5DXGzch68nYYamXrNxZ",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"height": 300,
"width": 300
}
],
"is_externally_hosted": false,
"is_playable": false,
"language": "en",
"languages": ["fr", "en"],
"name": "Starting Your Own Podcast: Tips, Tricks, and Advice From Anchor Creators",
"release_date": "1981-12-15",
"release_date_precision": "day",
"resume_point": {
"fully_played": false,
"resume_position_ms": 0
},
"type": "episode",
"uri": "spotify:episode:0zLhl3WsOCQHbe1BPTiHgr",
"restrictions": {
"reason": "string"
},
"show": {
"available_markets": ["US"],
"copyrights": [
{
"text": "string",
"type": "C"
}
],
"description": "string",
"html_description": "string",
"explicit": false,
"external_urls": {
"spotify": "string"
},
"href": "string",
"id": "string",
"images": [
{
"url": "https://i.scdn.co/image/ab67616d00001e02ff9ca10b55ce82ae553c8228",
"height": 300,
"width": 300
}
],
"is_externally_hosted": false,
"languages": ["string"],
"media_type": "string",
"name": "string",
"publisher": "string",
"type": "show",
"uri": "string",
"total_episodes": 0
}
}
"#;
crate::test::assert_deserialized!(SimplifiedEpisode, json);
}
}