use crate::{ApiRequest, PointId, TaskId};
pub trait ToRequestBody {
fn to_request_body(&self) -> Result<String, serde_json::Error>;
fn to_api_request(&self) -> ApiRequest;
}
pub const SELF_POSITION: &str = "SELF_POSITION";
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, Default)]
pub struct MoveToPoint {
pub id: PointId,
pub x: Option<f64>,
pub y: Option<f64>,
pub angle: Option<f64>,
pub max_speed: Option<f64>,
pub max_wspeed: Option<f64>,
pub max_acc: Option<f64>,
pub max_wacc: Option<f64>,
}
impl MoveToPoint {
pub fn zeros() -> Self {
Self::default()
}
pub fn with_id<T: Into<String>>(id: T) -> Self {
Self {
id: id.into(),
..Default::default()
}
}
pub fn new(x: f64, y: f64) -> Self {
Self {
x: Some(x),
y: Some(y),
..Default::default()
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
pub enum MoveMethod {
Forward,
Backward,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct GetNavStatus {
pub simple: Option<bool>,
}
impl GetNavStatus {
pub fn new() -> Self {
Self { simple: None }
}
pub fn with_simple(mut self, simple: bool) -> Self {
self.simple = Some(simple);
self
}
}
impl Default for GetNavStatus {
fn default() -> Self {
Self::new()
}
}
#[derive(
Debug, Clone, serde::Serialize, serde::Deserialize, Default, PartialEq,
)]
pub struct MoveToTarget {
#[serde(rename = "id")]
pub target: PointId,
#[serde(rename = "source_id")]
pub start: PointId,
pub task_id: Option<TaskId>,
pub method: Option<MoveMethod>,
pub spin: Option<bool>,
#[serde(default)]
pub delay: u64,
pub start_rot_dir: Option<i8>,
pub end_rot_dir: Option<i8>,
pub reach_dist: Option<f64>,
pub reach_angle: Option<f64>,
pub angle: Option<f64>,
pub max_speed: Option<f64>,
pub max_wspeed: Option<f64>,
pub max_acc: Option<f64>,
pub max_wacc: Option<f64>,
#[serde(flatten)]
pub jack_operation: Option<JackOperation>,
}
macro_rules! impl_move_to_target_builder {
( $($method_name:ident : $field_name:ident = $field_type:ty),* $(,)? ) => {
$(
pub fn $method_name(mut self, value: $field_type) -> Self {
self.$field_name = value.into();
self
}
)*
};
}
impl MoveToTarget {
pub fn new<T: Into<String>>(target: T) -> Self {
Self {
target: target.into(),
start: SELF_POSITION.to_string(),
..Default::default()
}
}
impl_move_to_target_builder! {
with_task_id: task_id = TaskId,
with_start: start = PointId,
with_method: method = MoveMethod,
with_operation: jack_operation = JackOperation,
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, PartialEq)]
#[serde(tag = "operation")]
pub enum JackOperation {
JackLoad,
JackUnload,
JackHeight { jack_height: f64 },
Wait,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct SetJackHeight {
pub height: f64,
}
impl SetJackHeight {
pub fn new(height: f64) -> Self {
Self { height }
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct MoveDesignedPath {
#[serde(rename = "move_task_list")]
pub path: Vec<MoveToTarget>,
}
impl MoveDesignedPath {
pub fn new(path: impl IntoIterator<Item = MoveToTarget>) -> Self {
Self {
path: path.into_iter().collect(),
}
}
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct GetTaskStatus {
pub task_ids: Vec<String>,
}
impl FromIterator<String> for GetTaskStatus {
fn from_iter<I: IntoIterator<Item = String>>(iter: I) -> Self {
Self {
task_ids: iter.into_iter().collect(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_move_to_point_serialization() {
let raw_json = r#"
{
"id": "AP1",
"source_id": "LM2",
"task_id": "12344321",
"operation": "JackHeight",
"jack_height": 0.2
}
"#;
let m1: MoveToTarget = serde_json::from_str(raw_json).unwrap();
let m2 = MoveToTarget {
target: "AP1".to_string(),
start: "LM2".to_string(),
task_id: Some("12344321".to_string()),
jack_operation: Some(JackOperation::JackHeight {
jack_height: 0.2,
}),
..Default::default()
};
let serialized = serde_json::to_string_pretty(&m2).unwrap();
let m2 = serde_json::from_str::<MoveToTarget>(&serialized).unwrap();
eprintln!("Serialized: {}", serialized);
assert_eq!(m1, m2);
let raw_json = r#"
{
"id": "AP1",
"source_id": "LM2",
"task_id": "12344321",
"operation": "JackLoad"
}
"#;
let m1: MoveToTarget = serde_json::from_str(raw_json).unwrap();
let m2 = MoveToTarget {
target: "AP1".to_string(),
start: "LM2".to_string(),
task_id: Some("12344321".to_string()),
jack_operation: Some(JackOperation::JackLoad),
..Default::default()
};
let serialized = serde_json::to_string_pretty(&m2).unwrap();
let m2 = serde_json::from_str::<MoveToTarget>(&serialized).unwrap();
assert_eq!(m1, m2);
}
}