Compartamentalize machine traits
This commit is contained in:
parent
706e30f587
commit
56bf99f985
@ -94,7 +94,6 @@ fn with<Database: IDatabase + 'static, Library: ILibrary + 'static>(
|
|||||||
let app = App::new(music_hoard, musicbrainz, app_sender);
|
let app = App::new(music_hoard, musicbrainz, app_sender);
|
||||||
let ui = Ui;
|
let ui = Ui;
|
||||||
|
|
||||||
|
|
||||||
// Run the TUI application.
|
// Run the TUI application.
|
||||||
Tui::run(terminal, app, ui, handler, listener).expect("failed to run tui");
|
Tui::run(terminal, app, ui, handler, listener).expect("failed to run tui");
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ use crate::tui::{
|
|||||||
app::{
|
app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
selection::{Delta, ListSelection},
|
selection::{Delta, ListSelection},
|
||||||
AppMatchesInfo, AppPublic, AppState, IAppInteractBrowse,
|
AppMatchesInfo, AppPublic, AppState, IAppBase, IAppInteractBrowse,
|
||||||
},
|
},
|
||||||
event::{Event, EventSender},
|
event::{Event, EventSender},
|
||||||
lib::interface::musicbrainz::{self, IMusicBrainz},
|
lib::interface::musicbrainz::{self, IMusicBrainz},
|
||||||
@ -183,6 +183,10 @@ impl IAppInteractBrowse for AppMachine<AppBrowse> {
|
|||||||
|
|
||||||
AppMachine::app_fetch_new(self.inner, fetch_rx)
|
AppMachine::app_fetch_new(self.inner, fetch_rx)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppBrowse> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppInteractCritical,
|
AppPublic, AppState, IAppBase,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppCritical {
|
pub struct AppCritical {
|
||||||
@ -33,7 +33,7 @@ impl<'a> From<&'a mut AppMachine<AppCritical>> for AppPublic<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppInteractCritical for AppMachine<AppCritical> {
|
impl IAppBase for AppMachine<AppCritical> {
|
||||||
type APP = App;
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppInteractError,
|
AppPublic, AppState, IAppBase, IAppInteractError,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppError {
|
pub struct AppError {
|
||||||
@ -39,6 +39,10 @@ impl IAppInteractError for AppMachine<AppError> {
|
|||||||
fn dismiss_error(self) -> Self::APP {
|
fn dismiss_error(self) -> Self::APP {
|
||||||
AppMachine::browse(self.inner).into()
|
AppMachine::browse(self.inner).into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppError> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -3,7 +3,7 @@ use std::sync::mpsc::{self, TryRecvError};
|
|||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
app::{
|
app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppMatchesInfo, AppPublic, AppState, IAppEventFetch, IAppInteractFetch,
|
AppMatchesInfo, AppPublic, AppState, IAppBase, IAppEventFetch, IAppInteractFetch,
|
||||||
},
|
},
|
||||||
lib::interface::musicbrainz::Error as MbError,
|
lib::interface::musicbrainz::Error as MbError,
|
||||||
};
|
};
|
||||||
@ -85,6 +85,10 @@ impl IAppInteractFetch for AppMachine<AppFetch> {
|
|||||||
fn abort(self) -> Self::APP {
|
fn abort(self) -> Self::APP {
|
||||||
AppMachine::browse(self.inner).into()
|
AppMachine::browse(self.inner).into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppFetch> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppInteractInfo,
|
AppPublic, AppState, IAppBase, IAppInteractInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppInfo;
|
pub struct AppInfo;
|
||||||
@ -35,6 +35,10 @@ impl IAppInteractInfo for AppMachine<AppInfo> {
|
|||||||
fn hide_info_overlay(self) -> Self::APP {
|
fn hide_info_overlay(self) -> Self::APP {
|
||||||
AppMachine::browse(self.inner).into()
|
AppMachine::browse(self.inner).into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppInfo> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -3,7 +3,7 @@ use std::cmp;
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppAlbumMatches, AppArtistMatches, AppMatchesInfo, AppPublic, AppPublicMatches, AppState,
|
AppAlbumMatches, AppArtistMatches, AppMatchesInfo, AppPublic, AppPublicMatches, AppState,
|
||||||
IAppInteractMatches, MatchOption, WidgetState,
|
IAppBase, IAppInteractMatches, MatchOption, WidgetState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::fetch::AppFetch;
|
use super::fetch::AppFetch;
|
||||||
@ -122,6 +122,10 @@ impl IAppInteractMatches for AppMachine<AppMatches> {
|
|||||||
fn abort(self) -> Self::APP {
|
fn abort(self) -> Self::APP {
|
||||||
AppMachine::browse(self.inner).into()
|
AppMachine::browse(self.inner).into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppMatches> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
selection::KeySelection,
|
selection::KeySelection,
|
||||||
AppPublic, AppState, IAppInteractReload,
|
AppPublic, AppState, IAppBase, IAppInteractReload,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppReload;
|
pub struct AppReload;
|
||||||
@ -53,6 +53,10 @@ impl IAppInteractReload for AppMachine<AppReload> {
|
|||||||
fn hide_reload_menu(self) -> Self::APP {
|
fn hide_reload_menu(self) -> Self::APP {
|
||||||
AppMachine::browse(self.inner).into()
|
AppMachine::browse(self.inner).into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppReload> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -6,7 +6,7 @@ use musichoard::collection::{album::Album, artist::Artist, track::Track};
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
selection::{ListSelection, SelectionState},
|
selection::{ListSelection, SelectionState},
|
||||||
AppPublic, AppState, Category, IAppInteractSearch,
|
AppPublic, AppState, Category, IAppBase, IAppInteractSearch,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Unlikely that this covers all possible strings, but it should at least cover strings
|
// Unlikely that this covers all possible strings, but it should at least cover strings
|
||||||
@ -98,6 +98,10 @@ impl IAppInteractSearch for AppMachine<AppSearch> {
|
|||||||
self.inner.selection.select_by_list(self.state.orig);
|
self.inner.selection.select_by_list(self.state.orig);
|
||||||
AppMachine::browse(self.inner).into()
|
AppMachine::browse(self.inner).into()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IAppBase for AppMachine<AppSearch> {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
fn no_op(self) -> Self::APP {
|
||||||
self.into()
|
self.into()
|
||||||
|
@ -20,14 +20,14 @@ pub enum AppState<BS, IS, RS, SS, FS, MS, ES, CS> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppInteract {
|
pub trait IAppInteract {
|
||||||
type BS: IAppInteractBrowse<APP = Self>;
|
type BS: IAppBase<APP = Self> + IAppInteractBrowse<APP = Self>;
|
||||||
type IS: IAppInteractInfo<APP = Self>;
|
type IS: IAppBase<APP = Self> + IAppInteractInfo<APP = Self>;
|
||||||
type RS: IAppInteractReload<APP = Self>;
|
type RS: IAppBase<APP = Self> + IAppInteractReload<APP = Self>;
|
||||||
type SS: IAppInteractSearch<APP = Self>;
|
type SS: IAppBase<APP = Self> + IAppInteractSearch<APP = Self>;
|
||||||
type FS: IAppInteractFetch<APP = Self> + IAppEventFetch<APP = Self>;
|
type FS: IAppBase<APP = Self> + IAppInteractFetch<APP = Self> + IAppEventFetch<APP = Self>;
|
||||||
type MS: IAppInteractMatches<APP = Self>;
|
type MS: IAppBase<APP = Self> + IAppInteractMatches<APP = Self>;
|
||||||
type ES: IAppInteractError<APP = Self>;
|
type ES: IAppBase<APP = Self> + IAppInteractError<APP = Self>;
|
||||||
type CS: IAppInteractCritical<APP = Self>;
|
type CS: IAppBase<APP = Self>;
|
||||||
|
|
||||||
fn is_running(&self) -> bool;
|
fn is_running(&self) -> bool;
|
||||||
fn force_quit(self) -> Self;
|
fn force_quit(self) -> Self;
|
||||||
@ -38,6 +38,12 @@ pub trait IAppInteract {
|
|||||||
) -> AppState<Self::BS, Self::IS, Self::RS, Self::SS, Self::FS, Self::MS, Self::ES, Self::CS>;
|
) -> AppState<Self::BS, Self::IS, Self::RS, Self::SS, Self::FS, Self::MS, Self::ES, Self::CS>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub trait IAppBase {
|
||||||
|
type APP: IAppInteract;
|
||||||
|
|
||||||
|
fn no_op(self) -> Self::APP;
|
||||||
|
}
|
||||||
|
|
||||||
pub trait IAppInteractBrowse {
|
pub trait IAppInteractBrowse {
|
||||||
type APP: IAppInteract;
|
type APP: IAppInteract;
|
||||||
|
|
||||||
@ -55,16 +61,12 @@ pub trait IAppInteractBrowse {
|
|||||||
fn begin_search(self) -> Self::APP;
|
fn begin_search(self) -> Self::APP;
|
||||||
|
|
||||||
fn fetch_musicbrainz(self) -> Self::APP;
|
fn fetch_musicbrainz(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppInteractInfo {
|
pub trait IAppInteractInfo {
|
||||||
type APP: IAppInteract;
|
type APP: IAppInteract;
|
||||||
|
|
||||||
fn hide_info_overlay(self) -> Self::APP;
|
fn hide_info_overlay(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppInteractReload {
|
pub trait IAppInteractReload {
|
||||||
@ -73,8 +75,6 @@ pub trait IAppInteractReload {
|
|||||||
fn reload_library(self) -> Self::APP;
|
fn reload_library(self) -> Self::APP;
|
||||||
fn reload_database(self) -> Self::APP;
|
fn reload_database(self) -> Self::APP;
|
||||||
fn hide_reload_menu(self) -> Self::APP;
|
fn hide_reload_menu(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppInteractSearch {
|
pub trait IAppInteractSearch {
|
||||||
@ -85,16 +85,12 @@ pub trait IAppInteractSearch {
|
|||||||
fn step_back(self) -> Self::APP;
|
fn step_back(self) -> Self::APP;
|
||||||
fn finish_search(self) -> Self::APP;
|
fn finish_search(self) -> Self::APP;
|
||||||
fn cancel_search(self) -> Self::APP;
|
fn cancel_search(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppInteractFetch {
|
pub trait IAppInteractFetch {
|
||||||
type APP: IAppInteract;
|
type APP: IAppInteract;
|
||||||
|
|
||||||
fn abort(self) -> Self::APP;
|
fn abort(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppEventFetch {
|
pub trait IAppEventFetch {
|
||||||
@ -111,22 +107,12 @@ pub trait IAppInteractMatches {
|
|||||||
fn select(self) -> Self::APP;
|
fn select(self) -> Self::APP;
|
||||||
|
|
||||||
fn abort(self) -> Self::APP;
|
fn abort(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait IAppInteractError {
|
pub trait IAppInteractError {
|
||||||
type APP: IAppInteract;
|
type APP: IAppInteract;
|
||||||
|
|
||||||
fn dismiss_error(self) -> Self::APP;
|
fn dismiss_error(self) -> Self::APP;
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub trait IAppInteractCritical {
|
|
||||||
type APP: IAppInteract;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// It would be preferable to have a getter for each field separately. However, the selection field
|
// It would be preferable to have a getter for each field separately. However, the selection field
|
||||||
|
@ -5,14 +5,13 @@ use mockall::automock;
|
|||||||
|
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
app::{
|
app::{
|
||||||
AppState, Delta, IAppInteract, IAppInteractBrowse, IAppInteractCritical, IAppInteractError,
|
AppState, Delta, IAppInteract, IAppInteractBrowse, IAppInteractError, IAppInteractFetch,
|
||||||
IAppInteractFetch, IAppInteractInfo, IAppInteractMatches, IAppInteractReload,
|
IAppInteractInfo, IAppInteractMatches, IAppInteractReload, IAppInteractSearch,
|
||||||
IAppInteractSearch,
|
|
||||||
},
|
},
|
||||||
event::{Event, EventError, EventReceiver},
|
event::{Event, EventError, EventReceiver},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::app::IAppEventFetch;
|
use super::app::{IAppBase, IAppEventFetch};
|
||||||
|
|
||||||
#[cfg_attr(test, automock)]
|
#[cfg_attr(test, automock)]
|
||||||
pub trait IEventHandler<APP: IAppInteract> {
|
pub trait IEventHandler<APP: IAppInteract> {
|
||||||
|
Loading…
Reference in New Issue
Block a user