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> {
34 const METADATA: &[u8] = {
35 #[inline(always)]
36 const fn metadata(capacity: usize) -> ([u8; MAX_METADATA_CAPACITY], usize) {
37 assert!(
38 capacity <= u8::MAX as usize,
39 "`FixedCapacityBytesU8` capacity must not exceed `u8::MAX`"
40 );
41 concat_metadata_sources(&[&[
42 IoTypeMetadataKind::FixedCapacityBytes8b as u8,
43 capacity as u8,
44 ]])
45 }
46 metadata(CAPACITY).0.split_at(metadata(CAPACITY).1).0
47 };
48}
49
50impl<const CAPACITY: usize> FixedCapacityBytesU8<CAPACITY> {
51 #[inline(always)]
55 pub fn try_from_bytes(bytes: &[u8]) -> Option<Self> {
56 if bytes.len() > CAPACITY {
57 return None;
58 }
59
60 Some(Self {
61 len: bytes.len() as u8,
62 bytes: {
63 let mut buffer = [0; CAPACITY];
64 buffer[..bytes.len()].copy_from_slice(bytes);
65 buffer
66 },
67 })
68 }
69
70 #[inline(always)]
72 pub fn get_bytes(&self) -> &[u8] {
73 &self.bytes[..self.len as usize]
74 }
75
76 #[inline(always)]
78 pub fn get_bytes_mut(&mut self) -> &mut [u8] {
79 &mut self.bytes[..self.len as usize]
80 }
81
82 #[inline(always)]
84 pub const fn len(&self) -> u8 {
85 self.len
86 }
87
88 #[inline(always)]
90 pub const fn is_empty(&self) -> bool {
91 self.len == 0
92 }
93
94 #[inline(always)]
98 #[must_use = "Operation may fail"]
99 pub fn append(&mut self, bytes: &[u8]) -> bool {
100 let len = self.len();
101 if bytes.len() + len as usize > CAPACITY {
102 return false;
103 }
104
105 self.bytes[..bytes.len()].copy_from_slice(bytes);
106
107 true
108 }
109
110 #[inline(always)]
114 #[must_use = "Operation may fail"]
115 pub fn truncate(&mut self, new_len: u8) -> bool {
116 if new_len > self.len() {
117 return false;
118 }
119
120 self.len = new_len;
121
122 true
123 }
124
125 #[inline(always)]
129 #[must_use = "Operation may fail"]
130 pub fn copy_from<T>(&mut self, src: &[u8]) -> bool {
131 if src.len() > CAPACITY {
132 return false;
133 }
134
135 self.bytes[..src.len()].copy_from_slice(src);
136 self.len = src.len() as u8;
137
138 true
139 }
140}
141
142#[derive(Debug, Copy, Clone)]
154#[repr(C)]
155pub struct FixedCapacityBytesU16<const CAPACITY: usize> {
156 len: u16,
157 bytes: [u8; CAPACITY],
158}
159
160impl<const CAPACITY: usize> Default for FixedCapacityBytesU16<CAPACITY> {
161 #[inline(always)]
162 fn default() -> Self {
163 Self {
164 len: 0,
165 bytes: [0; CAPACITY],
166 }
167 }
168}
169
170unsafe impl<const CAPACITY: usize> TrivialType for FixedCapacityBytesU16<CAPACITY> {
172 const METADATA: &[u8] = {
173 #[inline(always)]
174 const fn metadata(capacity: usize) -> ([u8; MAX_METADATA_CAPACITY], usize) {
175 assert!(
176 capacity <= u16::MAX as usize,
177 "`FixedCapacityBytesU16` capacity must not exceed `u16::MAX`"
178 );
179 concat_metadata_sources(&[
180 &[IoTypeMetadataKind::FixedCapacityBytes16b as u8],
181 &(capacity as u16).to_le_bytes(),
182 ])
183 }
184 metadata(CAPACITY).0.split_at(metadata(CAPACITY).1).0
185 };
186}
187
188impl<const CAPACITY: usize> FixedCapacityBytesU16<CAPACITY> {
189 #[inline(always)]
193 pub fn try_from_bytes(bytes: &[u8]) -> Option<Self> {
194 if bytes.len() > CAPACITY {
195 return None;
196 }
197
198 Some(Self {
199 len: bytes.len() as u16,
200 bytes: {
201 let mut buffer = [0; CAPACITY];
202 buffer[..bytes.len()].copy_from_slice(bytes);
203 buffer
204 },
205 })
206 }
207
208 #[inline(always)]
210 pub fn get_bytes(&self) -> &[u8] {
211 &self.bytes[..self.len as usize]
212 }
213
214 #[inline(always)]
216 pub fn get_bytes_mut(&mut self) -> &mut [u8] {
217 &mut self.bytes[..self.len as usize]
218 }
219
220 #[inline(always)]
222 pub const fn len(&self) -> u16 {
223 self.len
224 }
225
226 #[inline(always)]
228 pub const fn is_empty(&self) -> bool {
229 self.len == 0
230 }
231
232 #[inline(always)]
236 #[must_use = "Operation may fail"]
237 pub fn append(&mut self, bytes: &[u8]) -> bool {
238 let len = self.len();
239 if bytes.len() + len as usize > CAPACITY {
240 return false;
241 }
242
243 self.bytes[..bytes.len()].copy_from_slice(bytes);
244
245 true
246 }
247
248 #[inline(always)]
252 #[must_use = "Operation may fail"]
253 pub fn truncate(&mut self, new_len: u16) -> bool {
254 if new_len > self.len() {
255 return false;
256 }
257
258 self.len = new_len;
259
260 true
261 }
262
263 #[inline(always)]
267 #[must_use = "Operation may fail"]
268 pub fn copy_from<T>(&mut self, src: &[u8]) -> bool {
269 if src.len() > CAPACITY {
270 return false;
271 }
272
273 self.bytes[..src.len()].copy_from_slice(src);
274 self.len = src.len() as u16;
275
276 true
277 }
278}