ytmapi_rs/query/
recommendations.rs1use super::{PostMethod, PostQuery, Query};
2use crate::auth::AuthToken;
3use crate::common::{MoodCategoryParams, TasteToken};
4use crate::parse::{MoodCategorySection, MoodPlaylistCategory, TasteProfileArtist};
5use serde_json::{Value, json};
6use std::borrow::Cow;
7
8#[derive(Clone)]
9pub struct GetTasteProfileQuery;
10
11#[derive(Clone)]
12pub struct SetTasteProfileQuery<'a> {
13 taste_tokens: Vec<TasteToken<'a>>,
14}
15
16#[derive(Clone)]
17pub struct GetMoodCategoriesQuery;
18
19#[derive(Clone)]
20pub struct GetMoodPlaylistsQuery<'a> {
21 params: MoodCategoryParams<'a>,
22}
23
24impl<'a> SetTasteProfileQuery<'a> {
25 pub fn new(taste_tokens: impl IntoIterator<Item = TasteToken<'a>>) -> Self {
26 let taste_tokens = taste_tokens.into_iter().collect();
27 Self { taste_tokens }
28 }
29}
30
31impl<'a> GetMoodPlaylistsQuery<'a> {
32 pub fn new(params: MoodCategoryParams<'a>) -> Self {
33 Self { params }
34 }
35}
36
37impl<A: AuthToken> Query<A> for GetTasteProfileQuery {
38 type Output = Vec<TasteProfileArtist>;
39 type Method = PostMethod;
40}
41impl PostQuery for GetTasteProfileQuery {
42 fn header(&self) -> serde_json::Map<String, serde_json::Value> {
43 serde_json::Map::from_iter([("browseId".to_string(), json!("FEmusic_tastebuilder"))])
44 }
45 fn params(&self) -> Vec<(&str, Cow<'_, str>)> {
46 vec![]
47 }
48 fn path(&self) -> &str {
49 "browse"
50 }
51}
52
53impl<A> Query<A> for SetTasteProfileQuery<'_>
54where
55 A: AuthToken,
56{
57 type Output = ();
58 type Method = PostMethod;
59}
60impl PostQuery for SetTasteProfileQuery<'_> {
61 fn header(&self) -> serde_json::Map<String, serde_json::Value> {
62 let (impression_tokens, selection_tokens): (Vec<Value>, Vec<Value>) = self
63 .taste_tokens
64 .iter()
65 .map(|t| (json!(t.impression_value), json!(t.selection_value)))
66 .unzip();
67 serde_json::Map::from_iter([
68 ("browseId".to_string(), json!("FEmusic_home")),
69 (
70 "formData".to_string(),
71 json!({
72 "impressionValues": impression_tokens,
73 "selectedValues": selection_tokens
74 }),
75 ),
76 ])
77 }
78 fn params(&self) -> Vec<(&str, Cow<'_, str>)> {
79 vec![]
80 }
81 fn path(&self) -> &str {
82 "browse"
83 }
84}
85
86impl<A: AuthToken> Query<A> for GetMoodCategoriesQuery {
87 type Output = Vec<MoodCategorySection>;
88 type Method = PostMethod;
89}
90impl PostQuery for GetMoodCategoriesQuery {
91 fn header(&self) -> serde_json::Map<String, serde_json::Value> {
92 serde_json::Map::from_iter([("browseId".to_string(), json!("FEmusic_moods_and_genres"))])
93 }
94 fn params(&self) -> Vec<(&str, Cow<'_, str>)> {
95 vec![]
96 }
97 fn path(&self) -> &str {
98 "browse"
99 }
100}
101
102impl<A: AuthToken> Query<A> for GetMoodPlaylistsQuery<'_> {
103 type Output = Vec<MoodPlaylistCategory>;
104 type Method = PostMethod;
105}
106impl PostQuery for GetMoodPlaylistsQuery<'_> {
107 fn header(&self) -> serde_json::Map<String, serde_json::Value> {
108 serde_json::Map::from_iter([
109 (
110 "browseId".to_string(),
111 json!("FEmusic_moods_and_genres_category"),
112 ),
113 ("params".to_string(), json!(self.params)),
114 ])
115 }
116 fn params(&self) -> Vec<(&str, Cow<'_, str>)> {
117 vec![]
118 }
119 fn path(&self) -> &str {
120 "browse"
121 }
122}