Buttplug sex toy control library
1use buttplug_core::{
2 errors::{ButtplugError, ButtplugMessageError},
3 message::{
4 ButtplugClientMessageV4,
5 ButtplugDeviceMessage,
6 ButtplugMessage,
7 ButtplugMessageFinalizer,
8 ButtplugMessageSpecVersion,
9 ButtplugMessageValidator,
10 ButtplugServerMessageV4,
11 InputReadingV4,
12 },
13};
14use server_device_attributes::ServerDeviceAttributes;
15
16pub mod serializer;
17pub mod server_device_attributes;
18mod v0;
19mod v1;
20mod v2;
21mod v3;
22mod v4;
23
24pub use v0::*;
25pub use v1::*;
26pub use v2::*;
27pub use v3::*;
28pub use v4::*;
29
30#[derive(
31 Debug, Clone, PartialEq, ButtplugMessage, ButtplugMessageFinalizer, ButtplugMessageValidator,
32)]
33pub enum ButtplugClientMessageVariant {
34 V0(ButtplugClientMessageV0),
35 V1(ButtplugClientMessageV1),
36 V2(ButtplugClientMessageV2),
37 V3(ButtplugClientMessageV3),
38 V4(ButtplugClientMessageV4),
39}
40
41impl ButtplugClientMessageVariant {
42 pub fn version(&self) -> ButtplugMessageSpecVersion {
43 match self {
44 Self::V0(_) => ButtplugMessageSpecVersion::Version0,
45 Self::V1(_) => ButtplugMessageSpecVersion::Version1,
46 Self::V2(_) => ButtplugMessageSpecVersion::Version2,
47 Self::V3(_) => ButtplugMessageSpecVersion::Version3,
48 Self::V4(_) => ButtplugMessageSpecVersion::Version4,
49 }
50 }
51
52 pub fn device_index(&self) -> Option<u32> {
53 // TODO there has to be a better way to do this. We just need to dig through our enum and see if
54 // our message impls ButtplugDeviceMessage. Manually doing this works but is so gross.
55 match self {
56 Self::V0(msg) => match msg {
57 ButtplugClientMessageV0::FleshlightLaunchFW12Cmd(a) => Some(a.device_index()),
58 ButtplugClientMessageV0::SingleMotorVibrateCmd(a) => Some(a.device_index()),
59 ButtplugClientMessageV0::VorzeA10CycloneCmd(a) => Some(a.device_index()),
60 _ => None,
61 },
62 Self::V1(msg) => match msg {
63 ButtplugClientMessageV1::FleshlightLaunchFW12Cmd(a) => Some(a.device_index()),
64 ButtplugClientMessageV1::SingleMotorVibrateCmd(a) => Some(a.device_index()),
65 ButtplugClientMessageV1::VorzeA10CycloneCmd(a) => Some(a.device_index()),
66 ButtplugClientMessageV1::VibrateCmd(a) => Some(a.device_index()),
67 _ => None,
68 },
69 Self::V2(msg) => match msg {
70 ButtplugClientMessageV2::VibrateCmd(a) => Some(a.device_index()),
71 ButtplugClientMessageV2::RotateCmd(a) => Some(a.device_index()),
72 ButtplugClientMessageV2::LinearCmd(a) => Some(a.device_index()),
73 ButtplugClientMessageV2::BatteryLevelCmd(a) => Some(a.device_index()),
74 _ => None,
75 },
76 Self::V3(msg) => match msg {
77 ButtplugClientMessageV3::VibrateCmd(a) => Some(a.device_index()),
78 ButtplugClientMessageV3::SensorSubscribeCmd(a) => Some(a.device_index()),
79 ButtplugClientMessageV3::SensorUnsubscribeCmd(a) => Some(a.device_index()),
80 ButtplugClientMessageV3::ScalarCmd(a) => Some(a.device_index()),
81 ButtplugClientMessageV3::RotateCmd(a) => Some(a.device_index()),
82 ButtplugClientMessageV3::LinearCmd(a) => Some(a.device_index()),
83 ButtplugClientMessageV3::SensorReadCmd(a) => Some(a.device_index()),
84 _ => None,
85 },
86 Self::V4(msg) => match msg {
87 ButtplugClientMessageV4::OutputCmd(a) => Some(a.device_index()),
88 ButtplugClientMessageV4::InputCmd(a) => Some(a.device_index()),
89 _ => None,
90 },
91 }
92 }
93}
94
95impl From<ButtplugClientMessageV0> for ButtplugClientMessageVariant {
96 fn from(value: ButtplugClientMessageV0) -> Self {
97 ButtplugClientMessageVariant::V0(value)
98 }
99}
100
101impl From<ButtplugClientMessageV1> for ButtplugClientMessageVariant {
102 fn from(value: ButtplugClientMessageV1) -> Self {
103 ButtplugClientMessageVariant::V1(value)
104 }
105}
106
107impl From<ButtplugClientMessageV2> for ButtplugClientMessageVariant {
108 fn from(value: ButtplugClientMessageV2) -> Self {
109 ButtplugClientMessageVariant::V2(value)
110 }
111}
112
113impl From<ButtplugClientMessageV3> for ButtplugClientMessageVariant {
114 fn from(value: ButtplugClientMessageV3) -> Self {
115 ButtplugClientMessageVariant::V3(value)
116 }
117}
118
119impl From<ButtplugClientMessageV4> for ButtplugClientMessageVariant {
120 fn from(value: ButtplugClientMessageV4) -> Self {
121 ButtplugClientMessageVariant::V4(value)
122 }
123}
124
125#[derive(Debug, Clone, ButtplugMessage, ButtplugMessageFinalizer, ButtplugMessageValidator)]
126pub enum ButtplugServerMessageVariant {
127 V0(ButtplugServerMessageV0),
128 V1(ButtplugServerMessageV1),
129 V2(ButtplugServerMessageV2),
130 V3(ButtplugServerMessageV3),
131 V4(ButtplugServerMessageV4),
132}
133
134impl ButtplugServerMessageVariant {
135 pub fn version(&self) -> ButtplugMessageSpecVersion {
136 match self {
137 Self::V0(_) => ButtplugMessageSpecVersion::Version0,
138 Self::V1(_) => ButtplugMessageSpecVersion::Version1,
139 Self::V2(_) => ButtplugMessageSpecVersion::Version2,
140 Self::V3(_) => ButtplugMessageSpecVersion::Version3,
141 Self::V4(_) => ButtplugMessageSpecVersion::Version4,
142 }
143 }
144}
145
146impl From<ButtplugServerMessageV0> for ButtplugServerMessageVariant {
147 fn from(value: ButtplugServerMessageV0) -> Self {
148 ButtplugServerMessageVariant::V0(value)
149 }
150}
151
152impl From<ButtplugServerMessageV1> for ButtplugServerMessageVariant {
153 fn from(value: ButtplugServerMessageV1) -> Self {
154 ButtplugServerMessageVariant::V1(value)
155 }
156}
157
158impl From<ButtplugServerMessageV2> for ButtplugServerMessageVariant {
159 fn from(value: ButtplugServerMessageV2) -> Self {
160 ButtplugServerMessageVariant::V2(value)
161 }
162}
163
164impl From<ButtplugServerMessageV3> for ButtplugServerMessageVariant {
165 fn from(value: ButtplugServerMessageV3) -> Self {
166 ButtplugServerMessageVariant::V3(value)
167 }
168}
169
170impl From<ButtplugServerMessageV4> for ButtplugServerMessageVariant {
171 fn from(value: ButtplugServerMessageV4) -> Self {
172 ButtplugServerMessageVariant::V4(value)
173 }
174}
175
176/// Represents all possible messages a [ButtplugServer][crate::server::ButtplugServer] can send to a
177/// [ButtplugClient][crate::client::ButtplugClient] that denote an EVENT from a device. These are
178/// only used in notifications, so read requests will not need to be added here, only messages that
179/// will require Id of 0.
180#[derive(
181 Debug,
182 Clone,
183 PartialEq,
184 Eq,
185 ButtplugMessage,
186 ButtplugMessageValidator,
187 ButtplugMessageFinalizer,
188 FromSpecificButtplugMessage,
189)]
190pub enum ButtplugServerDeviceMessage {
191 // Generic Sensor Reading Messages
192 SensorReading(InputReadingV4),
193}
194
195impl From<ButtplugServerDeviceMessage> for ButtplugServerMessageV4 {
196 fn from(other: ButtplugServerDeviceMessage) -> Self {
197 match other {
198 ButtplugServerDeviceMessage::SensorReading(msg) => ButtplugServerMessageV4::InputReading(msg),
199 }
200 }
201}
202
203/// TryFrom for Buttplug Device Messages that need to use a device feature definition to convert
204pub(crate) trait TryFromDeviceAttributes<T>
205where
206 Self: Sized,
207{
208 fn try_from_device_attributes(
209 msg: T,
210 features: &ServerDeviceAttributes,
211 ) -> Result<Self, ButtplugError>;
212}