Make fetch also fetch artist MBID if it is missing #201
@ -91,14 +91,12 @@ impl IAppInteractBrowse for AppMachine<AppBrowse> {
|
||||
}
|
||||
};
|
||||
|
||||
let arid = match artist.musicbrainz {
|
||||
Some(ref mbid) => mbid.mbid(),
|
||||
None => {
|
||||
return AppMachine::error(self.inner, "cannot fetch: missing artist MBID").into()
|
||||
}
|
||||
};
|
||||
let mut matches = vec![];
|
||||
|
||||
match artist.musicbrainz {
|
||||
Some(ref mbid) => {
|
||||
let arid = mbid.mbid();
|
||||
|
||||
let mut artist_album_matches = vec![];
|
||||
let mut album_iter = artist.albums.iter().peekable();
|
||||
while let Some(album) = album_iter.next() {
|
||||
if album.musicbrainz.is_some() {
|
||||
@ -106,10 +104,7 @@ impl IAppInteractBrowse for AppMachine<AppBrowse> {
|
||||
}
|
||||
|
||||
match self.inner.musicbrainz.search_release_group(arid, album) {
|
||||
Ok(matches) => artist_album_matches.push(AppMatchesInfo {
|
||||
matching: album.clone(),
|
||||
matches,
|
||||
}),
|
||||
Ok(list) => matches.push(AppMatchesInfo::album(album.clone(), list)),
|
||||
Err(err) => return AppMachine::error(self.inner, err.to_string()).into(),
|
||||
}
|
||||
|
||||
@ -117,8 +112,14 @@ impl IAppInteractBrowse for AppMachine<AppBrowse> {
|
||||
thread::sleep(time::Duration::from_secs(1));
|
||||
}
|
||||
}
|
||||
}
|
||||
None => match self.inner.musicbrainz.search_artist(&artist.id.name) {
|
||||
Ok(list) => matches.push(AppMatchesInfo::artist(artist.clone(), list)),
|
||||
Err(err) => return AppMachine::error(self.inner, err.to_string()).into(),
|
||||
},
|
||||
};
|
||||
|
||||
AppMachine::matches(self.inner, artist_album_matches).into()
|
||||
AppMachine::matches(self.inner, matches).into()
|
||||
}
|
||||
|
||||
fn no_op(self) -> Self::APP {
|
||||
@ -257,7 +258,15 @@ mod tests {
|
||||
|
||||
let public_matches = public.state.unwrap_matches();
|
||||
|
||||
assert_eq!(public_matches.matches.as_ref().unwrap().album_ref().matching, &album_1);
|
||||
assert_eq!(
|
||||
public_matches
|
||||
.matches
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.album_ref()
|
||||
.matching,
|
||||
&album_1
|
||||
);
|
||||
assert_eq!(
|
||||
public_matches.matches.as_ref().unwrap().album_ref().list,
|
||||
matches_1.as_slice()
|
||||
@ -270,7 +279,15 @@ mod tests {
|
||||
|
||||
let public_matches = public.state.unwrap_matches();
|
||||
|
||||
assert_eq!(public_matches.matches.as_ref().unwrap().album_ref().matching, &album_4);
|
||||
assert_eq!(
|
||||
public_matches
|
||||
.matches
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.album_ref()
|
||||
.matching,
|
||||
&album_4
|
||||
);
|
||||
assert_eq!(
|
||||
public_matches.matches.as_ref().unwrap().album_ref().list,
|
||||
matches_4.as_slice()
|
||||
|
@ -1,20 +1,117 @@
|
||||
use std::cmp;
|
||||
|
||||
use musichoard::collection::album::Album;
|
||||
use musichoard::collection::{album::Album, artist::Artist};
|
||||
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppPublicAlbumMatches, AppPublicMatches, AppPublicMatchesKind, AppState,
|
||||
IAppInteractMatches, WidgetState,
|
||||
AppPublic, AppPublicAlbumMatches, AppPublicArtistMatches, AppPublicMatches,
|
||||
AppPublicMatchesKind, AppState, IAppInteractMatches, WidgetState,
|
||||
},
|
||||
lib::interface::musicbrainz::Match,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct AppMatchesInfo {
|
||||
pub struct AppArtistMatchesInfo {
|
||||
pub matching: Artist,
|
||||
pub list: Vec<Match<Artist>>,
|
||||
}
|
||||
|
||||
impl AppArtistMatchesInfo {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.list.is_empty()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.list.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'app> From<&'app AppArtistMatchesInfo> for AppPublicArtistMatches<'app> {
|
||||
fn from(value: &'app AppArtistMatchesInfo) -> Self {
|
||||
AppPublicArtistMatches {
|
||||
matching: &value.matching,
|
||||
list: &value.list,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct AppAlbumMatchesInfo {
|
||||
pub matching: Album,
|
||||
pub matches: Vec<Match<Album>>,
|
||||
pub list: Vec<Match<Album>>,
|
||||
}
|
||||
|
||||
impl AppAlbumMatchesInfo {
|
||||
fn is_empty(&self) -> bool {
|
||||
self.list.is_empty()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.list.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'app> From<&'app AppAlbumMatchesInfo> for AppPublicAlbumMatches<'app> {
|
||||
fn from(value: &'app AppAlbumMatchesInfo) -> Self {
|
||||
AppPublicAlbumMatches {
|
||||
matching: &value.matching,
|
||||
list: &value.list,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub enum AppMatchesInfo {
|
||||
Artist(AppArtistMatchesInfo),
|
||||
Album(AppAlbumMatchesInfo),
|
||||
}
|
||||
|
||||
impl AppMatchesInfo {
|
||||
fn is_empty(&self) -> bool {
|
||||
match self {
|
||||
Self::Artist(a) => a.is_empty(),
|
||||
Self::Album(a) => a.is_empty(),
|
||||
}
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
match self {
|
||||
Self::Artist(a) => a.len(),
|
||||
Self::Album(a) => a.len(),
|
||||
}
|
||||
}
|
||||
|
||||
fn artist_ref(&self) -> &AppArtistMatchesInfo {
|
||||
match self {
|
||||
Self::Artist(a) => a,
|
||||
Self::Album(_) => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
fn album_ref(&self) -> &AppAlbumMatchesInfo {
|
||||
match self {
|
||||
Self::Album(a) => a,
|
||||
Self::Artist(_) => panic!(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn artist(matching: Artist, list: Vec<Match<Artist>>) -> Self {
|
||||
AppMatchesInfo::Artist(AppArtistMatchesInfo { matching, list })
|
||||
}
|
||||
|
||||
pub fn album(matching: Album, list: Vec<Match<Album>>) -> Self {
|
||||
AppMatchesInfo::Album(AppAlbumMatchesInfo { matching, list })
|
||||
}
|
||||
}
|
||||
|
||||
impl<'app> From<&'app AppMatchesInfo> for AppPublicMatchesKind<'app> {
|
||||
fn from(value: &'app AppMatchesInfo) -> Self {
|
||||
match value {
|
||||
AppMatchesInfo::Artist(a) => AppPublicMatchesKind::Artist(a.into()),
|
||||
AppMatchesInfo::Album(a) => AppPublicMatchesKind::Album(a.into()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AppMatches {
|
||||
@ -29,7 +126,7 @@ impl AppMachine<AppMatches> {
|
||||
let mut state = WidgetState::default();
|
||||
if let Some(matches_info) = matches_info_vec.first() {
|
||||
index = Some(0);
|
||||
if !matches_info.matches.is_empty() {
|
||||
if !matches_info.is_empty() {
|
||||
state.list.select(Some(0));
|
||||
}
|
||||
}
|
||||
@ -53,12 +150,10 @@ impl From<AppMachine<AppMatches>> for App {
|
||||
|
||||
impl<'a> From<&'a mut AppMachine<AppMatches>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppMatches>) -> Self {
|
||||
let matches = machine.state.index.map(|index| {
|
||||
AppPublicMatchesKind::Album(AppPublicAlbumMatches {
|
||||
matching: &machine.state.matches_info_vec[index].matching,
|
||||
list: machine.state.matches_info_vec[index].matches.as_slice(),
|
||||
})
|
||||
});
|
||||
let matches = machine
|
||||
.state
|
||||
.index
|
||||
.map(|index| (&machine.state.matches_info_vec[index]).into());
|
||||
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
@ -88,7 +183,6 @@ impl IAppInteractMatches for AppMachine<AppMatches> {
|
||||
let to = cmp::min(
|
||||
result,
|
||||
self.state.matches_info_vec[self.state.index.unwrap()]
|
||||
.matches
|
||||
.len()
|
||||
.saturating_sub(1),
|
||||
);
|
||||
@ -103,7 +197,7 @@ impl IAppInteractMatches for AppMachine<AppMatches> {
|
||||
self.state.state = WidgetState::default();
|
||||
if let Some(index) = self.state.index {
|
||||
if let Some(matches_info) = self.state.matches_info_vec.get(index) {
|
||||
if !matches_info.matches.is_empty() {
|
||||
if !matches_info.is_empty() {
|
||||
self.state.state.list.select(Some(0));
|
||||
}
|
||||
return self.into();
|
||||
@ -157,10 +251,10 @@ mod tests {
|
||||
disambiguation: None,
|
||||
};
|
||||
|
||||
let matches_info_1 = AppMatchesInfo {
|
||||
let matches_info_1 = AppMatchesInfo::Album(AppAlbumMatchesInfo {
|
||||
matching: album_1.clone(),
|
||||
matches: vec![album_match_1_1.clone(), album_match_1_2.clone()],
|
||||
};
|
||||
list: vec![album_match_1_1.clone(), album_match_1_2.clone()],
|
||||
});
|
||||
|
||||
let album_2 = Album::new(
|
||||
AlbumId::new("Album 2"),
|
||||
@ -176,10 +270,10 @@ mod tests {
|
||||
disambiguation: None,
|
||||
};
|
||||
|
||||
let matches_info_2 = AppMatchesInfo {
|
||||
let matches_info_2 = AppMatchesInfo::Album(AppAlbumMatchesInfo {
|
||||
matching: album_2.clone(),
|
||||
matches: vec![album_match_2_1.clone()],
|
||||
};
|
||||
list: vec![album_match_2_1.clone()],
|
||||
});
|
||||
|
||||
vec![matches_info_1, matches_info_2]
|
||||
}
|
||||
@ -219,12 +313,17 @@ mod tests {
|
||||
let public_matches = public.state.unwrap_matches();
|
||||
|
||||
assert_eq!(
|
||||
public_matches.matches.as_ref().unwrap().album_ref().matching,
|
||||
&matches_info_vec[0].matching
|
||||
public_matches
|
||||
.matches
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.album_ref()
|
||||
.matching,
|
||||
&matches_info_vec[0].album_ref().matching
|
||||
);
|
||||
assert_eq!(
|
||||
public_matches.matches.as_ref().unwrap().album_ref().list,
|
||||
matches_info_vec[0].matches.as_slice()
|
||||
matches_info_vec[0].album_ref().list.as_slice()
|
||||
);
|
||||
assert_eq!(public_matches.state, &widget_state);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user