1use crate::message::payload::list_base::impl_list_base;
30use crate::message::WriteTo;
31use crate::message::{Error, FromBytes, Message};
32use crate::util::{Size, ToUsize, Wrap};
33use std::marker::PhantomData;
34use std::ops::{Index, IndexMut};
35use std::slice::{Chunks, ChunksMut};
36
37pub struct IterMut<'a, Item> {
38 data: ChunksMut<'a, u8>,
39 useless: PhantomData<Item>,
40}
41
42impl<'a, Item> IterMut<'a, Item> {
43 pub fn new(chunks: ChunksMut<'a, u8>) -> Self {
44 Self {
45 data: chunks,
46 useless: PhantomData,
47 }
48 }
49}
50
51impl<'a, Item: Wrap<&'a mut [u8]>> Iterator for IterMut<'a, Item> {
52 type Item = Item;
53
54 fn next(&mut self) -> Option<Self::Item> {
55 self.data.next().map(|v| unsafe { Item::wrap_unchecked(v) })
56 }
57}
58
59pub struct Iter<'a, Item> {
60 data: Chunks<'a, u8>,
61 useless: PhantomData<Item>,
62}
63
64impl<'a, Item> Iter<'a, Item> {
65 pub fn new(chunks: Chunks<'a, u8>) -> Self {
66 Self {
67 data: chunks,
68 useless: PhantomData,
69 }
70 }
71}
72
73impl<'a, Item: Wrap<&'a [u8]>> Iterator for Iter<'a, Item> {
74 type Item = Item;
75
76 fn next(&mut self) -> Option<Self::Item> {
77 self.data.next().map(|v| unsafe { Item::wrap_unchecked(v) })
78 }
79}
80
81#[derive(Copy, Clone, Debug)]
82pub struct Array<B, T, Item> {
83 data: B,
84 len: usize,
85 useless: PhantomData<T>,
86 useless1: PhantomData<Item>,
87}
88
89impl<B, T, Item> Array<B, T, Item> {
90 pub unsafe fn from_raw_parts(data: B, len: usize) -> Array<B, T, Item> {
104 Array {
105 data,
106 len,
107 useless: PhantomData,
108 useless1: PhantomData,
109 }
110 }
111}
112
113impl<B: AsRef<[u8]>, T, Item: Size> Array<B, T, Item> {
114 pub fn new(data: B) -> Array<B, T, Item> {
115 let len = data.as_ref().len() / Item::SIZE;
116 unsafe { Array::from_raw_parts(data, len) }
117 }
118}
119
120impl_list_base!(Array);
121
122impl<B: AsRef<[u8]>, T, Item> Array<B, T, Item> {
123 pub fn to_ref<Item1>(&self) -> Array<&[u8], T, Item1> {
124 unsafe { Array::from_raw_parts(self.data.as_ref(), self.len) }
125 }
126}
127
128impl<B: AsRef<[u8]>, T, Item: Size> Array<B, T, Item> {
129 pub fn from_parts(data: B, len: usize) -> Option<Array<B, T, Item>> {
130 match data.as_ref().len() == len * Item::SIZE {
131 true => Some(unsafe { Array::from_raw_parts(data, len) }),
132 false => None,
133 }
134 }
135}
136
137impl<'a, B: AsRef<[u8]>, T, Item: Size> Array<B, T, Item> {
138 pub fn get(&'a self, index: usize) -> Option<&'a [u8]> {
139 if index >= self.len {
140 None
141 } else {
142 let start = index * Item::SIZE;
143 let end = start + Item::SIZE;
144 Some(&self.data.as_ref()[start..end])
145 }
146 }
147
148 pub fn iter(&'a self) -> Chunks<'a, u8> {
149 self.data.as_ref().chunks(Item::SIZE)
150 }
151}
152
153impl<'a, B: AsMut<[u8]>, T, Item: Size> Array<B, T, Item> {
154 pub fn get_mut(&'a mut self, index: usize) -> Option<&'a mut [u8]> {
155 if index >= self.len {
156 None
157 } else {
158 let start = index * Item::SIZE;
159 let end = start + Item::SIZE;
160 Some(&mut self.data.as_mut()[start..end])
161 }
162 }
163
164 pub fn iter_mut(&'a mut self) -> ChunksMut<'a, u8> {
165 self.data.as_mut().chunks_mut(Item::SIZE)
166 }
167}
168
169impl<B: AsRef<[u8]>, T, Item: Size> Index<usize> for Array<B, T, Item> {
170 type Output = [u8];
171
172 fn index(&self, index: usize) -> &Self::Output {
173 if index >= self.len {
174 panic!("attempt to index item out of bounds, index={}, len={}", index, self.len)
175 }
176 let start = index * Item::SIZE;
177 let end = start + Item::SIZE;
178 &self.data.as_ref()[start..end]
179 }
180}
181
182impl<B: AsRef<[u8]> + AsMut<[u8]>, T, Item: Size> IndexMut<usize> for Array<B, T, Item> {
183 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
184 if index >= self.len {
185 panic!("attempt to index item out of bounds, index={}, len={}", index, self.len)
186 }
187 let start = index * Item::SIZE;
188 let end = start + Item::SIZE;
189 &mut self.data.as_mut()[start..end]
190 }
191}
192
193impl<'a, T: FromBytes<'a, Output: ToUsize>, Item: Size> FromBytes<'a> for Array<&'a [u8], T, Item> {
194 type Output = Array<&'a [u8], T, Item>;
195
196 fn from_bytes(slice: &'a [u8]) -> Result<Message<Self::Output>, Error> {
197 let msg = T::from_bytes(slice)?;
198 let control_size = msg.size();
199 let len = msg.into_inner().to_usize();
200 let total_size = control_size + (len * Item::SIZE);
201 if slice.len() < total_size {
202 Err(Error::Truncated)
203 } else {
204 let data = &slice[control_size..total_size];
205 Ok(Message::new(
206 total_size,
207 Array {
208 data,
209 len,
210 useless: PhantomData,
211 useless1: PhantomData,
212 },
213 ))
214 }
215 }
216}