music_player_graphql/schema/objects/
track.rs1use 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}