Integrate browse API into TUI MB daemon #230

Merged
wojtek merged 15 commits from 160---provide-a-keyboard-shortcut-to-pull-all-release-groups-of-an-artist into main 2024-10-06 15:32:46 +02:00
10 changed files with 89 additions and 86 deletions
Showing only changes of commit 898d2e1469 - Show all commits

View File

@ -290,7 +290,7 @@ mod tests {
machine::tests::{inner, music_hoard}, machine::tests::{inner, music_hoard},
Delta, IApp, IAppAccess, IAppInteractBrowse, MatchOption, MatchStateInfo, Delta, IApp, IAppAccess, IAppInteractBrowse, MatchOption, MatchStateInfo,
}, },
lib::interface::musicbrainz::{self, api::Match, daemon::MockIMbJobSender}, lib::interface::musicbrainz::{self, api::Entity, daemon::MockIMbJobSender},
testmod::COLLECTION, testmod::COLLECTION,
}; };
@ -310,13 +310,13 @@ mod tests {
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let matches: Vec<Match<ArtistMeta>> = vec![]; let matches: Vec<Entity<ArtistMeta>> = vec![];
let fetch_result = MatchStateInfo::artist_search(artist.clone(), matches); let fetch_result = MatchStateInfo::artist_search(artist.clone(), matches);
fetch_tx.send(Ok(fetch_result.clone())).unwrap(); fetch_tx.send(Ok(fetch_result.clone())).unwrap();
assert_eq!(fetch.try_recv(), Err(TryRecvError::Empty)); assert_eq!(fetch.try_recv(), Err(TryRecvError::Empty));
let lookup = Match::item(artist.clone()); let lookup = Entity::new(artist.clone());
let lookup_result = MatchStateInfo::artist_lookup(artist.clone(), lookup); let lookup_result = MatchStateInfo::artist_lookup(artist.clone(), lookup);
lookup_tx.send(Ok(lookup_result.clone())).unwrap(); lookup_tx.send(Ok(lookup_result.clone())).unwrap();
@ -601,7 +601,7 @@ mod tests {
let (tx, rx) = mpsc::channel::<MbApiResult>(); let (tx, rx) = mpsc::channel::<MbApiResult>();
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let artist_match = Match::with_score(COLLECTION[2].meta.clone(), 80); let artist_match = Entity::with_score(COLLECTION[2].meta.clone(), 80);
let artist_match_info = let artist_match_info =
MatchStateInfo::artist_search(artist.clone(), vec![artist_match.clone()]); MatchStateInfo::artist_search(artist.clone(), vec![artist_match.clone()]);
let fetch_result = Ok(artist_match_info); let fetch_result = Ok(artist_match_info);
@ -677,7 +677,7 @@ mod tests {
assert!(matches!(app, AppState::Fetch(_))); assert!(matches!(app, AppState::Fetch(_)));
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let match_info = MatchStateInfo::artist_search::<Match<ArtistMeta>>(artist, vec![]); let match_info = MatchStateInfo::artist_search::<Entity<ArtistMeta>>(artist, vec![]);
let fetch_result = Ok(match_info); let fetch_result = Ok(match_info);
tx.send(fetch_result).unwrap(); tx.send(fetch_result).unwrap();

View File

@ -37,7 +37,7 @@ impl GetInfo for MatchOption<ArtistMeta> {
fn into_info(&self, mut info: Self::InfoType) -> InfoOption<Self::InfoType> { fn into_info(&self, mut info: Self::InfoType) -> InfoOption<Self::InfoType> {
match self { match self {
MatchOption::Some(option) => info.musicbrainz = option.item.info.musicbrainz.clone(), MatchOption::Some(option) => info.musicbrainz = option.entity.info.musicbrainz.clone(),
MatchOption::CannotHaveMbid => info.musicbrainz = MbRefOption::CannotHaveMbid, MatchOption::CannotHaveMbid => info.musicbrainz = MbRefOption::CannotHaveMbid,
MatchOption::ManualInputMbid => return InfoOption::NeedInput, MatchOption::ManualInputMbid => return InfoOption::NeedInput,
} }
@ -50,7 +50,7 @@ impl GetInfo for MatchOption<AlbumMeta> {
fn into_info(&self, mut info: Self::InfoType) -> InfoOption<Self::InfoType> { fn into_info(&self, mut info: Self::InfoType) -> InfoOption<Self::InfoType> {
match self { match self {
MatchOption::Some(option) => info = option.item.info.clone(), MatchOption::Some(option) => info = option.entity.info.clone(),
MatchOption::CannotHaveMbid => info.musicbrainz = MbRefOption::CannotHaveMbid, MatchOption::CannotHaveMbid => info.musicbrainz = MbRefOption::CannotHaveMbid,
MatchOption::ManualInputMbid => return InfoOption::NeedInput, MatchOption::ManualInputMbid => return InfoOption::NeedInput,
} }
@ -271,18 +271,18 @@ mod tests {
IApp, IAppAccess, IAppInput, IApp, IAppAccess, IAppInput,
}, },
lib::interface::musicbrainz::{ lib::interface::musicbrainz::{
api::Match, api::Entity,
daemon::{MbParams, MockIMbJobSender}, daemon::{MbParams, MockIMbJobSender},
}, },
}; };
use super::*; use super::*;
impl<T> Match<T> { impl<T> Entity<T> {
pub fn with_score(item: T, score: u8) -> Self { pub fn with_score(entity: T, score: u8) -> Self {
Match { Entity {
score: Some(score), score: Some(score),
item, entity,
disambiguation: None, disambiguation: None,
} }
} }
@ -302,10 +302,10 @@ mod tests {
let artist = artist_meta(); let artist = artist_meta();
let artist_1 = artist.clone(); let artist_1 = artist.clone();
let artist_match_1 = Match::with_score(artist_1, 100); let artist_match_1 = Entity::with_score(artist_1, 100);
let artist_2 = artist.clone(); let artist_2 = artist.clone();
let mut artist_match_2 = Match::with_score(artist_2, 100); let mut artist_match_2 = Entity::with_score(artist_2, 100);
artist_match_2.disambiguation = Some(String::from("some disambiguation")); artist_match_2.disambiguation = Some(String::from("some disambiguation"));
let list = vec![artist_match_1.clone(), artist_match_2.clone()]; let list = vec![artist_match_1.clone(), artist_match_2.clone()];
@ -314,7 +314,7 @@ mod tests {
fn artist_lookup() -> MatchStateInfo { fn artist_lookup() -> MatchStateInfo {
let artist = artist_meta(); let artist = artist_meta();
let lookup = Match::item(artist.clone()); let lookup = Entity::new(artist.clone());
MatchStateInfo::artist_lookup(artist, lookup) MatchStateInfo::artist_lookup(artist, lookup)
} }
@ -335,12 +335,12 @@ mod tests {
let album = album_meta(); let album = album_meta();
let album_1 = album.clone(); let album_1 = album.clone();
let album_match_1 = Match::with_score(album_1, 100); let album_match_1 = Entity::with_score(album_1, 100);
let mut album_2 = album.clone(); let mut album_2 = album.clone();
album_2.id.title.push_str(" extra title part"); album_2.id.title.push_str(" extra title part");
album_2.info.secondary_types.pop(); album_2.info.secondary_types.pop();
let album_match_2 = Match::with_score(album_2, 100); let album_match_2 = Entity::with_score(album_2, 100);
let list = vec![album_match_1.clone(), album_match_2.clone()]; let list = vec![album_match_1.clone(), album_match_2.clone()];
MatchStateInfo::album_search(artist_id, album, list) MatchStateInfo::album_search(artist_id, album, list)
@ -349,7 +349,7 @@ mod tests {
fn album_lookup() -> MatchStateInfo { fn album_lookup() -> MatchStateInfo {
let artist_id = ArtistId::new("Artist"); let artist_id = ArtistId::new("Artist");
let album = album_meta(); let album = album_meta();
let lookup = Match::item(album.clone()); let lookup = Entity::new(album.clone());
MatchStateInfo::album_lookup(artist_id, album, lookup) MatchStateInfo::album_lookup(artist_id, album, lookup)
} }
@ -597,7 +597,7 @@ mod tests {
.with(predicate::always(), predicate::eq(requests)) .with(predicate::always(), predicate::eq(requests))
.return_once(|_, _| Ok(())); .return_once(|_, _| Ok(()));
let matches_vec: Vec<Match<ArtistMeta>> = vec![]; let matches_vec: Vec<Entity<ArtistMeta>> = vec![];
let artist_match = MatchStateInfo::artist_search(artist.clone(), matches_vec); let artist_match = MatchStateInfo::artist_search(artist.clone(), matches_vec);
let matches = AppMachine::match_state( let matches = AppMachine::match_state(
inner_with_mb(music_hoard(vec![]), mb_job_sender), inner_with_mb(music_hoard(vec![]), mb_job_sender),
@ -630,7 +630,7 @@ mod tests {
.with(predicate::always(), predicate::eq(requests)) .with(predicate::always(), predicate::eq(requests))
.return_once(|_, _| Ok(())); .return_once(|_, _| Ok(()));
let matches_vec: Vec<Match<AlbumMeta>> = vec![]; let matches_vec: Vec<Entity<AlbumMeta>> = vec![];
let album_match = let album_match =
MatchStateInfo::album_search(artist_id.clone(), album.clone(), matches_vec); MatchStateInfo::album_search(artist_id.clone(), album.clone(), matches_vec);
let matches = AppMachine::match_state( let matches = AppMachine::match_state(

View File

@ -226,7 +226,10 @@ mod tests {
use crate::tui::{ use crate::tui::{
app::{AppState, IApp, IAppInput, IAppInteractBrowse, InputEvent, MatchStateInfo}, app::{AppState, IApp, IAppInput, IAppInteractBrowse, InputEvent, MatchStateInfo},
lib::{interface::musicbrainz::{api::Match, daemon::MockIMbJobSender}, MockIMusicHoard}, lib::{
interface::musicbrainz::{api::Entity, daemon::MockIMbJobSender},
MockIMusicHoard,
},
}; };
use super::*; use super::*;
@ -517,7 +520,7 @@ mod tests {
let (_, rx) = mpsc::channel(); let (_, rx) = mpsc::channel();
let fetch = FetchState::new(rx); let fetch = FetchState::new(rx);
let artist = ArtistMeta::new(ArtistId::new("Artist")); let artist = ArtistMeta::new(ArtistId::new("Artist"));
let info = MatchStateInfo::artist_lookup(artist.clone(), Match::item(artist.clone())); let info = MatchStateInfo::artist_lookup(artist.clone(), Entity::new(artist.clone()));
app = app =
AppMachine::match_state(app.unwrap_browse().inner, MatchState::new(info, fetch)).into(); AppMachine::match_state(app.unwrap_browse().inner, MatchState::new(info, fetch)).into();

View File

@ -11,7 +11,7 @@ use musichoard::collection::{
Collection, Collection,
}; };
use crate::tui::lib::interface::musicbrainz::api::Match; use crate::tui::lib::interface::musicbrainz::api::Entity;
pub enum AppState<B, I, R, S, F, M, E, C> { pub enum AppState<B, I, R, S, F, M, E, C> {
Browse(B), Browse(B),
@ -215,13 +215,13 @@ pub type InputPublic<'app> = &'app tui_input::Input;
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub enum MatchOption<T> { pub enum MatchOption<T> {
Some(Match<T>), Some(Entity<T>),
CannotHaveMbid, CannotHaveMbid,
ManualInputMbid, ManualInputMbid,
} }
impl<T> From<Match<T>> for MatchOption<T> { impl<T> From<Entity<T>> for MatchOption<T> {
fn from(value: Match<T>) -> Self { fn from(value: Entity<T>) -> Self {
MatchOption::Some(value) MatchOption::Some(value)
} }
} }

View File

@ -25,7 +25,7 @@ use musichoard::{
}, },
}; };
use crate::tui::lib::interface::musicbrainz::api::{Error, IMusicBrainz, Match, Paged}; use crate::tui::lib::interface::musicbrainz::api::{Entity, Error, IMusicBrainz, Paged};
// GRCOV_EXCL_START // GRCOV_EXCL_START
pub struct MusicBrainz<Http> { pub struct MusicBrainz<Http> {
@ -39,7 +39,7 @@ impl<Http> MusicBrainz<Http> {
} }
impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> { impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
fn lookup_artist(&mut self, mbid: &Mbid) -> Result<Match<ArtistMeta>, Error> { fn lookup_artist(&mut self, mbid: &Mbid) -> Result<Entity<ArtistMeta>, Error> {
let request = LookupArtistRequest::new(mbid); let request = LookupArtistRequest::new(mbid);
let mb_response = self.client.lookup_artist(&request)?; let mb_response = self.client.lookup_artist(&request)?;
@ -47,7 +47,7 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
Ok(from_lookup_artist_response(mb_response)) Ok(from_lookup_artist_response(mb_response))
} }
fn lookup_release_group(&mut self, mbid: &Mbid) -> Result<Match<AlbumMeta>, Error> { fn lookup_release_group(&mut self, mbid: &Mbid) -> Result<Entity<AlbumMeta>, Error> {
let request = LookupReleaseGroupRequest::new(mbid); let request = LookupReleaseGroupRequest::new(mbid);
let mb_response = self.client.lookup_release_group(&request)?; let mb_response = self.client.lookup_release_group(&request)?;
@ -55,7 +55,7 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
Ok(from_lookup_release_group_response(mb_response)) Ok(from_lookup_release_group_response(mb_response))
} }
fn search_artist(&mut self, artist: &ArtistMeta) -> Result<Vec<Match<ArtistMeta>>, Error> { fn search_artist(&mut self, artist: &ArtistMeta) -> Result<Vec<Entity<ArtistMeta>>, Error> {
let query = SearchArtistRequest::new().string(&artist.id.name); let query = SearchArtistRequest::new().string(&artist.id.name);
let paging = PageSettings::default(); let paging = PageSettings::default();
@ -72,7 +72,7 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
&mut self, &mut self,
arid: &Mbid, arid: &Mbid,
album: &AlbumMeta, album: &AlbumMeta,
) -> Result<Vec<Match<AlbumMeta>>, Error> { ) -> Result<Vec<Entity<AlbumMeta>>, Error> {
// Some release groups may have a promotional early release messing up the search. Searching // Some release groups may have a promotional early release messing up the search. Searching
// with just the year should be enough anyway. // with just the year should be enough anyway.
let date = AlbumDate::new(album.date.year, None, None); let date = AlbumDate::new(album.date.year, None, None);
@ -98,7 +98,7 @@ impl<Http: IMusicBrainzHttp> IMusicBrainz for MusicBrainz<Http> {
&mut self, &mut self,
artist: &Mbid, artist: &Mbid,
paging: &mut PageSettings, paging: &mut PageSettings,
) -> Result<Paged<Vec<Match<AlbumMeta>>>, Error> { ) -> Result<Paged<Vec<Entity<AlbumMeta>>>, Error> {
let request = BrowseReleaseGroupRequest::artist(artist); let request = BrowseReleaseGroupRequest::artist(artist);
let mb_response = self.client.browse_release_group(&request, paging)?; let mb_response = self.client.browse_release_group(&request, paging)?;
@ -139,47 +139,47 @@ fn from_mb_release_group_meta(meta: MbReleaseGroupMeta) -> AlbumMeta {
} }
} }
fn from_lookup_artist_response(entity: LookupArtistResponse) -> Match<ArtistMeta> { fn from_lookup_artist_response(response: LookupArtistResponse) -> Entity<ArtistMeta> {
let (item, disambiguation) = from_mb_artist_meta(entity.meta); let (entity, disambiguation) = from_mb_artist_meta(response.meta);
Match { Entity {
score: None, score: None,
item, entity,
disambiguation, disambiguation,
} }
} }
fn from_lookup_release_group_response(entity: LookupReleaseGroupResponse) -> Match<AlbumMeta> { fn from_lookup_release_group_response(response: LookupReleaseGroupResponse) -> Entity<AlbumMeta> {
Match { Entity {
score: None, score: None,
item: from_mb_release_group_meta(entity.meta), entity: from_mb_release_group_meta(response.meta),
disambiguation: None, disambiguation: None,
} }
} }
fn from_search_artist_response_artist(entity: SearchArtistResponseArtist) -> Match<ArtistMeta> { fn from_search_artist_response_artist(response: SearchArtistResponseArtist) -> Entity<ArtistMeta> {
let (item, disambiguation) = from_mb_artist_meta(entity.meta); let (entity, disambiguation) = from_mb_artist_meta(response.meta);
Match { Entity {
score: Some(entity.score), score: Some(response.score),
item, entity,
disambiguation, disambiguation,
} }
} }
fn from_search_release_group_response_release_group( fn from_search_release_group_response_release_group(
entity: SearchReleaseGroupResponseReleaseGroup, response: SearchReleaseGroupResponseReleaseGroup,
) -> Match<AlbumMeta> { ) -> Entity<AlbumMeta> {
Match { Entity {
score: Some(entity.score), score: Some(response.score),
item: from_mb_release_group_meta(entity.meta), entity: from_mb_release_group_meta(response.meta),
disambiguation: None, disambiguation: None,
} }
} }
fn from_browse_release_group_response( fn from_browse_release_group_response(
entity: BrowseReleaseGroupResponse, entity: BrowseReleaseGroupResponse,
) -> Vec<Match<AlbumMeta>> { ) -> Vec<Entity<AlbumMeta>> {
let rgs = entity.release_groups.into_iter(); let rgs = entity.release_groups.into_iter();
let metas = rgs.map(from_mb_release_group_meta); let metas = rgs.map(from_mb_release_group_meta);
metas.map(|meta| Match::item(meta)).collect() metas.map(Entity::new).collect()
} }
// GRCOV_EXCL_STOP // GRCOV_EXCL_STOP

View File

@ -321,7 +321,7 @@ mod tests {
use crate::tui::{ use crate::tui::{
event::{Event, EventError, MockIFetchCompleteEventSender}, event::{Event, EventError, MockIFetchCompleteEventSender},
lib::interface::musicbrainz::api::{Match, MockIMusicBrainz}, lib::interface::musicbrainz::api::{Entity, MockIMusicBrainz},
testmod::COLLECTION, testmod::COLLECTION,
}; };
@ -408,11 +408,11 @@ mod tests {
VecDeque::from([MbParams::search_artist(artist)]) VecDeque::from([MbParams::search_artist(artist)])
} }
fn search_artist_expectations() -> (ArtistMeta, Vec<Match<ArtistMeta>>) { fn search_artist_expectations() -> (ArtistMeta, Vec<Entity<ArtistMeta>>) {
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let artist_match_1 = Match::with_score(artist.clone(), 100); let artist_match_1 = Entity::with_score(artist.clone(), 100);
let artist_match_2 = Match::with_score(artist.clone(), 50); let artist_match_2 = Entity::with_score(artist.clone(), 50);
let matches = vec![artist_match_1.clone(), artist_match_2.clone()]; let matches = vec![artist_match_1.clone(), artist_match_2.clone()];
(artist, matches) (artist, matches)
@ -441,23 +441,23 @@ mod tests {
mb_ref_opt_unwrap(mbref).mbid().clone() mb_ref_opt_unwrap(mbref).mbid().clone()
} }
fn search_album_expectations_1() -> (AlbumMeta, Vec<Match<AlbumMeta>>) { fn search_album_expectations_1() -> (AlbumMeta, Vec<Entity<AlbumMeta>>) {
let album_1 = COLLECTION[1].albums[0].meta.clone(); let album_1 = COLLECTION[1].albums[0].meta.clone();
let album_4 = COLLECTION[1].albums[3].meta.clone(); let album_4 = COLLECTION[1].albums[3].meta.clone();
let album_match_1_1 = Match::with_score(album_1.clone(), 100); let album_match_1_1 = Entity::with_score(album_1.clone(), 100);
let album_match_1_2 = Match::with_score(album_4.clone(), 50); let album_match_1_2 = Entity::with_score(album_4.clone(), 50);
let matches_1 = vec![album_match_1_1.clone(), album_match_1_2.clone()]; let matches_1 = vec![album_match_1_1.clone(), album_match_1_2.clone()];
(album_1, matches_1) (album_1, matches_1)
} }
fn search_album_expectations_4() -> (AlbumMeta, Vec<Match<AlbumMeta>>) { fn search_album_expectations_4() -> (AlbumMeta, Vec<Entity<AlbumMeta>>) {
let album_1 = COLLECTION[1].albums[0].meta.clone(); let album_1 = COLLECTION[1].albums[0].meta.clone();
let album_4 = COLLECTION[1].albums[3].meta.clone(); let album_4 = COLLECTION[1].albums[3].meta.clone();
let album_match_4_1 = Match::with_score(album_4.clone(), 100); let album_match_4_1 = Entity::with_score(album_4.clone(), 100);
let album_match_4_2 = Match::with_score(album_1.clone(), 30); let album_match_4_2 = Entity::with_score(album_1.clone(), 30);
let matches_4 = vec![album_match_4_1.clone(), album_match_4_2.clone()]; let matches_4 = vec![album_match_4_1.clone(), album_match_4_2.clone()];
(album_4, matches_4) (album_4, matches_4)
@ -539,7 +539,7 @@ mod tests {
fn lookup_artist_expectation( fn lookup_artist_expectation(
musicbrainz: &mut MockIMusicBrainz, musicbrainz: &mut MockIMusicBrainz,
mbid: &Mbid, mbid: &Mbid,
lookup: &Match<ArtistMeta>, lookup: &Entity<ArtistMeta>,
) { ) {
let result = Ok(lookup.clone()); let result = Ok(lookup.clone());
musicbrainz musicbrainz
@ -554,7 +554,7 @@ mod tests {
let mut musicbrainz = musicbrainz(); let mut musicbrainz = musicbrainz();
let mbid = mbid(); let mbid = mbid();
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let lookup = Match::item(artist.clone()); let lookup = Entity::new(artist.clone());
lookup_artist_expectation(&mut musicbrainz, &mbid, &lookup); lookup_artist_expectation(&mut musicbrainz, &mbid, &lookup);
let mut event_sender = event_sender(); let mut event_sender = event_sender();
@ -581,7 +581,7 @@ mod tests {
fn lookup_release_group_expectation( fn lookup_release_group_expectation(
musicbrainz: &mut MockIMusicBrainz, musicbrainz: &mut MockIMusicBrainz,
mbid: &Mbid, mbid: &Mbid,
lookup: &Match<AlbumMeta>, lookup: &Entity<AlbumMeta>,
) { ) {
let result = Ok(lookup.clone()); let result = Ok(lookup.clone());
musicbrainz musicbrainz
@ -596,7 +596,7 @@ mod tests {
let mut musicbrainz = musicbrainz(); let mut musicbrainz = musicbrainz();
let mbid = mbid(); let mbid = mbid();
let album = COLLECTION[1].albums[0].meta.clone(); let album = COLLECTION[1].albums[0].meta.clone();
let lookup = Match::item(album.clone()); let lookup = Entity::new(album.clone());
lookup_release_group_expectation(&mut musicbrainz, &mbid, &lookup); lookup_release_group_expectation(&mut musicbrainz, &mbid, &lookup);
let mut event_sender = event_sender(); let mut event_sender = event_sender();
@ -627,7 +627,7 @@ mod tests {
fn search_artist_expectation( fn search_artist_expectation(
musicbrainz: &mut MockIMusicBrainz, musicbrainz: &mut MockIMusicBrainz,
artist: &ArtistMeta, artist: &ArtistMeta,
matches: &[Match<ArtistMeta>], matches: &[Entity<ArtistMeta>],
) { ) {
let result = Ok(matches.to_owned()); let result = Ok(matches.to_owned());
musicbrainz musicbrainz
@ -669,7 +669,7 @@ mod tests {
seq: &mut Sequence, seq: &mut Sequence,
arid: &Mbid, arid: &Mbid,
album: &AlbumMeta, album: &AlbumMeta,
matches: &[Match<AlbumMeta>], matches: &[Entity<AlbumMeta>],
) { ) {
let result = Ok(matches.to_owned()); let result = Ok(matches.to_owned());
musicbrainz musicbrainz

View File

@ -10,33 +10,33 @@ use musichoard::{
#[cfg_attr(test, automock)] #[cfg_attr(test, automock)]
pub trait IMusicBrainz { pub trait IMusicBrainz {
fn lookup_artist(&mut self, mbid: &Mbid) -> Result<Match<ArtistMeta>, Error>; fn lookup_artist(&mut self, mbid: &Mbid) -> Result<Entity<ArtistMeta>, Error>;
fn lookup_release_group(&mut self, mbid: &Mbid) -> Result<Match<AlbumMeta>, Error>; fn lookup_release_group(&mut self, mbid: &Mbid) -> Result<Entity<AlbumMeta>, Error>;
fn search_artist(&mut self, artist: &ArtistMeta) -> Result<Vec<Match<ArtistMeta>>, Error>; fn search_artist(&mut self, artist: &ArtistMeta) -> Result<Vec<Entity<ArtistMeta>>, Error>;
fn search_release_group( fn search_release_group(
&mut self, &mut self,
arid: &Mbid, arid: &Mbid,
album: &AlbumMeta, album: &AlbumMeta,
) -> Result<Vec<Match<AlbumMeta>>, Error>; ) -> Result<Vec<Entity<AlbumMeta>>, Error>;
fn browse_release_group( fn browse_release_group(
&mut self, &mut self,
artist: &Mbid, artist: &Mbid,
paging: &mut PageSettings, paging: &mut PageSettings,
) -> Result<Paged<Vec<Match<AlbumMeta>>>, Error>; ) -> Result<Paged<Vec<Entity<AlbumMeta>>>, Error>;
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
pub struct Match<T> { pub struct Entity<T> {
pub score: Option<u8>, pub score: Option<u8>,
pub item: T, pub entity: T,
pub disambiguation: Option<String>, pub disambiguation: Option<String>,
} }
impl<T> Match<T> { impl<T> Entity<T> {
pub fn item(item: T) -> Self { pub fn new(entity: T) -> Self {
Match { Entity {
score: None, score: None,
item, entity,
disambiguation: None, disambiguation: None,
} }
} }

View File

@ -141,7 +141,7 @@ impl UiDisplay {
match match_option { match match_option {
MatchOption::Some(match_artist) => format!( MatchOption::Some(match_artist) => format!(
"{}{}", "{}{}",
display_fn(&match_artist.item, &match_artist.disambiguation), display_fn(&match_artist.entity, &match_artist.disambiguation),
Self::display_option_score(match_artist.score), Self::display_option_score(match_artist.score),
), ),
MatchOption::CannotHaveMbid => Self::display_cannot_have_mbid().to_string(), MatchOption::CannotHaveMbid => Self::display_cannot_have_mbid().to_string(),

View File

@ -22,7 +22,7 @@ impl<'a, 'b> MatchOverlay<'a, 'b> {
fn artists( fn artists(
matching: &ArtistMeta, matching: &ArtistMeta,
matches: &'a Vec<MatchOption<ArtistMeta>>, matches: &'a [MatchOption<ArtistMeta>],
state: &'b mut WidgetState, state: &'b mut WidgetState,
) -> Self { ) -> Self {
let matching = UiDisplay::display_artist_matching(matching); let matching = UiDisplay::display_artist_matching(matching);
@ -38,7 +38,7 @@ impl<'a, 'b> MatchOverlay<'a, 'b> {
fn albums( fn albums(
matching: &AlbumMeta, matching: &AlbumMeta,
matches: &'a Vec<MatchOption<AlbumMeta>>, matches: &'a [MatchOption<AlbumMeta>],
state: &'b mut WidgetState, state: &'b mut WidgetState,
) -> Self { ) -> Self {
let matching = UiDisplay::display_album_matching(matching); let matching = UiDisplay::display_album_matching(matching);

View File

@ -204,7 +204,7 @@ mod tests {
use crate::tui::{ use crate::tui::{
app::{AppPublic, AppPublicInner, Delta, MatchStatePublic}, app::{AppPublic, AppPublicInner, Delta, MatchStatePublic},
lib::interface::musicbrainz::api::Match, lib::interface::musicbrainz::api::Entity,
testmod::COLLECTION, testmod::COLLECTION,
tests::terminal, tests::terminal,
}; };
@ -331,7 +331,7 @@ mod tests {
fn artist_matches() -> MatchStateInfo { fn artist_matches() -> MatchStateInfo {
let artist = artist_meta(); let artist = artist_meta();
let artist_match = Match::with_score(artist.clone(), 80); let artist_match = Entity::with_score(artist.clone(), 80);
let list = vec![artist_match.clone(), artist_match.clone()]; let list = vec![artist_match.clone(), artist_match.clone()];
let mut info = MatchStateInfo::artist_search(artist, list); let mut info = MatchStateInfo::artist_search(artist, list);
@ -342,7 +342,7 @@ mod tests {
fn artist_lookup() -> MatchStateInfo { fn artist_lookup() -> MatchStateInfo {
let artist = artist_meta(); let artist = artist_meta();
let artist_lookup = Match::item(artist.clone()); let artist_lookup = Entity::new(artist.clone());
let mut info = MatchStateInfo::artist_lookup(artist, artist_lookup); let mut info = MatchStateInfo::artist_lookup(artist, artist_lookup);
info.push_cannot_have_mbid(); info.push_cannot_have_mbid();
@ -369,7 +369,7 @@ mod tests {
fn album_matches() -> MatchStateInfo { fn album_matches() -> MatchStateInfo {
let artist_id = album_artist_id(); let artist_id = album_artist_id();
let album = album_meta(); let album = album_meta();
let album_match = Match::with_score(album.clone(), 80); let album_match = Entity::with_score(album.clone(), 80);
let list = vec![album_match.clone(), album_match.clone()]; let list = vec![album_match.clone(), album_match.clone()];
let mut info = MatchStateInfo::album_search(artist_id, album, list); let mut info = MatchStateInfo::album_search(artist_id, album, list);
@ -381,7 +381,7 @@ mod tests {
fn album_lookup() -> MatchStateInfo { fn album_lookup() -> MatchStateInfo {
let artist_id = album_artist_id(); let artist_id = album_artist_id();
let album = album_meta(); let album = album_meta();
let album_lookup = Match::item(album.clone()); let album_lookup = Entity::new(album.clone());
let mut info = MatchStateInfo::album_lookup(artist_id, album, album_lookup); let mut info = MatchStateInfo::album_lookup(artist_id, album, album_lookup);
info.push_cannot_have_mbid(); info.push_cannot_have_mbid();