inspect_format/container/
common.rs
1pub trait BlockContainer {
6 type Data;
7 type ShareableData;
8
9 fn len(&self) -> usize;
11
12 fn is_empty(&self) -> bool {
14 self.len() == 0
15 }
16}
17
18pub trait ReadBytes: BlockContainer {
20 fn get_slice_at(&self, offset: usize, size: usize) -> Option<&[u8]>;
22
23 #[inline]
26 fn get_slice(&self, size: usize) -> Option<&[u8]> {
27 self.get_slice_at(0, size)
28 }
29
30 #[inline]
32 fn get_value<T: ContainerValue>(&self, offset: usize) -> Option<&T> {
33 self.get_slice_at(offset, std::mem::size_of::<T>()).map(|slice| {
34 let ptr = slice.as_ptr() as *const T;
35 unsafe { &*ptr }
38 })
39 }
40}
41
42pub trait CopyBytes: BlockContainer {
43 fn copy_bytes_at(&self, offset: usize, dst: &mut [u8]);
44
45 fn copy_bytes(&self, dst: &mut [u8]) {
46 self.copy_bytes_at(0, dst)
47 }
48}
49
50pub trait ContainerValue: private::Sealed {}
51
52mod private {
53 pub trait Sealed {}
54}
55
56macro_rules! impl_container_value {
57 ($($type:ty),*) => {
58 $(
59 impl private::Sealed for $type {}
60 impl ContainerValue for $type {}
61 )*
62 };
63}
64
65impl_container_value!(u8, u16, u32, u64, i64, f64);
66
67pub trait WriteBytes {
69 fn get_slice_mut_at(&mut self, offset: usize, size: usize) -> Option<&mut [u8]>;
72
73 #[inline]
76 fn get_slice_mut(&mut self, size: usize) -> Option<&mut [u8]> {
77 self.get_slice_mut_at(0, size)
78 }
79
80 #[inline]
81 fn copy_from_slice_at(&mut self, offset: usize, bytes: &[u8]) {
82 if let Some(slice) = self.get_slice_mut_at(offset, bytes.len()) {
84 slice.copy_from_slice(bytes);
85 }
86 }
87
88 #[inline]
89 fn copy_from_slice(&mut self, bytes: &[u8]) {
90 self.copy_from_slice_at(0, bytes);
91 }
92
93 #[inline]
95 fn get_value_mut<T: ContainerValue>(&mut self, offset: usize) -> Option<&mut T> {
96 self.get_slice_mut_at(offset, std::mem::size_of::<T>()).map(|slice| {
97 let ptr = slice.as_mut_ptr() as *mut T;
98 unsafe { &mut *ptr }
101 })
102 }
103
104 #[inline]
105 fn set_value<T: ContainerValue>(&mut self, offset: usize, value: T) {
106 if let Some(value_ref) = self.get_value_mut(offset) {
108 *value_ref = value;
109 }
110 }
111}
112
113impl BlockContainer for Vec<u8> {
114 type Data = Self;
115 type ShareableData = ();
116
117 #[inline]
119 fn len(&self) -> usize {
120 self.as_slice().len()
121 }
122}
123
124impl ReadBytes for Vec<u8> {
125 #[inline]
126 fn get_slice_at(&self, offset: usize, size: usize) -> Option<&[u8]> {
127 self.as_slice().get_slice_at(offset, size)
128 }
129}
130
131impl CopyBytes for Vec<u8> {
132 #[inline]
133 fn copy_bytes_at(&self, offset: usize, dst: &mut [u8]) {
134 if let Some(slice) = self.as_slice().get_slice_at(offset, dst.len()) {
135 dst.copy_from_slice(slice);
136 }
137 }
138}
139
140impl BlockContainer for [u8] {
141 type Data = ();
142 type ShareableData = ();
143
144 #[inline]
145 fn len(&self) -> usize {
146 <[u8]>::len(self)
147 }
148}
149
150impl ReadBytes for [u8] {
151 #[inline]
152 fn get_slice_at(&self, offset: usize, size: usize) -> Option<&[u8]> {
153 let upper_bound = offset.checked_add(size)?;
154 if offset >= self.len() || upper_bound > self.len() {
155 return None;
156 }
157 Some(&self[offset..upper_bound])
158 }
159}
160
161impl<const N: usize> BlockContainer for [u8; N] {
162 type Data = Self;
163 type ShareableData = ();
164
165 #[inline]
167 fn len(&self) -> usize {
168 self.as_slice().len()
169 }
170}
171
172impl<const N: usize> ReadBytes for [u8; N] {
173 #[inline]
174 fn get_slice_at(&self, offset: usize, size: usize) -> Option<&[u8]> {
175 self.as_slice().get_slice_at(offset, size)
176 }
177}
178
179impl<const N: usize> WriteBytes for [u8; N] {
181 #[inline]
182 fn get_slice_mut_at(&mut self, offset: usize, size: usize) -> Option<&mut [u8]> {
183 if offset >= self.len() {
184 return None;
185 }
186 let upper_bound = offset.checked_add(size)?;
187 if upper_bound > self.len() {
188 return None;
189 }
190 Some(&mut self[offset..upper_bound])
191 }
192}