Skip to main content

ytmapi_rs/query/
podcasts.rs

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