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
3 changed files with 52 additions and 19 deletions
Showing only changes of commit b51fa34935 - Show all commits

View File

@ -16,7 +16,7 @@ use crate::tui::{
AppPublicState, AppState, Category, IAppEventFetch, IAppInteractFetch, AppPublicState, AppState, Category, IAppEventFetch, IAppInteractFetch,
}, },
lib::interface::musicbrainz::daemon::{ lib::interface::musicbrainz::daemon::{
Error as DaemonError, IMbJobSender, MbApiResult, MbParams, ResultSender, Error as DaemonError, IMbJobSender, MbApiResult, MbParams, MbReturn, ResultSender,
}, },
}; };
@ -116,9 +116,7 @@ impl AppMachine<FetchState> {
pub fn app_fetch_next(inner: AppInner, mut fetch: FetchState) -> App { pub fn app_fetch_next(inner: AppInner, mut fetch: FetchState) -> App {
match fetch.try_recv() { match fetch.try_recv() {
Ok(fetch_result) => match fetch_result { Ok(fetch_result) => match fetch_result {
Ok(next_match) => { Ok(retval) => Self::handle_mb_api_return(inner, fetch, retval),
AppMachine::match_state(inner, MatchState::new(next_match, fetch)).into()
}
Err(fetch_err) => { Err(fetch_err) => {
AppMachine::error_state(inner, format!("fetch failed: {fetch_err}")).into() AppMachine::error_state(inner, format!("fetch failed: {fetch_err}")).into()
} }
@ -130,6 +128,15 @@ impl AppMachine<FetchState> {
} }
} }
fn handle_mb_api_return(inner: AppInner, fetch: FetchState, retval: MbReturn) -> App {
match retval {
MbReturn::Match(next_match) => {
AppMachine::match_state(inner, MatchState::new(next_match, fetch)).into()
}
_ => unimplemented!(),
}
}
pub fn app_lookup_artist( pub fn app_lookup_artist(
inner: AppInner, inner: AppInner,
fetch: FetchState, fetch: FetchState,
@ -311,13 +318,13 @@ mod tests {
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let matches: Vec<Entity<ArtistMeta>> = vec![]; let matches: Vec<Entity<ArtistMeta>> = vec![];
let fetch_result = EntityMatches::artist_search(artist.clone(), matches); let fetch_result = MbReturn::Match(EntityMatches::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 = Entity::new(artist.clone()); let lookup = Entity::new(artist.clone());
let lookup_result = EntityMatches::artist_lookup(artist.clone(), lookup); let lookup_result = MbReturn::Match(EntityMatches::artist_lookup(artist.clone(), lookup));
lookup_tx.send(Ok(lookup_result.clone())).unwrap(); lookup_tx.send(Ok(lookup_result.clone())).unwrap();
assert_eq!(fetch.try_recv(), Ok(Ok(lookup_result))); assert_eq!(fetch.try_recv(), Ok(Ok(lookup_result)));
@ -604,7 +611,7 @@ mod tests {
let artist_match = Entity::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 =
EntityMatches::artist_search(artist.clone(), vec![artist_match.clone()]); EntityMatches::artist_search(artist.clone(), vec![artist_match.clone()]);
let fetch_result = Ok(artist_match_info); let fetch_result = Ok(MbReturn::Match(artist_match_info));
tx.send(fetch_result).unwrap(); tx.send(fetch_result).unwrap();
let inner = inner(music_hoard(COLLECTION.clone())); let inner = inner(music_hoard(COLLECTION.clone()));
@ -678,7 +685,7 @@ mod tests {
let artist = COLLECTION[3].meta.clone(); let artist = COLLECTION[3].meta.clone();
let match_info = EntityMatches::artist_search::<Entity<ArtistMeta>>(artist, vec![]); let match_info = EntityMatches::artist_search::<Entity<ArtistMeta>>(artist, vec![]);
let fetch_result = Ok(match_info); let fetch_result = Ok(MbReturn::Match(match_info));
tx.send(fetch_result).unwrap(); tx.send(fetch_result).unwrap();
let app = app.unwrap_fetch().fetch_result_ready(); let app = app.unwrap_fetch().fetch_result_ready();

View File

@ -5,7 +5,9 @@ use crate::tui::{
event::IFetchCompleteEventSender, event::IFetchCompleteEventSender,
lib::interface::musicbrainz::{ lib::interface::musicbrainz::{
api::{Error as ApiError, IMusicBrainz}, api::{Error as ApiError, IMusicBrainz},
daemon::{Error, IMbJobSender, LookupParams, MbParams, ResultSender, SearchParams}, daemon::{
Error, IMbJobSender, LookupParams, MbParams, MbReturn, ResultSender, SearchParams,
},
}, },
}; };
@ -256,13 +258,13 @@ impl JobInstance {
.map(|rv| EntityMatches::album_search(params.artist_id, params.album, rv)), .map(|rv| EntityMatches::album_search(params.artist_id, params.album, rv)),
}, },
}; };
self.return_result(event_sender, result) self.return_result(event_sender, result.map(MbReturn::Match))
} }
fn return_result( fn return_result(
&mut self, &mut self,
event_sender: &mut dyn IFetchCompleteEventSender, event_sender: &mut dyn IFetchCompleteEventSender,
result: Result<EntityMatches, ApiError>, result: Result<MbReturn, ApiError>,
) -> Result<(), JobInstanceError> { ) -> Result<(), JobInstanceError> {
self.result_sender self.result_sender
.send(result) .send(result)
@ -575,7 +577,12 @@ mod tests {
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
let result = result_receiver.try_recv().unwrap(); let result = result_receiver.try_recv().unwrap();
assert_eq!(result, Ok(EntityMatches::artist_lookup(artist, lookup))); assert_eq!(
result,
Ok(MbReturn::Match(EntityMatches::artist_lookup(
artist, lookup
)))
);
} }
fn lookup_release_group_expectation( fn lookup_release_group_expectation(
@ -620,7 +627,9 @@ mod tests {
let artist_id = album_artist_id(); let artist_id = album_artist_id();
assert_eq!( assert_eq!(
result, result,
Ok(EntityMatches::album_lookup(artist_id, album, lookup)) Ok(MbReturn::Match(EntityMatches::album_lookup(
artist_id, album, lookup
)))
); );
} }
@ -661,7 +670,12 @@ mod tests {
assert_eq!(result, Ok(())); assert_eq!(result, Ok(()));
let result = result_receiver.try_recv().unwrap(); let result = result_receiver.try_recv().unwrap();
assert_eq!(result, Ok(EntityMatches::artist_search(artist, matches))); assert_eq!(
result,
Ok(MbReturn::Match(EntityMatches::artist_search(
artist, matches
)))
);
} }
fn search_release_group_expectation( fn search_release_group_expectation(
@ -716,21 +730,21 @@ mod tests {
let result = result_receiver.try_recv().unwrap(); let result = result_receiver.try_recv().unwrap();
assert_eq!( assert_eq!(
result, result,
Ok(EntityMatches::album_search( Ok(MbReturn::Match(EntityMatches::album_search(
artist_id.clone(), artist_id.clone(),
album_1, album_1,
matches_1 matches_1
)) )))
); );
let result = result_receiver.try_recv().unwrap(); let result = result_receiver.try_recv().unwrap();
assert_eq!( assert_eq!(
result, result,
Ok(EntityMatches::album_search( Ok(MbReturn::Match(EntityMatches::album_search(
artist_id.clone(), artist_id.clone(),
album_4, album_4,
matches_4 matches_4
)) )))
); );
} }

View File

@ -26,9 +26,21 @@ impl fmt::Display for Error {
} }
} }
pub type MbApiResult = Result<EntityMatches, MbApiError>; pub type MbApiResult = Result<MbReturn, MbApiError>;
pub type ResultSender = mpsc::Sender<MbApiResult>; pub type ResultSender = mpsc::Sender<MbApiResult>;
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum MbReturn {
Match(EntityMatches),
Fetch(EntityList),
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum EntityList {
Artist(Vec<ArtistMeta>),
Album(Vec<AlbumMeta>),
}
#[cfg_attr(test, automock)] #[cfg_attr(test, automock)]
pub trait IMbJobSender { pub trait IMbJobSender {
fn submit_foreground_job( fn submit_foreground_job(