1use serde::{Deserialize, Serialize};
4
5#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub enum InputPrimitive {
9 Rotate { delta: f64 },
10 Press,
11 Release,
12 LongPress,
13 Swipe { direction: Direction },
14 Slide { value: f64 },
15 Hover { proximity: f64 },
16 Touch { area: TouchArea },
17 LongTouch { area: TouchArea },
18 KeyPress { key: u32 },
19}
20
21#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
22#[serde(rename_all = "snake_case")]
23pub enum Direction {
24 Up,
25 Down,
26 Left,
27 Right,
28}
29
30#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
31#[serde(rename_all = "snake_case")]
32pub enum TouchArea {
33 Top,
34 Bottom,
35 Left,
36 Right,
37}
38
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
42#[serde(tag = "type", rename_all = "snake_case")]
43pub enum Intent {
44 Play,
45 Pause,
46 PlayPause,
47 Stop,
48 Next,
49 Previous,
50 VolumeChange { delta: f64 },
51 VolumeSet { value: f64 },
52 Mute,
53 Unmute,
54 SeekRelative { seconds: f64 },
55 SeekAbsolute { seconds: f64 },
56 BrightnessChange { delta: f64 },
57 BrightnessSet { value: f64 },
58 ColorTemperatureChange { delta: f64 },
59 PowerToggle,
60 PowerOn,
61 PowerOff,
62}
63
64impl InputPrimitive {
65 pub fn matches_route(&self, route_input: &str) -> bool {
68 match (self, route_input) {
69 (InputPrimitive::Rotate { .. }, "rotate") => true,
70 (InputPrimitive::Press, "press") => true,
71 (InputPrimitive::Release, "release") => true,
72 (InputPrimitive::LongPress, "long_press") => true,
73 (InputPrimitive::Slide { .. }, "slide") => true,
74 (InputPrimitive::Hover { .. }, "hover") => true,
75 (InputPrimitive::Swipe { direction }, s) => matches!(
76 (direction, s),
77 (Direction::Up, "swipe_up")
78 | (Direction::Down, "swipe_down")
79 | (Direction::Left, "swipe_left")
80 | (Direction::Right, "swipe_right")
81 ),
82 (InputPrimitive::Touch { area }, s) => matches!(
83 (area, s),
84 (TouchArea::Top, "touch_top")
85 | (TouchArea::Bottom, "touch_bottom")
86 | (TouchArea::Left, "touch_left")
87 | (TouchArea::Right, "touch_right")
88 ),
89 (InputPrimitive::LongTouch { area }, s) => matches!(
90 (area, s),
91 (TouchArea::Top, "long_touch_top")
92 | (TouchArea::Bottom, "long_touch_bottom")
93 | (TouchArea::Left, "long_touch_left")
94 | (TouchArea::Right, "long_touch_right")
95 ),
96 _ => false,
97 }
98 }
99
100 pub fn continuous_value(&self) -> Option<f64> {
102 match self {
103 InputPrimitive::Rotate { delta } | InputPrimitive::Slide { value: delta } => {
104 Some(*delta)
105 }
106 _ => None,
107 }
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn rotate_matches_rotate_route() {
117 let r = InputPrimitive::Rotate { delta: 0.03 };
118 assert!(r.matches_route("rotate"));
119 assert!(!r.matches_route("press"));
120 }
121
122 #[test]
123 fn swipe_direction_matters() {
124 let s = InputPrimitive::Swipe {
125 direction: Direction::Right,
126 };
127 assert!(s.matches_route("swipe_right"));
128 assert!(!s.matches_route("swipe_left"));
129 assert!(!s.matches_route("swipe_up"));
130 }
131}