bellande_step/
bellande_step.rs

1// Copyright (C) 2024 Bellande Robotics Sensors Research Innovation Center, Ronaldson Bellande
2
3// This program is free software: you can redistribute it and/or modify
4// it under the terms of the GNU General Public License as published by
5// the Free Software Foundation, either version 3 of the License, or
6// (at your option) any later version.
7
8// This program is distributed in the hope that it will be useful,
9// but WITHOUT ANY WARRANTY; without even the implied warranty of
10// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11// GNU General Public License for more details.
12
13// You should have received a copy of the GNU General Public License
14// along with this program.  If not, see <https://www.gnu.org/licenses/>.
15
16use reqwest;
17use serde_json::{json, Value};
18use std::error::Error;
19use std::path::{Path, PathBuf};
20use std::process::Command;
21use structopt::StructOpt;
22
23#[derive(StructOpt, Debug)]
24#[structopt(name = "bellande_step", about = "Bellande Step Tool")]
25struct Opt {
26    #[structopt(long, help = "First coordinate as JSON-formatted list")]
27    node0: String,
28
29    #[structopt(long, help = "Second coordinate as JSON-formatted list")]
30    node1: String,
31
32    #[structopt(long, help = "Limit for the algorithm")]
33    limit: i32,
34
35    #[structopt(long, help = "Number of dimensions")]
36    dimensions: i32,
37
38    #[structopt(long, help = "Use local executable instead of API")]
39    use_executable: bool,
40}
41
42pub async fn make_bellande_step_request(
43    node0: Value,
44    node1: Value,
45    limit: i32,
46    dimensions: i32,
47) -> Result<Value, Box<dyn Error>> {
48    let client = reqwest::Client::new();
49    let url = "https://bellande-robotics-sensors-research-innovation-center.org/api/Bellande_Step/bellande_step";
50
51    let payload = json!({
52        "node0": node0,
53        "node1": node1,
54        "limit": limit,
55        "dimensions": dimensions,
56        "auth": {
57            "authorization_key": "bellande_web_api_opensource"
58        }
59    });
60
61    let response = client
62        .post(url)
63        .header("accept", "application/json")
64        .header("Content-Type", "application/json")
65        .json(&payload)
66        .send()
67        .await?
68        .json::<Value>()
69        .await?;
70
71    Ok(response)
72}
73
74pub async fn make_bellande_step_request_local(
75    url: &str,
76    node0: Value,
77    node1: Value,
78    limit: i32,
79    dimensions: i32,
80) -> Result<Value, Box<dyn Error>> {
81    let client = reqwest::Client::new();
82    let url = url;
83
84    let payload = json!({
85        "node0": node0,
86        "node1": node1,
87        "limit": limit,
88        "dimensions": dimensions,
89        "auth": {
90            "authorization_key": "bellande_web_api_opensource"
91        }
92    });
93
94    let response = client
95        .post(url)
96        .header("accept", "application/json")
97        .header("Content-Type", "application/json")
98        .json(&payload)
99        .send()
100        .await?
101        .json::<Value>()
102        .await?;
103
104    Ok(response)
105}
106
107pub fn get_executable_path() -> PathBuf {
108    if cfg!(target_os = "windows") {
109        Path::new(env!("CARGO_MANIFEST_DIR")).join("Bellande_Step.exe")
110    } else {
111        Path::new(env!("CARGO_MANIFEST_DIR")).join("Bellande_Step")
112    }
113}
114
115pub fn run_bellande_step_executable(
116    node0: &str,
117    node1: &str,
118    limit: i32,
119    dimensions: i32,
120) -> Result<(), Box<dyn Error>> {
121    let executable_path = get_executable_path();
122    let passcode = "bellande_step_executable_access_key";
123
124    // Parse and validate input
125    let node0_list: Value = serde_json::from_str(node0)?;
126    let node1_list: Value = serde_json::from_str(node1)?;
127
128    // Validate dimensions
129    if let (Some(n0), Some(n1)) = (node0_list.as_array(), node1_list.as_array()) {
130        if n0.len() != dimensions as usize || n1.len() != dimensions as usize {
131            return Err(format!("Coordinates must have {} dimensions", dimensions).into());
132        }
133    }
134
135    // Prepare and run command
136    let output = Command::new(executable_path)
137        .args(&[
138            passcode,
139            &node0,
140            &node1,
141            &limit.to_string(),
142            &dimensions.to_string(),
143        ])
144        .output()?;
145
146    if output.status.success() {
147        println!("{}", String::from_utf8_lossy(&output.stdout));
148        Ok(())
149    } else {
150        Err(format!(
151            "Process failed: {}",
152            String::from_utf8_lossy(&output.stderr)
153        )
154        .into())
155    }
156}