Skip to main content

chilen_ipc/
library.rs

1use std::{path::PathBuf, time::Duration};
2
3use serde::{Deserialize, Serialize};
4
5// TODO: Add more tags for this
6/// Struct representing a track from the [music library](MusicLibrary).
7#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
8pub struct Track {
9    /// The path to the audio file.
10    pub path: PathBuf,
11    /// The path to the extracted cover file.
12    pub cover_path: Option<PathBuf>,
13    /// The duration of the track.
14    pub duration: Duration,
15    // TODO: Add an option to split the tag with separators like ",", ";", "/", etc.
16    /// The track artist.
17    pub artist: Option<String>,
18    /// The track title.
19    pub title: Option<String>,
20    /// The track album.
21    pub album: Option<String>,
22    // TODO: Same as with artist
23    /// The track genre.
24    pub genre: Option<String>,
25    // TODO: Add easy access to synced lyrics
26    /// Possibly synchronized lyrics text.
27    pub lyrics: Option<String>,
28    /// Contents of the comment tag.
29    pub comment: Option<String>,
30    pub track: Option<u32>,
31    pub track_total: Option<u32>,
32    pub disc: Option<u32>,
33    pub disc_total: Option<u32>,
34    /// Release year.
35    pub year: Option<u32>,
36}
37
38impl std::fmt::Display for Track {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        write!(
41            f,
42            "{} - {} ({})",
43            self.artist.clone().unwrap_or(String::from("Unknown")),
44            self.title.clone().unwrap_or(String::from("Unknown")),
45            self.path.to_string_lossy()
46        )
47    }
48}
49
50/// Struct representing a playlist in the [music library](MusicLibrary).
51#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
52pub struct Playlist {
53    /// The name of the playlist.
54    ///
55    /// Playlist names are unique.
56    pub name: String,
57    /// The content of the playlist.
58    ///
59    /// All tracks must already be in the [music library](MusicLibrary). If a track is removed from
60    /// the library (eg. by removing an audio file from the music directory and reloading the
61    /// library), it will also be removed from all the playlists.
62    pub tracks: Vec<Track>,
63}
64
65/// Struct representing the contents of the music library.
66#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
67pub struct MusicLibrary {
68    /// The list of playlists in the music library.
69    pub playlists: Vec<Playlist>,
70    /// The list of all tracks in the music library.
71    pub tracks: Vec<Track>,
72}
73
74/// Subcommand of [`Command`](crate::Command) for managing the music library.
75///
76/// The expected response may be different depending on the command sent. If it isn't specified in
77/// the variant documentation, assume [`Response::Ok`](crate::Response::Ok) is the expected
78/// response.
79#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
80pub enum LibraryCommand {
81    /// Create a new playlist, optionally with some tracks in it.
82    NewPlaylist {
83        /// The name for the new playlist. Must not already exist in the music library.
84        ///
85        /// If a playlist with the specified name already exists,
86        /// [`Error::PlaylistExists`](crate::Error::PlaylistExists) will be returned, and no
87        /// changes to the [music library](MusicLibrary) will be made.
88        name: String,
89        /// Optional list of paths to tracks to be added to the playlist.
90        ///
91        /// This command will fail if any of the tracks are not registered in the
92        /// [music library](MusicLibrary), or if the list contains duplicates.
93        tracks: Option<Vec<PathBuf>>,
94    },
95    /// Import a playlist from an M3U8 file.
96    PlaylistFromM3U8 {
97        /// The name for the imported playlist. Must not already exist in the music library.
98        ///
99        /// If left unspecified, it will be derived from the name set in the M3U8 playlist.
100        ///
101        /// If a playlist with the specified name already exists,
102        /// [`Error::PlaylistExists`](crate::Error::PlaylistExists) will be returned, and no changes
103        /// to the [music library](MusicLibrary) will be made.
104        name: Option<String>,
105        /// The path to the M3U8 file to import.
106        m3u8_file: PathBuf,
107    },
108    /// Export a playlist from the music library as an M3U8 file.
109    ExportPlaylistToM3U {
110        /// The name of the playlist to export.
111        ///
112        /// /// If no such playlist exists in the music library,
113        /// [`Error::UnknownPlaylist`](crate::Error::UnknownPlaylist) will be returned, and no
114        /// changes to the [music library](MusicLibrary) will be made.
115        name: String,
116        /// File path to which export the playlist file.
117        path: PathBuf,
118    },
119    /// Delete playlists from the music library.
120    DeletePlaylists {
121        /// List of the playlists to delete.
122        ///
123        /// If any of the provided playlists don't exist in the music library,
124        /// [`Error::UnkownPlaylist`](crate::Error::UnknownPlaylist) will be returned, and no changes to the
125        /// [music library](MusicLibrary) will be made.
126        names: Vec<String>,
127    },
128    /// Add tracks to an already existing playlist.
129    AddTracksToPlaylist {
130        /// The name of the playlist to add tracks to.
131        ///
132        /// If no such playlist exists in the music library,
133        /// [`Error::UnknownPlaylist`](crate::Error::UnknownPlaylist) will be returned, and no
134        /// changes to the [music library](MusicLibrary) will be made.
135        name: String,
136        /// List of paths to tracks to add to the playlist.
137        ///
138        /// **Note:** the daemon will return an error if any of the tracks are not registered in
139        /// the music library or if the list contains duplicates.
140        tracks: Vec<PathBuf>,
141    },
142    /// Remove tracks from a playlist.
143    RemoveTracksFromPlaylist {
144        /// The name of the playlist to remove tracks from.
145        ///
146        /// If a playlist with the specified name doesn't exist in the music library,
147        /// [`Error::UnknownPlaylist`](crate::Error::UnknownPlaylist) will be returned, and no
148        /// changes to the [music library](MusicLibrary) will be made.
149        name: String,
150        /// The list of track indices in the playlist to remove.
151        ///
152        /// Eg. to remove the first track you would pass `[0]`, to remove the first three
153        /// `[0, 1, 2]`, etc.
154        ///
155        /// If one or more of the indices is out of range,
156        /// [`Error::IndexOutOfBounds`](crate::Error::IndexOutOfBounds) will be returned, and no
157        /// changes to the [music library](MusicLibrary) will be made.
158        ids: Vec<usize>,
159    },
160    /// Get the contents of the [music library](MusicLibrary).
161    ///
162    /// The daemon will respond to this with [`Response::Library`](crate::Response::Library) if
163    /// successful.
164    GetLibrary,
165    /// Reload the library and rebuild the cache ignoring already cached covers.
166    ///
167    /// Will take more time than just reloading the cache.
168    Rebuild,
169    /// Reload the library using cached data if possible.
170    ///
171    /// This can be used to discover newly added tracks.
172    Reload,
173}