Fetch panics if a list shortens with a selection beyond the new length #258

Merged
wojtek merged 2 commits from 257---fetch-panics-if-a-list-shortens-with-a-selection-beyond-the-new-length into main 2025-01-05 12:47:51 +01:00
Showing only changes of commit 829bb89696 - Show all commits

View File

@ -6,13 +6,11 @@ use musichoard::collection::{
musicbrainz::{MbRefOption, Mbid}, musicbrainz::{MbRefOption, Mbid},
}; };
use crate::tui::{ use crate::tui::app::{
app::{ machine::{fetch_state::FetchState, input::Input, App, AppInner, AppMachine},
machine::{fetch_state::FetchState, input::Input, App, AppInner, AppMachine}, selection::KeySelection,
AlbumMatches, AppPublicState, AppState, ArtistMatches, Delta, EntityMatches, AlbumMatches, AppPublicState, AppState, ArtistMatches, Delta, EntityMatches, IAppInteractMatch,
IAppInteractMatch, MatchOption, MatchStatePublic, WidgetState, MatchOption, MatchStatePublic, WidgetState,
},
lib::IMusicHoard,
}; };
struct ArtistInfoTuple { struct ArtistInfoTuple {
@ -205,20 +203,21 @@ impl AppMachine<MatchState> {
} }
fn select_artist( fn select_artist(
mh: &mut Box<dyn IMusicHoard>, inner: &mut AppInner,
matches: &ArtistMatches, matches: &ArtistMatches,
tuple: ArtistInfoTuple, tuple: ArtistInfoTuple,
) -> Result<(), musichoard::Error> { ) -> Result<(), musichoard::Error> {
let mh = &mut inner.music_hoard;
mh.merge_artist_info(&matches.matching.id, tuple.info)?; mh.merge_artist_info(&matches.matching.id, tuple.info)?;
mh.set_artist_mb_ref(&matches.matching.id, tuple.mb_ref) mh.set_artist_mb_ref(&matches.matching.id, tuple.mb_ref)
} }
fn select_album( fn select_album(
mh: &mut Box<dyn IMusicHoard>, inner: &mut AppInner,
matches: &AlbumMatches, matches: &AlbumMatches,
tuple: AlbumInfoTuple, tuple: AlbumInfoTuple,
) -> Result<(), musichoard::Error> { ) -> Result<(), musichoard::Error> {
let coll = mh.get_collection(); let coll = inner.music_hoard.get_collection();
let mut clashing = vec![]; let mut clashing = vec![];
if let Some(artist) = coll.iter().find(|artist| artist.meta.id == matches.artist) { if let Some(artist) = coll.iter().find(|artist| artist.meta.id == matches.artist) {
// While we expect only one, there is nothing stopping anybody from having multiple // While we expect only one, there is nothing stopping anybody from having multiple
@ -231,8 +230,16 @@ impl AppMachine<MatchState> {
} }
for album in clashing.into_iter() { for album in clashing.into_iter() {
mh.remove_album(&matches.artist, &album)?; let coll = inner.music_hoard.get_filtered();
let selection = KeySelection::get(coll, &inner.selection);
inner.music_hoard.remove_album(&matches.artist, &album)?;
let coll = inner.music_hoard.get_filtered();
inner.selection.select_by_id(coll, selection);
} }
let mh = &mut inner.music_hoard;
mh.merge_album_info(&matches.artist, &matches.matching, tuple.info)?; mh.merge_album_info(&matches.artist, &matches.matching, tuple.info)?;
mh.set_album_mb_ref(&matches.artist, &matches.matching, tuple.mb_ref) mh.set_album_mb_ref(&matches.artist, &matches.matching, tuple.mb_ref)
} }
@ -279,14 +286,14 @@ impl IAppInteractMatch for AppMachine<MatchState> {
fn select(mut self) -> Self::APP { fn select(mut self) -> Self::APP {
let index = self.state.state.list.selected().unwrap(); let index = self.state.state.list.selected().unwrap();
let mh = &mut self.inner.music_hoard; let inner = &mut self.inner;
let result = match self.state.current { let result = match self.state.current {
EntityMatches::Artist(ref mut matches) => match matches.list.extract_info(index) { EntityMatches::Artist(ref mut matches) => match matches.list.extract_info(index) {
InfoOption::Info(tuple) => Self::select_artist(mh, matches, tuple), InfoOption::Info(tuple) => Self::select_artist(inner, matches, tuple),
InfoOption::NeedInput => return self.get_input(), InfoOption::NeedInput => return self.get_input(),
}, },
EntityMatches::Album(ref mut matches) => match matches.list.extract_info(index) { EntityMatches::Album(ref mut matches) => match matches.list.extract_info(index) {
InfoOption::Info(tuple) => Self::select_album(mh, matches, tuple), InfoOption::Info(tuple) => Self::select_album(inner, matches, tuple),
InfoOption::NeedInput => return self.get_input(), InfoOption::NeedInput => return self.get_input(),
}, },
}; };