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,
},
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 {
match fetch.try_recv() {
Ok(fetch_result) => match fetch_result {
Ok(next_match) => {
AppMachine::match_state(inner, MatchState::new(next_match, fetch)).into()
}
Ok(retval) => Self::handle_mb_api_return(inner, fetch, retval),
Err(fetch_err) => {
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(
inner: AppInner,
fetch: FetchState,
@ -311,13 +318,13 @@ mod tests {
let artist = COLLECTION[3].meta.clone();
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();
assert_eq!(fetch.try_recv(), Err(TryRecvError::Empty));
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();
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_info =
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();
let inner = inner(music_hoard(COLLECTION.clone()));
@ -678,7 +685,7 @@ mod tests {
let artist = COLLECTION[3].meta.clone();
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();
let app = app.unwrap_fetch().fetch_result_ready();

View File

@ -5,7 +5,9 @@ use crate::tui::{
event::IFetchCompleteEventSender,
lib::interface::musicbrainz::{
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)),
},
};
self.return_result(event_sender, result)
self.return_result(event_sender, result.map(MbReturn::Match))
}
fn return_result(
&mut self,
event_sender: &mut dyn IFetchCompleteEventSender,
result: Result<EntityMatches, ApiError>,
result: Result<MbReturn, ApiError>,
) -> Result<(), JobInstanceError> {
self.result_sender
.send(result)
@ -575,7 +577,12 @@ mod tests {
assert_eq!(result, Ok(()));
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(
@ -620,7 +627,9 @@ mod tests {
let artist_id = album_artist_id();
assert_eq!(
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(()));
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(
@ -716,21 +730,21 @@ mod tests {
let result = result_receiver.try_recv().unwrap();
assert_eq!(
result,
Ok(EntityMatches::album_search(
Ok(MbReturn::Match(EntityMatches::album_search(
artist_id.clone(),
album_1,
matches_1
))
)))
);
let result = result_receiver.try_recv().unwrap();
assert_eq!(
result,
Ok(EntityMatches::album_search(
Ok(MbReturn::Match(EntityMatches::album_search(
artist_id.clone(),
album_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>;
#[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)]
pub trait IMbJobSender {
fn submit_foreground_job(