pub mod app;
pub mod keyboard_help;
pub mod openapi_sync;
pub mod path_picker;
pub mod screens;
pub mod text_search;
pub mod utils;
use anyhow::Result;
use std::time::Duration;
use crate::client::RommClient;
use crate::config::{openapi_cache_path, should_check_updates, Config};
use self::app::App;
use self::openapi_sync::sync_openapi_registry;
use self::screens::connected_splash::StartupSplash;
use self::screens::setup_wizard::SetupWizard;
fn install_panic_hook() {
let original_hook = std::panic::take_hook();
std::panic::set_hook(Box::new(move |panic| {
let _ = crossterm::terminal::disable_raw_mode();
let _ = crossterm::execute!(
std::io::stdout(),
crossterm::terminal::LeaveAlternateScreen,
crossterm::event::DisableMouseCapture
);
original_hook(panic);
}));
}
fn startup_splash_for(
from_setup_wizard: bool,
config: &Config,
server_version: &Option<String>,
) -> Option<StartupSplash> {
if from_setup_wizard {
return Some(StartupSplash::new(
config.base_url.clone(),
server_version.clone(),
));
}
if server_version.is_some() {
return Some(StartupSplash::new(
config.base_url.clone(),
server_version.clone(),
));
}
None
}
fn startup_splash_for_launch(
from_setup_wizard: bool,
config: &Config,
server_version: &Option<String>,
update_pending: bool,
) -> Option<StartupSplash> {
if update_pending {
return None;
}
startup_splash_for(from_setup_wizard, config, server_version)
}
async fn run_started(
client: RommClient,
config: Config,
from_setup_wizard: bool,
mock_update: bool,
) -> Result<()> {
install_panic_hook();
let cache_path = openapi_cache_path()?;
let (registry, server_version) = sync_openapi_registry(&client, &cache_path).await?;
let startup_update = if mock_update {
Some(crate::update::UpdateStatus {
current_version: format!("{} (dev)", env!("CARGO_PKG_VERSION")),
latest_version: "9.9.9-mock".into(),
release_tag: "v9.9.9-mock".into(),
should_update: true,
release_url: "https://github.com/patricksmill/romm-cli".into(),
changelog_url: crate::update::changelog_url().to_string(),
})
} else if should_check_updates() {
match tokio::time::timeout(Duration::from_secs(2), crate::update::check_for_update()).await
{
Ok(Ok(status)) if status.should_update => Some(status),
_ => None,
}
} else {
None
};
let splash = startup_splash_for_launch(
from_setup_wizard,
&config,
&server_version,
startup_update.is_some(),
);
let mut app = App::new(
client,
config,
registry,
server_version,
splash,
startup_update,
);
app.run().await
}
pub async fn run(client: RommClient, config: Config, mock_update: bool) -> Result<()> {
run_started(client, config, false, mock_update).await
}
pub async fn run_interactive(verbose: bool, mock_update: bool) -> Result<()> {
let (from_wizard, config) = match crate::config::load_config() {
Ok(c) => (false, c),
Err(_) => (true, SetupWizard::new().run(verbose).await?),
};
let client = RommClient::new(&config, verbose)?;
run_started(client, config, from_wizard, mock_update).await
}
#[cfg(test)]
mod tests {
use super::*;
use crate::config::ExtrasDefaults;
fn test_config() -> Config {
Config {
base_url: "http://127.0.0.1:9".into(),
download_dir: "/tmp".into(),
use_https: false,
auth: None,
extras_defaults: ExtrasDefaults::default(),
save_sync: Default::default(),
roms_layout: Default::default(),
}
}
#[test]
fn startup_splash_for_launch_skips_splash_when_update_pending() {
let config = test_config();
let version = Some("4.0.0".into());
assert!(startup_splash_for_launch(false, &config, &version, true).is_none());
}
#[test]
fn startup_splash_for_launch_shows_splash_when_no_update() {
let config = test_config();
let version = Some("4.0.0".into());
assert!(startup_splash_for_launch(false, &config, &version, false).is_some());
}
}