use chrono::prelude::*; use clap::{Parser, Subcommand}; use std::{fs,process}; #[derive(Parser)] #[clap(name = "Bit Goblin Network Tester", author, version, about = "Network testing app.", long_about = None)] #[clap(propagate_version = true)] struct Cli { #[clap(subcommand)] command: Commands, } #[derive(Subcommand)] enum Commands { // ping subcommand Ping { #[clap(default_value_t = String::from("8.8.8.8"))] host: String }, // bandwidth test subcommand Bandwidth { #[clap(default_value_t = String::from("https://www.bitgoblin.tech/hardware-tests/export-01.mp4"))] download: String, #[clap(default_value_t = String::from("./tempfile"))] output: String, }, } fn main() { let cli = Cli::parse(); // map subcommands back to the main command match &cli.command { Commands::Ping { host } => ping_host(host), Commands::Bandwidth { download, output } => bandwidth_test(download, output) } } // ping a host fn ping_host(host: &str) { println!("Pinging host {}", host); // run the ping command with 100 pings let output = process::Command::new("ping") .arg(host) .arg("-c 100") .output() .expect("Failed to execute command"); // check that the command succeeded assert!(output.status.success()); // print out the ping results from stdout println!("{}", String::from_utf8_lossy(&output.stdout)); } // timed file copy test to guage bandwidth speeds fn bandwidth_test(download: &str, output: &str) { println!("Testing network bandwidth by downloading {}.", download); // get start time so we can track how long it takes to complete let start_time = Utc::now(); // do the download // get finish time let finish_time = Utc::now(); // compute time to complete let comp_time = finish_time - start_time; println!("{}", comp_time.num_milliseconds()); // clean up the test file match fs::remove_file(output) { Ok(()) => println!("Cleaning up..."), Err(e) => println!("There was a problem during cleanup - {}", e), } }