Buttplug sex toy control library

chore: Rebuild user device config file saving

Should at least serialize out now. Still not sure how it'll work. Needs tests.

+98 -19
+1 -1
crates/buttplug_client/src/device/feature.rs
··· 4 4 use buttplug_core::{ 5 5 errors::{ButtplugDeviceError, ButtplugError, ButtplugMessageError}, 6 6 message::{ 7 - ButtplugDeviceMessageNameV4, ButtplugServerMessageV4, DeviceFeature, DeviceFeatureOutput, DeviceFeatureOutputLimits, InputCmdV4, InputCommandType, InputType, InputTypeData, OutputCmdV4, OutputCommand, OutputPositionWithDuration, OutputRotateWithDirection, OutputType, OutputValue 7 + ButtplugDeviceMessageNameV4, ButtplugServerMessageV4, DeviceFeature, DeviceFeatureOutputLimits, InputCmdV4, InputCommandType, InputType, InputTypeData, OutputCmdV4, OutputCommand, OutputPositionWithDuration, OutputRotateWithDirection, OutputType, OutputValue 8 8 }, 9 9 }; 10 10
+23
crates/buttplug_server_device_config/src/device_config_file/device.rs
··· 78 78 message_gap_ms: Option<u32>, 79 79 } 80 80 81 + impl From<&ServerDeviceDefinition> for ConfigUserDeviceCustomization { 82 + fn from(value: &ServerDeviceDefinition) -> Self { 83 + Self { 84 + display_name: value.display_name().clone(), 85 + allow: value.allow(), 86 + deny: value.deny(), 87 + index: value.index(), 88 + message_gap_ms: value.message_gap_ms().clone() 89 + } 90 + } 91 + } 92 + 81 93 #[derive(Debug, Clone, Getters, MutGetters, Serialize, Deserialize, CopyGetters)] 82 94 pub struct ConfigUserDeviceDefinition { 83 95 #[getset(get_copy = "pub")] ··· 116 128 } 117 129 } 118 130 Ok(builder.finish()) 131 + } 132 + } 133 + 134 + impl From<&ServerDeviceDefinition> for ConfigUserDeviceDefinition { 135 + fn from(value: &ServerDeviceDefinition) -> Self { 136 + Self { 137 + id: value.id(), 138 + base_id: value.base_id().expect("Should always have a base id"), 139 + features: value.features().iter().map(|x| x.into()).collect(), 140 + user_config: value.into(), 141 + } 119 142 } 120 143 }
+72 -13
crates/buttplug_server_device_config/src/device_config_file/feature.rs
··· 16 16 use serde::{Deserialize, Serialize}; 17 17 use uuid::Uuid; 18 18 19 + #[derive(Serialize, Deserialize, Debug, Clone, Default, CopyGetters)] 20 + pub struct BaseFeatureSettings { 21 + #[serde( 22 + skip_serializing_if = "Option::is_none", 23 + default 24 + )] 25 + #[getset(get_copy = "pub")] 26 + alt_protocol_index: Option<u32>, 27 + } 28 + 29 + impl BaseFeatureSettings { 30 + pub fn is_none(&self) -> bool { 31 + self.alt_protocol_index.is_none() 32 + } 33 + } 34 + 19 35 #[derive(Serialize, Deserialize, Clone, Debug)] 20 36 struct BaseDeviceFeatureOutputValueProperties { 21 37 value: RangeInclusive<i32>, ··· 141 157 } 142 158 } 143 159 160 + impl From<&ServerDeviceFeatureOutputValueProperties> for UserDeviceFeatureOutputValueProperties { 161 + fn from(value: &ServerDeviceFeatureOutputValueProperties) -> Self { 162 + Self { 163 + value: value.value().user().clone(), 164 + disabled: value.disabled() 165 + } 166 + } 167 + } 168 + 144 169 #[derive(Serialize, Deserialize, Clone, Debug)] 145 170 struct UserDeviceFeatureOutputPositionProperties { 146 171 #[serde(skip_serializing_if = "Option::is_none")] ··· 165 190 } 166 191 } 167 192 193 + 194 + impl From<&ServerDeviceFeatureOutputPositionProperties> for UserDeviceFeatureOutputPositionProperties { 195 + fn from(value: &ServerDeviceFeatureOutputPositionProperties) -> Self { 196 + Self { 197 + value: value.position().user().clone(), 198 + reverse: value.reverse_position(), 199 + disabled: value.disabled() 200 + } 201 + } 202 + } 203 + 168 204 #[derive(Serialize, Deserialize, Clone, Debug)] 169 205 struct UserDeviceFeatureOutputPositionWithDurationProperties { 170 206 #[serde(skip_serializing_if = "Option::is_none")] ··· 195 231 ) 196 232 } 197 233 } 234 + 235 + impl From<&ServerDeviceFeatureOutputPositionWithDurationProperties> for UserDeviceFeatureOutputPositionWithDurationProperties { 236 + fn from(value: &ServerDeviceFeatureOutputPositionWithDurationProperties) -> Self { 237 + Self { 238 + position: value.position().user().clone(), 239 + duration: value.duration().user().clone(), 240 + reverse: value.reverse_position(), 241 + disabled: value.disabled() 242 + } 243 + } 244 + } 245 + 198 246 #[derive(Serialize, Deserialize, Clone, Debug)] 199 247 struct UserDeviceFeatureOutput { 200 248 #[serde(skip_serializing_if = "Option::is_none")] ··· 289 337 } 290 338 } 291 339 Ok(output) 340 + } 341 + } 342 + 343 + impl From<&ServerDeviceFeatureOutput> for UserDeviceFeatureOutput { 344 + fn from(value: &ServerDeviceFeatureOutput) -> Self { 345 + Self { 346 + vibrate: value.vibrate().as_ref().map(|x| x.into()), 347 + rotate: value.rotate().as_ref().map(|x| x.into()), 348 + rotate_with_direction: value.rotate_with_direction().as_ref().map(|x| x.into()), 349 + oscillate: value.oscillate().as_ref().map(|x| x.into()), 350 + constrict: value.constrict().as_ref().map(|x| x.into()), 351 + heater: value.heater().as_ref().map(|x| x.into()), 352 + led: value.led().as_ref().map(|x| x.into()), 353 + position: value.position().as_ref().map(|x| x.into()), 354 + position_with_duration: value.position_with_duration().as_ref().map(|x| x.into()), 355 + spray: value.spray().as_ref().map(|x| x.into()) 356 + } 292 357 } 293 358 } 294 359 ··· 427 492 } 428 493 } 429 494 430 - #[derive(Serialize, Deserialize, Debug, Clone, Default, CopyGetters)] 431 - pub struct BaseFeatureSettings { 432 - #[serde( 433 - skip_serializing_if = "Option::is_none", 434 - default 435 - )] 436 - #[getset(get_copy = "pub")] 437 - alt_protocol_index: Option<u32>, 438 - } 439 - 440 - impl BaseFeatureSettings { 441 - pub fn is_none(&self) -> bool { 442 - self.alt_protocol_index.is_none() 495 + impl From<&ServerDeviceFeature> for ConfigUserDeviceFeature { 496 + fn from(value: &ServerDeviceFeature) -> Self { 497 + Self { 498 + id: value.id(), 499 + base_id: value.base_id().expect("Should have base id"), 500 + output: value.output().as_ref().map(|x| x.into()), 501 + } 443 502 } 444 503 }
+1 -4
crates/buttplug_server_device_config/src/device_config_file/mod.rs
··· 259 259 Ok(dcm_builder) 260 260 } 261 261 262 - // TODO Update save_user_config to work with new device structures 263 - /* 264 262 pub fn save_user_config(dcm: &DeviceConfigurationManager) -> Result<String, ButtplugError> { 265 263 let user_specifiers = dcm.user_communication_specifiers(); 266 264 let user_definitions_vec = dcm ··· 268 266 .iter() 269 267 .map(|kv| UserDeviceConfigPair { 270 268 identifier: kv.key().clone(), 271 - config: kv.value().user_device().clone(), 269 + config: kv.value().into(), 272 270 }) 273 271 .collect(); 274 272 let user_protos = DashMap::new(); ··· 293 291 ))) 294 292 }) 295 293 } 296 - */ 297 294 298 295 #[cfg(test)] 299 296 mod test {
+1 -1
crates/buttplug_server_device_config/src/lib.rs
··· 143 143 mod device_config_file; 144 144 145 145 use buttplug_core::message::OutputType; 146 - pub use device_config_file::{load_protocol_configs}; //, save_user_config}; 146 + pub use device_config_file::{load_protocol_configs, save_user_config}; 147 147 mod device_config_manager; 148 148 pub use device_config_manager::*; 149 149 mod specifier;