Replace MH: IMusicHoard
generic with a trait object
#194
@ -70,8 +70,10 @@ struct DbOpt {
|
||||
no_database: bool,
|
||||
}
|
||||
|
||||
fn with<Database: IDatabase, Library: ILibrary>(builder: MusicHoardBuilder<Database, Library>) {
|
||||
let music_hoard = builder.build().expect("failed to initialise MusicHoard");
|
||||
fn with<Database: IDatabase + 'static, Library: ILibrary + 'static>(
|
||||
builder: MusicHoardBuilder<Database, Library>,
|
||||
) {
|
||||
let music_hoard = Box::new(builder.build().expect("failed to initialise MusicHoard"));
|
||||
|
||||
// Initialize the terminal user interface.
|
||||
let backend = CrosstermBackend::new(io::stdout());
|
||||
@ -92,7 +94,7 @@ fn with<Database: IDatabase, Library: ILibrary>(builder: MusicHoardBuilder<Datab
|
||||
Tui::run(terminal, app, ui, handler, listener).expect("failed to run tui");
|
||||
}
|
||||
|
||||
fn with_database<Library: ILibrary>(
|
||||
fn with_database<Library: ILibrary + 'static>(
|
||||
db_opt: DbOpt,
|
||||
builder: MusicHoardBuilder<NoDatabase, Library>,
|
||||
) {
|
||||
|
@ -2,19 +2,16 @@ use std::{thread, time};
|
||||
|
||||
use musichoard::collection::musicbrainz::IMusicBrainzRef;
|
||||
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{matches::AppMatchesInfo, App, AppInner, AppMachine},
|
||||
selection::{Delta, ListSelection},
|
||||
AppPublic, AppState, IAppInteractBrowse,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{matches::AppMatchesInfo, App, AppInner, AppMachine},
|
||||
selection::{Delta, ListSelection},
|
||||
AppPublic, AppState, IAppInteractBrowse,
|
||||
};
|
||||
|
||||
pub struct AppBrowse;
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppBrowse> {
|
||||
pub fn browse(inner: AppInner<MH>) -> Self {
|
||||
impl AppMachine<AppBrowse> {
|
||||
pub fn browse(inner: AppInner) -> Self {
|
||||
AppMachine {
|
||||
inner,
|
||||
state: AppBrowse,
|
||||
@ -22,14 +19,14 @@ impl<MH: IMusicHoard> AppMachine<MH, AppBrowse> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppBrowse>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppBrowse>) -> Self {
|
||||
impl From<AppMachine<AppBrowse>> for App {
|
||||
fn from(machine: AppMachine<AppBrowse>) -> Self {
|
||||
AppState::Browse(machine)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppBrowse>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppBrowse>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppBrowse>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppBrowse>) -> Self {
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
state: AppState::Browse(()),
|
||||
@ -37,8 +34,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppBrowse>> for AppPublic<
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractBrowse for AppMachine<MH, AppBrowse> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractBrowse for AppMachine<AppBrowse> {
|
||||
type APP = App;
|
||||
|
||||
fn quit(mut self) -> Self::APP {
|
||||
self.inner.running = false;
|
||||
|
@ -1,17 +1,14 @@
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppState, IAppInteractCritical,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppState, IAppInteractCritical,
|
||||
};
|
||||
|
||||
pub struct AppCritical {
|
||||
string: String,
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppCritical> {
|
||||
pub fn critical<S: Into<String>>(inner: AppInner<MH>, string: S) -> Self {
|
||||
impl AppMachine<AppCritical> {
|
||||
pub fn critical<S: Into<String>>(inner: AppInner, string: S) -> Self {
|
||||
AppMachine {
|
||||
inner,
|
||||
state: AppCritical {
|
||||
@ -21,14 +18,14 @@ impl<MH: IMusicHoard> AppMachine<MH, AppCritical> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppCritical>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppCritical>) -> Self {
|
||||
impl From<AppMachine<AppCritical>> for App {
|
||||
fn from(machine: AppMachine<AppCritical>) -> Self {
|
||||
AppState::Critical(machine)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppCritical>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppCritical>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppCritical>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppCritical>) -> Self {
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
state: AppState::Critical(&machine.state.string),
|
||||
@ -36,8 +33,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppCritical>> for AppPubli
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractCritical for AppMachine<MH, AppCritical> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractCritical for AppMachine<AppCritical> {
|
||||
type APP = App;
|
||||
|
||||
fn no_op(self) -> Self::APP {
|
||||
self.into()
|
||||
|
@ -1,17 +1,14 @@
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppState, IAppInteractError,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppState, IAppInteractError,
|
||||
};
|
||||
|
||||
pub struct AppError {
|
||||
string: String,
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppError> {
|
||||
pub fn error<S: Into<String>>(inner: AppInner<MH>, string: S) -> Self {
|
||||
impl AppMachine<AppError> {
|
||||
pub fn error<S: Into<String>>(inner: AppInner, string: S) -> Self {
|
||||
AppMachine {
|
||||
inner,
|
||||
state: AppError {
|
||||
@ -21,14 +18,14 @@ impl<MH: IMusicHoard> AppMachine<MH, AppError> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppError>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppError>) -> Self {
|
||||
impl From<AppMachine<AppError>> for App {
|
||||
fn from(machine: AppMachine<AppError>) -> Self {
|
||||
AppState::Error(machine)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppError>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppError>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppError>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppError>) -> Self {
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
state: AppState::Error(&machine.state.string),
|
||||
@ -36,8 +33,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppError>> for AppPublic<'
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractError for AppMachine<MH, AppError> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractError for AppMachine<AppError> {
|
||||
type APP = App;
|
||||
|
||||
fn dismiss_error(self) -> Self::APP {
|
||||
AppMachine::browse(self.inner).into()
|
||||
|
@ -1,15 +1,12 @@
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppState, IAppInteractInfo,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppState, IAppInteractInfo,
|
||||
};
|
||||
|
||||
pub struct AppInfo;
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppInfo> {
|
||||
pub fn info(inner: AppInner<MH>) -> Self {
|
||||
impl AppMachine<AppInfo> {
|
||||
pub fn info(inner: AppInner) -> Self {
|
||||
AppMachine {
|
||||
inner,
|
||||
state: AppInfo,
|
||||
@ -17,14 +14,14 @@ impl<MH: IMusicHoard> AppMachine<MH, AppInfo> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppInfo>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppInfo>) -> Self {
|
||||
impl From<AppMachine<AppInfo>> for App {
|
||||
fn from(machine: AppMachine<AppInfo>) -> Self {
|
||||
AppState::Info(machine)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppInfo>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppInfo>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppInfo>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppInfo>) -> Self {
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
state: AppState::Info(()),
|
||||
@ -32,8 +29,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppInfo>> for AppPublic<'a
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractInfo for AppMachine<MH, AppInfo> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractInfo for AppMachine<AppInfo> {
|
||||
type APP = App;
|
||||
|
||||
fn hide_info_overlay(self) -> Self::APP {
|
||||
AppMachine::browse(self.inner).into()
|
||||
|
@ -2,12 +2,9 @@ use std::cmp;
|
||||
|
||||
use musichoard::{collection::album::Album, interface::musicbrainz::Match};
|
||||
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppPublicMatches, AppState, IAppInteractMatches, WidgetState,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
AppPublic, AppPublicMatches, AppState, IAppInteractMatches, WidgetState,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
@ -22,8 +19,8 @@ pub struct AppMatches {
|
||||
state: WidgetState,
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppMatches> {
|
||||
pub fn matches(inner: AppInner<MH>, matches_info_vec: Vec<AppMatchesInfo>) -> Self {
|
||||
impl AppMachine<AppMatches> {
|
||||
pub fn matches(inner: AppInner, matches_info_vec: Vec<AppMatchesInfo>) -> Self {
|
||||
let mut index = None;
|
||||
let mut state = WidgetState::default();
|
||||
if let Some(matches_info) = matches_info_vec.first() {
|
||||
@ -44,14 +41,14 @@ impl<MH: IMusicHoard> AppMachine<MH, AppMatches> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppMatches>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppMatches>) -> Self {
|
||||
impl From<AppMachine<AppMatches>> for App {
|
||||
fn from(machine: AppMachine<AppMatches>) -> Self {
|
||||
AppState::Matches(machine)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppMatches>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppMatches>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppMatches>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppMatches>) -> Self {
|
||||
let (matching, matches) = match machine.state.index {
|
||||
Some(index) => (
|
||||
Some(&machine.state.matches_info_vec[index].matching),
|
||||
@ -71,8 +68,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppMatches>> for AppPublic
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractMatches for AppMachine<MH, AppMatches> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractMatches for AppMachine<AppMatches> {
|
||||
type APP = App;
|
||||
|
||||
fn prev_match(mut self) -> Self::APP {
|
||||
if let Some(list_index) = self.state.state.list.selected() {
|
||||
|
@ -19,30 +19,30 @@ use matches::AppMatches;
|
||||
use reload::AppReload;
|
||||
use search::AppSearch;
|
||||
|
||||
pub type App<MH> = AppState<
|
||||
AppMachine<MH, AppBrowse>,
|
||||
AppMachine<MH, AppInfo>,
|
||||
AppMachine<MH, AppReload>,
|
||||
AppMachine<MH, AppSearch>,
|
||||
AppMachine<MH, AppMatches>,
|
||||
AppMachine<MH, AppError>,
|
||||
AppMachine<MH, AppCritical>,
|
||||
pub type App = AppState<
|
||||
AppMachine<AppBrowse>,
|
||||
AppMachine<AppInfo>,
|
||||
AppMachine<AppReload>,
|
||||
AppMachine<AppSearch>,
|
||||
AppMachine<AppMatches>,
|
||||
AppMachine<AppError>,
|
||||
AppMachine<AppCritical>,
|
||||
>;
|
||||
|
||||
pub struct AppMachine<MH: IMusicHoard, STATE> {
|
||||
inner: AppInner<MH>,
|
||||
pub struct AppMachine<STATE> {
|
||||
inner: AppInner,
|
||||
state: STATE,
|
||||
}
|
||||
|
||||
pub struct AppInner<MH: IMusicHoard> {
|
||||
pub struct AppInner {
|
||||
running: bool,
|
||||
music_hoard: MH,
|
||||
music_hoard: Box<dyn IMusicHoard>,
|
||||
mb_api: Box<dyn IMusicBrainz>,
|
||||
selection: Selection,
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> App<MH> {
|
||||
pub fn new(mut music_hoard: MH, mb_api: Box<dyn IMusicBrainz>) -> Self {
|
||||
impl App {
|
||||
pub fn new(mut music_hoard: Box<dyn IMusicHoard>, mb_api: Box<dyn IMusicBrainz>) -> Self {
|
||||
let init_result = Self::init(&mut music_hoard);
|
||||
let inner = AppInner::new(music_hoard, mb_api);
|
||||
match init_result {
|
||||
@ -51,12 +51,12 @@ impl<MH: IMusicHoard> App<MH> {
|
||||
}
|
||||
}
|
||||
|
||||
fn init(music_hoard: &mut MH) -> Result<(), musichoard::Error> {
|
||||
fn init(music_hoard: &mut Box<dyn IMusicHoard>) -> Result<(), musichoard::Error> {
|
||||
music_hoard.rescan_library()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn inner_ref(&self) -> &AppInner<MH> {
|
||||
fn inner_ref(&self) -> &AppInner {
|
||||
match self {
|
||||
AppState::Browse(browse) => &browse.inner,
|
||||
AppState::Info(info) => &info.inner,
|
||||
@ -68,7 +68,7 @@ impl<MH: IMusicHoard> App<MH> {
|
||||
}
|
||||
}
|
||||
|
||||
fn inner_mut(&mut self) -> &mut AppInner<MH> {
|
||||
fn inner_mut(&mut self) -> &mut AppInner {
|
||||
match self {
|
||||
AppState::Browse(browse) => &mut browse.inner,
|
||||
AppState::Info(info) => &mut info.inner,
|
||||
@ -81,14 +81,14 @@ impl<MH: IMusicHoard> App<MH> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteract for App<MH> {
|
||||
type BS = AppMachine<MH, AppBrowse>;
|
||||
type IS = AppMachine<MH, AppInfo>;
|
||||
type RS = AppMachine<MH, AppReload>;
|
||||
type SS = AppMachine<MH, AppSearch>;
|
||||
type MS = AppMachine<MH, AppMatches>;
|
||||
type ES = AppMachine<MH, AppError>;
|
||||
type CS = AppMachine<MH, AppCritical>;
|
||||
impl IAppInteract for App {
|
||||
type BS = AppMachine<AppBrowse>;
|
||||
type IS = AppMachine<AppInfo>;
|
||||
type RS = AppMachine<AppReload>;
|
||||
type SS = AppMachine<AppSearch>;
|
||||
type MS = AppMachine<AppMatches>;
|
||||
type ES = AppMachine<AppError>;
|
||||
type CS = AppMachine<AppCritical>;
|
||||
|
||||
fn is_running(&self) -> bool {
|
||||
self.inner_ref().running
|
||||
@ -106,7 +106,7 @@ impl<MH: IMusicHoard> IAppInteract for App<MH> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppAccess for App<MH> {
|
||||
impl IAppAccess for App {
|
||||
fn get(&mut self) -> AppPublic {
|
||||
match self {
|
||||
AppState::Browse(browse) => browse.into(),
|
||||
@ -120,8 +120,8 @@ impl<MH: IMusicHoard> IAppAccess for App<MH> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> AppInner<MH> {
|
||||
pub fn new(music_hoard: MH, mb_api: Box<dyn IMusicBrainz>) -> Self {
|
||||
impl AppInner {
|
||||
pub fn new(music_hoard: Box<dyn IMusicHoard>, mb_api: Box<dyn IMusicBrainz>) -> Self {
|
||||
let selection = Selection::new(music_hoard.get_collection());
|
||||
AppInner {
|
||||
running: true,
|
||||
@ -132,8 +132,8 @@ impl<MH: IMusicHoard> AppInner<MH> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppInner<MH>> for AppPublicInner<'a> {
|
||||
fn from(inner: &'a mut AppInner<MH>) -> Self {
|
||||
impl<'a> From<&'a mut AppInner> for AppPublicInner<'a> {
|
||||
fn from(inner: &'a mut AppInner) -> Self {
|
||||
AppPublicInner {
|
||||
collection: inner.music_hoard.get_collection(),
|
||||
selection: &mut inner.selection,
|
||||
@ -203,14 +203,14 @@ mod tests {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn music_hoard(collection: Collection) -> MockIMusicHoard {
|
||||
let mut music_hoard = MockIMusicHoard::new();
|
||||
pub fn music_hoard(collection: Collection) -> Box<MockIMusicHoard> {
|
||||
let mut music_hoard = Box::new(MockIMusicHoard::new());
|
||||
music_hoard.expect_get_collection().return_const(collection);
|
||||
|
||||
music_hoard
|
||||
}
|
||||
|
||||
fn music_hoard_init(collection: Collection) -> MockIMusicHoard {
|
||||
fn music_hoard_init(collection: Collection) -> Box<MockIMusicHoard> {
|
||||
let mut music_hoard = music_hoard(collection);
|
||||
|
||||
music_hoard
|
||||
@ -225,14 +225,14 @@ mod tests {
|
||||
Box::new(MockIMusicBrainz::new())
|
||||
}
|
||||
|
||||
pub fn inner(music_hoard: MockIMusicHoard) -> AppInner<MockIMusicHoard> {
|
||||
pub fn inner(music_hoard: Box<MockIMusicHoard>) -> AppInner {
|
||||
AppInner::new(music_hoard, mb_api())
|
||||
}
|
||||
|
||||
pub fn inner_with_mb(
|
||||
music_hoard: MockIMusicHoard,
|
||||
music_hoard: Box<MockIMusicHoard>,
|
||||
mb_api: Box<MockIMusicBrainz>,
|
||||
) -> AppInner<MockIMusicHoard> {
|
||||
) -> AppInner {
|
||||
AppInner::new(music_hoard, mb_api)
|
||||
}
|
||||
|
||||
@ -362,7 +362,7 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn init_error() {
|
||||
let mut music_hoard = MockIMusicHoard::new();
|
||||
let mut music_hoard = Box::new(MockIMusicHoard::new());
|
||||
|
||||
music_hoard
|
||||
.expect_rescan_library()
|
||||
|
@ -1,16 +1,13 @@
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
selection::KeySelection,
|
||||
AppPublic, AppState, IAppInteractReload,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
selection::KeySelection,
|
||||
AppPublic, AppState, IAppInteractReload,
|
||||
};
|
||||
|
||||
pub struct AppReload;
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppReload> {
|
||||
pub fn reload(inner: AppInner<MH>) -> Self {
|
||||
impl AppMachine<AppReload> {
|
||||
pub fn reload(inner: AppInner) -> Self {
|
||||
AppMachine {
|
||||
inner,
|
||||
state: AppReload,
|
||||
@ -18,13 +15,13 @@ impl<MH: IMusicHoard> AppMachine<MH, AppReload> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppReload>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppReload>) -> Self {
|
||||
impl From<AppMachine<AppReload>> for App {
|
||||
fn from(machine: AppMachine<AppReload>) -> Self {
|
||||
AppState::Reload(machine)
|
||||
}
|
||||
}
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppReload>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppReload>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppReload>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppReload>) -> Self {
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
state: AppState::Reload(()),
|
||||
@ -32,8 +29,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppReload>> for AppPublic<
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractReload for AppMachine<MH, AppReload> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractReload for AppMachine<AppReload> {
|
||||
type APP = App;
|
||||
|
||||
fn reload_library(mut self) -> Self::APP {
|
||||
let previous = KeySelection::get(
|
||||
@ -62,12 +59,12 @@ impl<MH: IMusicHoard> IAppInteractReload for AppMachine<MH, AppReload> {
|
||||
}
|
||||
}
|
||||
|
||||
trait IAppInteractReloadPrivate<MH: IMusicHoard> {
|
||||
fn refresh(self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App<MH>;
|
||||
trait IAppInteractReloadPrivate {
|
||||
fn refresh(self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App;
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractReloadPrivate<MH> for AppMachine<MH, AppReload> {
|
||||
fn refresh(mut self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App<MH> {
|
||||
impl IAppInteractReloadPrivate for AppMachine<AppReload> {
|
||||
fn refresh(mut self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App {
|
||||
match result {
|
||||
Ok(()) => {
|
||||
self.inner
|
||||
|
@ -3,13 +3,10 @@ use once_cell::sync::Lazy;
|
||||
|
||||
use musichoard::collection::{album::Album, artist::Artist, track::Track};
|
||||
|
||||
use crate::tui::{
|
||||
app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
selection::{ListSelection, SelectionState},
|
||||
AppPublic, AppState, Category, IAppInteractSearch,
|
||||
},
|
||||
lib::IMusicHoard,
|
||||
use crate::tui::app::{
|
||||
machine::{App, AppInner, AppMachine},
|
||||
selection::{ListSelection, SelectionState},
|
||||
AppPublic, AppState, Category, IAppInteractSearch,
|
||||
};
|
||||
|
||||
// Unlikely that this covers all possible strings, but it should at least cover strings
|
||||
@ -34,8 +31,8 @@ struct AppSearchMemo {
|
||||
char: bool,
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> AppMachine<MH, AppSearch> {
|
||||
pub fn search(inner: AppInner<MH>, orig: ListSelection) -> Self {
|
||||
impl AppMachine<AppSearch> {
|
||||
pub fn search(inner: AppInner, orig: ListSelection) -> Self {
|
||||
AppMachine {
|
||||
inner,
|
||||
state: AppSearch {
|
||||
@ -47,14 +44,14 @@ impl<MH: IMusicHoard> AppMachine<MH, AppSearch> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> From<AppMachine<MH, AppSearch>> for App<MH> {
|
||||
fn from(machine: AppMachine<MH, AppSearch>) -> Self {
|
||||
impl From<AppMachine<AppSearch>> for App {
|
||||
fn from(machine: AppMachine<AppSearch>) -> Self {
|
||||
AppState::Search(machine)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppSearch>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<MH, AppSearch>) -> Self {
|
||||
impl<'a> From<&'a mut AppMachine<AppSearch>> for AppPublic<'a> {
|
||||
fn from(machine: &'a mut AppMachine<AppSearch>) -> Self {
|
||||
AppPublic {
|
||||
inner: (&mut machine.inner).into(),
|
||||
state: AppState::Search(&machine.state.string),
|
||||
@ -62,8 +59,8 @@ impl<'a, MH: IMusicHoard> From<&'a mut AppMachine<MH, AppSearch>> for AppPublic<
|
||||
}
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractSearch for AppMachine<MH, AppSearch> {
|
||||
type APP = App<MH>;
|
||||
impl IAppInteractSearch for AppMachine<AppSearch> {
|
||||
type APP = App;
|
||||
|
||||
fn append_character(mut self, ch: char) -> Self::APP {
|
||||
self.state.string.push(ch);
|
||||
@ -127,7 +124,7 @@ trait IAppInteractSearchPrivate {
|
||||
fn normalize_search(search: &str, lowercase: bool, asciify: bool) -> String;
|
||||
}
|
||||
|
||||
impl<MH: IMusicHoard> IAppInteractSearchPrivate for AppMachine<MH, AppSearch> {
|
||||
impl IAppInteractSearchPrivate for AppMachine<AppSearch> {
|
||||
fn incremental_search(&mut self, next: bool) {
|
||||
let collection = self.inner.music_hoard.get_collection();
|
||||
let search = &self.state.string;
|
||||
|
@ -191,8 +191,8 @@ mod tests {
|
||||
Terminal::new(backend).unwrap()
|
||||
}
|
||||
|
||||
fn music_hoard(collection: Collection) -> MockIMusicHoard {
|
||||
let mut music_hoard = MockIMusicHoard::new();
|
||||
fn music_hoard(collection: Collection) -> Box<MockIMusicHoard> {
|
||||
let mut music_hoard = Box::new(MockIMusicHoard::new());
|
||||
|
||||
music_hoard.expect_reload_database().returning(|| Ok(()));
|
||||
music_hoard.expect_rescan_library().returning(|| Ok(()));
|
||||
@ -201,7 +201,7 @@ mod tests {
|
||||
music_hoard
|
||||
}
|
||||
|
||||
fn app(collection: Collection) -> App<MockIMusicHoard> {
|
||||
fn app(collection: Collection) -> App {
|
||||
App::new(music_hoard(collection), Box::new(MockIMusicBrainz::new()))
|
||||
}
|
||||
|
||||
@ -216,11 +216,11 @@ mod tests {
|
||||
listener
|
||||
}
|
||||
|
||||
fn handler() -> MockIEventHandler<App<MockIMusicHoard>> {
|
||||
fn handler() -> MockIEventHandler<App> {
|
||||
let mut handler = MockIEventHandler::new();
|
||||
handler
|
||||
.expect_handle_next_event()
|
||||
.return_once(|app: App<MockIMusicHoard>| Ok(app.force_quit()));
|
||||
.return_once(|app: App| Ok(app.force_quit()));
|
||||
handler
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user