use reqwest;
use serde_json::{json, Value};
use std::error::Error;
use std::path::{Path, PathBuf};
use std::process::{self, Command};
use structopt::StructOpt;
#[derive(StructOpt, Debug)]
#[structopt(
name = "bellande_node_importance",
about = "Bellande Node Importance Tool"
)]
struct Opt {
#[structopt(
long,
help = "Node to evaluate as JSON object with coordinates and segment"
)]
node: String,
#[structopt(long, help = "List of recent nodes as JSON array")]
recent_nodes: String,
#[structopt(long, help = "Dictionary of important nodes by segment as JSON object")]
important_nodes: String,
#[structopt(long, help = "Dictionary of adjacent segments as JSON object")]
adjacent_segments: String,
#[structopt(long, help = "Grid steps for each dimension as JSON array")]
grid_steps: String,
#[structopt(
long,
help = "Minimum required segment coverage ratio",
default_value = "0.5"
)]
min_segment_coverage: f64,
#[structopt(long, help = "Use local executable instead of API")]
use_executable: bool,
}
pub async fn make_bellande_node_importance_request(
node: Value,
recent_nodes: Value,
important_nodes: Value,
adjacent_segments: Value,
grid_steps: Value,
min_segment_coverage: f64,
) -> Result<Value, Box<dyn Error>> {
let client = reqwest::Client::new();
let url = "https://bellande-robotics-sensors-research-innovation-center.org/api/Bellande_Node_Importance/node_importance";
let payload = json!({
"node": node,
"nodes": recent_nodes,
"important_nodes": important_nodes,
"adjacent_segments": adjacent_segments,
"grid_steps": grid_steps,
"min_segment_coverage": min_segment_coverage,
"auth": {
"authorization_key": "bellande_web_api_opensource"
}
});
let response = client
.post(url)
.header("accept", "application/json")
.header("Content-Type", "application/json")
.json(&payload)
.send()
.await?
.json::<Value>()
.await?;
Ok(response)
}
pub async fn make_bellande_node_importance_request_local(
url: &str,
node: Value,
recent_nodes: Value,
important_nodes: Value,
adjacent_segments: Value,
grid_steps: Value,
min_segment_coverage: f64,
) -> Result<Value, Box<dyn Error>> {
let client = reqwest::Client::new();
let url = url;
let payload = json!({
"node": node,
"nodes": recent_nodes,
"important_nodes": important_nodes,
"adjacent_segments": adjacent_segments,
"grid_steps": grid_steps,
"min_segment_coverage": min_segment_coverage,
"auth": {
"authorization_key": "bellande_web_api_opensource"
}
});
let response = client
.post(url)
.header("accept", "application/json")
.header("Content-Type", "application/json")
.json(&payload)
.send()
.await?
.json::<Value>()
.await?;
Ok(response)
}
pub fn get_executable_path() -> PathBuf {
if cfg!(target_os = "windows") {
Path::new(env!("CARGO_MANIFEST_DIR")).join("Bellande_Node_Importance.exe")
} else {
Path::new(env!("CARGO_MANIFEST_DIR")).join("Bellande_Node_Importance")
}
}
pub fn run_bellande_node_importance_executable(
node: &str,
recent_nodes: &str,
important_nodes: &str,
adjacent_segments: &str,
grid_steps: &str,
min_segment_coverage: f64,
) -> Result<(), Box<dyn Error>> {
let executable_path = get_executable_path();
let passcode = "bellande_node_importance_executable_access_key";
let node_obj: Value = serde_json::from_str(node)?;
let grid_steps_list: Value = serde_json::from_str(grid_steps)?;
if let (Some(coords), Some(steps)) = (node_obj["coords"].as_array(), grid_steps_list.as_array())
{
if coords.len() != steps.len() {
return Err(format!(
"Node coordinates must match grid steps dimensions ({})",
steps.len()
)
.into());
}
}
let output = Command::new(executable_path)
.args(&[
passcode,
node,
recent_nodes,
important_nodes,
adjacent_segments,
grid_steps,
&min_segment_coverage.to_string(),
])
.output()?;
if output.status.success() {
println!("{}", String::from_utf8_lossy(&output.stdout));
Ok(())
} else {
Err(format!(
"Process failed: {}",
String::from_utf8_lossy(&output.stderr)
)
.into())
}
}