ble_data_struct/descriptors/
characteristic_aggregate_format.rs

1//! Characteristic Aggregate Format (Attribute Type: 0x2905) module.
2
3use crate::Uuid16bit;
4
5/// Characteristic Aggregate Format.
6#[derive(Debug, PartialEq, Clone)]
7pub struct CharacteristicAggregateFormat {
8    /// List of Attribute Handles
9    pub list_of_attribute_handles: Vec<u16>,
10}
11
12impl CharacteristicAggregateFormat {
13    /// Create [`CharacteristicAggregateFormat`] from [`String`].
14    ///
15    /// # Examples
16    ///
17    /// ```
18    /// use ble_data_struct::{
19    ///     descriptors::characteristic_aggregate_format::CharacteristicAggregateFormat, Uuid16bit,
20    /// };
21    ///
22    /// let list_of_attribute_handles: Vec<u16> = [0x0201, 0x0403].to_vec();
23    /// let result = CharacteristicAggregateFormat::new(&list_of_attribute_handles.clone());
24    /// assert_eq!(list_of_attribute_handles, result.list_of_attribute_handles);
25    /// ```
26    pub fn new(list_of_attribute_handles: &Vec<u16>) -> Self {
27        Self {
28            list_of_attribute_handles: list_of_attribute_handles.clone(),
29        }
30    }
31}
32
33impl TryFrom<&Vec<u8>> for CharacteristicAggregateFormat {
34    type Error = String;
35    /// Create [`CharacteristicAggregateFormat`] from [`Vec<u8>`].
36    ///
37    /// # Examples
38    ///
39    /// ```
40    /// use ble_data_struct::{
41    ///     descriptors::characteristic_aggregate_format::CharacteristicAggregateFormat, Uuid16bit,
42    /// };
43    ///
44    /// let list_of_attribute_handles: Vec<u16> = [0x0201, 0x0403].to_vec();
45    /// let data: Vec<u8> = list_of_attribute_handles
46    ///     .clone()
47    ///     .iter()
48    ///     .flat_map(|f| f.to_le_bytes())
49    ///     .collect();
50    /// 
51    /// let result = CharacteristicAggregateFormat::try_from(&data);
52    /// assert!(result.is_ok());
53    /// let descriptor = result.unwrap();
54    /// assert_eq!(
55    ///     list_of_attribute_handles,
56    ///     descriptor.list_of_attribute_handles
57    /// );
58    /// 
59    /// let result = CharacteristicAggregateFormat::try_from(&Vec::new());
60    /// assert!(!result.is_ok());
61    /// 
62    /// let result = CharacteristicAggregateFormat::try_from(&vec![0, 1, 2]);
63    /// assert!(!result.is_ok());
64    /// ```
65    fn try_from(value: &Vec<u8>) -> Result<Self, String> {
66        let len = value.len();
67        if len < 2 {
68            return Err(format!("Invalid data size :{}", len).to_string());
69        }
70        if len % 2 == 1 {
71            return Err(format!("Invalid data size :{}", len).to_string());
72        }
73        Ok(Self {
74            list_of_attribute_handles: value
75                .windows(2)
76                .step_by(2)
77                .map(|w| u16::from_le_bytes(w[0..2].try_into().unwrap()))
78                .collect(),
79        })
80    }
81}
82
83impl Into<Vec<u8>> for CharacteristicAggregateFormat {
84    /// Create [`Vec<u8>`] from [`CharacteristicAggregateFormat`].
85    ///
86    /// # Examples
87    ///
88    /// ```
89    /// use ble_data_struct::{
90    ///     descriptors::characteristic_aggregate_format::CharacteristicAggregateFormat, Uuid16bit,
91    /// };
92    ///
93    /// let list_of_attribute_handles: Vec<u16> = [0x0201, 0x0403].to_vec();
94    /// let result = CharacteristicAggregateFormat::new(&list_of_attribute_handles.clone());
95    /// 
96    /// let data: Vec<u8> = list_of_attribute_handles
97    ///     .clone()
98    ///     .iter()
99    ///     .flat_map(|f| f.to_le_bytes())
100    ///     .collect();
101    /// let into_data: Vec<u8> = result.into();
102    /// assert_eq!(data, into_data);
103    /// ```
104    fn into(self) -> Vec<u8> {
105        return self
106            .list_of_attribute_handles
107            .clone()
108            .iter()
109            .flat_map(|f| f.to_le_bytes())
110            .collect();
111    }
112}
113
114impl Uuid16bit for CharacteristicAggregateFormat {
115    /// return `0x2905`.
116    ///
117    /// # Examples
118    ///
119    /// ```
120    /// use ble_data_struct::{
121    ///     descriptors::characteristic_aggregate_format::CharacteristicAggregateFormat, Uuid16bit,
122    /// };
123    ///
124    /// assert_eq!(0x2905, CharacteristicAggregateFormat::uuid_16bit());
125    /// ```
126    fn uuid_16bit() -> u16 {
127        0x2905
128    }
129}
130
131#[cfg(test)]
132mod tests {
133    use crate::{
134        descriptors::characteristic_aggregate_format::CharacteristicAggregateFormat, Uuid16bit,
135    };
136
137    #[test]
138    fn test_new() {
139        let list_of_attribute_handles: Vec<u16> = [0x0201, 0x0403].to_vec();
140        let result = CharacteristicAggregateFormat::new(&list_of_attribute_handles.clone());
141        assert_eq!(list_of_attribute_handles, result.list_of_attribute_handles);
142    }
143
144    #[test]
145    fn test_try_from() {
146        let list_of_attribute_handles: Vec<u16> = [0x0201, 0x0403].to_vec();
147        let data: Vec<u8> = list_of_attribute_handles
148            .clone()
149            .iter()
150            .flat_map(|f| f.to_le_bytes())
151            .collect();
152
153        let result = CharacteristicAggregateFormat::try_from(&data);
154        assert!(result.is_ok());
155        let descriptor = result.unwrap();
156        assert_eq!(
157            list_of_attribute_handles,
158            descriptor.list_of_attribute_handles
159        );
160
161        let result = CharacteristicAggregateFormat::try_from(&Vec::new());
162        assert!(!result.is_ok());
163
164        let result = CharacteristicAggregateFormat::try_from(&vec![0, 1, 2]);
165        assert!(!result.is_ok());
166    }
167
168    #[test]
169    fn test_into() {
170        let list_of_attribute_handles: Vec<u16> = [0x0201, 0x0403].to_vec();
171        let result = CharacteristicAggregateFormat::new(&list_of_attribute_handles.clone());
172
173        let data: Vec<u8> = list_of_attribute_handles
174            .clone()
175            .iter()
176            .flat_map(|f| f.to_le_bytes())
177            .collect();
178        let into_data: Vec<u8> = result.into();
179        assert_eq!(data, into_data);
180    }
181
182    #[test]
183    fn test_uuid_16bit() {
184        assert_eq!(0x2905, CharacteristicAggregateFormat::uuid_16bit());
185    }
186}