ads_proto/proto/sumup/
sumup_response.rs

1use crate::error::AdsError;
2use crate::proto::proto_traits::{ReadFrom, WriteTo};
3use crate::proto::response::{ReadResponse, ReadWriteResponse, WriteResponse};
4use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
5use std::io::{self, Read, Write};
6
7//Helper struct
8#[derive(Debug, Clone, PartialEq, Eq)]
9struct AccessData {
10    result: u32,
11    length: u32,
12}
13
14impl WriteTo for AccessData {
15    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
16        wtr.write_u32::<LittleEndian>(self.result)?;
17        wtr.write_u32::<LittleEndian>(self.length)?;
18        Ok(())
19    }
20}
21
22impl ReadFrom for AccessData {
23    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
24        let result = read.read_u32::<LittleEndian>()?;
25        let length = read.read_u32::<LittleEndian>()?;
26
27        Ok(AccessData { result, length })
28    }
29}
30
31///Ads Sumup Read Write response
32///Bundle multiple responses toghether. Add this data to the read write response or parse from.
33#[derive(Debug, Clone, PartialEq, Eq)]
34pub struct SumupReadWriteResponse {
35    pub read_write_responses: Vec<ReadWriteResponse>,
36}
37
38impl SumupReadWriteResponse {
39    pub fn new(read_write_responses: Vec<ReadWriteResponse>) -> Self {
40        SumupReadWriteResponse {
41            read_write_responses,
42        }
43    }
44}
45
46impl ReadFrom for SumupReadWriteResponse {
47    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
48        let mut data_buf: Vec<u8> = Vec::new();
49        let mut read_access: Vec<AccessData> = Vec::new();
50
51        //Read all bytes to get the total length
52        read.read_to_end(&mut data_buf)?;
53        let total_data_len = data_buf.len() as u32;
54        let mut access_data_length: u32 = 0;
55        let mut data_length: u32 = 0;
56        let mut data_buf = data_buf.as_slice();
57
58        //Get the access data bytes
59        for _ in 0..total_data_len / 8 {
60            let access_data = AccessData::read_from(&mut data_buf)?;
61            access_data_length += 8;
62            data_length += access_data.length;
63            read_access.push(access_data);
64            if (total_data_len - data_length - access_data_length) == 0 {
65                break;
66            }
67        }
68
69        //Get the actual data/value bytes and create ReadWriteResponses
70        let mut read_write_response: Vec<ReadWriteResponse> = Vec::new();
71        for access in read_access {
72            let mut buf = vec![0; access.length as usize];
73            data_buf.read_exact(&mut buf)?;
74            read_write_response.push(ReadWriteResponse::new(AdsError::from(access.result), buf));
75        }
76        Ok(SumupReadWriteResponse::new(read_write_response))
77    }
78}
79
80impl WriteTo for SumupReadWriteResponse {
81    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
82        let mut access_data: Vec<u8> = Vec::new();
83        let mut data: Vec<u8> = Vec::new();
84        for response in &self.read_write_responses {
85            access_data.write_u32::<LittleEndian>(response.result.as_u32())?;
86            access_data.write_u32::<LittleEndian>(response.length)?;
87            data.write_all(response.data.as_slice())?;
88        }
89        access_data.append(&mut data);
90        wtr.write_all(&access_data)?;
91        Ok(())
92    }
93}
94
95///Ads Sumup Read response
96///Bundle multiple responses toghether. Add this data to the read write response or parse from.
97#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct SumupReadResponse {
99    pub read_responses: Vec<ReadResponse>,
100}
101
102impl SumupReadResponse {
103    pub fn new(read_responses: Vec<ReadResponse>) -> Self {
104        SumupReadResponse { read_responses }
105    }
106}
107
108impl ReadFrom for SumupReadResponse {
109    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
110        let mut data_buf: Vec<u8> = Vec::new();
111        let mut read_access: Vec<AccessData> = Vec::new();
112
113        //Read all bytes to get the total length
114        read.read_to_end(&mut data_buf)?;
115        let total_data_len = data_buf.len() as u32;
116        let mut access_data_length: u32 = 0;
117        let mut data_length: u32 = 0;
118        let mut data_buf = data_buf.as_slice();
119
120        //Get the access data bytes
121        for _ in 0..total_data_len / 8 {
122            let access_data = AccessData::read_from(&mut data_buf)?;
123            access_data_length += 8;
124            data_length += access_data.length;
125            read_access.push(access_data);
126            if (total_data_len - data_length - access_data_length) == 0 {
127                break;
128            }
129        }
130
131        //Get the actual data/value bytes and create ReadWriteResponses
132        let mut read_response: Vec<ReadResponse> = Vec::new();
133        for access in read_access {
134            let mut buf = vec![0; access.length as usize];
135            data_buf.read_exact(&mut buf)?;
136            read_response.push(ReadResponse::new(AdsError::from(access.result), buf));
137        }
138        Ok(SumupReadResponse::new(read_response))
139    }
140}
141
142impl WriteTo for SumupReadResponse {
143    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
144        let mut access_data: Vec<u8> = Vec::new();
145        let mut data: Vec<u8> = Vec::new();
146        for response in &self.read_responses {
147            access_data.write_u32::<LittleEndian>(response.result.as_u32())?;
148            access_data.write_u32::<LittleEndian>(response.length)?;
149            data.write_all(response.data.as_slice())?;
150        }
151        access_data.append(&mut data);
152        wtr.write_all(&access_data)?;
153        Ok(())
154    }
155}
156
157///Ads Sumup Write response
158///Bundle multiple responses toghether. Add this data to the read write response or parse from.
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct SumupWriteResponse {
161    pub write_responses: Vec<WriteResponse>,
162}
163
164impl SumupWriteResponse {
165    pub fn new(write_responses: Vec<WriteResponse>) -> Self {
166        SumupWriteResponse { write_responses }
167    }
168}
169
170impl ReadFrom for SumupWriteResponse {
171    fn read_from<R: Read>(read: &mut R) -> io::Result<Self> {
172        let mut data_buf: Vec<u8> = Vec::new();
173        read.read_to_end(&mut data_buf)?;
174        let mut write_resp: Vec<WriteResponse> = Vec::new();
175        let mut buf = data_buf.as_slice();
176        for _ in 0..(data_buf.len() / 4) {
177            write_resp.push(WriteResponse::read_from(&mut buf)?)
178        }
179        Ok(SumupWriteResponse::new(write_resp))
180    }
181}
182
183impl WriteTo for SumupWriteResponse {
184    fn write_to<W: Write>(&self, mut wtr: W) -> io::Result<()> {
185        for result in &self.write_responses {
186            result.write_to(&mut wtr)?;
187        }
188        Ok(())
189    }
190}
191
192#[cfg(test)]
193mod tests {
194    use super::*;
195
196    #[test]
197    fn sumup_read_write_write_to_test() {
198        let mut response_group: Vec<ReadWriteResponse> = Vec::new();
199        let data_1 = vec![1, 0];
200        let response_1 = ReadWriteResponse::new(AdsError::ErrNoError, data_1);
201        response_group.push(response_1);
202        let data_2 = vec![2, 0, 0, 0];
203        let response_2 = ReadWriteResponse::new(AdsError::ErrNoError, data_2);
204        response_group.push(response_2);
205        let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
206        let response_3 = ReadWriteResponse::new(AdsError::ErrNoError, data_3);
207        response_group.push(response_3);
208
209        let sum_read_write_response = SumupReadWriteResponse::new(response_group);
210        let mut buf: Vec<u8> = Vec::new();
211        sum_read_write_response.write_to(&mut buf).unwrap();
212
213        #[rustfmt::skip]
214        let compare_data = vec![
215            0,0,0,0,        //result response 1
216            2,0,0,0,        //data length response 1
217            0,0,0,0,        //result response 2
218            4,0,0,0,        //data length response 1
219            0,0,0,0,        //result response 3
220            8,0,0,0,        //data length response 1
221            1,0,            //data response 1
222            2,0,0,0,        //data response 2
223            3,0,0,0,0,0,0,0 //data response 3
224        ];
225
226        assert_eq!(buf, compare_data);
227    }
228
229    #[test]
230    fn sumup_read_write_read_from_test() {
231        #[rustfmt::skip]
232        let data = vec![
233            0,0,0,0,        //result response 1
234            2,0,0,0,        //data length response 1
235            0,0,0,0,        //result response 2
236            4,0,0,0,        //data length response 1
237            0,0,0,0,        //result response 3
238            8,0,0,0,        //data length response 1
239            1,0,            //data response 1
240            2,0,0,0,        //data response 2
241            3,0,0,0,0,0,0,0 //data response 3
242        ];
243
244        let sum_read_response = SumupReadResponse::read_from(&mut data.as_slice()).unwrap();
245
246        let data_1 = vec![1, 0];
247        let response_1 = ReadResponse::new(AdsError::ErrNoError, data_1);
248        let data_2 = vec![2, 0, 0, 0];
249        let response_2 = ReadResponse::new(AdsError::ErrNoError, data_2);
250        let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
251        let response_3 = ReadResponse::new(AdsError::ErrNoError, data_3);
252
253        assert_eq!(sum_read_response.read_responses[0], response_1);
254        assert_eq!(sum_read_response.read_responses[1], response_2);
255        assert_eq!(sum_read_response.read_responses[2], response_3);
256
257        let value_1: u16 = sum_read_response.read_responses[0]
258            .data
259            .as_slice()
260            .read_u16::<LittleEndian>()
261            .unwrap();
262        assert_eq!(value_1, 1);
263        assert_eq!(
264            sum_read_response.read_responses[0].result,
265            AdsError::ErrNoError
266        );
267        assert_eq!(sum_read_response.read_responses[0].length, 2);
268        let value_2: u32 = sum_read_response.read_responses[1]
269            .data
270            .as_slice()
271            .read_u32::<LittleEndian>()
272            .unwrap();
273        assert_eq!(value_2, 2);
274        assert_eq!(
275            sum_read_response.read_responses[1].result,
276            AdsError::ErrNoError
277        );
278        assert_eq!(sum_read_response.read_responses[1].length, 4);
279        let value_3: u64 = sum_read_response.read_responses[2]
280            .data
281            .as_slice()
282            .read_u64::<LittleEndian>()
283            .unwrap();
284        assert_eq!(value_3, 3);
285        assert_eq!(
286            sum_read_response.read_responses[2].result,
287            AdsError::ErrNoError
288        );
289        assert_eq!(sum_read_response.read_responses[2].length, 8);
290    }
291
292    #[test]
293    fn sumup_read_write_to_test() {
294        let mut response_group: Vec<ReadResponse> = Vec::new();
295        let data_1 = vec![1, 0];
296        let response_1 = ReadResponse::new(AdsError::ErrNoError, data_1);
297        response_group.push(response_1);
298        let data_2 = vec![2, 0, 0, 0];
299        let response_2 = ReadResponse::new(AdsError::ErrNoError, data_2);
300        response_group.push(response_2);
301        let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
302        let response_3 = ReadResponse::new(AdsError::ErrNoError, data_3);
303        response_group.push(response_3);
304
305        let sum_read_write_response = SumupReadResponse::new(response_group);
306        let mut buf: Vec<u8> = Vec::new();
307        sum_read_write_response.write_to(&mut buf).unwrap();
308
309        #[rustfmt::skip]
310        let compare_data = vec![
311            0,0,0,0,        //result response 1
312            2,0,0,0,        //data length response 1
313            0,0,0,0,        //result response 2
314            4,0,0,0,        //data length response 1
315            0,0,0,0,        //result response 3
316            8,0,0,0,        //data length response 1
317            1,0,            //data response 1
318            2,0,0,0,        //data response 2
319            3,0,0,0,0,0,0,0 //data response 3
320        ];
321
322        assert_eq!(buf, compare_data);
323    }
324
325    #[test]
326    fn sumup_read_read_from_test() {
327        #[rustfmt::skip]
328        let data = vec![
329            0,0,0,0,        //result response 1
330            2,0,0,0,        //data length response 1
331            0,0,0,0,        //result response 2
332            4,0,0,0,        //data length response 1
333            0,0,0,0,        //result response 3
334            8,0,0,0,        //data length response 1
335            1,0,            //data response 1
336            2,0,0,0,        //data response 2
337            3,0,0,0,0,0,0,0 //data response 3
338        ];
339
340        let sum_read_response = SumupReadResponse::read_from(&mut data.as_slice()).unwrap();
341
342        let data_1 = vec![1, 0];
343        let response_1 = ReadResponse::new(AdsError::ErrNoError, data_1);
344        let data_2 = vec![2, 0, 0, 0];
345        let response_2 = ReadResponse::new(AdsError::ErrNoError, data_2);
346        let data_3 = vec![3, 0, 0, 0, 0, 0, 0, 0];
347        let response_3 = ReadResponse::new(AdsError::ErrNoError, data_3);
348
349        assert_eq!(sum_read_response.read_responses[0], response_1);
350        assert_eq!(sum_read_response.read_responses[1], response_2);
351        assert_eq!(sum_read_response.read_responses[2], response_3);
352
353        let value_1: u16 = sum_read_response.read_responses[0]
354            .data
355            .as_slice()
356            .read_u16::<LittleEndian>()
357            .unwrap();
358        assert_eq!(value_1, 1);
359        assert_eq!(
360            sum_read_response.read_responses[0].result,
361            AdsError::ErrNoError
362        );
363        assert_eq!(sum_read_response.read_responses[0].length, 2);
364        let value_2: u32 = sum_read_response.read_responses[1]
365            .data
366            .as_slice()
367            .read_u32::<LittleEndian>()
368            .unwrap();
369        assert_eq!(value_2, 2);
370        assert_eq!(
371            sum_read_response.read_responses[1].result,
372            AdsError::ErrNoError
373        );
374        assert_eq!(sum_read_response.read_responses[1].length, 4);
375        let value_3: u64 = sum_read_response.read_responses[2]
376            .data
377            .as_slice()
378            .read_u64::<LittleEndian>()
379            .unwrap();
380        assert_eq!(value_3, 3);
381        assert_eq!(
382            sum_read_response.read_responses[2].result,
383            AdsError::ErrNoError
384        );
385        assert_eq!(sum_read_response.read_responses[2].length, 8);
386    }
387
388    #[test]
389    fn sumup_write_write_to_test() {
390        let mut response_group: Vec<WriteResponse> = Vec::new();
391        let response_1 = WriteResponse::new(AdsError::ErrNoError);
392        response_group.push(response_1);
393        let response_2 = WriteResponse::new(AdsError::AdsErrClientPortNotOpen);
394        response_group.push(response_2);
395        let response_3 = WriteResponse::new(AdsError::ErrNoError);
396        response_group.push(response_3);
397
398        let sum_read_write_response = SumupWriteResponse::new(response_group);
399        let mut buf: Vec<u8> = Vec::new();
400        sum_read_write_response.write_to(&mut buf).unwrap();
401
402        #[rustfmt::skip]
403        let compare_data = vec![
404            0,0,0,0,        //AdsError::ErrNoError
405            72,7,0,0,       //AdsError::AdsErrClientPortNotOpen
406            0,0,0,0,        //AdsError::ErrNoError        
407        ];
408
409        assert_eq!(buf, compare_data);
410    }
411
412    #[test]
413    fn sumup_write_read_from_test() {
414        #[rustfmt::skip]
415        let data = vec![
416            0,0,0,0,        //AdsError::ErrNoError
417            72,7,0,0,       //AdsError::AdsErrClientPortNotOpen
418            0,0,0,0,        //AdsError::ErrNoError        
419        ];
420
421        let sum_write_response = SumupWriteResponse::read_from(&mut data.as_slice()).unwrap();
422
423        let mut response_group: Vec<WriteResponse> = Vec::new();
424        let response_1 = WriteResponse::new(AdsError::ErrNoError);
425        response_group.push(response_1);
426        let response_2 = WriteResponse::new(AdsError::AdsErrClientPortNotOpen);
427        response_group.push(response_2);
428        let response_3 = WriteResponse::new(AdsError::ErrNoError);
429        response_group.push(response_3);
430        let compare = SumupWriteResponse::new(response_group);
431
432        assert_eq!(sum_write_response, compare);
433    }
434}