music_player_graphql/schema/objects/
track.rs

1use async_graphql::*;
2use music_player_entity::{select_result, track::Model};
3use music_player_types::types::{self, RemoteTrackUrl};
4use music_player_types::types::{RemoteCoverUrl, SimplifiedSong as TrackType};
5use serde::Serialize;
6
7use super::{album::Album, artist::Artist};
8
9#[derive(InputObject, Default, Clone)]
10pub struct TrackInput {
11    pub id: ID,
12    pub title: String,
13    pub duration: Option<f32>,
14    pub disc_number: u32,
15    pub track_number: Option<u32>,
16    pub uri: String,
17}
18
19#[derive(Default, Clone, Serialize)]
20pub struct Track {
21    pub id: ID,
22    pub title: String,
23    pub duration: Option<f32>,
24    pub disc_number: u32,
25    pub track_number: Option<u32>,
26    pub uri: String,
27    pub artists: Vec<Artist>,
28    pub album: Album,
29    pub artist: String,
30    pub cover: Option<String>,
31    pub artist_id: String,
32    pub album_id: String,
33    pub album_title: String,
34}
35
36#[Object]
37impl Track {
38    async fn id(&self) -> &str {
39        &self.id
40    }
41
42    async fn title(&self) -> &str {
43        &self.title
44    }
45
46    async fn duration(&self) -> Option<f32> {
47        self.duration
48    }
49
50    async fn disc_number(&self) -> u32 {
51        self.disc_number
52    }
53
54    async fn track_number(&self) -> Option<u32> {
55        self.track_number
56    }
57
58    async fn uri(&self) -> &str {
59        &self.uri
60    }
61
62    async fn artists(&self) -> Vec<Artist> {
63        self.artists.clone()
64    }
65
66    async fn album(&self) -> Album {
67        self.album.clone()
68    }
69
70    async fn artist(&self) -> &str {
71        &self.artist
72    }
73
74    async fn cover(&self) -> Option<String> {
75        self.cover.clone()
76    }
77
78    async fn artist_id(&self) -> &str {
79        &self.artist_id
80    }
81
82    async fn album_id(&self) -> &str {
83        &self.album_id
84    }
85
86    async fn album_title(&self) -> &str {
87        &self.album_title
88    }
89}
90
91impl RemoteTrackUrl for Track {
92    fn with_remote_track_url(&self, base_url: &str) -> Self {
93        Self {
94            uri: format!("{}/tracks/{}", base_url, self.id.to_string()),
95            ..self.clone()
96        }
97    }
98}
99
100impl RemoteCoverUrl for Track {
101    fn with_remote_cover_url(&self, base_url: &str) -> Self {
102        Self {
103            album: Album {
104                cover: match self.album.cover {
105                    Some(ref cover) => Some(format!("{}/covers/{}", base_url, cover)),
106                    None => None,
107                },
108                ..self.album.clone()
109            },
110            ..self.clone()
111        }
112    }
113}
114
115impl From<Model> for Track {
116    fn from(model: Model) -> Self {
117        Self {
118            id: ID(model.id),
119            title: model.title,
120            uri: model.uri,
121            duration: model.duration,
122            track_number: model.track,
123            artists: model.artists.into_iter().map(Into::into).collect(),
124            album: model.album.into(),
125            artist: model.artist,
126            ..Default::default()
127        }
128    }
129}
130
131impl Into<Model> for TrackInput {
132    fn into(self) -> Model {
133        Model {
134            id: self.id.0,
135            title: self.title,
136            uri: self.uri,
137            duration: self.duration,
138            track: self.track_number,
139            ..Default::default()
140        }
141    }
142}
143
144impl From<TrackType> for Track {
145    fn from(song: TrackType) -> Self {
146        Self {
147            id: ID(song.id),
148            title: song.title,
149            artist: song.artist,
150            duration: Some(song.duration.as_secs_f32()),
151            cover: song.cover,
152            artist_id: song.artist_id,
153            album_id: song.album_id,
154            album_title: song.album,
155            ..Default::default()
156        }
157    }
158}
159
160impl From<types::Track> for Track {
161    fn from(track: types::Track) -> Self {
162        Self {
163            id: ID(track.id),
164            title: track.title,
165            uri: track.uri,
166            duration: track.duration,
167            track_number: track.track_number,
168            artist: track.artist,
169            album: match track.album.clone() {
170                Some(album) => album.into(),
171                None => Default::default(),
172            },
173            artists: track
174                .artists
175                .clone()
176                .into_iter()
177                .map(|artist| artist.into())
178                .collect(),
179            album_title: match track.album.clone() {
180                Some(album) => album.title,
181                None => String::new(),
182            },
183            album_id: match track.album.clone() {
184                Some(album) => album.id,
185                None => String::new(),
186            },
187            artist_id: match track.artists.clone().first() {
188                Some(artist) => artist.id.clone(),
189                None => String::new(),
190            },
191            cover: match track.album {
192                Some(album) => album.cover,
193                None => None,
194            },
195            ..Default::default()
196        }
197    }
198}
199
200impl From<select_result::PlaylistTrack> for Track {
201    fn from(result: select_result::PlaylistTrack) -> Self {
202        Self {
203            id: ID(result.track_id),
204            title: result.track_title,
205            duration: Some(result.track_duration),
206            track_number: result.track_number,
207            artist: result.track_artist,
208            album_title: result.album_title.clone(),
209            album_id: result.album_id.clone(),
210            artist_id: result.artist_id.clone(),
211            cover: result.album_cover.clone(),
212            album: Album {
213                id: ID(result.album_id),
214                title: result.album_title,
215                cover: result.album_cover,
216                year: result.album_year,
217                ..Default::default()
218            },
219            ..Default::default()
220        }
221    }
222}