this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat(scrobble): accept a list of artist names and MB IDs in args

+87 -16
+87 -16
src/main.rs
··· 114 114 #[arg(short, long)] 115 115 duration: Option<i64>, 116 116 117 - /// The artist name 117 + /// A comma-separated list of artist name 118 118 #[arg(short, long)] 119 - artist_name: Option<String>, 119 + artist_names: Option<String>, 120 120 121 - /// The MusicBrainz ID of the artist 121 + /// A comma-separated list of artist MusicBrainz IDs 122 122 #[arg(long)] 123 - artist_mb_id: Option<String>, 123 + artist_mb_ids: Option<String>, 124 124 125 125 /// The name of the release/album 126 126 #[arg(short, long)] ··· 210 210 format!("v{}", env!("CARGO_PKG_VERSION")) 211 211 } 212 212 213 + fn parse_artist_list( 214 + artist_names: Option<String>, 215 + artist_mb_ids: Option<String>, 216 + ) -> Result<Option<Vec<Artist>>, OnyxError> { 217 + Ok(match artist_names { 218 + Some(names) => { 219 + let mut artists = Vec::new(); 220 + 221 + let names: Vec<&str> = names.split(",").collect(); 222 + for name in names { 223 + let name = name.trim(); 224 + 225 + if name.is_empty() { 226 + continue; 227 + } 228 + 229 + artists.push(Artist { 230 + artist_name: name.to_owned(), 231 + artist_mb_id: None, 232 + }); 233 + } 234 + 235 + if let Some(mb_ids) = artist_mb_ids { 236 + let mb_ids: Vec<&str> = mb_ids.split(",").collect(); 237 + 238 + if mb_ids.len() > artists.len() { 239 + return Err(OnyxError::Parse( 240 + "cannot be more `artist_mb_ids` than `artist_names`".into(), 241 + )); 242 + } 243 + 244 + for i in 0..mb_ids.len() { 245 + let id = mb_ids[i].trim(); 246 + 247 + if !id.is_empty() { 248 + artists[i].artist_mb_id = Some(id.to_owned()); 249 + } 250 + } 251 + } 252 + 253 + Some(artists) 254 + } 255 + None => None, 256 + }) 257 + } 258 + 213 259 async fn run_onyx() -> Result<(), OnyxError> { 214 260 let mut matches = get_command().get_matches(); 215 261 let args = Args::from_arg_matches_mut(&mut matches).unwrap(); ··· 290 336 track_mb_id, 291 337 recording_mb_id, 292 338 duration, 293 - artist_name, 294 - artist_mb_id, 339 + artist_names, 340 + artist_mb_ids, 295 341 release_name, 296 342 release_mb_id, 297 343 origin_url, ··· 300 346 track_discriminant, 301 347 release_discriminant, 302 348 } => { 303 - let artist = artist_name.map(|a| Artist { 304 - artist_name: a, 305 - artist_mb_id, 306 - }); 307 - 308 - let artists = if let Some(artist) = artist { 309 - Some(vec![artist]) 310 - } else { 311 - None 312 - }; 349 + let artists = parse_artist_list(artist_names, artist_mb_ids)?; 313 350 314 351 let track = Play { 315 352 track_name, ··· 420 457 std::process::exit(1); 421 458 } 422 459 } 460 + 461 + #[cfg(test)] 462 + mod tests { 463 + use crate::*; 464 + 465 + #[test] 466 + fn test_parse_artists() { 467 + let artist_names = "Test 1 , Test 2 , Test 3, Test 4, "; 468 + let artist_mb_ids = "ABCD, 1234, DCBA"; 469 + 470 + match parse_artist_list( 471 + Some(artist_names.to_string()), 472 + Some(artist_mb_ids.to_string()), 473 + ) { 474 + Ok(l) => { 475 + let artists = l.unwrap(); 476 + 477 + assert!(artists.len() == 4); 478 + 479 + assert!(artists[0].artist_name == "Test 1"); 480 + assert!(artists[0].artist_mb_id.as_ref().unwrap() == "ABCD"); 481 + assert!(artists[1].artist_name == "Test 2"); 482 + assert!(artists[1].artist_mb_id.as_ref().unwrap() == "1234"); 483 + assert!(artists[2].artist_name == "Test 3"); 484 + assert!(artists[2].artist_mb_id.as_ref().unwrap() == "DCBA"); 485 + assert!(artists[3].artist_name == "Test 4"); 486 + assert!(artists[3].artist_mb_id.is_none()); 487 + } 488 + Err(e) => { 489 + panic!("parse_artist_list: {e}"); 490 + } 491 + } 492 + } 493 + }