Buttplug sex toy control library
at dev 138 lines 4.6 kB view raw
1use getset::{CopyGetters, Getters, MutGetters}; 2use serde::{Deserialize, Serialize}; 3use uuid::Uuid; 4 5use crate::{ButtplugDeviceConfigError, ServerDeviceDefinition, ServerDeviceDefinitionBuilder}; 6 7use super::feature::{ConfigBaseDeviceFeature, ConfigUserDeviceFeature}; 8 9#[derive(Debug, Clone, Getters, CopyGetters, Serialize, Deserialize)] 10pub struct ConfigBaseDeviceDefinition { 11 #[getset(get = "pub")] 12 identifier: Option<Vec<String>>, 13 #[getset(get = "pub")] 14 /// Given name of the device this instance represents. 15 name: String, 16 #[getset(get_copy = "pub")] 17 id: Uuid, 18 #[getset(get = "pub")] 19 protocol_variant: Option<String>, 20 #[getset(get_copy = "pub")] 21 message_gap_ms: Option<u32>, 22 #[getset(get = "pub")] 23 features: Option<Vec<ConfigBaseDeviceFeature>>, 24} 25 26impl ConfigBaseDeviceDefinition { 27 pub fn update_with_configuration(&self, config: ConfigBaseDeviceDefinition) -> Self { 28 Self { 29 identifier: config.identifier().clone(), 30 name: config.name().clone(), 31 id: config.id(), 32 protocol_variant: config.protocol_variant.or(self.protocol_variant.clone()), 33 message_gap_ms: config.message_gap_ms.or(self.message_gap_ms), 34 features: config.features.or(self.features.clone()), 35 } 36 } 37} 38 39impl From<ConfigBaseDeviceDefinition> for ServerDeviceDefinition { 40 fn from(val: ConfigBaseDeviceDefinition) -> Self { 41 let mut builder = ServerDeviceDefinitionBuilder::new(&val.name, &val.id); 42 if let Some(variant) = val.protocol_variant { 43 builder.protocol_variant(&variant); 44 } 45 if let Some(gap) = val.message_gap_ms { 46 builder.message_gap_ms(gap); 47 } 48 if let Some(features) = val.features { 49 for feature in features { 50 builder.add_feature(&feature.into()); 51 } 52 } 53 builder.finish() 54 } 55} 56 57#[derive(Serialize, Deserialize, Debug, Getters, CopyGetters, Default, Clone, MutGetters)] 58pub struct ConfigUserDeviceCustomization { 59 #[serde(default, skip_serializing_if = "Option::is_none")] 60 #[getset(get = "pub")] 61 display_name: Option<String>, 62 #[serde(default)] 63 #[getset(get_copy = "pub")] 64 allow: bool, 65 #[serde(default)] 66 #[getset(get_copy = "pub")] 67 deny: bool, 68 #[getset(get_copy = "pub", get_mut = "pub")] 69 index: u32, 70 #[getset(get_copy = "pub")] 71 #[serde(default, skip_serializing_if = "Option::is_none")] 72 message_gap_ms: Option<u32>, 73} 74 75impl From<&ServerDeviceDefinition> for ConfigUserDeviceCustomization { 76 fn from(value: &ServerDeviceDefinition) -> Self { 77 Self { 78 display_name: value.display_name().clone(), 79 allow: value.allow(), 80 deny: value.deny(), 81 index: value.index(), 82 message_gap_ms: value.message_gap_ms(), 83 } 84 } 85} 86 87#[derive(Debug, Clone, Getters, MutGetters, Serialize, Deserialize, CopyGetters)] 88pub struct ConfigUserDeviceDefinition { 89 #[getset(get_copy = "pub")] 90 id: Uuid, 91 #[getset(get_copy = "pub")] 92 base_id: Uuid, 93 #[getset(get = "pub")] 94 /// Message attributes for this device instance. 95 #[getset(get = "pub", get_mut = "pub")] 96 features: Vec<ConfigUserDeviceFeature>, 97 #[getset(get = "pub", get_mut = "pub")] 98 /// Per-user configurations specific to this device instance. 99 user_config: ConfigUserDeviceCustomization, 100} 101 102impl ConfigUserDeviceDefinition { 103 pub fn build_from_base_definition( 104 &self, 105 base: &ServerDeviceDefinition, 106 ) -> Result<ServerDeviceDefinition, ButtplugDeviceConfigError> { 107 let mut builder = ServerDeviceDefinitionBuilder::from_base(base, self.id, false); 108 builder.display_name(&self.user_config.display_name); 109 if let Some(message_gap_ms) = self.user_config.message_gap_ms { 110 builder.message_gap_ms(message_gap_ms); 111 } 112 self.user_config.allow.then(|| builder.allow(true)); 113 self.user_config.deny.then(|| builder.deny(true)); 114 builder.index(self.user_config.index); 115 if self.features().len() != base.features().len() { 116 return Err(ButtplugDeviceConfigError::UserFeatureMismatch); 117 } 118 for feature in self.features() { 119 if let Some(base_feature) = base.features().iter().find(|x| x.id() == feature.base_id()) { 120 builder.add_feature(&feature.with_base_feature(base_feature)?); 121 } else { 122 return Err(ButtplugDeviceConfigError::UserFeatureMismatch); 123 } 124 } 125 Ok(builder.finish()) 126 } 127} 128 129impl From<&ServerDeviceDefinition> for ConfigUserDeviceDefinition { 130 fn from(value: &ServerDeviceDefinition) -> Self { 131 Self { 132 id: value.id(), 133 base_id: value.base_id().expect("Should always have a base id"), 134 features: value.features().iter().map(|x| x.into()).collect(), 135 user_config: value.into(), 136 } 137 } 138}