librespot_metadata/playlist/
annotation.rs1use std::fmt::Debug;
2
3use protobuf::Message;
4
5use crate::{
6 Metadata,
7 image::TranscodedPictures,
8 request::{MercuryRequest, RequestResult},
9};
10
11use librespot_core::{Error, Session, SpotifyId, SpotifyUri};
12use librespot_protocol as protocol;
13pub use protocol::playlist_annotate3::AbuseReportState;
14
15#[derive(Debug, Clone)]
16pub struct PlaylistAnnotation {
17 pub description: String,
18 pub picture: String,
19 pub transcoded_pictures: TranscodedPictures,
20 pub has_abuse_reporting: bool,
21 pub abuse_report_state: AbuseReportState,
22}
23
24#[async_trait]
25impl Metadata for PlaylistAnnotation {
26 type Message = protocol::playlist_annotate3::PlaylistAnnotation;
27
28 async fn request(session: &Session, playlist_uri: &SpotifyUri) -> RequestResult {
29 let current_user = session.username();
30
31 let SpotifyUri::Playlist {
32 id: playlist_id, ..
33 } = playlist_uri
34 else {
35 return Err(Error::invalid_argument("playlist_uri"));
36 };
37
38 Self::request_for_user(session, ¤t_user, playlist_id).await
39 }
40
41 fn parse(msg: &Self::Message, _: &SpotifyUri) -> Result<Self, Error> {
42 Ok(Self {
43 description: msg.description().to_owned(),
44 picture: msg.picture().to_owned(), transcoded_pictures: msg.transcoded_picture.as_slice().try_into()?,
46 has_abuse_reporting: msg.is_abuse_reporting_enabled(),
47 abuse_report_state: msg.abuse_report_state(),
48 })
49 }
50}
51
52impl PlaylistAnnotation {
53 async fn request_for_user(
54 session: &Session,
55 username: &str,
56 playlist_id: &SpotifyId,
57 ) -> RequestResult {
58 let uri = format!(
59 "hm://playlist-annotate/v1/annotation/user/{}/playlist/{}",
60 username,
61 playlist_id.to_base62()?
62 );
63 <Self as MercuryRequest>::request(session, &uri).await
64 }
65
66 #[allow(dead_code)]
67 async fn get_for_user(
68 session: &Session,
69 username: &str,
70 playlist_uri: &SpotifyUri,
71 ) -> Result<Self, Error> {
72 let SpotifyUri::Playlist {
73 id: playlist_id, ..
74 } = playlist_uri
75 else {
76 return Err(Error::invalid_argument("playlist_uri"));
77 };
78
79 let response = Self::request_for_user(session, username, playlist_id).await?;
80 let msg = <Self as Metadata>::Message::parse_from_bytes(&response)?;
81 Self::parse(&msg, playlist_uri)
82 }
83}
84
85impl MercuryRequest for PlaylistAnnotation {}
86
87impl TryFrom<&<PlaylistAnnotation as Metadata>::Message> for PlaylistAnnotation {
88 type Error = librespot_core::Error;
89 fn try_from(
90 annotation: &<PlaylistAnnotation as Metadata>::Message,
91 ) -> Result<Self, Self::Error> {
92 Ok(Self {
93 description: annotation.description().to_owned(),
94 picture: annotation.picture().to_owned(),
95 transcoded_pictures: annotation.transcoded_picture.as_slice().try_into()?,
96 has_abuse_reporting: annotation.is_abuse_reporting_enabled(),
97 abuse_report_state: annotation.abuse_report_state(),
98 })
99 }
100}