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}