ble_data_struct/descriptors/characteristic_extended_properties.rs
1//! Characteristic Extended Properties (Attribute Type: 0x2900) module.
2
3use crate::Uuid16bit;
4
5/// Characteristic Extended Properties.
6#[derive(Debug, PartialEq, Clone)]
7pub struct CharacteristicExtendedProperties {
8 /// Characteristic Extended Properties Bit Field
9 pub properties: u16,
10}
11
12impl CharacteristicExtendedProperties {
13 /// Create [`CharacteristicExtendedProperties`] from `Characteristic Extended Properties Bit Field`.
14 ///
15 /// # Examples
16 ///
17 /// ```
18 /// use ble_data_struct::descriptors::client_characteristic_configuration::{
19 /// ClientCharacteristicConfiguration, INDICATION, NOTIFICATION,
20 /// };
21 ///
22 /// let result = ClientCharacteristicConfiguration::new(NOTIFICATION);
23 /// assert_eq!(NOTIFICATION, result.configuration);
24 /// ```
25 pub fn new(properties: u16) -> Self {
26 Self { properties }
27 }
28
29 /// check Reliable Write.
30 ///
31 /// # Examples
32 ///
33 /// ```
34 /// use ble_data_struct::descriptors::client_characteristic_configuration::{
35 /// ClientCharacteristicConfiguration, INDICATION, NOTIFICATION,
36 /// };
37 ///
38 /// let result = ClientCharacteristicConfiguration::new(NOTIFICATION);
39 /// assert!(result.is_notification());
40 /// assert!(!result.is_indication());
41 /// ```
42 pub fn is_reliable_write(&self) -> bool {
43 self.properties == RELIABLE_WRITE
44 }
45
46 /// check Writable Auxiliaries.
47 ///
48 /// # Examples
49 ///
50 /// ```
51 /// use ble_data_struct::descriptors::client_characteristic_configuration::{
52 /// ClientCharacteristicConfiguration, INDICATION, NOTIFICATION,
53 /// };
54 ///
55 /// let result = ClientCharacteristicConfiguration::new(INDICATION);
56 /// assert!(!result.is_notification());
57 /// assert!(result.is_indication());
58 /// ```
59 pub fn is_writable_auxiliaries(&self) -> bool {
60 self.properties == WRITABLE_AUXILIARIES
61 }
62}
63
64/// Reliable Write
65pub const RELIABLE_WRITE: u16 = 0b00000001;
66
67/// Writable Auxiliaries
68pub const WRITABLE_AUXILIARIES: u16 = 0b00000010;
69
70impl TryFrom<&Vec<u8>> for CharacteristicExtendedProperties {
71 type Error = String;
72 /// Create [`CharacteristicExtendedProperties`] from [`Vec<u8>`].
73 ///
74 /// # Examples
75 ///
76 /// ```
77 /// use ble_data_struct::descriptors::client_characteristic_configuration::{
78 /// ClientCharacteristicConfiguration, INDICATION, NOTIFICATION,
79 /// };
80 ///
81 /// let configuration = NOTIFICATION.to_le_bytes().to_vec();
82 /// let result = ClientCharacteristicConfiguration::try_from(&configuration);
83 /// assert!(result.is_ok());
84 /// assert_eq!(NOTIFICATION, result.unwrap().configuration);
85 ///
86 /// let configuration = INDICATION.to_le_bytes().to_vec();
87 /// let result = ClientCharacteristicConfiguration::try_from(&configuration);
88 /// assert!(result.is_ok());
89 /// assert_eq!(INDICATION, result.unwrap().configuration);
90 ///
91 /// let configuration = Vec::new();
92 /// let result = ClientCharacteristicConfiguration::try_from(&configuration);
93 /// assert!(!result.is_ok());
94 /// ```
95 fn try_from(value: &Vec<u8>) -> Result<Self, String> {
96 let len = value.len();
97 if len != 2 {
98 return Err(format!("Invalid data size :{}", len).to_string());
99 }
100 Ok(Self {
101 properties: u16::from_le_bytes(value[..2].try_into().unwrap()),
102 })
103 }
104}
105
106impl Into<Vec<u8>> for CharacteristicExtendedProperties {
107 /// Create [`Vec<u8>`] from [`CharacteristicExtendedProperties`].
108 ///
109 /// # Examples
110 ///
111 /// ```
112 /// use ble_data_struct::descriptors::client_characteristic_configuration::{
113 /// ClientCharacteristicConfiguration, INDICATION, NOTIFICATION,
114 /// };
115 ///
116 /// let configuration = NOTIFICATION.to_le_bytes().to_vec();
117 /// let result = ClientCharacteristicConfiguration::new(NOTIFICATION);
118 /// let into_data: Vec<u8> = result.into();
119 /// assert_eq!(configuration, into_data);
120 ///
121 /// let configuration = INDICATION.to_le_bytes().to_vec();
122 /// let result = ClientCharacteristicConfiguration::new(INDICATION);
123 /// let into_data: Vec<u8> = result.into();
124 /// assert_eq!(configuration, into_data);
125 /// ```
126 fn into(self) -> Vec<u8> {
127 u16::to_le_bytes(self.properties).to_vec()
128 }
129}
130
131impl Uuid16bit for CharacteristicExtendedProperties {
132 /// return `0x2900`.
133 ///
134 /// # Examples
135 ///
136 /// ```
137 /// use ble_data_struct::Uuid16bit;
138 /// use ble_data_struct::descriptors::characteristic_extended_properties::CharacteristicExtendedProperties;
139 ///
140 /// assert_eq!(0x2900, CharacteristicExtendedProperties::uuid_16bit());
141 /// ```
142 fn uuid_16bit() -> u16 {
143 0x2900
144 }
145}
146
147#[cfg(test)]
148mod tests {
149 use crate::{descriptors::characteristic_extended_properties::{
150 CharacteristicExtendedProperties, RELIABLE_WRITE, WRITABLE_AUXILIARIES,
151 }, Uuid16bit};
152
153 #[test]
154 fn test_new() {
155 let result = CharacteristicExtendedProperties::new(RELIABLE_WRITE);
156 assert_eq!(RELIABLE_WRITE, result.properties);
157 }
158
159 #[test]
160 fn test_is_reliable_write() {
161 let result = CharacteristicExtendedProperties::new(RELIABLE_WRITE);
162 assert!(result.is_reliable_write());
163 assert!(!result.is_writable_auxiliaries());
164 }
165
166 #[test]
167 fn test_is_writable_auxiliaries() {
168 let result = CharacteristicExtendedProperties::new(WRITABLE_AUXILIARIES);
169 assert!(!result.is_reliable_write());
170 assert!(result.is_writable_auxiliaries());
171 }
172
173 #[test]
174 fn test_try_from() {
175 let properties = RELIABLE_WRITE.to_le_bytes().to_vec();
176 let result = CharacteristicExtendedProperties::try_from(&properties);
177 assert!(result.is_ok());
178 assert_eq!(RELIABLE_WRITE, result.unwrap().properties);
179
180 let properties = WRITABLE_AUXILIARIES.to_le_bytes().to_vec();
181 let result = CharacteristicExtendedProperties::try_from(&properties);
182 assert!(result.is_ok());
183 assert_eq!(WRITABLE_AUXILIARIES, result.unwrap().properties);
184
185 let properties = Vec::new();
186 let result = CharacteristicExtendedProperties::try_from(&properties);
187 assert!(!result.is_ok());
188 }
189
190 #[test]
191 fn test_into() {
192 let properties = RELIABLE_WRITE.to_le_bytes().to_vec();
193 let result = CharacteristicExtendedProperties::new(RELIABLE_WRITE);
194 let into_data: Vec<u8> = result.into();
195 assert_eq!(properties, into_data);
196
197 let properties = WRITABLE_AUXILIARIES.to_le_bytes().to_vec();
198 let result = CharacteristicExtendedProperties::new(WRITABLE_AUXILIARIES);
199 let into_data: Vec<u8> = result.into();
200 assert_eq!(properties, into_data);
201 }
202
203 #[test]
204 fn test_uuid_16bit() {
205 assert_eq!(0x2900, CharacteristicExtendedProperties::uuid_16bit());
206 }
207}