audio tagging utilities

add validations

Stella 246eafff 1d6313c8

Changed files
+17 -3
src
+17 -3
src/main.rs
··· 48 title: String, 49 artist: String, 50 album: Option<String>, 51 cover_bytes: Option<u64>, 52 } 53 54 impl AudioFileEntry { 55 - fn to_summary(&self) -> AudioFileSummary { 56 let title = self.tags.title().unwrap_or("Unknown").to_string(); 57 let artist = self.tags.artist().unwrap_or("Unknown").to_string(); 58 ··· 64 None => (None, None), 65 }; 66 67 AudioFileSummary { 68 path: self.path.clone(), 69 title, 70 artist, 71 album, 72 cover_bytes: cover_size, 73 } 74 } 75 } ··· 311 match args.output { 312 Output::Json => { 313 // pretty JSON array 314 - let summaries: Vec<_> = audio_files.into_iter().map(|e| e.to_summary()).collect(); 315 match serde_json::to_string_pretty(&summaries) { 316 Ok(s) => println!("{}", s), 317 Err(e) => eprintln!("Failed to serialize summaries to pretty JSON: {}", e), ··· 330 match args.output { 331 Output::Debug => println!("{:?}", entry), 332 Output::Json => { 333 - let summary = entry.to_summary(); 334 match serde_json::to_string(&summary) { 335 Ok(s) => println!("{}", s), 336 Err(e) => eprintln!("Failed to serialize JSON for {}: {}", entry.path.display(), e),
··· 48 title: String, 49 artist: String, 50 album: Option<String>, 51 + #[serde(skip_serializing_if = "Option::is_none")] 52 cover_bytes: Option<u64>, 53 + #[serde(skip_serializing_if = "Vec::is_empty")] 54 + validation_errors: Vec<String>, 55 } 56 57 impl AudioFileEntry { 58 + fn to_summary_with_validators(&self, validators: Option<&[Box<dyn Validator>]>) -> AudioFileSummary { 59 let title = self.tags.title().unwrap_or("Unknown").to_string(); 60 let artist = self.tags.artist().unwrap_or("Unknown").to_string(); 61 ··· 67 None => (None, None), 68 }; 69 70 + // collect validation errors if validators provided 71 + let mut errors = Vec::new(); 72 + if let Some(vals) = validators { 73 + for v in vals.iter() { 74 + if let Some(reason) = v.validate(self) { 75 + errors.push(reason); 76 + } 77 + } 78 + } 79 + 80 AudioFileSummary { 81 path: self.path.clone(), 82 title, 83 artist, 84 album, 85 cover_bytes: cover_size, 86 + validation_errors: errors, 87 } 88 } 89 } ··· 325 match args.output { 326 Output::Json => { 327 // pretty JSON array 328 + let summaries: Vec<_> = audio_files.into_iter().map(|e| e.to_summary_with_validators(Some(&validators))).collect(); 329 match serde_json::to_string_pretty(&summaries) { 330 Ok(s) => println!("{}", s), 331 Err(e) => eprintln!("Failed to serialize summaries to pretty JSON: {}", e), ··· 344 match args.output { 345 Output::Debug => println!("{:?}", entry), 346 Output::Json => { 347 + let summary = entry.to_summary_with_validators(Some(&validators)); 348 match serde_json::to_string(&summary) { 349 Ok(s) => println!("{}", s), 350 Err(e) => eprintln!("Failed to serialize JSON for {}: {}", entry.path.display(), e),