Handle idle time between fetch results #212
@ -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, IAppBase, IAppInteractBrowse,
|
AppMatchesInfo, AppPublic, AppState, IAppInteractBrowse,
|
||||||
},
|
},
|
||||||
event::{Event, EventSender},
|
event::{Event, EventSender},
|
||||||
lib::interface::musicbrainz::{self, IMusicBrainz},
|
lib::interface::musicbrainz::{self, IMusicBrainz},
|
||||||
@ -185,14 +185,6 @@ impl IAppInteractBrowse for AppMachine<AppBrowse> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppBrowse> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use mockall::{predicate, Sequence};
|
use mockall::{predicate, Sequence};
|
||||||
@ -490,11 +482,4 @@ mod tests {
|
|||||||
|
|
||||||
assert_eq!(fetch_rx.try_recv().unwrap_err(), TryRecvError::Disconnected);
|
assert_eq!(fetch_rx.try_recv().unwrap_err(), TryRecvError::Disconnected);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let browse = AppMachine::browse(inner(music_hoard(vec![])));
|
|
||||||
let app = browse.no_op();
|
|
||||||
app.unwrap_browse();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppBase,
|
AppPublic, AppState,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppCritical {
|
pub struct AppCritical {
|
||||||
@ -32,25 +32,3 @@ impl<'a> From<&'a mut AppMachine<AppCritical>> for AppPublic<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppCritical> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use crate::tui::app::machine::tests::{inner, music_hoard};
|
|
||||||
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let critical = AppMachine::critical(inner(music_hoard(vec![])), "get rekt");
|
|
||||||
let app = critical.no_op();
|
|
||||||
app.unwrap_critical();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppBase, IAppInteractError,
|
AppPublic, AppState, IAppInteractError,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppError {
|
pub struct AppError {
|
||||||
@ -41,14 +41,6 @@ impl IAppInteractError for AppMachine<AppError> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppError> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::tui::app::machine::tests::{inner, music_hoard};
|
use crate::tui::app::machine::tests::{inner, music_hoard};
|
||||||
@ -61,11 +53,4 @@ mod tests {
|
|||||||
let app = error.dismiss_error();
|
let app = error.dismiss_error();
|
||||||
app.unwrap_browse();
|
app.unwrap_browse();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let error = AppMachine::error(inner(music_hoard(vec![])), "get rekt");
|
|
||||||
let app = error.no_op();
|
|
||||||
app.unwrap_error();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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, IAppBase, IAppEventFetch, IAppInteractFetch,
|
AppMatchesInfo, AppPublic, AppState, IAppEventFetch, IAppInteractFetch,
|
||||||
},
|
},
|
||||||
lib::interface::musicbrainz::Error as MbError,
|
lib::interface::musicbrainz::Error as MbError,
|
||||||
};
|
};
|
||||||
@ -87,14 +87,6 @@ impl IAppInteractFetch for AppMachine<AppFetch> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppFetch> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl IAppEventFetch for AppMachine<AppFetch> {
|
impl IAppEventFetch for AppMachine<AppFetch> {
|
||||||
type APP = App;
|
type APP = App;
|
||||||
|
|
||||||
@ -188,15 +180,4 @@ mod tests {
|
|||||||
let app = app.abort();
|
let app = app.abort();
|
||||||
assert!(matches!(app, AppState::Browse(_)));
|
assert!(matches!(app, AppState::Browse(_)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let (_, rx) = mpsc::channel::<FetchResult>();
|
|
||||||
|
|
||||||
let fetch = AppFetch::new(rx);
|
|
||||||
let app = AppMachine::fetch(inner(music_hoard(COLLECTION.clone())), fetch);
|
|
||||||
|
|
||||||
let app = app.no_op();
|
|
||||||
assert!(matches!(app, AppState::Fetch(_)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use crate::tui::app::{
|
use crate::tui::app::{
|
||||||
machine::{App, AppInner, AppMachine},
|
machine::{App, AppInner, AppMachine},
|
||||||
AppPublic, AppState, IAppBase, IAppInteractInfo,
|
AppPublic, AppState, IAppInteractInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppInfo;
|
pub struct AppInfo;
|
||||||
@ -37,14 +37,6 @@ impl IAppInteractInfo for AppMachine<AppInfo> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppInfo> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::tui::app::machine::tests::{inner, music_hoard};
|
use crate::tui::app::machine::tests::{inner, music_hoard};
|
||||||
@ -57,11 +49,4 @@ mod tests {
|
|||||||
let app = info.hide_info_overlay();
|
let app = info.hide_info_overlay();
|
||||||
app.unwrap_browse();
|
app.unwrap_browse();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let info = AppMachine::info(inner(music_hoard(vec![])));
|
|
||||||
let app = info.no_op();
|
|
||||||
app.unwrap_info();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
IAppBase, IAppInteractMatches, MatchOption, WidgetState,
|
IAppInteractMatches, MatchOption, WidgetState,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::fetch::AppFetch;
|
use super::fetch::AppFetch;
|
||||||
@ -124,14 +124,6 @@ impl IAppInteractMatches for AppMachine<AppMatches> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppMatches> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
@ -213,7 +205,7 @@ mod tests {
|
|||||||
assert_eq!(matches.state.current, None);
|
assert_eq!(matches.state.current, None);
|
||||||
assert_eq!(matches.state.state, widget_state);
|
assert_eq!(matches.state.state, widget_state);
|
||||||
|
|
||||||
let mut app = matches.no_op();
|
let mut app: App = matches.into();
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
let public_matches = public.state.unwrap_matches();
|
let public_matches = public.state.unwrap_matches();
|
||||||
|
|
||||||
@ -236,7 +228,7 @@ mod tests {
|
|||||||
assert_eq!(matches.state.current.as_ref(), Some(&album_match));
|
assert_eq!(matches.state.current.as_ref(), Some(&album_match));
|
||||||
assert_eq!(matches.state.state, widget_state);
|
assert_eq!(matches.state.state, widget_state);
|
||||||
|
|
||||||
let mut app = matches.no_op();
|
let mut app: App = matches.into();
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
let public_matches = public.state.unwrap_matches();
|
let public_matches = public.state.unwrap_matches();
|
||||||
|
|
||||||
@ -319,11 +311,4 @@ mod tests {
|
|||||||
let matches = AppMachine::matches(inner(music_hoard(vec![])), matches(None));
|
let matches = AppMachine::matches(inner(music_hoard(vec![])), matches(None));
|
||||||
matches.select().unwrap_browse();
|
matches.select().unwrap_browse();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let matches = AppMachine::matches(inner(music_hoard(vec![])), matches(None));
|
|
||||||
let app = matches.no_op();
|
|
||||||
app.unwrap_matches();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,8 @@ use matches::AppMatches;
|
|||||||
use reload::AppReload;
|
use reload::AppReload;
|
||||||
use search::AppSearch;
|
use search::AppSearch;
|
||||||
|
|
||||||
|
use super::IAppBase;
|
||||||
|
|
||||||
pub type App = AppState<
|
pub type App = AppState<
|
||||||
AppMachine<AppBrowse>,
|
AppMachine<AppBrowse>,
|
||||||
AppMachine<AppInfo>,
|
AppMachine<AppInfo>,
|
||||||
@ -121,6 +123,14 @@ impl IAppInteract for App {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Into<App>> IAppBase for T {
|
||||||
|
type APP = App;
|
||||||
|
|
||||||
|
fn no_op(self) -> Self::APP {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl IAppAccess for App {
|
impl IAppAccess for App {
|
||||||
fn get(&mut self) -> AppPublic {
|
fn get(&mut self) -> AppPublic {
|
||||||
match self {
|
match self {
|
||||||
@ -277,6 +287,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Browse(_)));
|
assert!(matches!(state, AppState::Browse(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Browse(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Browse(_)));
|
assert!(matches!(public.state, AppState::Browse(_)));
|
||||||
|
|
||||||
@ -295,6 +310,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Info(_)));
|
assert!(matches!(state, AppState::Info(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Info(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Info(_)));
|
assert!(matches!(public.state, AppState::Info(_)));
|
||||||
|
|
||||||
@ -313,6 +333,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Reload(_)));
|
assert!(matches!(state, AppState::Reload(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Reload(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Reload(_)));
|
assert!(matches!(public.state, AppState::Reload(_)));
|
||||||
|
|
||||||
@ -331,6 +356,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Search(_)));
|
assert!(matches!(state, AppState::Search(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Search(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Search("")));
|
assert!(matches!(public.state, AppState::Search("")));
|
||||||
|
|
||||||
@ -352,6 +382,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Fetch(_)));
|
assert!(matches!(state, AppState::Fetch(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Fetch(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Fetch(_)));
|
assert!(matches!(public.state, AppState::Fetch(_)));
|
||||||
|
|
||||||
@ -372,6 +407,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Matches(_)));
|
assert!(matches!(state, AppState::Matches(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Matches(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Matches(_)));
|
assert!(matches!(public.state, AppState::Matches(_)));
|
||||||
|
|
||||||
@ -390,6 +430,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Error(_)));
|
assert!(matches!(state, AppState::Error(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Error(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Error("get rekt")));
|
assert!(matches!(public.state, AppState::Error("get rekt")));
|
||||||
|
|
||||||
@ -408,6 +453,11 @@ mod tests {
|
|||||||
assert!(matches!(state, AppState::Critical(_)));
|
assert!(matches!(state, AppState::Critical(_)));
|
||||||
app = state;
|
app = state;
|
||||||
|
|
||||||
|
app = app.no_op();
|
||||||
|
let state = app.state();
|
||||||
|
assert!(matches!(state, AppState::Critical(_)));
|
||||||
|
app = state;
|
||||||
|
|
||||||
let public = app.get();
|
let public = app.get();
|
||||||
assert!(matches!(public.state, AppState::Critical("get rekt")));
|
assert!(matches!(public.state, AppState::Critical("get rekt")));
|
||||||
|
|
||||||
|
@ -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, IAppBase, IAppInteractReload,
|
AppPublic, AppState, IAppInteractReload,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct AppReload;
|
pub struct AppReload;
|
||||||
@ -55,14 +55,6 @@ impl IAppInteractReload for AppMachine<AppReload> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppReload> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait IAppInteractReloadPrivate {
|
trait IAppInteractReloadPrivate {
|
||||||
fn refresh(self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App;
|
fn refresh(self, previous: KeySelection, result: Result<(), musichoard::Error>) -> App;
|
||||||
}
|
}
|
||||||
@ -135,11 +127,4 @@ mod tests {
|
|||||||
let app = reload.reload_database();
|
let app = reload.reload_database();
|
||||||
app.unwrap_error();
|
app.unwrap_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let reload = AppMachine::reload(inner(music_hoard(vec![])));
|
|
||||||
let app = reload.no_op();
|
|
||||||
app.unwrap_reload();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -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, IAppBase, IAppInteractSearch,
|
AppPublic, AppState, Category, 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
|
||||||
@ -100,14 +100,6 @@ impl IAppInteractSearch for AppMachine<AppSearch> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IAppBase for AppMachine<AppSearch> {
|
|
||||||
type APP = App;
|
|
||||||
|
|
||||||
fn no_op(self) -> Self::APP {
|
|
||||||
self.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
trait IAppInteractSearchPrivate {
|
trait IAppInteractSearchPrivate {
|
||||||
fn incremental_search(&mut self, next: bool);
|
fn incremental_search(&mut self, next: bool);
|
||||||
fn next<P, T>(pred: P, name: &str, next: bool, st: SelectionState<'_, T>) -> Option<usize>
|
fn next<P, T>(pred: P, name: &str, next: bool, st: SelectionState<'_, T>) -> Option<usize>
|
||||||
@ -548,13 +540,6 @@ mod tests {
|
|||||||
let browse = search.cancel_search().unwrap_browse();
|
let browse = search.cancel_search().unwrap_browse();
|
||||||
assert_eq!(browse.inner.selection.selected(), None);
|
assert_eq!(browse.inner.selection.selected(), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn no_op() {
|
|
||||||
let search = AppMachine::search(inner(music_hoard(vec![])), orig(None));
|
|
||||||
let app = search.no_op();
|
|
||||||
app.unwrap_search();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(nightly)]
|
#[cfg(nightly)]
|
||||||
|
Loading…
Reference in New Issue
Block a user