haply 1.0.0

Haply Robotics Client Library for the Inverse Service
Documentation
//! Shared enums and constants for device types, modes, and settings.

use serde::de::{self, Visitor};
use serde::{Deserialize, Deserializer, Serialize};
use ts_rs::TS;

// Device type constants
pub const DEVICE_TYPE_INVERSE3: &str = "inverse3";
pub const DEVICE_TYPE_INVERSE3X: &str = "inverse3x";
pub const DEVICE_TYPE_MINVERSE: &str = "minverse";
pub const DEVICE_TYPE_WIRELESS_VERSE_GRIP: &str = "wireless_verse_grip";
pub const DEVICE_TYPE_CUSTOM_VERSE_GRIP: &str = "custom_verse_grip";

#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum DeviceType {
    #[default]
    Inverse3,
    Inverse3x,
    Minverse,
    VerseGrip,
    WirelessVerseGrip,
    CustomVerseGrip,
    Ruko,
    Kingfisher,
}

impl<'de> Deserialize<'de> for DeviceType {
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
    where
        D: Deserializer<'de>,
    {
        struct DeviceTypeVisitor;

        impl<'de> Visitor<'de> for DeviceTypeVisitor {
            type Value = DeviceType;

            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
                formatter.write_str("a string or an integer representing device type")
            }

            fn visit_str<E>(self, value: &str) -> Result<DeviceType, E>
            where
                E: de::Error,
            {
                match value {
                    "inverse3" => Ok(DeviceType::Inverse3),
                    "inverse3x" => Ok(DeviceType::Inverse3x),
                    "minverse" => Ok(DeviceType::Minverse),
                    "verse_grip" => Ok(DeviceType::VerseGrip),
                    "wireless_verse_grip" => Ok(DeviceType::WirelessVerseGrip),
                    "custom_verse_grip" => Ok(DeviceType::CustomVerseGrip),
                    "ruko" => Ok(DeviceType::Ruko),
                    "kingfisher" => Ok(DeviceType::Kingfisher),
                    _ => Err(E::custom(format!("unknown device type: {}", value))),
                }
            }

            fn visit_u64<E>(self, value: u64) -> Result<DeviceType, E>
            where
                E: de::Error,
            {
                match value {
                    4 => Ok(DeviceType::Inverse3),
                    6 => Ok(DeviceType::Minverse),
                    _ => Err(E::custom(format!("unknown device type code: {}", value))),
                }
            }

            fn visit_i64<E>(self, value: i64) -> Result<DeviceType, E>
            where
                E: de::Error,
            {
                if value < 0 {
                    return Err(E::custom(format!("negative device type code: {}", value)));
                }
                self.visit_u64(value as u64)
            }
        }

        deserializer.deserialize_any(DeviceTypeVisitor)
    }
}

#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum DeviceMode {
    #[default]
    Idle,
    Position,
    Angular,
}

#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum ControlDomain {
    #[default]
    Undefined,
    Cartesian,
    Angular,
}

#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum ControlMode {
    #[default]
    Idle,
    Position,
    Force,
}

#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum Handedness {
    Left,
    #[default]
    Right,
}

#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub enum StreamingMode {
    #[default]
    USB,
    Radio,
}

#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum CoordinateOrigin {
    #[default]
    DeviceBase,
    WorkspaceCenter,
}

/// Controls how duplicate device entries across `wireless_verse_grip` and
/// `custom_verse_grip` are handled when the same `device_id` appears in both.
#[derive(Copy, Clone, Debug, PartialEq, Default)]
pub enum VerseGripDuplicateMode {
    /// Keep `custom_verse_grip` entries, hide wireless duplicates (default).
    #[default]
    PreferCustom,
    /// Keep `wireless_verse_grip` entries, hide custom duplicates.
    PreferWireless,
    /// Keep both -- no deduplication.
    KeepBoth,
}