A modern Music Player Daemon based on Rockbox open source high quality audio player
libadwaita
audio
rust
zig
deno
mpris
rockbox
mpd
1use async_graphql::*;
2use rockbox_sys::types::mp3_entry::Mp3Entry;
3use serde::{Deserialize, Serialize};
4use tantivy::schema::Schema;
5use tantivy::schema::SchemaBuilder;
6use tantivy::schema::Value;
7use tantivy::schema::*;
8use tantivy::TantivyDocument;
9
10#[derive(Default, Debug, Clone, Serialize, Deserialize)]
11pub struct Track {
12 pub id: Option<String>,
13 pub title: String,
14 pub artist: String,
15 pub album: String,
16 pub genre: String,
17 pub disc: String,
18 pub track_string: String,
19 pub year_string: String,
20 pub composer: String,
21 pub comment: String,
22 pub album_artist: String,
23 pub grouping: String,
24 pub discnum: i32,
25 pub tracknum: i32,
26 pub layer: i32,
27 pub year: i32,
28 pub bitrate: u32,
29 pub frequency: u64,
30 pub filesize: u64,
31 pub length: u64,
32 pub elapsed: u64,
33 pub path: String,
34 pub album_id: Option<String>,
35 pub artist_id: Option<String>,
36 pub genre_id: Option<String>,
37 pub album_art: Option<String>,
38}
39
40#[Object]
41impl Track {
42 async fn id(&self) -> Option<&str> {
43 self.id.as_deref()
44 }
45
46 async fn title(&self) -> &str {
47 &self.title
48 }
49
50 async fn artist(&self) -> &str {
51 &self.artist
52 }
53
54 async fn album(&self) -> &str {
55 &self.album
56 }
57
58 async fn genre(&self) -> &str {
59 &self.genre
60 }
61
62 async fn disc(&self) -> &str {
63 &self.disc
64 }
65
66 async fn track_string(&self) -> &str {
67 &self.track_string
68 }
69
70 async fn year_string(&self) -> &str {
71 &self.year_string
72 }
73
74 async fn composer(&self) -> &str {
75 &self.composer
76 }
77
78 async fn comment(&self) -> &str {
79 &self.comment
80 }
81
82 async fn album_artist(&self) -> &str {
83 &self.album_artist
84 }
85
86 async fn grouping(&self) -> &str {
87 &self.grouping
88 }
89
90 async fn discnum(&self) -> i32 {
91 self.discnum
92 }
93
94 async fn tracknum(&self) -> i32 {
95 self.tracknum
96 }
97
98 async fn layer(&self) -> i32 {
99 self.layer
100 }
101
102 async fn year(&self) -> i32 {
103 self.year
104 }
105
106 async fn bitrate(&self) -> u32 {
107 self.bitrate
108 }
109
110 async fn frequency(&self) -> u64 {
111 self.frequency
112 }
113
114 async fn filesize(&self) -> u64 {
115 self.filesize
116 }
117
118 async fn length(&self) -> u64 {
119 self.length
120 }
121
122 async fn elapsed(&self) -> u64 {
123 self.elapsed
124 }
125
126 async fn path(&self) -> &str {
127 &self.path
128 }
129
130 async fn album_id(&self) -> Option<&str> {
131 self.album_id.as_deref()
132 }
133
134 async fn artist_id(&self) -> Option<&str> {
135 self.artist_id.as_deref()
136 }
137
138 async fn genre_id(&self) -> Option<&str> {
139 self.genre_id.as_deref()
140 }
141
142 async fn album_art(&self) -> Option<&str> {
143 self.album_art.as_deref()
144 }
145}
146
147impl From<Mp3Entry> for Track {
148 fn from(mp3entry: Mp3Entry) -> Self {
149 let title = mp3entry.title;
150 let artist = mp3entry.artist;
151 let album = mp3entry.album;
152 let genre = mp3entry.genre_string;
153 let disc = mp3entry.disc_string;
154 let track_string = mp3entry.track_string;
155 let year_string = mp3entry.year_string;
156 let composer = mp3entry.composer;
157 let comment = mp3entry.comment;
158 let album_artist = mp3entry.albumartist;
159 let grouping = mp3entry.grouping;
160 let discnum = mp3entry.discnum;
161 let tracknum = mp3entry.tracknum;
162 let layer = mp3entry.layer;
163 let year = mp3entry.year;
164 let bitrate = mp3entry.bitrate;
165 let frequency = mp3entry.frequency;
166 let filesize = mp3entry.filesize;
167 let length = mp3entry.length;
168 let elapsed = mp3entry.elapsed;
169 let path = mp3entry.path;
170 let album_id = mp3entry.album_id;
171 let artist_id = mp3entry.artist_id;
172 let genre_id = mp3entry.genre_id;
173 let album_art = mp3entry.album_art;
174
175 Track {
176 title,
177 artist,
178 album,
179 genre,
180 disc,
181 track_string,
182 year_string,
183 composer,
184 comment,
185 album_artist,
186 grouping,
187 discnum,
188 tracknum,
189 layer,
190 year,
191 bitrate,
192 frequency,
193 filesize,
194 length,
195 elapsed,
196 path,
197 album_id,
198 artist_id,
199 genre_id,
200 album_art,
201 ..Default::default()
202 }
203 }
204}
205
206impl From<rockbox_library::entity::track::Track> for Track {
207 fn from(track: rockbox_library::entity::track::Track) -> Self {
208 Self {
209 id: Some(track.id),
210 title: track.title,
211 artist: track.artist,
212 album: track.album,
213 genre: track.genre.unwrap_or_default(),
214 year_string: track.year_string.unwrap_or_default(),
215 composer: track.composer,
216 album_artist: track.album_artist,
217 discnum: track.disc_number as i32,
218 tracknum: track.track_number.unwrap_or_default() as i32,
219 year: track.year.unwrap_or_default() as i32,
220 bitrate: track.bitrate,
221 frequency: track.frequency as u64,
222 filesize: track.filesize as u64,
223 length: track.length as u64,
224 artist_id: Some(track.artist_id),
225 album_id: Some(track.album_id),
226 genre_id: Some(track.genre_id),
227 path: track.path,
228 album_art: track.album_art,
229 ..Default::default()
230 }
231 }
232}
233
234impl From<rockbox_search::track::Track> for Track {
235 fn from(track: rockbox_search::track::Track) -> Self {
236 Self {
237 id: Some(track.id),
238 title: track.title,
239 artist: track.artist,
240 album: track.album,
241 genre: track.genre,
242 year_string: track.year_string,
243 composer: track.composer,
244 album_artist: track.album_artist,
245 discnum: track.disc_number as i32,
246 tracknum: track.track_number as i32,
247 year: track.year as i32,
248 bitrate: track.bitrate as u32,
249 frequency: track.frequency as u64,
250 filesize: track.filesize as u64,
251 length: track.length as u64,
252 artist_id: track.artist_id,
253 album_id: track.album_id,
254 genre_id: track.genre_id,
255 path: track.path,
256 album_art: track.album_art,
257 ..Default::default()
258 }
259 }
260}
261
262impl From<rockbox_search::liked_track::LikedTrack> for Track {
263 fn from(track: rockbox_search::liked_track::LikedTrack) -> Self {
264 Self {
265 id: Some(track.id),
266 title: track.title,
267 artist: track.artist,
268 album: track.album,
269 genre: track.genre,
270 year_string: track.year_string,
271 composer: track.composer,
272 album_artist: track.album_artist,
273 discnum: track.disc_number as i32,
274 tracknum: track.track_number as i32,
275 year: track.year as i32,
276 bitrate: track.bitrate as u32,
277 frequency: track.frequency as u64,
278 filesize: track.filesize as u64,
279 length: track.length as u64,
280 artist_id: track.artist_id,
281 album_id: track.album_id,
282 genre_id: track.genre_id,
283 path: track.path,
284 album_art: track.album_art,
285 ..Default::default()
286 }
287 }
288}
289
290impl From<TantivyDocument> for Track {
291 fn from(document: TantivyDocument) -> Self {
292 let mut schema_builder: SchemaBuilder = Schema::builder();
293
294 let id_field = schema_builder.add_text_field("id", STRING | STORED);
295 let path_field = schema_builder.add_text_field("path", TEXT | STORED);
296 let title_field = schema_builder.add_text_field("title", TEXT | STORED);
297 let artist_field = schema_builder.add_text_field("artist", TEXT | STORED);
298 let album_field = schema_builder.add_text_field("album", TEXT | STORED);
299 let album_artist_field = schema_builder.add_text_field("album_artist", TEXT | STORED);
300 let bitrate_field = schema_builder.add_i64_field("bitrate", STORED);
301 let composer_field = schema_builder.add_text_field("composer", TEXT | STORED);
302 let disc_number_field = schema_builder.add_i64_field("disc_number", STORED);
303 let filesize_field = schema_builder.add_i64_field("filesize", STORED);
304 let frequency_field = schema_builder.add_i64_field("frequency", STORED);
305 let length_field = schema_builder.add_i64_field("length", STORED);
306 let track_number_field = schema_builder.add_i64_field("track_number", STORED);
307 let year_field = schema_builder.add_i64_field("year", STORED);
308 let year_string_field = schema_builder.add_text_field("year_string", STRING | STORED);
309 let genre_field = schema_builder.add_text_field("genre", TEXT | STORED);
310 let md5_field = schema_builder.add_text_field("md5", STRING | STORED);
311 let album_art_field = schema_builder.add_text_field("album_art", STRING | STORED);
312 let artist_id_field = schema_builder.add_text_field("artist_id", STRING | STORED);
313 let album_id_field = schema_builder.add_text_field("album_id", STRING | STORED);
314 let genre_id_field = schema_builder.add_text_field("genre_id", STRING | STORED);
315 let created_at_field = schema_builder.add_text_field("created_at", STRING | STORED);
316 let updated_at_field = schema_builder.add_text_field("updated_at", STRING | STORED);
317
318 let id = document
319 .get_first(id_field)
320 .unwrap()
321 .as_str()
322 .unwrap()
323 .to_string();
324 let path = document
325 .get_first(path_field)
326 .unwrap()
327 .as_str()
328 .unwrap()
329 .to_string();
330 let title = document
331 .get_first(title_field)
332 .unwrap()
333 .as_str()
334 .unwrap()
335 .to_string();
336 let artist = document
337 .get_first(artist_field)
338 .unwrap()
339 .as_str()
340 .unwrap()
341 .to_string();
342 let album = document
343 .get_first(album_field)
344 .unwrap()
345 .as_str()
346 .unwrap()
347 .to_string();
348 let album_artist = document
349 .get_first(album_artist_field)
350 .unwrap()
351 .as_str()
352 .unwrap()
353 .to_string();
354 let bitrate = document.get_first(bitrate_field).unwrap().as_i64().unwrap() as u32;
355 let composer = document
356 .get_first(composer_field)
357 .unwrap()
358 .as_str()
359 .unwrap()
360 .to_string();
361 let disc_number = document
362 .get_first(disc_number_field)
363 .unwrap()
364 .as_i64()
365 .unwrap() as u64;
366 let filesize = document
367 .get_first(filesize_field)
368 .unwrap()
369 .as_i64()
370 .unwrap() as u64;
371 let frequency = document
372 .get_first(frequency_field)
373 .unwrap()
374 .as_i64()
375 .unwrap() as u64;
376 let length = document.get_first(length_field).unwrap().as_i64().unwrap() as u64;
377 let track_number = document
378 .get_first(track_number_field)
379 .unwrap()
380 .as_i64()
381 .unwrap() as u64;
382 let year = document.get_first(year_field).unwrap().as_i64().unwrap() as i32;
383 let year_string = document
384 .get_first(year_string_field)
385 .unwrap()
386 .as_str()
387 .unwrap()
388 .to_string();
389 let genre = document
390 .get_first(genre_field)
391 .unwrap()
392 .as_str()
393 .unwrap()
394 .to_string();
395 let album_art = match document.get_first(album_art_field) {
396 Some(album_art) => album_art.as_str(),
397 None => None,
398 };
399 let album_art = match album_art {
400 Some("") => None,
401 Some(album_art) => Some(album_art.to_string()),
402 None => None,
403 };
404 let artist_id = match document.get_first(artist_id_field) {
405 Some(artist_id) => Some(artist_id.as_str().unwrap().to_string()),
406 None => None,
407 };
408 let album_id = match document.get_first(album_id_field) {
409 Some(album_id) => Some(album_id.as_str().unwrap().to_string()),
410 None => None,
411 };
412 let album_id = match album_id {
413 Some(album_id) => Some(album_id.to_string()),
414 None => None,
415 };
416 let genre_id = match document.get_first(genre_id_field) {
417 Some(genre_id) => Some(genre_id.as_str().unwrap().to_string()),
418 None => None,
419 };
420
421 Self {
422 id: Some(id),
423 path,
424 title,
425 artist,
426 album,
427 album_artist,
428 bitrate,
429 composer,
430 discnum: disc_number as i32,
431 filesize,
432 frequency,
433 length,
434 tracknum: track_number as i32,
435 year,
436 year_string,
437 genre,
438 album_art,
439 artist_id,
440 album_id,
441 genre_id,
442 ..Default::default()
443 }
444 }
445}