2023-04-13 14:09:59 +02:00
|
|
|
use ratatui::backend::CrosstermBackend;
|
|
|
|
use ratatui::Terminal;
|
|
|
|
use std::io;
|
2023-04-10 00:13:18 +02:00
|
|
|
use std::path::PathBuf;
|
|
|
|
|
|
|
|
use structopt::StructOpt;
|
|
|
|
|
|
|
|
use musichoard::{
|
2023-04-13 14:09:59 +02:00
|
|
|
collection::MhCollectionManager,
|
|
|
|
database::json::{JsonDatabase, JsonDatabaseFileBackend},
|
|
|
|
library::beets::{BeetsLibrary, BeetsLibraryCommandExecutor},
|
|
|
|
};
|
|
|
|
|
|
|
|
mod tui;
|
|
|
|
use tui::{
|
2023-04-13 15:29:14 +02:00
|
|
|
app::TuiApp, event::EventChannel, handler::TuiEventHandler, listener::TuiEventListener, ui::Ui,
|
2023-04-13 14:09:59 +02:00
|
|
|
Tui,
|
2023-04-10 00:13:18 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#[derive(StructOpt)]
|
|
|
|
struct Opt {
|
|
|
|
#[structopt(
|
|
|
|
short = "b",
|
2023-04-13 14:09:59 +02:00
|
|
|
long = "beets",
|
2023-04-10 00:13:18 +02:00
|
|
|
name = "beets config file path",
|
|
|
|
parse(from_os_str)
|
|
|
|
)]
|
|
|
|
beets_config_file_path: Option<PathBuf>,
|
|
|
|
|
|
|
|
#[structopt(
|
|
|
|
short = "d",
|
|
|
|
long = "database",
|
|
|
|
name = "database file path",
|
|
|
|
default_value = "database.json",
|
|
|
|
parse(from_os_str)
|
|
|
|
)]
|
|
|
|
database_file_path: PathBuf,
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() {
|
2023-04-13 14:09:59 +02:00
|
|
|
// Create the application.
|
2023-04-10 00:13:18 +02:00
|
|
|
let opt = Opt::from_args();
|
|
|
|
|
2023-04-13 15:29:14 +02:00
|
|
|
let beets = BeetsLibrary::new(
|
2023-04-10 22:03:04 +02:00
|
|
|
BeetsLibraryCommandExecutor::default().config(opt.beets_config_file_path.as_deref()),
|
2023-04-13 15:29:14 +02:00
|
|
|
);
|
2023-04-10 00:13:18 +02:00
|
|
|
|
2023-04-13 15:29:14 +02:00
|
|
|
let database = JsonDatabase::new(JsonDatabaseFileBackend::new(&opt.database_file_path));
|
2023-04-10 00:13:18 +02:00
|
|
|
|
2023-04-13 15:29:14 +02:00
|
|
|
let collection_manager = MhCollectionManager::new(beets, database);
|
2023-04-13 14:09:59 +02:00
|
|
|
|
|
|
|
// Initialize the terminal user interface.
|
|
|
|
let backend = CrosstermBackend::new(io::stdout());
|
|
|
|
let terminal = Terminal::new(backend).expect("failed to initialise terminal");
|
|
|
|
|
|
|
|
let channel = EventChannel::new();
|
|
|
|
let listener = TuiEventListener::new(channel.sender());
|
|
|
|
let handler = TuiEventHandler::new(channel.receiver());
|
|
|
|
|
|
|
|
let ui = Ui::new();
|
|
|
|
|
2023-04-13 15:29:14 +02:00
|
|
|
let app = TuiApp::new(collection_manager).expect("failed to initialise app");
|
2023-04-13 14:09:59 +02:00
|
|
|
|
|
|
|
// Run the TUI application.
|
|
|
|
Tui::run(terminal, app, ui, handler, listener).expect("failed to run tui");
|
|
|
|
}
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
#[macro_use]
|
|
|
|
mod testlib;
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use mockall::mock;
|
|
|
|
use once_cell::sync::Lazy;
|
|
|
|
|
|
|
|
use musichoard::collection::{self, Collection, CollectionManager};
|
|
|
|
use musichoard::*;
|
|
|
|
|
|
|
|
pub static COLLECTION: Lazy<Vec<Artist>> = Lazy::new(|| collection!());
|
|
|
|
|
|
|
|
mock! {
|
|
|
|
pub CollectionManager {}
|
|
|
|
|
|
|
|
impl CollectionManager for CollectionManager {
|
|
|
|
fn rescan_library(&mut self) -> Result<(), collection::Error>;
|
|
|
|
fn save_to_database(&mut self) -> Result<(), collection::Error>;
|
|
|
|
fn get_collection(&self) -> &Collection;
|
|
|
|
}
|
|
|
|
}
|
2023-04-10 00:13:18 +02:00
|
|
|
}
|