use std::{ env, ffi::OsString, process::ExitCode, sync::{atomic::AtomicBool, Arc}, }; use irtt_cli::{ applet::{ default_applet_for_features, detect_applet_from_argv0, AppletAvailability, RequestedApplet, }, signal::install_signal_handler, }; fn main() -> ExitCode { match run_from_env() { Ok(()) => ExitCode::SUCCESS, Err(err) => { eprintln!("irtt-rs: {err}"); ExitCode::FAILURE } } } fn run_from_env() -> Result<(), Box> { let argv: Vec = env::args_os().collect(); let argv0 = argv .first() .and_then(|arg| arg.to_str()) .unwrap_or("irtt-rs"); let requested = match detect_applet_from_argv0(argv0) { Some(applet) => applet, None => default_requested_applet()?, }; let shutdown_requested = Arc::new(AtomicBool::new(false)); install_signal_handler(Arc::clone(&shutdown_requested)) .map_err(|err| format!("failed to install signal handler: {err}"))?; match requested { RequestedApplet::Client => run_client_applet(argv, shutdown_requested.as_ref()), RequestedApplet::Tui => run_tui_applet(argv, shutdown_requested.as_ref()), RequestedApplet::Server => Err("server applet is not available in this build".into()), } } fn default_requested_applet() -> Result> { match default_applet_for_features(cfg!(feature = "client"), cfg!(feature = "tui"), false) { AppletAvailability::Client => Ok(RequestedApplet::Client), AppletAvailability::Tui => Ok(RequestedApplet::Tui), AppletAvailability::Server => Ok(RequestedApplet::Server), AppletAvailability::None => Err("no runnable applet is available in this build".into()), } } #[cfg(feature = "client")] fn run_client_applet( argv: Vec, shutdown_requested: &AtomicBool, ) -> Result<(), Box> { use clap::Parser; let args = irtt_cli::cmd::client::ClientArgs::parse_from(argv); irtt_cli::cmd::client::run_stream(args, shutdown_requested) } #[cfg(not(feature = "client"))] fn run_client_applet( _argv: Vec, _shutdown_requested: &AtomicBool, ) -> Result<(), Box> { Err("client applet is not available; rebuild with the client feature".into()) } #[cfg(feature = "tui")] fn run_tui_applet( argv: Vec, shutdown_requested: &AtomicBool, ) -> Result<(), Box> { use clap::Parser; let args = irtt_cli::cmd::tui::TuiArgs::parse_from(argv); irtt_cli::cmd::tui::run_tui(args, shutdown_requested) } #[cfg(not(feature = "tui"))] fn run_tui_applet( _argv: Vec, _shutdown_requested: &AtomicBool, ) -> Result<(), Box> { Err("TUI applet is not available; rebuild with the tui feature".into()) }