1use std::str::FromStr;
2
3use crate::dsu::DSUFrame;
4use crate::errors::DeviceError;
5
6pub trait Device {
8 fn initialize(&self) -> Result<(), DeviceError>;
10
11 fn read_frame(&self) -> Result<DSUFrame, DeviceError>;
13}
14
15pub trait FrameDevice<F> {
17 fn to_dsu_frame(&self, frame: &F, gyro_disabled: bool) -> DSUFrame;
18 fn is_device_button_pressed(&self, button: &DeviceButton, frame: &F) -> bool;
20}
21
22#[derive(Debug, Clone)]
24pub enum DeviceButton {
25 DpadLeft,
27 DpadDown,
29 DpadRight,
31 DpadUp,
33 Start,
35 Select,
37 Guide,
39 Quaternary,
41 A,
43 B,
45 X,
47 Y,
49 L1,
51 R1,
53 L2,
55 R2,
57 L3,
59 R3,
61 L4,
63 L5,
65 R4,
67 R5,
69 LeftStickTouch,
71 RightStickTouch,
73 LeftPadTouch,
75 RightPadTouch,
77 LeftGrip,
79 RightGrip,
81 Unknown,
83}
84
85impl FromStr for DeviceButton {
86 type Err = DeviceError;
87
88 fn from_str(s: &str) -> Result<Self, Self::Err> {
89 match s {
90 "dpad_left" => Ok(Self::DpadLeft),
91 "dpad_down" => Ok(Self::DpadDown),
92 "dpad_right" => Ok(Self::DpadRight),
93 "dpad_up" => Ok(Self::DpadUp),
94 "start" => Ok(Self::Start),
95 "select" => Ok(Self::Select),
96 "guide" => Ok(Self::Guide),
97 "quaternary" => Ok(Self::Quaternary),
98 "a" => Ok(Self::A),
99 "b" => Ok(Self::B),
100 "x" => Ok(Self::X),
101 "y" => Ok(Self::Y),
102 "l1" => Ok(Self::L1),
103 "r1" => Ok(Self::R1),
104 "l2" => Ok(Self::L2),
105 "r2" => Ok(Self::R2),
106 "l3" => Ok(Self::L3),
107 "r3" => Ok(Self::R3),
108 "l4" => Ok(Self::L4),
109 "l5" => Ok(Self::L5),
110 "r4" => Ok(Self::R4),
111 "r5" => Ok(Self::R5),
112 "left_stick_touch" => Ok(Self::LeftStickTouch),
113 "right_stick_touch" => Ok(Self::RightStickTouch),
114 "left_pad_touch" => Ok(Self::LeftPadTouch),
115 "right_pad_touch" => Ok(Self::RightPadTouch),
116 "left_grip" => Ok(Self::LeftGrip),
117 "right_grip" => Ok(Self::RightGrip),
118 _ => Err(DeviceError::InvalidDeviceButton(s.to_string())),
119 }
120 }
121}
122
123impl std::fmt::Display for DeviceButton {
124 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
125 match self {
126 Self::DpadLeft => write!(f, "dpad_left"),
127 Self::DpadDown => write!(f, "dpad_down"),
128 Self::DpadRight => write!(f, "dpad_right"),
129 Self::DpadUp => write!(f, "dpad_up"),
130 Self::Start => write!(f, "start"),
131 Self::Select => write!(f, "select"),
132 Self::Guide => write!(f, "guide"),
133 Self::Quaternary => write!(f, "quaternary"),
134 Self::A => write!(f, "a"),
135 Self::B => write!(f, "b"),
136 Self::X => write!(f, "x"),
137 Self::Y => write!(f, "y"),
138 Self::L1 => write!(f, "l1"),
139 Self::R1 => write!(f, "r1"),
140 Self::L2 => write!(f, "l2"),
141 Self::R2 => write!(f, "r2"),
142 Self::L3 => write!(f, "l3"),
143 Self::R3 => write!(f, "r3"),
144 Self::L4 => write!(f, "l4"),
145 Self::L5 => write!(f, "l5"),
146 Self::R4 => write!(f, "r4"),
147 Self::R5 => write!(f, "r5"),
148 Self::LeftStickTouch => write!(f, "left_stick_touch"),
149 Self::RightStickTouch => write!(f, "right_stick_touch"),
150 Self::LeftPadTouch => write!(f, "left_pad_touch"),
151 Self::RightPadTouch => write!(f, "right_pad_touch"),
152 Self::LeftGrip => write!(f, "left_grip"),
153 Self::RightGrip => write!(f, "right_grip"),
154 Self::Unknown => write!(f, "unknown"),
155 }
156 }
157}
158
159#[derive(Default, Debug, Clone)]
165pub enum GyroActivationMode {
166 #[default]
167 Any,
168 All,
169}
170
171impl FromStr for GyroActivationMode {
172 type Err = DeviceError;
173
174 fn from_str(s: &str) -> Result<Self, Self::Err> {
175 match s {
176 "any" => Ok(Self::Any),
177 "all" => Ok(Self::All),
178 _ => Err(DeviceError::InvalidGyroActivationMode(s.to_string())),
179 }
180 }
181}
182
183impl std::fmt::Display for GyroActivationMode {
184 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
185 match self {
186 Self::Any => write!(f, "any"),
187 Self::All => write!(f, "all"),
188 }
189 }
190}
191
192#[derive(Debug, Clone)]
199pub struct DeviceConfig {
200 pub no_enable_lizard_mode_on_close: bool,
202 pub gyro_activation_inputs: Vec<DeviceButton>,
204 pub gyro_activation_mode: GyroActivationMode,
206 pub gyro_deadzone: f32,
208 pub gyro_pitch_scale: f32,
210 pub gyro_yaw_scale: f32,
212 pub gyro_roll_scale: f32,
214}
215
216impl Default for DeviceConfig {
217 fn default() -> Self {
218 Self {
219 no_enable_lizard_mode_on_close: false,
220 gyro_activation_inputs: Vec::new(),
221 gyro_activation_mode: GyroActivationMode::default(),
222 gyro_deadzone: 0.0,
223 gyro_pitch_scale: 1.0,
224 gyro_yaw_scale: 1.0,
225 gyro_roll_scale: 1.0,
226 }
227 }
228}