haply 1.1.0

Haply Robotics Client Library for the Inverse Service
Documentation
//! SDF Haptic Effects (HFX) module types — commands, objects, and session state.

use serde::{Deserialize, Serialize};
use ts_rs::TS;

use super::commands::TransformPatch;
use super::primitives::{EasingType, SdfPrimitive, SymmetryMode};

// ============================================================
// SDF HFX object (shared between commands and state)
// ============================================================

/// A single SDF haptic effect object.
/// All fields except `id` are `Option` to support partial updates.
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfHfxObject {
    pub id: String,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub shape: Option<SdfPrimitive>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub transform: Option<TransformPatch>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub force_scale: Option<f32>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub range: Option<f32>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub ease: Option<EasingType>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub reverse_easing: Option<bool>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub symmetry: Option<SymmetryMode>,
}

/// SDF HFX object with routing info — used in incoming session state and flat HTTP routes.
/// Extends `SdfHfxObject` with `session_id` and `devices`.
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfHfxData {
    #[serde(flatten)]
    pub object: SdfHfxObject,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub session_id: Option<u64>,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub devices: Option<Vec<String>>,
}

// ============================================================
// Outgoing WS command
// ============================================================

/// SDF command mode — determines how `objects` are applied.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, TS)]
#[serde(rename_all = "snake_case")]
pub enum SdfCommandMode {
    /// Atomic replace — clears all existing effects, inserts `objects`.
    Set,
    /// Partial patch — only provided fields are applied; `id` required.
    Update,
    /// Remove effects by `id`.
    Remove,
}

/// Outgoing SDF command sent in `inverse3[].commands.sdf`.
#[derive(Clone, Debug, PartialEq, Deserialize, Serialize, TS)]
pub struct SdfCommand {
    pub mode: SdfCommandMode,

    #[serde(skip_serializing_if = "Option::is_none")]
    pub from_space: Option<String>,

    pub objects: Vec<SdfHfxObject>,
}

// ============================================================
// Outgoing WS configure
// ============================================================

/// SDF output configure — toggles streaming of SDF state in session frames.
/// Sent in `inverse3[].configure.sdf`.
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfOutputConfigure {
    pub state_output: bool,
}

// ============================================================
// Incoming session state/status/config
// ============================================================

/// SDF session state — array of active effects, streamed in `session.state.sdf`.
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfSessionState {
    #[serde(default)]
    pub objects: Vec<SdfHfxData>,
}

/// SDF session status — effect count, streamed in `session.status.sdf`.
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfSessionStatus {
    pub count: u32,
}

/// SDF session config — whether state output is enabled, in `session.config.sdf`.
#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfSessionConfig {
    pub state_output: bool,
}

/// Wrapper for the SDF objects list used in flat HTTP route bodies.
#[derive(Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
pub struct SdfObjectList {
    pub objects: Vec<SdfHfxData>,
}