ytmapi_rs/query/
podcasts.rs

1use super::{PostMethod, PostQuery, Query};
2use crate::{
3    auth::AuthToken,
4    common::{EpisodeID, PodcastChannelID, PodcastChannelParams, PodcastID},
5    parse::{Episode, GetEpisode, GetPodcast, GetPodcastChannel},
6};
7use serde_json::json;
8
9pub struct GetChannelQuery<'a> {
10    channel_id: PodcastChannelID<'a>,
11}
12pub struct GetChannelEpisodesQuery<'a> {
13    channel_id: PodcastChannelID<'a>,
14    podcast_channel_params: PodcastChannelParams<'a>,
15}
16pub struct GetPodcastQuery<'a> {
17    podcast_id: PodcastID<'a>,
18}
19pub struct GetEpisodeQuery<'a> {
20    episode_id: EpisodeID<'a>,
21}
22pub struct GetNewEpisodesQuery;
23
24// NOTE: This is technically the same page as the GetArtist page. It's possible
25// this could be generalised.
26impl<'a> GetChannelQuery<'a> {
27    pub fn new(channel_id: impl Into<PodcastChannelID<'a>>) -> Self {
28        Self {
29            channel_id: channel_id.into(),
30        }
31    }
32}
33impl<'a> GetChannelEpisodesQuery<'a> {
34    pub fn new(
35        channel_id: impl Into<PodcastChannelID<'a>>,
36        podcast_channel_params: impl Into<PodcastChannelParams<'a>>,
37    ) -> GetChannelEpisodesQuery<'a> {
38        GetChannelEpisodesQuery {
39            channel_id: channel_id.into(),
40            podcast_channel_params: podcast_channel_params.into(),
41        }
42    }
43}
44impl<'a> GetPodcastQuery<'a> {
45    pub fn new(podcast_id: impl Into<PodcastID<'a>>) -> Self {
46        Self {
47            podcast_id: podcast_id.into(),
48        }
49    }
50}
51impl<'a> GetEpisodeQuery<'a> {
52    pub fn new(episode_id: impl Into<EpisodeID<'a>>) -> Self {
53        Self {
54            episode_id: episode_id.into(),
55        }
56    }
57}
58
59impl<A: AuthToken> Query<A> for GetChannelQuery<'_> {
60    type Output = GetPodcastChannel;
61    type Method = PostMethod;
62}
63impl<A: AuthToken> Query<A> for GetChannelEpisodesQuery<'_> {
64    type Output = Vec<Episode>;
65    type Method = PostMethod;
66}
67impl<A: AuthToken> Query<A> for GetPodcastQuery<'_> {
68    type Output = GetPodcast;
69    type Method = PostMethod;
70}
71impl<A: AuthToken> Query<A> for GetEpisodeQuery<'_> {
72    type Output = GetEpisode;
73    type Method = PostMethod;
74}
75impl<A: AuthToken> Query<A> for GetNewEpisodesQuery {
76    type Output = Vec<Episode>;
77    type Method = PostMethod;
78}
79
80impl PostQuery for GetChannelQuery<'_> {
81    fn header(&self) -> serde_json::Map<String, serde_json::Value> {
82        FromIterator::from_iter([("browseId".into(), json!(self.channel_id))])
83    }
84    fn params(&self) -> std::vec::Vec<(&str, std::borrow::Cow<'_, str>)> {
85        vec![]
86    }
87    fn path(&self) -> &str {
88        "browse"
89    }
90}
91impl PostQuery for GetChannelEpisodesQuery<'_> {
92    fn header(&self) -> serde_json::Map<String, serde_json::Value> {
93        FromIterator::from_iter([
94            ("browseId".into(), json!(self.channel_id)),
95            ("params".into(), json!(self.podcast_channel_params)),
96        ])
97    }
98    fn params(&self) -> std::vec::Vec<(&str, std::borrow::Cow<'_, str>)> {
99        vec![]
100    }
101    fn path(&self) -> &str {
102        "browse"
103    }
104}
105// TODO: Continuations
106impl PostQuery for GetPodcastQuery<'_> {
107    fn header(&self) -> serde_json::Map<String, serde_json::Value> {
108        // TODO: Confirm if any parsing required
109        FromIterator::from_iter([("browseId".into(), json!(self.podcast_id))])
110    }
111    fn params(&self) -> std::vec::Vec<(&str, std::borrow::Cow<'_, str>)> {
112        vec![]
113    }
114    fn path(&self) -> &str {
115        "browse"
116    }
117}
118impl PostQuery for GetEpisodeQuery<'_> {
119    fn header(&self) -> serde_json::Map<String, serde_json::Value> {
120        // TODO: Confirm if any parsing required
121        FromIterator::from_iter([("browseId".into(), json!(self.episode_id))])
122    }
123    fn params(&self) -> std::vec::Vec<(&str, std::borrow::Cow<'_, str>)> {
124        vec![]
125    }
126    fn path(&self) -> &str {
127        "browse"
128    }
129}
130// Gets the NewEpisodes auto-playlist. In future there could be other similar
131// playlists, we can instead re-implement this as GetEpisodesPlaylist.
132impl PostQuery for GetNewEpisodesQuery {
133    fn header(&self) -> serde_json::Map<String, serde_json::Value> {
134        FromIterator::from_iter([("browseId".into(), json!("VLRDPN"))])
135    }
136    fn params(&self) -> std::vec::Vec<(&str, std::borrow::Cow<'_, str>)> {
137        vec![]
138    }
139    fn path(&self) -> &str {
140        "browse"
141    }
142}