ble_data_struct/descriptors/
client_characteristic_configuration.rs

1//! Client Characteristic Configuration (Attribute Type: 0x2902) module.
2
3use crate::Uuid16bit;
4
5/// Client Characteristic Configuration.
6#[derive(Debug, PartialEq, Clone)]
7pub struct ClientCharacteristicConfiguration {
8    /// Characteristic Configuration Bits
9    pub configuration: u16,
10}
11
12impl ClientCharacteristicConfiguration {
13    /// Create [`ClientCharacteristicConfiguration`] from `Characteristic Configuration Bit`.
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(configuration: u16) -> Self {
26        Self { configuration }
27    }
28
29    /// check Notification configuration.
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_notification(&self) -> bool {
43        self.configuration == NOTIFICATION
44    }
45
46    /// check Inidication configuration.
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_indication(&self) -> bool {
60        self.configuration == INDICATION
61    }
62}
63
64/// Notification
65pub const NOTIFICATION: u16 = 0b00000001;
66
67/// Indication
68pub const INDICATION: u16 = 0b00000010;
69
70impl TryFrom<&Vec<u8>> for ClientCharacteristicConfiguration {
71    type Error = String;
72    /// Create [`ClientCharacteristicConfiguration`] 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            configuration: u16::from_le_bytes(value[..2].try_into().unwrap()),
102        })
103    }
104}
105
106impl Into<Vec<u8>> for ClientCharacteristicConfiguration {
107    /// Create [`Vec<u8>`] from [`ClientCharacteristicConfiguration`].
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.configuration).to_vec()
128    }
129}
130
131impl Uuid16bit for ClientCharacteristicConfiguration {
132    /// return `0x2902`.
133    ///
134    /// # Examples
135    ///
136    /// ```
137    /// use ble_data_struct::Uuid16bit;
138    /// use ble_data_struct::descriptors::client_characteristic_configuration::ClientCharacteristicConfiguration;
139    ///
140    /// assert_eq!(0x2902, ClientCharacteristicConfiguration::uuid_16bit());
141    /// ```
142    fn uuid_16bit() -> u16 {
143        0x2902
144    }
145}
146
147#[cfg(test)]
148mod tests {
149    use crate::{descriptors::client_characteristic_configuration::{
150        ClientCharacteristicConfiguration, INDICATION, NOTIFICATION,
151    }, Uuid16bit};
152
153    #[test]
154    fn test_new() {
155        let result = ClientCharacteristicConfiguration::new(NOTIFICATION);
156        assert_eq!(NOTIFICATION, result.configuration);
157    }
158
159    #[test]
160    fn test_is_notification() {
161        let result = ClientCharacteristicConfiguration::new(NOTIFICATION);
162        assert!(result.is_notification());
163        assert!(!result.is_indication());
164    }
165
166    #[test]
167    fn test_is_indication() {
168        let result = ClientCharacteristicConfiguration::new(INDICATION);
169        assert!(!result.is_notification());
170        assert!(result.is_indication());
171    }
172
173    #[test]
174    fn test_try_from() {
175        let configuration = NOTIFICATION.to_le_bytes().to_vec();
176        let result = ClientCharacteristicConfiguration::try_from(&configuration);
177        assert!(result.is_ok());
178        assert_eq!(NOTIFICATION, result.unwrap().configuration);
179
180        let configuration = INDICATION.to_le_bytes().to_vec();
181        let result = ClientCharacteristicConfiguration::try_from(&configuration);
182        assert!(result.is_ok());
183        assert_eq!(INDICATION, result.unwrap().configuration);
184
185        let configuration = Vec::new();
186        let result = ClientCharacteristicConfiguration::try_from(&configuration);
187        assert!(!result.is_ok());
188    }
189
190    #[test]
191    fn test_into() {
192        let configuration = NOTIFICATION.to_le_bytes().to_vec();
193        let result = ClientCharacteristicConfiguration::new(NOTIFICATION);
194        let into_data: Vec<u8> = result.into();
195        assert_eq!(configuration, into_data);
196
197        let configuration = INDICATION.to_le_bytes().to_vec();
198        let result = ClientCharacteristicConfiguration::new(INDICATION);
199        let into_data: Vec<u8> = result.into();
200        assert_eq!(configuration, into_data);
201    }
202
203    #[test]
204    fn test_uuid_16bit() {
205        assert_eq!(0x2902, ClientCharacteristicConfiguration::uuid_16bit());
206    }
207}