mod app;
#[cfg(any(target_os = "macos", test))]
mod apple;
mod gpu;
mod hist;
mod mcp;
#[cfg(not(target_os = "macos"))]
mod nvidia;
mod ps;
mod sys;
mod ui;
use clap::Parser;
use std::time::Duration;
#[derive(Parser)]
#[command(version, args_conflicts_with_subcommands = true)]
struct Args {
#[command(subcommand)]
command: Option<Command>,
#[arg(short = 'd', long, default_value_t = 1000, value_parser = clap::value_parser!(u64).range(100..=60000))]
interval: u64,
#[arg(long)]
once: bool,
}
#[derive(clap::Subcommand)]
enum Command {
Mcp,
}
fn main() -> anyhow::Result<()> {
let args = Args::parse();
if let Some(Command::Mcp) = args.command {
return mcp::run();
}
let every = Duration::from_millis(args.interval);
let app = app::App::new(sys::Sys::new(), gpu::Gpus::new(), every);
if args.once {
return match ui::print_once(&app, &mut std::io::stdout().lock()) {
Err(e) if e.kind() == std::io::ErrorKind::BrokenPipe => Ok(()),
r => Ok(r?),
};
}
let mut app = app;
let mut terminal = ratatui::init();
let result = app.run(&mut terminal);
ratatui::restore();
result
}
#[cfg(test)]
mod tests {
use super::Args;
use clap::Parser;
#[test]
fn mcp_takes_none_of_the_screen_s_flags() {
assert!(Args::try_parse_from(["otop", "mcp"]).is_ok());
assert!(Args::try_parse_from(["otop", "--once", "mcp"]).is_err());
assert!(Args::try_parse_from(["otop", "-d", "500", "mcp"]).is_err());
assert!(Args::try_parse_from(["otop", "-d", "500"]).is_ok());
}
}