mod cli;
mod port;
mod process;
mod ui;
use anyhow::Result;
use clap::Parser;
use cli::{Cli, Commands};
fn main() {
if let Err(e) = run() {
ui::display_error(&e);
std::process::exit(1);
}
}
fn run() -> Result<()> {
let cli = Cli::parse();
if cli.version {
display_version();
return Ok(());
}
match cli.command {
Some(Commands::Find { ports }) => handle_find(ports)?,
Some(Commands::Kill { ports }) => handle_kill(ports)?,
Some(Commands::List) => handle_list()?,
None => {
println!("使用 'ziro --help' 查看可用命令");
}
}
Ok(())
}
fn display_version() {
let version = env!("CARGO_PKG_VERSION");
println!("\x1b[1;36mziro\x1b[0m \x1b[1;37mv{version}\x1b[0m");
}
fn handle_find(ports: Vec<u16>) -> Result<()> {
if ports.is_empty() {
println!("请指定至少一个端口号");
return Ok(());
}
let port_infos = port::find_processes_by_ports(&ports)?;
ui::display_ports_tree(&ports, port_infos);
Ok(())
}
fn handle_kill(ports: Vec<u16>) -> Result<()> {
if ports.is_empty() {
println!("请指定至少一个端口号");
return Ok(());
}
let port_infos = port::find_processes_by_ports(&ports)?;
if port_infos.is_empty() {
println!("未找到占用指定端口的进程");
for &port in &ports {
ui::display_port_not_found(port);
}
return Ok(());
}
let selected = ui::select_processes_to_kill(port_infos)?;
if selected.is_empty() {
return Ok(());
}
let pids: Vec<u32> = selected.iter().map(|info| info.process.pid).collect();
let results = process::kill_processes(&pids);
ui::display_kill_results(&results);
Ok(())
}
fn handle_list() -> Result<()> {
let port_infos = port::list_all_ports()?;
ui::display_ports_tree_all(port_infos);
Ok(())
}