diff --git a/src/tui/app/machine/browse.rs b/src/tui/app/machine/browse.rs index 7ebebba..6157aa9 100644 --- a/src/tui/app/machine/browse.rs +++ b/src/tui/app/machine/browse.rs @@ -3,9 +3,9 @@ use std::{sync::mpsc, thread, time}; use musichoard::collection::musicbrainz::IMusicBrainzRef; use crate::tui::app::{ - machine::{matches::AppMatchesInfo, App, AppInner, AppMachine}, + machine::{App, AppInner, AppMachine}, selection::{Delta, ListSelection}, - AppPublic, AppState, IAppInteractBrowse, + AppMatchesInfo, AppPublic, AppState, IAppInteractBrowse, }; pub struct AppBrowse; @@ -139,8 +139,8 @@ mod tests { use crate::tui::{ app::{ machine::tests::{inner, inner_with_mb, music_hoard}, - AppPublicAlbumMatches, AppPublicArtistMatches, AppPublicMatchesInfo, Category, - IAppAccess, IAppInteract, IAppInteractMatches, + AppAlbumMatches, AppArtistMatches, AppMatchesInfo, Category, IAppAccess, IAppInteract, + IAppInteractMatches, }, lib::interface::musicbrainz::{self, Match, MockIMusicBrainz}, testmod::COLLECTION, @@ -263,11 +263,11 @@ mod tests { let public_matches = public.state.unwrap_matches(); - let expected = Some(AppPublicMatchesInfo::Album(AppPublicAlbumMatches { - matching: &album_1, - list: &matches_1, + let expected = Some(AppMatchesInfo::Album(AppAlbumMatches { + matching: album_1.clone(), + list: matches_1.clone(), })); - assert_eq!(public_matches.matches, expected); + assert_eq!(public_matches.matches, expected.as_ref()); let mut app = app.unwrap_matches().select(); @@ -276,11 +276,11 @@ mod tests { let public_matches = public.state.unwrap_matches(); - let expected = Some(AppPublicMatchesInfo::Album(AppPublicAlbumMatches { - matching: &album_4, - list: &matches_4, + let expected = Some(AppMatchesInfo::Album(AppAlbumMatches { + matching: album_4.clone(), + list: matches_4.clone(), })); - assert_eq!(public_matches.matches, expected); + assert_eq!(public_matches.matches, expected.as_ref()); let app = app.unwrap_matches().select(); app.unwrap_browse(); @@ -324,11 +324,11 @@ mod tests { let public_matches = public.state.unwrap_matches(); - let expected = Some(AppPublicMatchesInfo::Artist(AppPublicArtistMatches { - matching: &artist, - list: &matches, + let expected = Some(AppMatchesInfo::Artist(AppArtistMatches { + matching: artist.clone(), + list: matches.clone(), })); - assert_eq!(public_matches.matches, expected); + assert_eq!(public_matches.matches, expected.as_ref()); let app = app.unwrap_matches().select(); app.unwrap_browse(); diff --git a/src/tui/app/machine/matches.rs b/src/tui/app/machine/matches.rs index 80265d4..56f32d6 100644 --- a/src/tui/app/machine/matches.rs +++ b/src/tui/app/machine/matches.rs @@ -1,23 +1,12 @@ use std::{cmp, sync::mpsc}; -use musichoard::collection::{album::Album, artist::Artist}; - -use crate::tui::{ - app::{ - machine::{App, AppInner, AppMachine}, - AppPublic, AppPublicAlbumMatches, AppPublicArtistMatches, AppPublicMatches, - AppPublicMatchesInfo, AppState, IAppInteractMatches, WidgetState, - }, - lib::interface::musicbrainz::Match, +use crate::tui::app::{ + machine::{App, AppInner, AppMachine}, + AppAlbumMatches, AppArtistMatches, AppMatchesInfo, AppPublic, AppPublicMatches, AppState, + IAppInteractMatches, WidgetState, }; -#[derive(Clone, Debug, PartialEq, Eq)] -pub struct AppArtistMatchesInfo { - pub matching: Artist, - pub list: Vec>, -} - -impl AppArtistMatchesInfo { +impl AppArtistMatches { fn is_empty(&self) -> bool { self.list.is_empty() } @@ -27,22 +16,7 @@ impl AppArtistMatchesInfo { } } -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 list: Vec>, -} - -impl AppAlbumMatchesInfo { +impl AppAlbumMatches { fn is_empty(&self) -> bool { self.list.is_empty() } @@ -52,21 +26,6 @@ impl AppAlbumMatchesInfo { } } -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 { @@ -81,23 +40,6 @@ impl AppMatchesInfo { Self::Album(a) => a.len(), } } - - pub fn artist(matching: Artist, list: Vec>) -> Self { - AppMatchesInfo::Artist(AppArtistMatchesInfo { matching, list }) - } - - pub fn album(matching: Album, list: Vec>) -> Self { - AppMatchesInfo::Album(AppAlbumMatchesInfo { matching, list }) - } -} - -impl<'app> From<&'app AppMatchesInfo> for AppPublicMatchesInfo<'app> { - fn from(value: &'app AppMatchesInfo) -> Self { - match value { - AppMatchesInfo::Artist(a) => AppPublicMatchesInfo::Artist(a.into()), - AppMatchesInfo::Album(a) => AppPublicMatchesInfo::Album(a.into()), - } - } } pub struct AppMatches { @@ -209,13 +151,16 @@ impl IAppInteractMatchesPrivate for AppMatches { mod tests { use mpsc::Receiver; use musichoard::collection::{ - album::{AlbumDate, AlbumId, AlbumPrimaryType, AlbumSecondaryType}, - artist::ArtistId, + album::{Album, AlbumDate, AlbumId, AlbumPrimaryType, AlbumSecondaryType}, + artist::{Artist, ArtistId}, }; - use crate::tui::app::{ - machine::tests::{inner, music_hoard}, - IAppAccess, + use crate::tui::{ + app::{ + machine::tests::{inner, music_hoard}, + IAppAccess, + }, + lib::interface::musicbrainz::Match, }; use super::*; @@ -322,7 +267,7 @@ mod tests { let public = app.get(); let public_matches = public.state.unwrap_matches(); - assert_eq!(public_matches.matches, Some((&matches_info_vec[0]).into())); + assert_eq!(public_matches.matches, Some(&matches_info_vec[0])); assert_eq!(public_matches.state, &widget_state); } diff --git a/src/tui/app/mod.rs b/src/tui/app/mod.rs index 90c49fe..6b4d4a3 100644 --- a/src/tui/app/mod.rs +++ b/src/tui/app/mod.rs @@ -129,26 +129,36 @@ pub struct AppPublicInner<'app> { pub selection: &'app mut Selection, } -#[derive(Debug, PartialEq, Eq)] -pub struct AppPublicArtistMatches<'app> { - pub matching: &'app Artist, - pub list: &'app [Match], +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct AppArtistMatches { + pub matching: Artist, + pub list: Vec>, } -#[derive(Debug, PartialEq, Eq)] -pub struct AppPublicAlbumMatches<'app> { - pub matching: &'app Album, - pub list: &'app [Match], +#[derive(Clone, Debug, PartialEq, Eq)] +pub struct AppAlbumMatches { + pub matching: Album, + pub list: Vec>, } -#[derive(Debug, PartialEq, Eq)] -pub enum AppPublicMatchesInfo<'app> { - Artist(AppPublicArtistMatches<'app>), - Album(AppPublicAlbumMatches<'app>), +#[derive(Clone, Debug, PartialEq, Eq)] +pub enum AppMatchesInfo { + Artist(AppArtistMatches), + Album(AppAlbumMatches), +} + +impl AppMatchesInfo { + pub fn artist(matching: Artist, list: Vec>) -> Self { + AppMatchesInfo::Artist(AppArtistMatches { matching, list }) + } + + pub fn album(matching: Album, list: Vec>) -> Self { + AppMatchesInfo::Album(AppAlbumMatches { matching, list }) + } } pub struct AppPublicMatches<'app> { - pub matches: Option>, + pub matches: Option<&'app AppMatchesInfo>, pub state: &'app mut WidgetState, } diff --git a/src/tui/ui/display.rs b/src/tui/ui/display.rs index f566c56..eb5b847 100644 --- a/src/tui/ui/display.rs +++ b/src/tui/ui/display.rs @@ -4,7 +4,7 @@ use musichoard::collection::{ track::{TrackFormat, TrackQuality}, }; -use crate::tui::{app::AppPublicMatchesInfo, lib::interface::musicbrainz::Match}; +use crate::tui::{app::AppMatchesInfo, lib::interface::musicbrainz::Match}; pub struct UiDisplay; @@ -114,11 +114,11 @@ impl UiDisplay { "Matching nothing" } - pub fn display_matching_info(matches: Option<&AppPublicMatchesInfo>) -> String { + pub fn display_matching_info(matches: Option<&AppMatchesInfo>) -> String { match matches.as_ref() { Some(kind) => match kind { - AppPublicMatchesInfo::Artist(m) => UiDisplay::display_artist_matching(m.matching), - AppPublicMatchesInfo::Album(m) => UiDisplay::display_album_matching(m.matching), + AppMatchesInfo::Artist(m) => UiDisplay::display_artist_matching(&m.matching), + AppMatchesInfo::Album(m) => UiDisplay::display_album_matching(&m.matching), }, None => UiDisplay::display_nothing_matching().to_string(), } diff --git a/src/tui/ui/matches.rs b/src/tui/ui/matches.rs index 301ed17..41603b0 100644 --- a/src/tui/ui/matches.rs +++ b/src/tui/ui/matches.rs @@ -2,7 +2,7 @@ use musichoard::collection::{album::Album, artist::Artist}; use ratatui::widgets::{List, ListItem}; use crate::tui::{ - app::{AppPublicMatchesInfo, WidgetState}, + app::{AppMatchesInfo, WidgetState}, lib::interface::musicbrainz::Match, ui::display::UiDisplay, }; @@ -14,11 +14,11 @@ pub struct MatchesState<'a, 'b> { } impl<'a, 'b> MatchesState<'a, 'b> { - pub fn new(matches: Option, state: &'b mut WidgetState) -> Self { + pub fn new(matches: Option<&AppMatchesInfo>, state: &'b mut WidgetState) -> Self { match matches { Some(info) => match info { - AppPublicMatchesInfo::Artist(m) => Self::artists(m.matching, m.list, state), - AppPublicMatchesInfo::Album(m) => Self::albums(m.matching, m.list, state), + AppMatchesInfo::Artist(m) => Self::artists(&m.matching, &m.list, state), + AppMatchesInfo::Album(m) => Self::albums(&m.matching, &m.list, state), }, None => Self::empty(state), } diff --git a/src/tui/ui/minibuffer.rs b/src/tui/ui/minibuffer.rs index e8e0610..3e6e0f1 100644 --- a/src/tui/ui/minibuffer.rs +++ b/src/tui/ui/minibuffer.rs @@ -59,7 +59,7 @@ impl Minibuffer<'_> { }, AppState::Matches(public) => Minibuffer { paragraphs: vec![ - Paragraph::new(UiDisplay::display_matching_info(public.matches.as_ref())), + Paragraph::new(UiDisplay::display_matching_info(public.matches)), Paragraph::new("q: abort"), ], columns: 2, diff --git a/src/tui/ui/mod.rs b/src/tui/ui/mod.rs index 47b2939..7231d8d 100644 --- a/src/tui/ui/mod.rs +++ b/src/tui/ui/mod.rs @@ -14,10 +14,7 @@ use ratatui::{layout::Rect, widgets::Paragraph, Frame}; use musichoard::collection::{album::Album, Collection}; use crate::tui::{ - app::{ - AppPublicMatchesInfo, AppPublicState, AppState, Category, IAppAccess, Selection, - WidgetState, - }, + app::{AppMatchesInfo, AppPublicState, AppState, Category, IAppAccess, Selection, WidgetState}, ui::{ browse::{ AlbumArea, AlbumState, ArtistArea, ArtistState, FrameArea, TrackArea, TrackState, @@ -135,7 +132,7 @@ impl Ui { } fn render_matches_overlay( - matches: Option, + matches: Option<&AppMatchesInfo>, state: &mut WidgetState, frame: &mut Frame, ) { @@ -185,10 +182,7 @@ mod tests { }; use crate::tui::{ - app::{ - AppPublic, AppPublicAlbumMatches, AppPublicArtistMatches, AppPublicInner, - AppPublicMatches, Delta, - }, + app::{AppPublic, AppPublicInner, AppPublicMatches, Delta}, lib::interface::musicbrainz::Match, testmod::COLLECTION, tests::terminal, @@ -196,33 +190,6 @@ mod tests { use super::*; - impl<'app> AppPublicArtistMatches<'app> { - fn get(&self) -> AppPublicArtistMatches<'app> { - AppPublicArtistMatches { - matching: self.matching, - list: self.list, - } - } - } - - impl<'app> AppPublicAlbumMatches<'app> { - fn get(&self) -> AppPublicAlbumMatches<'app> { - AppPublicAlbumMatches { - matching: self.matching, - list: self.list, - } - } - } - - impl<'app> AppPublicMatchesInfo<'app> { - fn get(&self) -> AppPublicMatchesInfo<'app> { - match self { - Self::Artist(a) => Self::Artist(a.get()), - Self::Album(a) => Self::Album(a.get()), - } - } - } - // Automock does not support returning types with generic lifetimes. impl<'app> IAppAccess for AppPublic<'app> { fn get(&mut self) -> AppPublic { @@ -237,7 +204,7 @@ mod tests { AppState::Reload(()) => AppState::Reload(()), AppState::Search(s) => AppState::Search(s), AppState::Matches(ref mut m) => AppState::Matches(AppPublicMatches { - matches: m.matches.as_mut().map(|k| k.get()), + matches: m.matches, state: m.state, }), AppState::Error(s) => AppState::Error(s), @@ -257,18 +224,12 @@ mod tests { } } - fn artist_matches<'app>( - matching: &'app Artist, - list: &'app [Match], - ) -> AppPublicMatchesInfo<'app> { - AppPublicMatchesInfo::Artist(AppPublicArtistMatches { matching, list }) + fn artist_matches(matching: Artist, list: Vec>) -> AppMatchesInfo { + AppMatchesInfo::artist(matching, list) } - fn album_matches<'app>( - matching: &'app Album, - list: &'app [Match], - ) -> AppPublicMatchesInfo<'app> { - AppPublicMatchesInfo::Album(AppPublicAlbumMatches { matching, list }) + fn album_matches(matching: Album, list: Vec>) -> AppMatchesInfo { + AppMatchesInfo::album(matching, list) } fn draw_test_suite(collection: &Collection, selection: &mut Selection) { @@ -364,21 +325,21 @@ mod tests { let mut terminal = terminal(); let artist = Artist::new(ArtistId::new("an artist")); - let artist_match = Match { score: 80, item: artist.clone(), disambiguation: None, }; + let list = vec![artist_match.clone(), artist_match.clone()]; + let artist_matches = artist_matches(artist, list); - let list = [artist_match.clone(), artist_match.clone()]; let mut widget_state = WidgetState::default(); widget_state.list.select(Some(0)); let mut app = AppPublic { inner: public_inner(collection, &mut selection), state: AppState::Matches(AppPublicMatches { - matches: Some(artist_matches(&artist, &list)), + matches: Some(&artist_matches), state: &mut widget_state, }), }; @@ -398,21 +359,21 @@ mod tests { Some(AlbumPrimaryType::Album), vec![AlbumSecondaryType::Live, AlbumSecondaryType::Compilation], ); - let album_match = Match { score: 80, item: album.clone(), disambiguation: None, }; + let list = vec![album_match.clone(), album_match.clone()]; + let album_matches = album_matches(album, list); - let list = [album_match.clone(), album_match.clone()]; let mut widget_state = WidgetState::default(); widget_state.list.select(Some(0)); let mut app = AppPublic { inner: public_inner(collection, &mut selection), state: AppState::Matches(AppPublicMatches { - matches: Some(album_matches(&album, &list)), + matches: Some(&album_matches), state: &mut widget_state, }), };