binary_layout/fields/primitive/
slice_access.rs1use core::convert::TryFrom;
2
3use super::super::{Field, StorageIntoFieldView, StorageToFieldView};
4use super::PrimitiveField;
5use crate::endianness::Endianness;
6use crate::utils::data::Data;
7
8pub trait FieldSliceAccess<'a>: Field {
12 type SliceType: 'a;
14 type MutSliceType: 'a;
16
17 fn data(storage: &'a [u8]) -> Self::SliceType;
33
34 fn data_mut(storage: &'a mut [u8]) -> Self::MutSliceType;
50}
51
52impl<'a, E: Endianness, const OFFSET_: usize> FieldSliceAccess<'a>
56 for PrimitiveField<[u8], E, OFFSET_>
57{
58 type SliceType = &'a [u8];
59 type MutSliceType = &'a mut [u8];
60
61 #[inline(always)]
77 fn data(storage: &'a [u8]) -> &'a [u8] {
78 &storage[Self::OFFSET..]
79 }
80
81 #[inline(always)]
97 fn data_mut(storage: &'a mut [u8]) -> &'a mut [u8] {
98 &mut storage[Self::OFFSET..]
99 }
100}
101impl<E: Endianness, const OFFSET_: usize> Field for PrimitiveField<[u8], E, OFFSET_> {
102 type Endian = E;
104 const OFFSET: usize = OFFSET_;
106 const SIZE: Option<usize> = None;
108}
109impl<'a, E: Endianness, const OFFSET_: usize> StorageToFieldView<&'a [u8]>
110 for PrimitiveField<[u8], E, OFFSET_>
111{
112 type View = &'a [u8];
113
114 #[inline(always)]
115 fn view(storage: &'a [u8]) -> Self::View {
116 &storage[Self::OFFSET..]
117 }
118}
119
120impl<'a, E: Endianness, const OFFSET_: usize> StorageToFieldView<&'a mut [u8]>
121 for PrimitiveField<[u8], E, OFFSET_>
122{
123 type View = &'a mut [u8];
124
125 #[inline(always)]
126 fn view(storage: &'a mut [u8]) -> Self::View {
127 &mut storage[Self::OFFSET..]
128 }
129}
130
131impl<S: AsRef<[u8]>, E: Endianness, const OFFSET_: usize> StorageIntoFieldView<S>
132 for PrimitiveField<[u8], E, OFFSET_>
133{
134 type View = Data<S>;
135
136 #[inline(always)]
137 fn into_view(storage: S) -> Self::View {
138 Data::from(storage).into_subregion(Self::OFFSET..)
139 }
140}
141
142impl<'a, E: Endianness, const N: usize, const OFFSET_: usize> FieldSliceAccess<'a>
146 for PrimitiveField<[u8; N], E, OFFSET_>
147{
148 type SliceType = &'a [u8; N];
149 type MutSliceType = &'a mut [u8; N];
150
151 #[inline(always)]
169 fn data(storage: &'a [u8]) -> &'a [u8; N] {
170 <&[u8; N]>::try_from(&storage[Self::OFFSET..(Self::OFFSET + N)]).unwrap()
171 }
172
173 #[inline(always)]
191 fn data_mut(storage: &'a mut [u8]) -> &'a mut [u8; N] {
192 <&mut [u8; N]>::try_from(&mut storage[Self::OFFSET..(Self::OFFSET + N)]).unwrap()
193 }
194}
195impl<E: Endianness, const N: usize, const OFFSET_: usize> Field
196 for PrimitiveField<[u8; N], E, OFFSET_>
197{
198 type Endian = E;
200 const OFFSET: usize = OFFSET_;
202 const SIZE: Option<usize> = Some(N);
204}
205impl<'a, E: Endianness, const N: usize, const OFFSET_: usize> StorageToFieldView<&'a [u8]>
206 for PrimitiveField<[u8; N], E, OFFSET_>
207{
208 type View = &'a [u8; N];
209
210 #[inline(always)]
211 fn view(storage: &'a [u8]) -> Self::View {
212 Self::View::try_from(&storage[Self::OFFSET..(Self::OFFSET + N)]).unwrap()
213 }
214}
215
216impl<'a, E: Endianness, const N: usize, const OFFSET_: usize> StorageToFieldView<&'a mut [u8]>
217 for PrimitiveField<[u8; N], E, OFFSET_>
218{
219 type View = &'a mut [u8; N];
220
221 #[inline(always)]
222 fn view(storage: &'a mut [u8]) -> Self::View {
223 Self::View::try_from(&mut storage[Self::OFFSET..(Self::OFFSET + N)]).unwrap()
224 }
225}
226
227impl<S: AsRef<[u8]>, E: Endianness, const N: usize, const OFFSET_: usize> StorageIntoFieldView<S>
228 for PrimitiveField<[u8; N], E, OFFSET_>
229{
230 type View = Data<S>;
231
232 #[inline(always)]
233 fn into_view(storage: S) -> Self::View {
234 Data::from(storage).into_subregion(Self::OFFSET..(Self::OFFSET + N))
235 }
236}
237
238#[cfg(test)]
239mod tests {
240 #![allow(clippy::float_cmp)]
241 use crate::prelude::*;
242 use crate::PrimitiveField;
243
244 #[test]
245 fn test_slice() {
246 let mut storage = [0; 1024];
247
248 type Field1 = PrimitiveField<[u8], LittleEndian, 5>;
249 type Field2 = PrimitiveField<[u8], BigEndian, 7>;
250 type Field3 = PrimitiveField<[u8], NativeEndian, 9>;
251
252 Field1::data_mut(&mut storage)[..5].copy_from_slice(&[10, 20, 30, 40, 50]);
253 Field2::data_mut(&mut storage)[..5].copy_from_slice(&[60, 70, 80, 90, 100]);
254 Field3::data_mut(&mut storage)[..5].copy_from_slice(&[110, 120, 130, 140, 150]);
255
256 assert_eq!(&[10, 20, 60, 70, 110], &Field1::data(&storage)[..5]);
257 assert_eq!(&[60, 70, 110, 120, 130], &Field2::data(&storage)[..5]);
258 assert_eq!(&[110, 120, 130, 140, 150], &Field3::data(&storage)[..5]);
259
260 let _a: &[u8] = Field1::data(&storage);
262 let _b: &mut [u8] = Field1::data_mut(&mut storage);
263 }
264
265 #[test]
266 fn test_array() {
267 let mut storage = [0; 1024];
268
269 type Field1 = PrimitiveField<[u8; 2], LittleEndian, 5>;
270 type Field2 = PrimitiveField<[u8; 5], BigEndian, 6>;
271 type Field3 = PrimitiveField<[u8; 5], NativeEndian, 7>;
272
273 Field1::data_mut(&mut storage).copy_from_slice(&[10, 20]);
274 Field2::data_mut(&mut storage).copy_from_slice(&[60, 70, 80, 90, 100]);
275 Field3::data_mut(&mut storage).copy_from_slice(&[60, 70, 80, 90, 100]);
276
277 assert_eq!(&[10, 60], Field1::data(&storage));
278 assert_eq!(&[60, 60, 70, 80, 90], Field2::data(&storage));
279 assert_eq!(&[60, 70, 80, 90, 100], Field3::data(&storage));
280
281 assert_eq!(Some(2), PrimitiveField::<[u8; 2], LittleEndian, 5>::SIZE);
282 assert_eq!(Some(5), PrimitiveField::<[u8; 5], BigEndian, 5>::SIZE);
283 assert_eq!(Some(5), PrimitiveField::<[u8; 5], NativeEndian, 5>::SIZE);
284
285 let _a: &[u8; 2] = Field1::data(&storage);
287 let _b: &mut [u8; 2] = Field1::data_mut(&mut storage);
288 }
289}