Buttplug sex toy control library
1use buttplug_core::message::OutputType;
2
3use crate::ButtplugClientError;
4
5pub enum ClientDeviceCommandValue {
6 Int(i32),
7 Float(f64),
8}
9
10impl From<i32> for ClientDeviceCommandValue {
11 fn from(val: i32) -> Self {
12 ClientDeviceCommandValue::Int(val)
13 }
14}
15
16impl From<u32> for ClientDeviceCommandValue {
17 fn from(val: u32) -> Self {
18 ClientDeviceCommandValue::Int(val as i32)
19 }
20}
21
22impl From<f64> for ClientDeviceCommandValue {
23 fn from(val: f64) -> Self {
24 ClientDeviceCommandValue::Float(val)
25 }
26}
27
28pub enum ClientDeviceOutputCommand {
29 // u32 types use steps, need to compare before sending
30 Vibrate(u32),
31 Rotate(i32),
32 Oscillate(u32),
33 Constrict(u32),
34 Temperature(i32),
35 Led(u32),
36 Spray(u32),
37 Position(u32),
38 PositionWithDuration(u32, u32),
39 // f64 types are old style float, will need to convert before sending
40 VibrateFloat(f64),
41 RotateFloat(f64),
42 OscillateFloat(f64),
43 ConstrictFloat(f64),
44 TemperatureFloat(f64),
45 LedFloat(f64),
46 SprayFloat(f64),
47 PositionFloat(f64),
48 PositionWithDurationFloat(f64, u32),
49}
50
51impl ClientDeviceOutputCommand {
52 pub fn from_command_value_float(
53 output_type: OutputType,
54 value: f64,
55 ) -> Result<Self, ButtplugClientError> {
56 match output_type {
57 OutputType::Vibrate => Ok(ClientDeviceOutputCommand::VibrateFloat(value)),
58 OutputType::Oscillate => Ok(ClientDeviceOutputCommand::OscillateFloat(value)),
59 OutputType::Rotate => Ok(ClientDeviceOutputCommand::RotateFloat(value)),
60 OutputType::Constrict => Ok(ClientDeviceOutputCommand::ConstrictFloat(value)),
61 OutputType::Temperature => Ok(ClientDeviceOutputCommand::TemperatureFloat(value)),
62 OutputType::Led => Ok(ClientDeviceOutputCommand::LedFloat(value)),
63 OutputType::Spray => Ok(ClientDeviceOutputCommand::SprayFloat(value)),
64 OutputType::Position => Ok(ClientDeviceOutputCommand::PositionFloat(value)),
65 _ => Err(ButtplugClientError::ButtplugOutputCommandConversionError(
66 "Cannot use PositionWithDuration with this method".to_owned(),
67 )),
68 }
69 }
70}
71
72impl From<&ClientDeviceOutputCommand> for OutputType {
73 fn from(val: &ClientDeviceOutputCommand) -> Self {
74 match val {
75 ClientDeviceOutputCommand::Vibrate(_) | ClientDeviceOutputCommand::VibrateFloat(_) => {
76 OutputType::Vibrate
77 }
78 ClientDeviceOutputCommand::Oscillate(_) | ClientDeviceOutputCommand::OscillateFloat(_) => {
79 OutputType::Oscillate
80 }
81 ClientDeviceOutputCommand::Rotate(_) | ClientDeviceOutputCommand::RotateFloat(_) => {
82 OutputType::Rotate
83 }
84 ClientDeviceOutputCommand::Constrict(_) | ClientDeviceOutputCommand::ConstrictFloat(_) => {
85 OutputType::Constrict
86 }
87 ClientDeviceOutputCommand::Temperature(_) | ClientDeviceOutputCommand::TemperatureFloat(_) => {
88 OutputType::Temperature
89 }
90 ClientDeviceOutputCommand::Led(_) | ClientDeviceOutputCommand::LedFloat(_) => OutputType::Led,
91 ClientDeviceOutputCommand::Spray(_) | ClientDeviceOutputCommand::SprayFloat(_) => {
92 OutputType::Spray
93 }
94 ClientDeviceOutputCommand::Position(_) | ClientDeviceOutputCommand::PositionFloat(_) => {
95 OutputType::Position
96 }
97 ClientDeviceOutputCommand::PositionWithDuration(_, _)
98 | ClientDeviceOutputCommand::PositionWithDurationFloat(_, _) => {
99 OutputType::PositionWithDuration
100 }
101 }
102 }
103}