Skip to main content

mecomp_prost/
conversions.rs

1//! Conversions between prost-generated types and core types.
2
3use std::time::Duration;
4
5use mecomp_storage::db::schemas::dynamic::query::Compile;
6
7#[allow(clippy::cast_possible_wrap)]
8#[must_use]
9pub fn convert_std_duration(duration: Duration) -> prost_types::Duration {
10    prost_types::Duration {
11        seconds: duration.as_secs().clamp(0, i64::MAX as u64) as i64,
12        nanos: duration.subsec_nanos().clamp(0, i32::MAX as u32) as i32,
13    }
14}
15
16impl From<crate::Song> for mecomp_storage::db::schemas::song::Song {
17    fn from(value: crate::Song) -> Self {
18        Self {
19            id: mecomp_storage::db::schemas::RecordId::from(value.id).into(),
20            title: value.title,
21            artist: value.artists.into(),
22            album_artist: value.album_artists.into(),
23            album: value.album,
24            genre: value.genres.into(),
25            runtime: value.runtime.normalized().try_into().unwrap_or_default(),
26            track: value.track,
27            disc: value.disc,
28            release_year: value.release_year,
29            extension: value.extension,
30            path: value.path.into(),
31        }
32    }
33}
34
35impl From<mecomp_storage::db::schemas::song::Song> for crate::Song {
36    fn from(value: mecomp_storage::db::schemas::song::Song) -> Self {
37        Self {
38            id: crate::RecordId::new(value.id.table(), value.id.key()),
39            title: value.title,
40            artists: value.artist.into(),
41            album_artists: value.album_artist.into(),
42            album: value.album,
43            genres: value.genre.into(),
44            runtime: convert_std_duration(value.runtime),
45            track: value.track,
46            disc: value.disc,
47            release_year: value.release_year,
48            extension: value.extension,
49            path: format!("{}", value.path.display()),
50        }
51    }
52}
53
54impl From<crate::SongBrief> for mecomp_storage::db::schemas::song::SongBrief {
55    fn from(value: crate::SongBrief) -> Self {
56        Self {
57            id: mecomp_storage::db::schemas::RecordId::from(value.id).into(),
58            title: value.title,
59            artist: value.artists.into(),
60            album_artist: value.album_artists.into(),
61            album: value.album,
62            genre: value.genres.into(),
63            runtime: value.runtime.normalized().try_into().unwrap_or_default(),
64            track: value.track,
65            disc: value.disc,
66            release_year: value.release_year,
67            path: value.path.into(),
68        }
69    }
70}
71
72impl From<mecomp_storage::db::schemas::song::SongBrief> for crate::SongBrief {
73    fn from(value: mecomp_storage::db::schemas::song::SongBrief) -> Self {
74        Self {
75            id: crate::RecordId::new(value.id.table(), value.id.key()),
76            title: value.title,
77            artists: value.artist.into(),
78            album_artists: value.album_artist.into(),
79            album: value.album,
80            genres: value.genre.into(),
81            runtime: convert_std_duration(value.runtime),
82            track: value.track,
83            disc: value.disc,
84            release_year: value.release_year,
85            path: format!("{}", value.path.display()),
86        }
87    }
88}
89
90impl From<mecomp_storage::db::schemas::song::Song> for crate::SongBrief {
91    fn from(value: mecomp_storage::db::schemas::song::Song) -> Self {
92        Self {
93            id: crate::RecordId::new(value.id.table(), value.id.key()),
94            title: value.title,
95            artists: value.artist.into(),
96            album_artists: value.album_artist.into(),
97            album: value.album,
98            genres: value.genre.into(),
99            runtime: convert_std_duration(value.runtime),
100            track: value.track,
101            disc: value.disc,
102            release_year: value.release_year,
103            path: format!("{}", value.path.display()),
104        }
105    }
106}
107
108impl From<crate::Song> for crate::SongBrief {
109    fn from(value: crate::Song) -> Self {
110        Self {
111            id: value.id,
112            title: value.title,
113            artists: value.artists,
114            album_artists: value.album_artists,
115            album: value.album,
116            genres: value.genres,
117            runtime: value.runtime,
118            track: value.track,
119            disc: value.disc,
120            release_year: value.release_year,
121            path: value.path,
122        }
123    }
124}
125
126impl From<crate::RepeatMode> for mecomp_core::state::RepeatMode {
127    fn from(value: crate::RepeatMode) -> Self {
128        match value {
129            crate::RepeatMode::None | crate::RepeatMode::Unspecified => Self::None,
130            crate::RepeatMode::One => Self::One,
131            crate::RepeatMode::All => Self::All,
132        }
133    }
134}
135
136impl From<mecomp_core::state::RepeatMode> for crate::RepeatMode {
137    fn from(val: mecomp_core::state::RepeatMode) -> Self {
138        match val {
139            mecomp_core::state::RepeatMode::None => Self::None,
140            mecomp_core::state::RepeatMode::One => Self::One,
141            mecomp_core::state::RepeatMode::All => Self::All,
142        }
143    }
144}
145
146impl From<crate::PlaybackStatus> for mecomp_core::state::Status {
147    fn from(value: crate::PlaybackStatus) -> Self {
148        match value {
149            crate::PlaybackStatus::Unspecified | crate::PlaybackStatus::Stopped => Self::Stopped,
150            crate::PlaybackStatus::Playing => Self::Playing,
151            crate::PlaybackStatus::Paused => Self::Paused,
152        }
153    }
154}
155
156impl From<mecomp_core::state::Status> for crate::PlaybackStatus {
157    fn from(val: mecomp_core::state::Status) -> Self {
158        match val {
159            mecomp_core::state::Status::Stopped => Self::Stopped,
160            mecomp_core::state::Status::Playing => Self::Playing,
161            mecomp_core::state::Status::Paused => Self::Paused,
162        }
163    }
164}
165
166impl From<crate::StateRuntime> for mecomp_core::state::StateRuntime {
167    fn from(value: crate::StateRuntime) -> Self {
168        Self {
169            seek_position: value
170                .seek_position
171                .normalized()
172                .try_into()
173                .unwrap_or_default(),
174            seek_percent: mecomp_core::state::Percent::new(value.seek_percent),
175            duration: value.duration.normalized().try_into().unwrap_or_default(),
176        }
177    }
178}
179
180impl From<mecomp_core::state::StateRuntime> for crate::StateRuntime {
181    fn from(value: mecomp_core::state::StateRuntime) -> Self {
182        Self {
183            seek_position: convert_std_duration(value.seek_position),
184            seek_percent: value.seek_percent.into_inner(),
185            duration: convert_std_duration(value.duration),
186        }
187    }
188}
189
190impl From<crate::StateAudio> for mecomp_core::state::StateAudio {
191    #[allow(clippy::cast_possible_truncation)]
192    fn from(value: crate::StateAudio) -> Self {
193        Self {
194            queue: value.queue.into_iter().map(Into::into).collect(),
195            queue_position: value.queue_position.map(|v| v as usize),
196            current_song: value.current_song.map(Into::into),
197            repeat_mode: crate::RepeatMode::try_from(value.repeat_mode)
198                .map(Into::into)
199                .unwrap_or_default(),
200            runtime: value.runtime.map(Into::into),
201            status: crate::PlaybackStatus::try_from(value.status)
202                .map(Into::into)
203                .unwrap_or_default(),
204            muted: value.muted,
205            volume: value.volume,
206        }
207    }
208}
209
210impl From<mecomp_core::state::StateAudio> for crate::StateAudio {
211    fn from(value: mecomp_core::state::StateAudio) -> Self {
212        Self {
213            queue: value.queue.into_iter().map(Into::into).collect(),
214            queue_position: value.queue_position.map(|v| v as u64),
215            current_song: value.current_song.map(Into::into),
216            repeat_mode: crate::RepeatMode::from(value.repeat_mode) as i32,
217            runtime: value.runtime.map(Into::into),
218            status: crate::PlaybackStatus::from(value.status) as i32,
219            muted: value.muted,
220            volume: value.volume,
221        }
222    }
223}
224
225impl From<mecomp_storage::db::schemas::RecordId> for crate::RecordId {
226    fn from(value: mecomp_storage::db::schemas::RecordId) -> Self {
227        Self {
228            id: value.id.to_string(),
229            tb: value.tb,
230        }
231    }
232}
233
234impl From<crate::RecordId> for mecomp_storage::db::schemas::RecordId {
235    fn from(value: crate::RecordId) -> Self {
236        Self {
237            id: mecomp_storage::db::schemas::Id::String(value.id),
238            tb: value.tb,
239        }
240    }
241}
242
243impl From<crate::SeekType> for mecomp_core::state::SeekType {
244    fn from(value: crate::SeekType) -> Self {
245        match value {
246            crate::SeekType::Unspecified | crate::SeekType::Absolute => Self::Absolute,
247            crate::SeekType::RelativeForwards => Self::RelativeForwards,
248            crate::SeekType::RelativeBackwards => Self::RelativeBackwards,
249        }
250    }
251}
252
253impl From<mecomp_core::state::SeekType> for crate::SeekType {
254    fn from(val: mecomp_core::state::SeekType) -> Self {
255        match val {
256            mecomp_core::state::SeekType::Absolute => Self::Absolute,
257            mecomp_core::state::SeekType::RelativeForwards => Self::RelativeForwards,
258            mecomp_core::state::SeekType::RelativeBackwards => Self::RelativeBackwards,
259        }
260    }
261}
262
263impl<T> From<T> for crate::Ulid
264where
265    T: Into<String>,
266{
267    fn from(value: T) -> Self {
268        Self::new(value.into())
269    }
270}
271
272impl From<crate::RecordId> for crate::Ulid {
273    fn from(value: crate::RecordId) -> Self {
274        Self { id: value.id }
275    }
276}
277
278impl From<mecomp_storage::db::schemas::artist::Artist> for crate::Artist {
279    fn from(value: mecomp_storage::db::schemas::artist::Artist) -> Self {
280        Self {
281            id: crate::RecordId::new(value.id.table(), value.id.key()),
282            name: value.name,
283            runtime: convert_std_duration(value.runtime),
284            album_count: value.album_count,
285            song_count: value.song_count,
286        }
287    }
288}
289
290impl From<mecomp_storage::db::schemas::artist::Artist> for crate::ArtistBrief {
291    fn from(value: mecomp_storage::db::schemas::artist::Artist) -> Self {
292        Self {
293            id: crate::RecordId::new(value.id.table(), value.id.key()),
294            name: value.name,
295        }
296    }
297}
298
299impl From<mecomp_storage::db::schemas::artist::ArtistBrief> for crate::ArtistBrief {
300    fn from(value: mecomp_storage::db::schemas::artist::ArtistBrief) -> Self {
301        Self {
302            id: crate::RecordId::new(value.id.table(), value.id.key()),
303            name: value.name,
304        }
305    }
306}
307
308impl From<crate::Artist> for crate::ArtistBrief {
309    fn from(value: crate::Artist) -> Self {
310        Self {
311            id: value.id,
312            name: value.name,
313        }
314    }
315}
316
317impl From<mecomp_storage::db::schemas::album::Album> for crate::Album {
318    fn from(value: mecomp_storage::db::schemas::album::Album) -> Self {
319        Self {
320            id: crate::RecordId::new(value.id.table(), value.id.key()),
321            title: value.title,
322            artists: value.artist.into(),
323            release: value.release,
324            runtime: convert_std_duration(value.runtime),
325            song_count: value.song_count,
326            discs: value.discs,
327            genres: value.genre.into(),
328        }
329    }
330}
331
332impl From<mecomp_storage::db::schemas::album::AlbumBrief> for crate::AlbumBrief {
333    fn from(value: mecomp_storage::db::schemas::album::AlbumBrief) -> Self {
334        Self {
335            id: crate::RecordId::new(value.id.table(), value.id.key()),
336            title: value.title,
337            artists: value.artist.into(),
338            release: value.release,
339            discs: value.discs,
340            genres: value.genre.into(),
341        }
342    }
343}
344
345impl From<mecomp_storage::db::schemas::album::Album> for crate::AlbumBrief {
346    fn from(value: mecomp_storage::db::schemas::album::Album) -> Self {
347        Self {
348            id: crate::RecordId::new(value.id.table(), value.id.key()),
349            title: value.title,
350            artists: value.artist.into(),
351            release: value.release,
352            discs: value.discs,
353            genres: value.genre.into(),
354        }
355    }
356}
357
358impl From<crate::Album> for crate::AlbumBrief {
359    fn from(value: crate::Album) -> Self {
360        Self {
361            id: value.id,
362            title: value.title,
363            artists: value.artists,
364            release: value.release,
365            discs: value.discs,
366            genres: value.genres,
367        }
368    }
369}
370
371impl From<mecomp_storage::db::schemas::playlist::Playlist> for crate::Playlist {
372    fn from(value: mecomp_storage::db::schemas::playlist::Playlist) -> Self {
373        Self {
374            id: crate::RecordId::new(value.id.table(), value.id.key()),
375            name: value.name,
376            runtime: convert_std_duration(value.runtime),
377            song_count: value.song_count,
378        }
379    }
380}
381impl From<mecomp_storage::db::schemas::playlist::PlaylistBrief> for crate::PlaylistBrief {
382    fn from(value: mecomp_storage::db::schemas::playlist::PlaylistBrief) -> Self {
383        Self {
384            id: crate::RecordId::new(value.id.table(), value.id.key()),
385            name: value.name,
386        }
387    }
388}
389impl From<mecomp_storage::db::schemas::playlist::Playlist> for crate::PlaylistBrief {
390    fn from(value: mecomp_storage::db::schemas::playlist::Playlist) -> Self {
391        Self {
392            id: crate::RecordId::new(value.id.table(), value.id.key()),
393            name: value.name,
394        }
395    }
396}
397
398impl From<crate::Playlist> for crate::PlaylistBrief {
399    fn from(value: crate::Playlist) -> Self {
400        Self {
401            id: value.id,
402            name: value.name,
403        }
404    }
405}
406
407impl From<mecomp_storage::db::schemas::collection::Collection> for crate::Collection {
408    fn from(value: mecomp_storage::db::schemas::collection::Collection) -> Self {
409        Self {
410            id: crate::RecordId::new(value.id.table(), value.id.key()),
411            name: value.name,
412            runtime: convert_std_duration(value.runtime),
413            song_count: value.song_count,
414        }
415    }
416}
417
418impl From<mecomp_storage::db::schemas::collection::CollectionBrief> for crate::CollectionBrief {
419    fn from(value: mecomp_storage::db::schemas::collection::CollectionBrief) -> Self {
420        Self {
421            id: crate::RecordId::new(value.id.table(), value.id.key()),
422            name: value.name,
423        }
424    }
425}
426
427impl From<crate::Collection> for crate::CollectionBrief {
428    fn from(value: crate::Collection) -> Self {
429        Self {
430            id: value.id,
431            name: value.name,
432        }
433    }
434}
435
436impl From<mecomp_storage::db::schemas::dynamic::DynamicPlaylist> for crate::DynamicPlaylist {
437    fn from(value: mecomp_storage::db::schemas::dynamic::DynamicPlaylist) -> Self {
438        Self {
439            id: crate::RecordId::new(value.id.table(), value.id.key()),
440            name: value.name,
441            query: value.query.compile_for_storage(),
442        }
443    }
444}