mod app;
use app::{
App, AppMainLoop,
cli::Args,
config::Config,
logging,
terminal::{init_terminal, restore_terminal},
};
use clap::Parser;
#[tokio::main]
async fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
let args = Args::parse();
if let Some(path) = &args.generate_config {
let config_path = if path.is_dir() || path.to_str() == Some(".") {
path.join("config.toml")
} else {
path.clone()
};
Config::generate_default(config_path)?;
return Ok(());
}
let config_path = args.config.clone().unwrap_or_else(|| {
dirs::config_dir()
.map(|d| d.join("zarumet").join("config.toml"))
.unwrap_or_default()
});
let config_existed = config_path.exists();
let (mut config, config_warnings) = Config::load(args.config.clone())?;
if let Some(ref addr) = args.address {
config.mpd.address = addr.clone();
}
if config.logging.enabled {
logging::ensure_log_directory()?;
logging::init_logger(&config.logging)?;
logging::log_startup_info();
logging::log_config_loading(&config_path, !config_existed);
for warning in &config_warnings {
log::warn!("{}", warning);
}
}
let terminal = init_terminal()?;
let logging_enabled = config.logging.enabled;
#[cfg(target_os = "linux")]
{
if config.pipewire.bit_perfect_enabled
&& let Err(e) = crate::app::audio::pipewire::initialize_supported_rates()
{
log::warn!("Failed to initialize PipeWire supported rates: {}", e);
}
}
let mut app = App::new_with_config(config, args.clone())?;
if !config_warnings.is_empty() {
app.config_warnings = config_warnings;
app.show_config_warnings_popup = true;
}
let result = app.run(terminal).await;
if logging_enabled {
crate::logging::log_shutdown_info();
}
restore_terminal()?;
result
}