use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub enum InputPrimitive {
Rotate { delta: f64 },
Press,
Release,
LongPress,
Swipe { direction: Direction },
Slide { value: f64 },
Hover { proximity: f64 },
Touch { area: TouchArea },
LongTouch { area: TouchArea },
KeyPress { key: u32 },
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum Direction {
Up,
Down,
Left,
Right,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum TouchArea {
Top,
Bottom,
Left,
Right,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "snake_case")]
pub enum Intent {
Play,
Pause,
PlayPause,
Stop,
Next,
Previous,
VolumeChange { delta: f64 },
VolumeSet { value: f64 },
Mute,
Unmute,
SeekRelative { seconds: f64 },
SeekAbsolute { seconds: f64 },
BrightnessChange { delta: f64 },
BrightnessSet { value: f64 },
ColorTemperatureChange { delta: f64 },
PowerToggle,
PowerOn,
PowerOff,
}
impl InputPrimitive {
pub fn matches_route(&self, route_input: &str) -> bool {
match (self, route_input) {
(InputPrimitive::Rotate { .. }, "rotate") => true,
(InputPrimitive::Press, "press") => true,
(InputPrimitive::Release, "release") => true,
(InputPrimitive::LongPress, "long_press") => true,
(InputPrimitive::Slide { .. }, "slide") => true,
(InputPrimitive::Hover { .. }, "hover") => true,
(InputPrimitive::Swipe { direction }, s) => matches!(
(direction, s),
(Direction::Up, "swipe_up")
| (Direction::Down, "swipe_down")
| (Direction::Left, "swipe_left")
| (Direction::Right, "swipe_right")
),
(InputPrimitive::Touch { area }, s) => matches!(
(area, s),
(TouchArea::Top, "touch_top")
| (TouchArea::Bottom, "touch_bottom")
| (TouchArea::Left, "touch_left")
| (TouchArea::Right, "touch_right")
),
(InputPrimitive::LongTouch { area }, s) => matches!(
(area, s),
(TouchArea::Top, "long_touch_top")
| (TouchArea::Bottom, "long_touch_bottom")
| (TouchArea::Left, "long_touch_left")
| (TouchArea::Right, "long_touch_right")
),
_ => false,
}
}
pub fn continuous_value(&self) -> Option<f64> {
match self {
InputPrimitive::Rotate { delta } | InputPrimitive::Slide { value: delta } => {
Some(*delta)
}
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn rotate_matches_rotate_route() {
let r = InputPrimitive::Rotate { delta: 0.03 };
assert!(r.matches_route("rotate"));
assert!(!r.matches_route("press"));
}
#[test]
fn swipe_direction_matters() {
let s = InputPrimitive::Swipe {
direction: Direction::Right,
};
assert!(s.matches_route("swipe_right"));
assert!(!s.matches_route("swipe_left"));
assert!(!s.matches_route("swipe_up"));
}
}