Append I to interface traits
This commit is contained in:
parent
712d3a65a7
commit
badee4a5b5
@ -6,7 +6,7 @@ use serde::Serialize;
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use mockall::automock;
|
use mockall::automock;
|
||||||
|
|
||||||
use super::{Database, Error};
|
use super::{Error, IDatabase};
|
||||||
|
|
||||||
pub mod backend;
|
pub mod backend;
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ impl<JDB: JsonDatabaseBackend> JsonDatabase<JDB> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<JDB: JsonDatabaseBackend> Database for JsonDatabase<JDB> {
|
impl<JDB: JsonDatabaseBackend> IDatabase for JsonDatabase<JDB> {
|
||||||
fn read<D: DeserializeOwned>(&self, collection: &mut D) -> Result<(), Error> {
|
fn read<D: DeserializeOwned>(&self, collection: &mut D) -> Result<(), Error> {
|
||||||
let serialized = self.backend.read()?;
|
let serialized = self.backend.read()?;
|
||||||
*collection = serde_json::from_str(&serialized)?;
|
*collection = serde_json::from_str(&serialized)?;
|
||||||
|
@ -38,7 +38,7 @@ impl From<std::io::Error> for Error {
|
|||||||
|
|
||||||
/// Trait for interacting with the database.
|
/// Trait for interacting with the database.
|
||||||
#[cfg_attr(test, automock)]
|
#[cfg_attr(test, automock)]
|
||||||
pub trait Database {
|
pub trait IDatabase {
|
||||||
/// Read collection from the database.
|
/// Read collection from the database.
|
||||||
fn read<D: DeserializeOwned + 'static>(&self, collection: &mut D) -> Result<(), Error>;
|
fn read<D: DeserializeOwned + 'static>(&self, collection: &mut D) -> Result<(), Error>;
|
||||||
|
|
||||||
|
20
src/lib.rs
20
src/lib.rs
@ -5,8 +5,8 @@ pub mod library;
|
|||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use database::Database;
|
use database::IDatabase;
|
||||||
use library::{Library, Query};
|
use library::{ILibrary, Query};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
@ -99,7 +99,7 @@ pub struct MusicHoard<LIB, DB> {
|
|||||||
collection: Collection,
|
collection: Collection,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<LIB: Library, DB: Database> MusicHoard<LIB, DB> {
|
impl<LIB: ILibrary, DB: IDatabase> MusicHoard<LIB, DB> {
|
||||||
/// Create a new [`MusicHoard`] with the provided [`Library`] and [`Database`].
|
/// Create a new [`MusicHoard`] with the provided [`Library`] and [`Database`].
|
||||||
pub fn new(library: LIB, database: DB) -> Self {
|
pub fn new(library: LIB, database: DB) -> Self {
|
||||||
MusicHoard {
|
MusicHoard {
|
||||||
@ -133,7 +133,7 @@ mod tests {
|
|||||||
use mockall::predicate;
|
use mockall::predicate;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
|
|
||||||
use crate::{database::MockDatabase, library::MockLibrary};
|
use crate::{database::MockIDatabase, library::MockILibrary};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
@ -141,8 +141,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn read_get_write() {
|
fn read_get_write() {
|
||||||
let mut library = MockLibrary::new();
|
let mut library = MockILibrary::new();
|
||||||
let mut database = MockDatabase::new();
|
let mut database = MockIDatabase::new();
|
||||||
|
|
||||||
let library_input = Query::new();
|
let library_input = Query::new();
|
||||||
let library_result = Ok(COLLECTION.to_owned());
|
let library_result = Ok(COLLECTION.to_owned());
|
||||||
@ -171,8 +171,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn library_error() {
|
fn library_error() {
|
||||||
let mut library = MockLibrary::new();
|
let mut library = MockILibrary::new();
|
||||||
let database = MockDatabase::new();
|
let database = MockIDatabase::new();
|
||||||
|
|
||||||
let library_result = Err(library::Error::Invalid(String::from("invalid data")));
|
let library_result = Err(library::Error::Invalid(String::from("invalid data")));
|
||||||
|
|
||||||
@ -193,8 +193,8 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn database_error() {
|
fn database_error() {
|
||||||
let library = MockLibrary::new();
|
let library = MockILibrary::new();
|
||||||
let mut database = MockDatabase::new();
|
let mut database = MockIDatabase::new();
|
||||||
|
|
||||||
let database_result = Err(database::Error::IoError(String::from("I/O error")));
|
let database_result = Err(database::Error::IoError(String::from("I/O error")));
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ use mockall::automock;
|
|||||||
|
|
||||||
use crate::{Album, AlbumId, Artist, ArtistId, Track, TrackFormat};
|
use crate::{Album, AlbumId, Artist, ArtistId, Track, TrackFormat};
|
||||||
|
|
||||||
use super::{Error, Field, Library, Query};
|
use super::{Error, Field, ILibrary, Query};
|
||||||
|
|
||||||
pub mod executor;
|
pub mod executor;
|
||||||
|
|
||||||
@ -101,7 +101,7 @@ impl<BLE: BeetsLibraryExecutor> BeetsLibrary<BLE> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<BLE: BeetsLibraryExecutor> Library for BeetsLibrary<BLE> {
|
impl<BLE: BeetsLibraryExecutor> ILibrary for BeetsLibrary<BLE> {
|
||||||
fn list(&mut self, query: &Query) -> Result<Vec<Artist>, Error> {
|
fn list(&mut self, query: &Query) -> Result<Vec<Artist>, Error> {
|
||||||
let cmd = Self::list_cmd_and_args(query);
|
let cmd = Self::list_cmd_and_args(query);
|
||||||
let output = self.executor.exec(&cmd)?;
|
let output = self.executor.exec(&cmd)?;
|
||||||
|
@ -105,7 +105,7 @@ impl From<Utf8Error> for Error {
|
|||||||
|
|
||||||
/// Trait for interacting with the music library.
|
/// Trait for interacting with the music library.
|
||||||
#[cfg_attr(test, automock)]
|
#[cfg_attr(test, automock)]
|
||||||
pub trait Library {
|
pub trait ILibrary {
|
||||||
/// List lirbary items that match the a specific query.
|
/// List lirbary items that match the a specific query.
|
||||||
fn list(&mut self, query: &Query) -> Result<Vec<Artist>, Error>;
|
fn list(&mut self, query: &Query) -> Result<Vec<Artist>, Error>;
|
||||||
}
|
}
|
||||||
|
10
src/main.rs
10
src/main.rs
@ -7,21 +7,21 @@ use structopt::StructOpt;
|
|||||||
use musichoard::{
|
use musichoard::{
|
||||||
database::{
|
database::{
|
||||||
json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
||||||
Database,
|
IDatabase,
|
||||||
},
|
},
|
||||||
library::{
|
library::{
|
||||||
beets::{
|
beets::{
|
||||||
executor::{ssh::BeetsLibrarySshExecutor, BeetsLibraryProcessExecutor},
|
executor::{ssh::BeetsLibrarySshExecutor, BeetsLibraryProcessExecutor},
|
||||||
BeetsLibrary,
|
BeetsLibrary,
|
||||||
},
|
},
|
||||||
Library,
|
ILibrary,
|
||||||
},
|
},
|
||||||
MusicHoard,
|
MusicHoard,
|
||||||
};
|
};
|
||||||
|
|
||||||
mod tui;
|
mod tui;
|
||||||
use tui::ui::MhUi;
|
use tui::ui::MhUi;
|
||||||
use tui::{event::EventChannel, handler::TuiEventHandler, listener::TuiEventListener, Tui};
|
use tui::{event::EventChannel, handler::TuiEventHandler, listener::EventListener, Tui};
|
||||||
|
|
||||||
#[derive(StructOpt)]
|
#[derive(StructOpt)]
|
||||||
struct Opt {
|
struct Opt {
|
||||||
@ -39,7 +39,7 @@ struct Opt {
|
|||||||
database_file_path: PathBuf,
|
database_file_path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with<LIB: Library, DB: Database>(lib: LIB, db: DB) {
|
fn with<LIB: ILibrary, DB: IDatabase>(lib: LIB, db: DB) {
|
||||||
let music_hoard = MusicHoard::new(lib, db);
|
let music_hoard = MusicHoard::new(lib, db);
|
||||||
|
|
||||||
// Initialize the terminal user interface.
|
// Initialize the terminal user interface.
|
||||||
@ -47,7 +47,7 @@ fn with<LIB: Library, DB: Database>(lib: LIB, db: DB) {
|
|||||||
let terminal = Terminal::new(backend).expect("failed to initialise terminal");
|
let terminal = Terminal::new(backend).expect("failed to initialise terminal");
|
||||||
|
|
||||||
let channel = EventChannel::new();
|
let channel = EventChannel::new();
|
||||||
let listener = TuiEventListener::new(channel.sender());
|
let listener = EventListener::new(channel.sender());
|
||||||
let handler = TuiEventHandler::new(channel.receiver());
|
let handler = TuiEventHandler::new(channel.receiver());
|
||||||
|
|
||||||
let ui = MhUi::new(music_hoard).expect("failed to initialise ui");
|
let ui = MhUi::new(music_hoard).expect("failed to initialise ui");
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use musichoard::{MusicHoard, library::Library, database::Database, Collection};
|
use musichoard::{database::IDatabase, library::ILibrary, Collection, MusicHoard};
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use mockall::automock;
|
use mockall::automock;
|
||||||
@ -18,7 +18,7 @@ impl From<musichoard::Error> for Error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GRCOV_EXCL_START
|
// GRCOV_EXCL_START
|
||||||
impl<LIB: Library, DB: Database> IMusicHoard for MusicHoard<LIB, DB> {
|
impl<LIB: ILibrary, DB: IDatabase> IMusicHoard for MusicHoard<LIB, DB> {
|
||||||
fn rescan_library(&mut self) -> Result<(), Error> {
|
fn rescan_library(&mut self) -> Result<(), Error> {
|
||||||
Ok(MusicHoard::rescan_library(self)?)
|
Ok(MusicHoard::rescan_library(self)?)
|
||||||
}
|
}
|
||||||
|
@ -7,22 +7,22 @@ use mockall::automock;
|
|||||||
use super::event::{Event, EventError, EventSender};
|
use super::event::{Event, EventError, EventSender};
|
||||||
|
|
||||||
#[cfg_attr(test, automock)]
|
#[cfg_attr(test, automock)]
|
||||||
pub trait EventListener {
|
pub trait IEventListener {
|
||||||
fn spawn(self) -> thread::JoinHandle<EventError>;
|
fn spawn(self) -> thread::JoinHandle<EventError>;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct TuiEventListener {
|
pub struct EventListener {
|
||||||
events: EventSender,
|
events: EventSender,
|
||||||
}
|
}
|
||||||
|
|
||||||
// GRCOV_EXCL_START
|
// GRCOV_EXCL_START
|
||||||
impl TuiEventListener {
|
impl EventListener {
|
||||||
pub fn new(events: EventSender) -> Self {
|
pub fn new(events: EventSender) -> Self {
|
||||||
TuiEventListener { events }
|
EventListener { events }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EventListener for TuiEventListener {
|
impl IEventListener for EventListener {
|
||||||
fn spawn(self) -> thread::JoinHandle<EventError> {
|
fn spawn(self) -> thread::JoinHandle<EventError> {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
loop {
|
loop {
|
||||||
|
@ -14,7 +14,7 @@ use std::marker::PhantomData;
|
|||||||
|
|
||||||
use self::event::EventError;
|
use self::event::EventError;
|
||||||
use self::handler::EventHandler;
|
use self::handler::EventHandler;
|
||||||
use self::listener::EventListener;
|
use self::listener::IEventListener;
|
||||||
use self::ui::Ui;
|
use self::ui::Ui;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq)]
|
#[derive(Debug, PartialEq, Eq)]
|
||||||
@ -72,7 +72,7 @@ impl<B: Backend, UI: Ui> Tui<B, UI> {
|
|||||||
term: Terminal<B>,
|
term: Terminal<B>,
|
||||||
ui: UI,
|
ui: UI,
|
||||||
handler: impl EventHandler<UI>,
|
handler: impl EventHandler<UI>,
|
||||||
listener: impl EventListener,
|
listener: impl IEventListener,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
let mut tui = Tui {
|
let mut tui = Tui {
|
||||||
terminal: term,
|
terminal: term,
|
||||||
@ -131,7 +131,7 @@ impl<B: Backend, UI: Ui> Tui<B, UI> {
|
|||||||
term: Terminal<B>,
|
term: Terminal<B>,
|
||||||
ui: UI,
|
ui: UI,
|
||||||
handler: impl EventHandler<UI>,
|
handler: impl EventHandler<UI>,
|
||||||
listener: impl EventListener,
|
listener: impl IEventListener,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
Self::enable()?;
|
Self::enable()?;
|
||||||
let result = Self::main(term, ui, handler, listener);
|
let result = Self::main(term, ui, handler, listener);
|
||||||
@ -164,7 +164,7 @@ mod tests {
|
|||||||
event::EventError,
|
event::EventError,
|
||||||
handler::MockEventHandler,
|
handler::MockEventHandler,
|
||||||
lib::MockIMusicHoard,
|
lib::MockIMusicHoard,
|
||||||
listener::MockEventListener,
|
listener::MockIEventListener,
|
||||||
ui::{MhUi, Ui},
|
ui::{MhUi, Ui},
|
||||||
Error, Tui,
|
Error, Tui,
|
||||||
};
|
};
|
||||||
@ -183,8 +183,8 @@ mod tests {
|
|||||||
MhUi::new(music_hoard).unwrap()
|
MhUi::new(music_hoard).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn listener() -> MockEventListener {
|
fn listener() -> MockIEventListener {
|
||||||
let mut listener = MockEventListener::new();
|
let mut listener = MockIEventListener::new();
|
||||||
listener.expect_spawn().return_once(|| {
|
listener.expect_spawn().return_once(|| {
|
||||||
thread::spawn(|| {
|
thread::spawn(|| {
|
||||||
thread::park();
|
thread::park();
|
||||||
@ -246,7 +246,7 @@ mod tests {
|
|||||||
let listener_handle: thread::JoinHandle<EventError> = thread::spawn(|| error);
|
let listener_handle: thread::JoinHandle<EventError> = thread::spawn(|| error);
|
||||||
while !listener_handle.is_finished() {}
|
while !listener_handle.is_finished() {}
|
||||||
|
|
||||||
let mut listener = MockEventListener::new();
|
let mut listener = MockIEventListener::new();
|
||||||
listener.expect_spawn().return_once(|| listener_handle);
|
listener.expect_spawn().return_once(|| listener_handle);
|
||||||
|
|
||||||
let mut handler = MockEventHandler::new();
|
let mut handler = MockEventHandler::new();
|
||||||
@ -269,7 +269,7 @@ mod tests {
|
|||||||
let listener_handle: thread::JoinHandle<EventError> = thread::spawn(|| panic!());
|
let listener_handle: thread::JoinHandle<EventError> = thread::spawn(|| panic!());
|
||||||
while !listener_handle.is_finished() {}
|
while !listener_handle.is_finished() {}
|
||||||
|
|
||||||
let mut listener = MockEventListener::new();
|
let mut listener = MockIEventListener::new();
|
||||||
listener.expect_spawn().return_once(|| listener_handle);
|
listener.expect_spawn().return_once(|| listener_handle);
|
||||||
|
|
||||||
let mut handler = MockEventHandler::new();
|
let mut handler = MockEventHandler::new();
|
||||||
|
@ -3,7 +3,7 @@ use std::{fs, path::PathBuf};
|
|||||||
use musichoard::{
|
use musichoard::{
|
||||||
database::{
|
database::{
|
||||||
json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
json::{backend::JsonDatabaseFileBackend, JsonDatabase},
|
||||||
Database,
|
IDatabase,
|
||||||
},
|
},
|
||||||
Artist,
|
Artist,
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ use once_cell::sync::Lazy;
|
|||||||
use musichoard::{
|
use musichoard::{
|
||||||
library::{
|
library::{
|
||||||
beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary},
|
beets::{executor::BeetsLibraryProcessExecutor, BeetsLibrary},
|
||||||
Field, Library, Query,
|
Field, ILibrary, Query,
|
||||||
},
|
},
|
||||||
Artist,
|
Artist,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user