use clap::{Parser, Subcommand};
use core::time::Duration;
use dimas_com::zenoh::Communicator;
use dimas_config::Config;
use dimas_core::{Result, enums::OperationState};
#[derive(Debug, Parser)]
#[clap(version, about, long_about = None)]
struct DimasctlArgs {
selector: Option<String>,
#[clap(subcommand)]
command: DimasctlCommand,
}
fn operation_state_parser(s: &str) -> Result<OperationState> {
OperationState::try_from(s)
}
#[derive(Debug, Subcommand)]
enum DimasctlCommand {
List,
Ping {
target: String,
#[arg(short, long, default_value = "1")]
count: u8,
},
Scout,
SetState {
#[arg(value_parser = operation_state_parser)]
state: Option<OperationState>,
},
Shutdown {
target: String,
},
}
fn main() -> Result<()> {
let args = DimasctlArgs::parse();
let config = Config::default();
let h_zid = "ZenohId";
let h_kind = "Kind";
let h_state = "State";
let h_name = "Prefix/Name";
let base_selector = args
.selector
.clone()
.map_or_else(|| String::from("**"), |selector| selector);
match &args.command {
DimasctlCommand::List => {
let com =
Communicator::new(config.zenoh_config()).expect("failed to create 'Communicator'");
println!("List of found DiMAS entities:");
println!("{h_zid:32} {h_kind:6} {h_state:10} {h_name}");
let list = dimas_commands::about_list(&com, &base_selector)?;
for item in list {
println!(
"{:32} {:6} {:10} {}",
item.zid(),
item.kind(),
item.state().to_string(),
item.name()
);
}
}
DimasctlCommand::Ping { target, count } => {
let target = args
.selector
.map_or_else(|| target.to_owned(), |value| format!("{value}/{target}"));
let com =
Communicator::new(config.zenoh_config()).expect("failed to create 'Communicator'");
for _ in 0..*count {
let list = dimas_commands::ping_list(&com, &target)?;
for item in list {
#[allow(clippy::cast_precision_loss)]
let time = item.1 as f64 / 2_000_000.0;
println!("{:32} {:6.2}ms {}", item.0.zid(), time, item.0.name(),);
}
if *count > 1 {
println!("\r");
std::thread::sleep(Duration::from_millis(1000));
}
}
}
DimasctlCommand::Scout => {
println!("List of scouted Zenoh entities:");
println!("ZenohId Kind Locators");
let list = dimas_commands::scouting_list(&config)?;
for item in list {
println!(
"{:32} {:6} {:?}",
item.zid(),
item.kind(),
item.locators()
);
}
}
DimasctlCommand::SetState { state } => {
let com =
Communicator::new(config.zenoh_config()).expect("failed to create 'Communicator'");
println!("List of current states of DiMAS entities:");
println!("{h_zid:32} {h_kind:6} {h_state:10} {h_name}");
let list = dimas_commands::set_state(&com, &base_selector, state.to_owned())?;
for item in list {
println!(
"{:32} {:6} {:10} {}",
item.zid(),
item.kind(),
item.state().to_string(),
item.name()
);
}
}
DimasctlCommand::Shutdown { target } => {
let target = args
.selector
.map_or_else(|| target.to_owned(), |value| format!("{value}/{target}"));
let com =
Communicator::new(config.zenoh_config()).expect("failed to create 'Communicator'");
println!("List of shut down DiMAS entities:");
println!("{h_zid:32} {h_kind:6} {h_state:10} {h_name}");
let list = dimas_commands::shutdown(&com, &target)?;
for item in list {
println!(
"{:32} {:6} {:10} {}",
item.zid(),
item.kind(),
item.state().to_string(),
item.name()
);
}
}
}
Ok(())
}