librespot_metadata/
lyrics.rs1use bytes::Bytes;
2
3use librespot_core::{Error, FileId, Session, SpotifyId};
4
5impl Lyrics {
6 pub async fn get(session: &Session, id: &SpotifyId) -> Result<Self, Error> {
7 let spclient = session.spclient();
8 let lyrics = spclient.get_lyrics(id).await?;
9 Self::try_from(&lyrics)
10 }
11
12 pub async fn get_for_image(
13 session: &Session,
14 id: &SpotifyId,
15 image_id: &FileId,
16 ) -> Result<Self, Error> {
17 let spclient = session.spclient();
18 let lyrics = spclient.get_lyrics_for_image(id, image_id).await?;
19 Self::try_from(&lyrics)
20 }
21}
22
23impl TryFrom<&Bytes> for Lyrics {
24 type Error = Error;
25
26 fn try_from(lyrics: &Bytes) -> Result<Self, Self::Error> {
27 serde_json::from_slice(lyrics).map_err(|err| err.into())
28 }
29}
30
31#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct Lyrics {
34 pub colors: Colors,
35 pub has_vocal_removal: bool,
36 pub lyrics: LyricsInner,
37}
38
39#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
40#[serde(rename_all = "camelCase")]
41pub struct Colors {
42 pub background: i32,
43 pub highlight_text: i32,
44 pub text: i32,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
48#[serde(rename_all = "camelCase")]
49pub struct LyricsInner {
50 pub is_dense_typeface: bool,
52 pub is_rtl_language: bool,
53 pub language: String,
54 pub lines: Vec<Line>,
55 pub provider: String,
56 pub provider_display_name: String,
57 pub provider_lyrics_id: String,
58 pub sync_lyrics_uri: String,
59 pub sync_type: SyncType,
60}
61
62#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
63#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
64pub enum SyncType {
65 Unsynced,
66 LineSynced,
67}
68
69#[derive(Debug, Clone, PartialEq, Eq, serde::Deserialize)]
70#[serde(rename_all = "camelCase")]
71pub struct Line {
72 pub start_time_ms: String,
73 pub end_time_ms: String,
74 pub words: String,
75 }