utils.rs (2933B)
1 use crate::constants::SUPPORTED_EXTENSIONS; 2 use crate::db::TrackReport; 3 use std::ffi::OsStr; 4 use std::path::Path; 5 6 pub fn is_supported_audio_file(path: &Path) -> bool { 7 path.is_file() && path.extension().is_some_and(is_supported_extension) 8 } 9 10 pub fn is_supported_extension(ext: &OsStr) -> bool { 11 let ext_lower = ext.to_string_lossy().to_lowercase(); 12 SUPPORTED_EXTENSIONS.contains(&*ext_lower) 13 } 14 15 pub fn print_entries(entries: &[(String, TrackReport)], empty_msg: &str, count_suffix: &str) { 16 if entries.is_empty() { 17 eprintln!("{empty_msg}"); 18 } else { 19 for (key, report) in entries { 20 println!("{key}: {report}"); 21 } 22 println!("\n{} {count_suffix}", entries.len()); 23 } 24 } 25 26 /// Format a primary database key from artist and track name. 27 #[must_use] 28 pub fn format_primary_key(artist: Option<&str>, track: Option<&str>) -> String { 29 format!( 30 "{} - {}", 31 artist.unwrap_or("Unknown"), 32 track.unwrap_or("Unknown") 33 ) 34 } 35 36 #[cfg(test)] 37 mod tests { 38 use super::*; 39 use std::ffi::OsStr; 40 41 #[test] 42 fn supported_extension_is_case_insensitive() { 43 assert!(is_supported_extension(OsStr::new("mp3"))); 44 assert!(is_supported_extension(OsStr::new("MP3"))); 45 assert!(is_supported_extension(OsStr::new("Flac"))); 46 assert!(is_supported_extension(OsStr::new("OGG"))); 47 } 48 49 #[test] 50 fn unsupported_extension_is_rejected() { 51 assert!(!is_supported_extension(OsStr::new("txt"))); 52 assert!(!is_supported_extension(OsStr::new("png"))); 53 assert!(!is_supported_extension(OsStr::new(""))); 54 } 55 56 #[test] 57 fn supported_audio_file_requires_existing_file() { 58 let dir = tempfile::tempdir().unwrap(); 59 60 let audio = dir.path().join("track.flac"); 61 std::fs::write(&audio, b"not really audio").unwrap(); 62 assert!(is_supported_audio_file(&audio)); 63 64 // A directory is never a supported audio file, even with an audio suffix. 65 let fake_dir = dir.path().join("album.mp3"); 66 std::fs::create_dir(&fake_dir).unwrap(); 67 assert!(!is_supported_audio_file(&fake_dir)); 68 69 // A real file with no/unsupported extension is rejected. 70 let doc = dir.path().join("notes.txt"); 71 std::fs::write(&doc, b"hi").unwrap(); 72 assert!(!is_supported_audio_file(&doc)); 73 74 // A path that does not exist is rejected. 75 assert!(!is_supported_audio_file(&dir.path().join("missing.mp3"))); 76 } 77 78 #[test] 79 fn primary_key_uses_unknown_for_missing_parts() { 80 assert_eq!( 81 format_primary_key(Some("Aphex Twin"), Some("Xtal")), 82 "Aphex Twin - Xtal" 83 ); 84 assert_eq!(format_primary_key(None, Some("Xtal")), "Unknown - Xtal"); 85 assert_eq!(format_primary_key(Some("Aphex Twin"), None), "Aphex Twin - Unknown"); 86 assert_eq!(format_primary_key(None, None), "Unknown - Unknown"); 87 } 88 }