Skip to main content

haply/device_model/
enums.rs

1//! Shared enums and constants for device types, modes, and settings.
2
3use serde::de::{self, Visitor};
4use serde::{Deserialize, Deserializer, Serialize};
5use ts_rs::TS;
6
7// Device type constants
8pub const DEVICE_TYPE_INVERSE3: &str = "inverse3";
9pub const DEVICE_TYPE_INVERSE3X: &str = "inverse3x";
10pub const DEVICE_TYPE_MINVERSE: &str = "minverse";
11pub const DEVICE_TYPE_WIRELESS_VERSE_GRIP: &str = "wireless_verse_grip";
12pub const DEVICE_TYPE_CUSTOM_VERSE_GRIP: &str = "custom_verse_grip";
13
14#[derive(Copy, Clone, Debug, PartialEq, Default, Serialize, TS)]
15#[serde(rename_all = "snake_case")]
16pub enum DeviceType {
17    #[default]
18    Inverse3,
19    Inverse3x,
20    Minverse,
21    VerseGrip,
22    WirelessVerseGrip,
23    CustomVerseGrip,
24    Ruko,
25    Kingfisher,
26}
27
28impl<'de> Deserialize<'de> for DeviceType {
29    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
30    where
31        D: Deserializer<'de>,
32    {
33        struct DeviceTypeVisitor;
34
35        impl<'de> Visitor<'de> for DeviceTypeVisitor {
36            type Value = DeviceType;
37
38            fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
39                formatter.write_str("a string or an integer representing device type")
40            }
41
42            fn visit_str<E>(self, value: &str) -> Result<DeviceType, E>
43            where
44                E: de::Error,
45            {
46                match value {
47                    "inverse3" => Ok(DeviceType::Inverse3),
48                    "inverse3x" => Ok(DeviceType::Inverse3x),
49                    "minverse" => Ok(DeviceType::Minverse),
50                    "verse_grip" => Ok(DeviceType::VerseGrip),
51                    "wireless_verse_grip" => Ok(DeviceType::WirelessVerseGrip),
52                    "custom_verse_grip" => Ok(DeviceType::CustomVerseGrip),
53                    "ruko" => Ok(DeviceType::Ruko),
54                    "kingfisher" => Ok(DeviceType::Kingfisher),
55                    _ => Err(E::custom(format!("unknown device type: {}", value))),
56                }
57            }
58
59            fn visit_u64<E>(self, value: u64) -> Result<DeviceType, E>
60            where
61                E: de::Error,
62            {
63                match value {
64                    4 => Ok(DeviceType::Inverse3),
65                    6 => Ok(DeviceType::Minverse),
66                    _ => Err(E::custom(format!("unknown device type code: {}", value))),
67                }
68            }
69
70            fn visit_i64<E>(self, value: i64) -> Result<DeviceType, E>
71            where
72                E: de::Error,
73            {
74                if value < 0 {
75                    return Err(E::custom(format!("negative device type code: {}", value)));
76                }
77                self.visit_u64(value as u64)
78            }
79        }
80
81        deserializer.deserialize_any(DeviceTypeVisitor)
82    }
83}
84
85#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
86#[serde(rename_all = "snake_case")]
87pub enum DeviceMode {
88    #[default]
89    Idle,
90    Position,
91    Angular,
92}
93
94#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
95#[serde(rename_all = "snake_case")]
96pub enum ControlDomain {
97    #[default]
98    Undefined,
99    Cartesian,
100    Angular,
101}
102
103#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
104#[serde(rename_all = "snake_case")]
105pub enum ControlMode {
106    #[default]
107    Idle,
108    Position,
109    Force,
110}
111
112#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
113#[serde(rename_all = "snake_case")]
114pub enum Handedness {
115    Left,
116    #[default]
117    Right,
118}
119
120#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
121pub enum StreamingMode {
122    #[default]
123    USB,
124    Radio,
125}
126
127#[derive(Copy, Clone, Debug, PartialEq, Default, Deserialize, Serialize, TS)]
128#[serde(rename_all = "snake_case")]
129pub enum CoordinateOrigin {
130    #[default]
131    DeviceBase,
132    WorkspaceCenter,
133}
134
135/// Controls how duplicate device entries across `wireless_verse_grip` and
136/// `custom_verse_grip` are handled when the same `device_id` appears in both.
137#[derive(Copy, Clone, Debug, PartialEq, Default)]
138pub enum VerseGripDuplicateMode {
139    /// Keep `custom_verse_grip` entries, hide wireless duplicates (default).
140    #[default]
141    PreferCustom,
142    /// Keep `wireless_verse_grip` entries, hide custom duplicates.
143    PreferWireless,
144    /// Keep both -- no deduplication.
145    KeepBoth,
146}