modbus_core/frame/
data.rs1use super::*;
2use crate::error::*;
3
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub struct Data<'d> {
7 pub(crate) data: RawData<'d>,
8 pub(crate) quantity: usize,
9}
10
11impl<'d> Data<'d> {
12 pub fn from_words(words: &[u16], target: &'d mut [u8]) -> Result<Self, Error> {
14 if (words.len() * 2 > target.len()) || words.is_empty() {
15 return Err(Error::BufferSize);
16 }
17 for (i, w) in words.iter().enumerate() {
18 BigEndian::write_u16(&mut target[i * 2..], *w);
19 }
20 Ok(Data {
21 data: target,
22 quantity: words.len(),
23 })
24 }
25 pub(crate) fn copy_to(&self, buf: &mut [u8]) {
27 let cnt = self.quantity * 2;
28 debug_assert!(buf.len() >= cnt);
29 (0..cnt).for_each(|idx| {
30 buf[idx] = self.data[idx];
31 });
32 }
33 #[must_use]
35 pub const fn len(&self) -> usize {
36 self.quantity
37 }
38 #[must_use]
40 pub const fn is_empty(&self) -> bool {
41 self.quantity == 0
42 }
43 #[must_use]
45 pub fn get(&self, idx: usize) -> Option<Word> {
46 if idx + 1 > self.quantity {
47 return None;
48 }
49 let idx = idx * 2;
50 Some(BigEndian::read_u16(&self.data[idx..idx + 2]))
51 }
52}
53
54#[derive(Debug, Clone, PartialEq, Eq)]
57pub struct DataIter<'d> {
58 cnt: usize,
59 data: Data<'d>,
60}
61
62impl<'d> Iterator for DataIter<'d> {
63 type Item = Word;
64
65 fn next(&mut self) -> Option<Self::Item> {
66 let result = self.data.get(self.cnt);
67 self.cnt += 1;
68 result
69 }
70}
71
72impl<'d> IntoIterator for Data<'d> {
73 type Item = Word;
74 type IntoIter = DataIter<'d>;
75
76 fn into_iter(self) -> Self::IntoIter {
77 DataIter { cnt: 0, data: self }
78 }
79}
80
81#[cfg(test)]
82mod tests {
83
84 use super::*;
85
86 #[test]
87 fn from_word_slice() {
88 let words: &[u16] = &[0xABCD, 0xEF00, 0x1234];
89 let buff: &mut [u8] = &mut [0; 5];
90 assert!(Data::from_words(words, buff).is_err());
91 let buff: &mut [u8] = &mut [0; 6];
92 let data = Data::from_words(words, buff).unwrap();
93 assert_eq!(data.len(), 3);
94 let mut iter = data.into_iter();
95 assert_eq!(iter.next(), Some(0xABCD));
96 assert_eq!(iter.next(), Some(0xEF00));
97 assert_eq!(iter.next(), Some(0x1234));
98 assert_eq!(iter.next(), None);
99 }
100
101 #[test]
102 fn data_len() {
103 let data = Data {
104 data: &[0, 1, 2],
105 quantity: 5,
106 };
107 assert_eq!(data.len(), 5);
108 }
109
110 #[test]
111 fn data_empty() {
112 let data = Data {
113 data: &[0, 1, 2],
114 quantity: 0,
115 };
116 assert!(data.is_empty());
117 }
118
119 #[test]
120 fn data_get() {
121 let data = Data {
122 data: &[0xAB, 0xBC, 0x12],
123 quantity: 1,
124 };
125 assert_eq!(data.get(0), Some(0xABBC));
126 assert_eq!(data.get(1), None);
127
128 let data = Data {
129 data: &[0xFF, 0xAB, 0xCD, 0xEF, 0x33],
130 quantity: 2,
131 };
132 assert_eq!(data.get(0), Some(0xFFAB));
133 assert_eq!(data.get(1), Some(0xCDEF));
134 assert_eq!(data.get(2), None);
135 }
136
137 #[test]
138 fn data_iter() {
139 let data = Data {
140 data: &[0x01, 0x02, 0x03, 0x04, 0xAA, 0xBB],
141 quantity: 3,
142 };
143 let mut data_iter = DataIter { cnt: 0, data };
144 assert_eq!(data_iter.next(), Some(0x0102));
145 assert_eq!(data_iter.next(), Some(0x0304));
146 assert_eq!(data_iter.next(), Some(0xAABB));
147 assert_eq!(data_iter.next(), None);
148 }
149
150 #[test]
151 fn data_into_iter() {
152 let data = Data {
153 data: &[0x01, 0x02, 0x03, 0x04, 0xAA, 0xBB],
154 quantity: 3,
155 };
156 let mut data_iter = data.into_iter();
157 assert!(data_iter.next().is_some());
158 assert!(data_iter.next().is_some());
159 assert!(data_iter.next().is_some());
160 assert!(data_iter.next().is_none());
161 }
162}