1use core::fmt;
4use std::str::FromStr;
5
6impl crate::SearchResult {
7 #[must_use]
8 pub const fn len(&self) -> usize {
9 self.songs.len() + self.albums.len() + self.artists.len()
10 }
11
12 #[must_use]
13 pub const fn is_empty(&self) -> bool {
14 self.len() == 0
15 }
16}
17
18impl crate::SearchRequest {
19 #[must_use]
20 pub fn new(query: impl Into<String>, limit: u64) -> Self {
21 Self {
22 query: query.into(),
23 limit,
24 }
25 }
26}
27
28impl crate::LibraryAnalyzeRequest {
29 #[must_use]
30 pub const fn new(overwrite: bool) -> Self {
31 Self { overwrite }
32 }
33}
34
35impl crate::RecordId {
36 #[allow(clippy::needless_pass_by_value)]
37 pub fn new(tb: impl ToString, id: impl ToString) -> Self {
38 Self {
39 tb: tb.to_string(),
40 id: id.to_string(),
41 }
42 }
43
44 #[must_use]
45 pub fn ulid(&self) -> crate::Ulid {
46 crate::Ulid {
47 id: self.id.clone(),
48 }
49 }
50}
51
52impl<S, U> From<(S, U)> for crate::RecordId
53where
54 S: ToString,
55 U: Into<crate::Ulid>,
56{
57 fn from((tb, id): (S, U)) -> Self {
58 Self::new(tb, id.into())
59 }
60}
61
62impl FromStr for crate::RecordId {
63 type Err = ();
64
65 fn from_str(s: &str) -> Result<Self, Self::Err> {
66 mecomp_storage::db::schemas::RecordId::from_str(s).map(Into::into)
67 }
68}
69
70impl fmt::Display for crate::RecordId {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 write!(f, "{}:{}", self.tb, self.id)
73 }
74}
75
76impl crate::Ulid {
77 #[allow(clippy::needless_pass_by_value)]
78 pub fn new(id: impl ToString) -> Self {
79 Self { id: id.to_string() }
80 }
81}
82
83impl fmt::Display for crate::Ulid {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 self.id.fmt(f)
86 }
87}
88
89impl crate::RecordIdList {
90 #[must_use]
91 pub const fn new(ids: Vec<crate::RecordId>) -> Self {
92 Self { ids }
93 }
94}
95
96impl crate::PlaybackSkipRequest {
97 #[must_use]
98 pub const fn new(amount: u64) -> Self {
99 Self { amount }
100 }
101}
102
103impl crate::PlaybackRepeatRequest {
104 #[must_use]
105 pub fn new(mode: impl Into<crate::RepeatMode>) -> Self {
106 Self {
107 mode: mode.into() as i32,
108 }
109 }
110}
111
112impl crate::PlaybackSeekRequest {
113 #[must_use]
114 #[allow(clippy::cast_possible_wrap)]
115 pub fn new(mode: impl Into<crate::SeekType>, duration: std::time::Duration) -> Self {
116 Self {
117 seek: mode.into() as i32,
118 duration: prost_types::Duration {
119 seconds: duration.as_secs() as i64,
120 nanos: duration.subsec_nanos() as i32,
121 }
122 .normalized(),
123 }
124 }
125}
126
127impl crate::PlaybackVolumeSetRequest {
128 #[must_use]
129 pub const fn new(volume: f32) -> Self {
130 Self { volume }
131 }
132}
133
134impl crate::PlaybackVolumeAdjustRequest {
135 #[must_use]
136 pub const fn new(amount: f32) -> Self {
137 Self { amount }
138 }
139}
140
141impl crate::PlaylistAddRequest {
142 #[must_use]
143 pub fn new(playlist_id: impl Into<crate::Ulid>, record_id: crate::RecordId) -> Self {
144 Self {
145 playlist_id: playlist_id.into(),
146 record_id,
147 }
148 }
149}
150
151impl crate::PlaylistAddListRequest {
152 #[must_use]
153 pub fn new(playlist_id: impl Into<crate::Ulid>, record_ids: Vec<crate::RecordId>) -> Self {
154 Self {
155 playlist_id: playlist_id.into(),
156 record_ids,
157 }
158 }
159}
160
161impl crate::PlaylistRenameRequest {
162 #[must_use]
163 pub fn new(playlist_id: impl Into<crate::Ulid>, new_name: impl Into<String>) -> Self {
164 Self {
165 playlist_id: playlist_id.into(),
166 name: new_name.into(),
167 }
168 }
169}
170
171impl crate::PlaylistRemoveSongsRequest {
172 #[must_use]
173 pub fn new(playlist_id: impl Into<crate::Ulid>, song_ids: Vec<impl Into<crate::Ulid>>) -> Self {
174 Self {
175 playlist_id: playlist_id.into(),
176 song_ids: song_ids.into_iter().map(Into::into).collect(),
177 }
178 }
179}
180
181impl crate::QueueRemoveRangeRequest {
182 #[must_use]
183 pub const fn new(start: u64, end: u64) -> Self {
184 Self { start, end }
185 }
186}
187
188impl crate::QueueSetIndexRequest {
189 #[must_use]
190 pub const fn new(index: u64) -> Self {
191 Self { index }
192 }
193}
194
195impl crate::DynamicPlaylistCreateRequest {
196 #[allow(clippy::needless_pass_by_value)]
197 #[must_use]
198 pub fn new(name: impl ToString, query: impl ToString) -> Self {
199 Self {
200 name: name.to_string(),
201 query: query.to_string(),
202 }
203 }
204}
205
206impl crate::DynamicPlaylistUpdateRequest {
207 #[must_use]
208 pub fn new(id: impl Into<crate::Ulid>, changes: crate::DynamicPlaylistChangeSet) -> Self {
209 Self {
210 id: id.into(),
211 changes,
212 }
213 }
214}
215
216impl crate::DynamicPlaylistChangeSet {
217 #[must_use]
218 pub const fn new() -> Self {
219 Self {
220 new_name: None,
221 new_query: None,
222 }
223 }
224
225 #[must_use]
226 pub fn name(mut self, name: impl Into<String>) -> Self {
227 self.new_name = Some(name.into());
228 self
229 }
230
231 #[must_use]
232 pub fn query(mut self, query: impl Into<String>) -> Self {
233 self.new_query = Some(query.into());
234 self
235 }
236}
237
238impl crate::RadioSimilarRequest {
239 #[must_use]
240 pub const fn new(record_ids: Vec<crate::RecordId>, limit: u32) -> Self {
241 Self { record_ids, limit }
242 }
243}
244
245impl crate::CollectionFreezeRequest {
246 pub fn new(id: impl ToString, name: impl Into<String>) -> Self {
247 Self {
248 id: crate::Ulid::new(id),
249 name: name.into(),
250 }
251 }
252}
253
254impl crate::RegisterListenerRequest {
255 #[must_use]
256 pub fn new(addr: std::net::SocketAddr) -> Self {
257 Self {
258 host: addr.ip().to_string(),
259 port: u32::from(addr.port()),
260 }
261 }
262}
263
264impl crate::Path {
265 #[must_use]
266 pub fn new(path: impl AsRef<std::path::Path>) -> Self {
267 Self {
268 path: format!("{}", path.as_ref().display()),
269 }
270 }
271}
272
273impl crate::PlaylistName {
274 #[must_use]
275 pub fn new(name: impl Into<String>) -> Self {
276 Self { name: name.into() }
277 }
278}
279
280impl crate::PlaylistExportRequest {
281 #[must_use]
282 pub fn new(playlist_id: impl Into<crate::Ulid>, path: impl AsRef<std::path::Path>) -> Self {
283 Self {
284 playlist_id: playlist_id.into(),
285 path: format!("{}", path.as_ref().display()),
286 }
287 }
288}
289
290impl crate::PlaylistImportRequest {
291 #[must_use]
292 pub fn new(path: impl AsRef<std::path::Path>) -> Self {
293 Self {
294 path: format!("{}", path.as_ref().display()),
295 name: None,
296 }
297 }
298
299 #[must_use]
300 #[allow(clippy::needless_pass_by_value)]
301 pub fn with_name(path: impl AsRef<std::path::Path>, name: impl ToString) -> Self {
302 Self {
303 path: format!("{}", path.as_ref().display()),
304 name: Some(name.to_string()),
305 }
306 }
307}