use clap::Args;
use console::style;
use serde_json::{json, Value};
use zenoh::{self, key_expr::KeyExpr};
use crate::error::Result;
#[derive(Args)]
pub struct CallArgs {
service: String,
#[clap(short, long)]
data: Option<String>,
#[clap(short, long, default_value = "5")]
timeout: u64,
}
pub async fn execute(args: CallArgs) -> Result<()> {
println!(
"{label} {service}",
label = style("Calling service:").bold(),
service = args.service
);
let request_data = match &args.data {
Some(data) => {
println!(" With data: {data}");
serde_json::from_str::<Value>(data)?
}
None => {
println!(" With empty data");
json!({})
}
};
let session = zenoh::open(zenoh::config::Config::default()).await?;
let service_path = format!("zenobuf/service/{service}", service = args.service);
let key_expr = KeyExpr::try_from(service_path)?;
let request_bytes = serde_json::to_vec(&request_data)?;
println!(" Waiting for response...");
let timeout = std::time::Duration::from_secs(args.timeout);
let replies = session
.get(key_expr)
.payload(request_bytes)
.timeout(timeout)
.await?;
match replies.recv_async().await {
Ok(reply) => {
match reply.result() {
Ok(sample) => {
let payload = sample.payload().to_bytes();
match serde_json::from_slice::<Value>(&payload) {
Ok(json) => {
println!("\n{}", style("Response:").bold());
println!("{}", serde_json::to_string_pretty(&json)?);
}
Err(_) => {
let payload_str = String::from_utf8_lossy(&payload);
println!("\n{}", style("Response:").bold());
println!("{payload_str}");
}
}
}
Err(e) => {
println!("\n{}", style("Error:").bold().red());
println!(" {e}");
}
}
}
Err(e) => {
println!("\n{}", style("Error:").bold().red());
println!(" {e}");
}
}
Ok(())
}