Formatting

This commit is contained in:
Connor Johnstone
2026-03-18 15:37:21 -04:00
parent d09557d953
commit d358b79a6b
3 changed files with 59 additions and 29 deletions

View File

@@ -82,7 +82,10 @@ async fn main() -> anyhow::Result<()> {
} else if results.is_empty() {
println!("No artists found.");
} else {
println!("{:<40} {:<8} {:<5} {}", "NAME", "COUNTRY", "SCORE", "DISAMBIGUATION");
println!(
"{:<40} {:<8} {:<5} DISAMBIGUATION",
"NAME", "COUNTRY", "SCORE"
);
for r in &results {
println!(
"{:<40} {:<8} {:<5} {}",
@@ -104,7 +107,10 @@ async fn main() -> anyhow::Result<()> {
} else if results.is_empty() {
println!("No albums found.");
} else {
println!("{:<35} {:<25} {:<6} {:<5}", "TITLE", "ARTIST", "YEAR", "SCORE");
println!(
"{:<35} {:<25} {:<6} {:<5}",
"TITLE", "ARTIST", "YEAR", "SCORE"
);
for r in &results {
println!(
"{:<35} {:<25} {:<6} {:<5}",
@@ -126,13 +132,19 @@ async fn main() -> anyhow::Result<()> {
} else if results.is_empty() {
println!("No tracks found.");
} else {
println!("{:<35} {:<25} {:<25} {:<5}", "TITLE", "ARTIST", "ALBUM", "SCORE");
println!(
"{:<35} {:<25} {:<25} {:<5}",
"TITLE", "ARTIST", "ALBUM", "SCORE"
);
for r in &results {
println!(
"{:<35} {:<25} {:<25} {:<5}",
truncate(&r.title, 35),
truncate(&r.artist, 25),
r.album.as_deref().map(|a| truncate(a, 25)).unwrap_or_default(),
r.album
.as_deref()
.map(|a| truncate(a, 25))
.unwrap_or_default(),
r.score,
);
}

View File

@@ -1,5 +1,5 @@
use shanty_tag::provider::MetadataProvider;
use shanty_tag::MusicBrainzClient;
use shanty_tag::provider::MetadataProvider;
use crate::error::SearchResult;
use crate::provider::{
@@ -20,11 +20,7 @@ impl MusicBrainzSearch {
}
impl SearchProvider for MusicBrainzSearch {
async fn search_artist(
&self,
query: &str,
limit: u32,
) -> SearchResult<Vec<ArtistResult>> {
async fn search_artist(&self, query: &str, limit: u32) -> SearchResult<Vec<ArtistResult>> {
let results = self.client.search_artist(query, limit).await?;
Ok(results
.into_iter()
@@ -55,7 +51,11 @@ impl SearchProvider for MusicBrainzSearch {
title: r.title,
artist: r.artist,
artist_id: r.artist_mbid,
year: r.date.as_deref().and_then(|d| d.split('-').next()).map(String::from),
year: r
.date
.as_deref()
.and_then(|d| d.split('-').next())
.map(String::from),
track_count: r.track_count,
score: r.score,
})
@@ -85,10 +85,7 @@ impl SearchProvider for MusicBrainzSearch {
.collect())
}
async fn get_discography(
&self,
artist_id: &str,
) -> SearchResult<Discography> {
async fn get_discography(&self, artist_id: &str) -> SearchResult<Discography> {
let releases = self.client.get_artist_releases(artist_id, 100).await?;
// Try to get the artist name from the first release, or use the MBID

View File

@@ -87,7 +87,10 @@ impl SearchProvider for MockSearch {
})
}
async fn get_release_groups(&self, _artist_id: &str) -> SearchResult<Vec<shanty_search::ReleaseGroupResult>> {
async fn get_release_groups(
&self,
_artist_id: &str,
) -> SearchResult<Vec<shanty_search::ReleaseGroupResult>> {
Ok(vec![])
}
}
@@ -104,14 +107,20 @@ async fn test_search_artist() {
#[tokio::test]
async fn test_search_artist_no_results() {
let provider = MockSearch;
let results = provider.search_artist("Nonexistent Band", 10).await.unwrap();
let results = provider
.search_artist("Nonexistent Band", 10)
.await
.unwrap();
assert!(results.is_empty());
}
#[tokio::test]
async fn test_search_album() {
let provider = MockSearch;
let results = provider.search_album("Dark Side", Some("Pink Floyd"), 10).await.unwrap();
let results = provider
.search_album("Dark Side", Some("Pink Floyd"), 10)
.await
.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].title, "The Dark Side of the Moon");
}
@@ -119,10 +128,16 @@ async fn test_search_album() {
#[tokio::test]
async fn test_search_track() {
let provider = MockSearch;
let results = provider.search_track("Time", Some("Pink Floyd"), 10).await.unwrap();
let results = provider
.search_track("Time", Some("Pink Floyd"), 10)
.await
.unwrap();
assert_eq!(results.len(), 1);
assert_eq!(results[0].title, "Time");
assert_eq!(results[0].album.as_deref(), Some("The Dark Side of the Moon"));
assert_eq!(
results[0].album.as_deref(),
Some("The Dark Side of the Moon")
);
}
#[tokio::test]
@@ -162,18 +177,25 @@ async fn test_cache_roundtrip() {
}];
// Cache miss
let cached: Option<Vec<ArtistResult>> =
cache::get_cached(Some(db.conn()), "test:artist:query").await.unwrap();
let cached: Option<Vec<ArtistResult>> = cache::get_cached(Some(db.conn()), "test:artist:query")
.await
.unwrap();
assert!(cached.is_none());
// Store
cache::set_cached(Some(db.conn()), "test:artist:query", "musicbrainz", &results)
.await
.unwrap();
cache::set_cached(
Some(db.conn()),
"test:artist:query",
"musicbrainz",
&results,
)
.await
.unwrap();
// Cache hit
let cached: Option<Vec<ArtistResult>> =
cache::get_cached(Some(db.conn()), "test:artist:query").await.unwrap();
let cached: Option<Vec<ArtistResult>> = cache::get_cached(Some(db.conn()), "test:artist:query")
.await
.unwrap();
assert!(cached.is_some());
assert_eq!(cached.unwrap()[0].name, "Cached Artist");
}
@@ -181,8 +203,7 @@ async fn test_cache_roundtrip() {
#[tokio::test]
async fn test_cache_none_conn() {
// With no DB connection, caching is a no-op
let cached: Option<Vec<ArtistResult>> =
cache::get_cached(None, "anything").await.unwrap();
let cached: Option<Vec<ArtistResult>> = cache::get_cached(None, "anything").await.unwrap();
assert!(cached.is_none());
// set_cached with None conn should not error