ab_io_type/
fixed_capacity_bytes.rs1use crate::metadata::{IoTypeMetadataKind, MAX_METADATA_CAPACITY, concat_metadata_sources};
2use crate::trivial_type::TrivialType;
3
4#[derive(Debug, Copy, Clone)]
16#[repr(C)]
17pub struct FixedCapacityBytesU8<const CAPACITY: usize> {
18 len: u8,
19 bytes: [u8; CAPACITY],
20}
21
22impl<const CAPACITY: usize> Default for FixedCapacityBytesU8<CAPACITY> {
23 #[inline(always)]
24 fn default() -> Self {
25 Self {
26 len: 0,
27 bytes: [0; CAPACITY],
28 }
29 }
30}
31
32unsafe impl<const CAPACITY: usize> TrivialType for FixedCapacityBytesU8<CAPACITY> {
33 const METADATA: &[u8] = {
34 #[inline(always)]
35 const fn metadata(capacity: usize) -> ([u8; MAX_METADATA_CAPACITY], usize) {
36 assert!(
37 capacity <= u8::MAX as usize,
38 "`FixedCapacityBytesU8` capacity must not exceed `u8::MAX`"
39 );
40 concat_metadata_sources(&[&[
41 IoTypeMetadataKind::FixedCapacityBytes8b as u8,
42 capacity as u8,
43 ]])
44 }
45 metadata(CAPACITY).0.split_at(metadata(CAPACITY).1).0
46 };
47}
48
49impl<const CAPACITY: usize> FixedCapacityBytesU8<CAPACITY> {
50 #[inline(always)]
54 pub fn try_from_bytes(bytes: &[u8]) -> Option<Self> {
55 if bytes.len() > CAPACITY {
56 return None;
57 }
58
59 Some(Self {
60 len: bytes.len() as u8,
61 bytes: {
62 let mut buffer = [0; CAPACITY];
63 buffer[..bytes.len()].copy_from_slice(bytes);
64 buffer
65 },
66 })
67 }
68
69 #[inline(always)]
71 pub fn get_bytes(&self) -> &[u8] {
72 &self.bytes[..self.len as usize]
73 }
74
75 #[inline(always)]
77 pub fn get_bytes_mut(&mut self) -> &mut [u8] {
78 &mut self.bytes[..self.len as usize]
79 }
80
81 #[inline(always)]
83 pub const fn len(&self) -> u8 {
84 self.len
85 }
86
87 #[inline(always)]
89 pub const fn is_empty(&self) -> bool {
90 self.len == 0
91 }
92
93 #[inline(always)]
97 #[must_use = "Operation may fail"]
98 pub fn append(&mut self, bytes: &[u8]) -> bool {
99 let len = self.len();
100 if bytes.len() + len as usize > CAPACITY {
101 return false;
102 }
103
104 self.bytes[..bytes.len()].copy_from_slice(bytes);
105
106 true
107 }
108
109 #[inline(always)]
113 #[must_use = "Operation may fail"]
114 pub fn truncate(&mut self, new_len: u8) -> bool {
115 if new_len > self.len() {
116 return false;
117 }
118
119 self.len = new_len;
120
121 true
122 }
123
124 #[inline(always)]
128 #[must_use = "Operation may fail"]
129 pub fn copy_from<T>(&mut self, src: &[u8]) -> bool {
130 if src.len() > CAPACITY {
131 return false;
132 }
133
134 self.bytes[..src.len()].copy_from_slice(src);
135 self.len = src.len() as u8;
136
137 true
138 }
139}
140
141#[derive(Debug, Copy, Clone)]
153#[repr(C)]
154pub struct FixedCapacityBytesU16<const CAPACITY: usize> {
155 len: u16,
156 bytes: [u8; CAPACITY],
157}
158
159impl<const CAPACITY: usize> Default for FixedCapacityBytesU16<CAPACITY> {
160 #[inline(always)]
161 fn default() -> Self {
162 Self {
163 len: 0,
164 bytes: [0; CAPACITY],
165 }
166 }
167}
168
169unsafe impl<const CAPACITY: usize> TrivialType for FixedCapacityBytesU16<CAPACITY> {
170 const METADATA: &[u8] = {
171 #[inline(always)]
172 const fn metadata(capacity: usize) -> ([u8; MAX_METADATA_CAPACITY], usize) {
173 assert!(
174 capacity <= u16::MAX as usize,
175 "`FixedCapacityBytesU16` capacity must not exceed `u16::MAX`"
176 );
177 concat_metadata_sources(&[
178 &[IoTypeMetadataKind::FixedCapacityBytes16b as u8],
179 &(capacity as u16).to_le_bytes(),
180 ])
181 }
182 metadata(CAPACITY).0.split_at(metadata(CAPACITY).1).0
183 };
184}
185
186impl<const CAPACITY: usize> FixedCapacityBytesU16<CAPACITY> {
187 #[inline(always)]
191 pub fn try_from_bytes(bytes: &[u8]) -> Option<Self> {
192 if bytes.len() > CAPACITY {
193 return None;
194 }
195
196 Some(Self {
197 len: bytes.len() as u16,
198 bytes: {
199 let mut buffer = [0; CAPACITY];
200 buffer[..bytes.len()].copy_from_slice(bytes);
201 buffer
202 },
203 })
204 }
205
206 #[inline(always)]
208 pub fn get_bytes(&self) -> &[u8] {
209 &self.bytes[..self.len as usize]
210 }
211
212 #[inline(always)]
214 pub fn get_bytes_mut(&mut self) -> &mut [u8] {
215 &mut self.bytes[..self.len as usize]
216 }
217
218 #[inline(always)]
220 pub const fn len(&self) -> u16 {
221 self.len
222 }
223
224 #[inline(always)]
226 pub const fn is_empty(&self) -> bool {
227 self.len == 0
228 }
229
230 #[inline(always)]
234 #[must_use = "Operation may fail"]
235 pub fn append(&mut self, bytes: &[u8]) -> bool {
236 let len = self.len();
237 if bytes.len() + len as usize > CAPACITY {
238 return false;
239 }
240
241 self.bytes[..bytes.len()].copy_from_slice(bytes);
242
243 true
244 }
245
246 #[inline(always)]
250 #[must_use = "Operation may fail"]
251 pub fn truncate(&mut self, new_len: u16) -> bool {
252 if new_len > self.len() {
253 return false;
254 }
255
256 self.len = new_len;
257
258 true
259 }
260
261 #[inline(always)]
265 #[must_use = "Operation may fail"]
266 pub fn copy_from<T>(&mut self, src: &[u8]) -> bool {
267 if src.len() > CAPACITY {
268 return false;
269 }
270
271 self.bytes[..src.len()].copy_from_slice(src);
272 self.len = src.len() as u16;
273
274 true
275 }
276}