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}