ab_io_type/
fixed_capacity_bytes.rs1#[cfg(test)]
2mod tests;
3
4use crate::metadata::{IoTypeMetadataKind, MAX_METADATA_CAPACITY, concat_metadata_sources};
5use crate::trivial_type::TrivialType;
6
7pub(crate) const SUPPORTED_CAPACITY_U8<const CAPACITY: usize>: usize = {
11 assert!(
12 CAPACITY <= u8::MAX as usize,
13 "Capacity must not exceed `u8::MAX`"
14 );
15 0
16};
17pub(crate) const SUPPORTED_CAPACITY_U16<const CAPACITY: usize>: usize = {
21 assert!(
22 CAPACITY <= u16::MAX as usize,
23 "Capacity must not exceed `u16::MAX`"
24 );
25 assert!(
27 CAPACITY.is_multiple_of(2),
28 "Capacity must be a multiple of 2"
29 );
30 0
31};
32
33#[derive(Debug, Copy, Clone)]
47#[repr(C)]
48pub struct FixedCapacityBytesU8<const CAPACITY: usize> {
49 len: u8,
50 bytes: [u8; CAPACITY],
51 _supported: [(); SUPPORTED_CAPACITY_U8::<CAPACITY>],
56}
57
58impl<const CAPACITY: usize> Default for FixedCapacityBytesU8<CAPACITY>
59where
60 [(); SUPPORTED_CAPACITY_U8::<CAPACITY>]:,
61{
62 #[inline(always)]
63 fn default() -> Self {
64 Self {
65 len: 0,
66 bytes: [0; CAPACITY],
67 _supported: const { [(); SUPPORTED_CAPACITY_U8::<CAPACITY>] },
68 }
69 }
70}
71
72unsafe impl<const CAPACITY: usize> TrivialType for FixedCapacityBytesU8<CAPACITY>
74where
75 [(); SUPPORTED_CAPACITY_U8::<CAPACITY>]:,
76{
77 const METADATA: &[u8] = {
78 #[inline(always)]
79 const fn metadata(capacity: usize) -> ([u8; MAX_METADATA_CAPACITY], usize) {
80 concat_metadata_sources(&[&[
81 IoTypeMetadataKind::FixedCapacityBytes8b as u8,
82 capacity as u8,
83 ]])
84 }
85 metadata(CAPACITY).0.split_at(metadata(CAPACITY).1).0
86 };
87}
88
89impl<const CAPACITY: usize> FixedCapacityBytesU8<CAPACITY>
90where
91 [(); SUPPORTED_CAPACITY_U8::<CAPACITY>]:,
92{
93 #[inline(always)]
97 pub fn try_from_bytes(bytes: &[u8]) -> Option<Self> {
98 if bytes.len() > CAPACITY {
99 return None;
100 }
101
102 Some(Self {
103 len: bytes.len() as u8,
104 bytes: {
105 let mut buffer = [0; CAPACITY];
106 buffer[..bytes.len()].copy_from_slice(bytes);
107 buffer
108 },
109 _supported: const { [(); SUPPORTED_CAPACITY_U8::<CAPACITY>] },
110 })
111 }
112
113 #[inline(always)]
115 pub fn get_bytes(&self) -> &[u8] {
116 &self.bytes[..self.len as usize]
117 }
118
119 #[inline(always)]
121 pub fn get_bytes_mut(&mut self) -> &mut [u8] {
122 &mut self.bytes[..self.len as usize]
123 }
124
125 #[inline(always)]
127 pub const fn len(&self) -> u8 {
128 self.len
129 }
130
131 #[inline(always)]
133 pub const fn is_empty(&self) -> bool {
134 self.len == 0
135 }
136
137 #[inline(always)]
141 #[must_use = "Operation may fail"]
142 pub fn append(&mut self, bytes: &[u8]) -> bool {
143 let len = self.len();
144 if bytes.len() + len as usize > CAPACITY {
145 return false;
146 }
147
148 self.bytes[len as usize..][..bytes.len()].copy_from_slice(bytes);
149 self.len += bytes.len() as u8;
150
151 true
152 }
153
154 #[inline(always)]
158 #[must_use = "Operation may fail"]
159 pub fn truncate(&mut self, new_len: u8) -> bool {
160 if new_len > self.len() {
161 return false;
162 }
163
164 self.len = new_len;
165
166 true
167 }
168
169 #[inline(always)]
173 #[must_use = "Operation may fail"]
174 pub fn copy_from<T>(&mut self, src: &[u8]) -> bool {
175 if src.len() > CAPACITY {
176 return false;
177 }
178
179 self.bytes[..src.len()].copy_from_slice(src);
180 self.len = src.len() as u8;
181
182 true
183 }
184}
185
186#[derive(Debug, Copy, Clone)]
200#[repr(C)]
201pub struct FixedCapacityBytesU16<const CAPACITY: usize> {
202 len: u16,
203 bytes: [u8; CAPACITY],
204 _supported: [(); SUPPORTED_CAPACITY_U16::<CAPACITY>],
209}
210
211impl<const CAPACITY: usize> Default for FixedCapacityBytesU16<CAPACITY>
212where
213 [(); SUPPORTED_CAPACITY_U16::<CAPACITY>]:,
214{
215 #[inline(always)]
216 fn default() -> Self {
217 Self {
218 len: 0,
219 bytes: [0; CAPACITY],
220 _supported: const { [(); SUPPORTED_CAPACITY_U16::<CAPACITY>] },
221 }
222 }
223}
224
225unsafe impl<const CAPACITY: usize> TrivialType for FixedCapacityBytesU16<CAPACITY>
228where
229 [(); SUPPORTED_CAPACITY_U16::<CAPACITY>]:,
230{
231 const METADATA: &[u8] = {
232 #[inline(always)]
233 const fn metadata(capacity: usize) -> ([u8; MAX_METADATA_CAPACITY], usize) {
234 concat_metadata_sources(&[
235 &[IoTypeMetadataKind::FixedCapacityBytes16b as u8],
236 &(capacity as u16).to_le_bytes(),
237 ])
238 }
239 metadata(CAPACITY).0.split_at(metadata(CAPACITY).1).0
240 };
241}
242
243impl<const CAPACITY: usize> FixedCapacityBytesU16<CAPACITY>
244where
245 [(); SUPPORTED_CAPACITY_U16::<CAPACITY>]:,
246{
247 #[inline(always)]
251 pub fn try_from_bytes(bytes: &[u8]) -> Option<Self> {
252 if bytes.len() > CAPACITY {
253 return None;
254 }
255
256 Some(Self {
257 len: bytes.len() as u16,
258 bytes: {
259 let mut buffer = [0; CAPACITY];
260 buffer[..bytes.len()].copy_from_slice(bytes);
261 buffer
262 },
263 _supported: const { [(); SUPPORTED_CAPACITY_U16::<CAPACITY>] },
264 })
265 }
266
267 #[inline(always)]
269 pub fn get_bytes(&self) -> &[u8] {
270 &self.bytes[..self.len as usize]
271 }
272
273 #[inline(always)]
275 pub fn get_bytes_mut(&mut self) -> &mut [u8] {
276 &mut self.bytes[..self.len as usize]
277 }
278
279 #[inline(always)]
281 pub const fn len(&self) -> u16 {
282 self.len
283 }
284
285 #[inline(always)]
287 pub const fn is_empty(&self) -> bool {
288 self.len == 0
289 }
290
291 #[inline(always)]
295 #[must_use = "Operation may fail"]
296 pub fn append(&mut self, bytes: &[u8]) -> bool {
297 let len = self.len();
298 if bytes.len() + len as usize > CAPACITY {
299 return false;
300 }
301
302 self.bytes[len as usize..][..bytes.len()].copy_from_slice(bytes);
303 self.len += bytes.len() as u16;
304
305 true
306 }
307
308 #[inline(always)]
312 #[must_use = "Operation may fail"]
313 pub fn truncate(&mut self, new_len: u16) -> bool {
314 if new_len > self.len() {
315 return false;
316 }
317
318 self.len = new_len;
319
320 true
321 }
322
323 #[inline(always)]
327 #[must_use = "Operation may fail"]
328 pub fn copy_from<T>(&mut self, src: &[u8]) -> bool {
329 if src.len() > CAPACITY {
330 return false;
331 }
332
333 self.bytes[..src.len()].copy_from_slice(src);
334 self.len = src.len() as u16;
335
336 true
337 }
338}