Sort albums by month if two releases of the same artist happen in the same year #155
@ -75,12 +75,7 @@ fn with<LIB: ILibrary, DB: IDatabase>(builder: MusicHoardBuilder<LIB, DB>) {
|
|||||||
let ui = Ui;
|
let ui = Ui;
|
||||||
|
|
||||||
// Run the TUI application.
|
// Run the TUI application.
|
||||||
let result = Tui::run(terminal, app, ui, handler, listener);
|
Tui::run(terminal, app, ui, handler, listener).expect("failed to run tui");
|
||||||
if let Err(tui::Error::ListenerPanic(err)) = result {
|
|
||||||
std::panic::resume_unwind(err);
|
|
||||||
} else {
|
|
||||||
result.expect("failed to run tui")
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_database<LIB: ILibrary>(db_opt: DbOpt, builder: MusicHoardBuilder<LIB, NoDatabase>) {
|
fn with_database<LIB: ILibrary>(db_opt: DbOpt, builder: MusicHoardBuilder<LIB, NoDatabase>) {
|
||||||
|
@ -16,10 +16,7 @@ use crossterm::{
|
|||||||
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
|
terminal::{self, EnterAlternateScreen, LeaveAlternateScreen},
|
||||||
};
|
};
|
||||||
use ratatui::{backend::Backend, Terminal};
|
use ratatui::{backend::Backend, Terminal};
|
||||||
use std::{
|
use std::{io, marker::PhantomData};
|
||||||
marker::PhantomData,
|
|
||||||
{any::Any, io},
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::tui::{
|
use crate::tui::{
|
||||||
app::{IAppAccess, IAppInteract},
|
app::{IAppAccess, IAppInteract},
|
||||||
@ -29,11 +26,11 @@ use crate::tui::{
|
|||||||
ui::IUi,
|
ui::IUi,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Eq, PartialEq)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
Io(String),
|
Io(String),
|
||||||
Event(String),
|
Event(String),
|
||||||
ListenerPanic(Box<dyn Any + Send>),
|
ListenerPanic,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<io::Error> for Error {
|
impl From<io::Error> for Error {
|
||||||
@ -115,10 +112,9 @@ impl<B: Backend, UI: IUi, APP: IAppInteract + IAppAccess> Tui<B, UI, APP> {
|
|||||||
match listener_handle.join() {
|
match listener_handle.join() {
|
||||||
Ok(err) => return Err(err.into()),
|
Ok(err) => return Err(err.into()),
|
||||||
// Calling std::panic::resume_unwind(err) as recommended by the Rust docs
|
// Calling std::panic::resume_unwind(err) as recommended by the Rust docs
|
||||||
// will not produce an error message. The panic error message is printed at
|
// will not produce an error message. This may be due to the panic simply
|
||||||
// the location of the panic which at the time is hidden by the TUI.
|
// causing the process to abort in which case there is nothing to unwind.
|
||||||
// Therefore, propagate the error for the caller to resume unwinding.
|
Err(_) => return Err(Error::ListenerPanic),
|
||||||
Err(panic) => return Err(Error::ListenerPanic(panic)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,8 +252,8 @@ mod tests {
|
|||||||
let result = Tui::main(terminal, app, ui, handler, listener);
|
let result = Tui::main(terminal, app, ui, handler, listener);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
|
|
||||||
let recv_err = EventError::Recv.to_string();
|
let error = EventError::Recv;
|
||||||
matches!(result.unwrap_err(), Error::Event(err) if err == recv_err);
|
assert_eq!(result.unwrap_err(), Error::Event(error.to_string()));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -281,9 +277,8 @@ mod tests {
|
|||||||
let result = Tui::main(terminal, app, ui, handler, listener);
|
let result = Tui::main(terminal, app, ui, handler, listener);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
|
|
||||||
let io_err =
|
let error = EventError::Io(io::Error::new(io::ErrorKind::Interrupted, "error"));
|
||||||
EventError::Io(io::Error::new(io::ErrorKind::Interrupted, "error")).to_string();
|
assert_eq!(result.unwrap_err(), Error::Event(error.to_string()));
|
||||||
matches!(result.unwrap_err(), Error::Event(err) if err == io_err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -305,14 +300,14 @@ mod tests {
|
|||||||
|
|
||||||
let result = Tui::main(terminal, app, ui, handler, listener);
|
let result = Tui::main(terminal, app, ui, handler, listener);
|
||||||
assert!(result.is_err());
|
assert!(result.is_err());
|
||||||
assert!(matches!(result.unwrap_err(), Error::ListenerPanic(_)));
|
assert_eq!(result.unwrap_err(), Error::ListenerPanic);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn errors() {
|
fn errors() {
|
||||||
let io_err: Error = io::Error::new(io::ErrorKind::Interrupted, "error").into();
|
let io_err: Error = io::Error::new(io::ErrorKind::Interrupted, "error").into();
|
||||||
let event_err: Error = EventError::Recv.into();
|
let event_err: Error = EventError::Recv.into();
|
||||||
let listener_err = Error::ListenerPanic(Box::new("hello"));
|
let listener_err = Error::ListenerPanic;
|
||||||
|
|
||||||
assert!(!format!("{:?}", io_err).is_empty());
|
assert!(!format!("{:?}", io_err).is_empty());
|
||||||
assert!(!format!("{:?}", event_err).is_empty());
|
assert!(!format!("{:?}", event_err).is_empty());
|
||||||
|
Loading…
Reference in New Issue
Block a user