1use super::ShaderType;
2use core::mem::MaybeUninit;
3use thiserror::Error;
4
5#[derive(Clone, Copy, Debug, Error)]
6pub enum Error {
7 #[error("could not read/write {expected} bytes from/into {found} byte sized buffer")]
8 BufferTooSmall { expected: u64, found: u64 },
9}
10
11pub type Result<T> = core::result::Result<T, Error>;
12
13pub struct WriteContext {
14 pub rts_array_length: Option<u32>,
18}
19
20pub struct Writer<B: BufferMut> {
21 pub ctx: WriteContext,
22 cursor: Cursor<B>,
23}
24
25impl<B: BufferMut> Writer<B> {
26 #[inline]
27 pub fn new<T: ?Sized + ShaderType>(data: &T, buffer: B, offset: usize) -> Result<Self> {
28 let mut cursor = Cursor::new(buffer, offset);
29 let size = data.size().get();
30 if cursor.try_enlarge(offset + size as usize).is_err() {
31 Err(Error::BufferTooSmall {
32 expected: size,
33 found: cursor.capacity() as u64,
34 })
35 } else {
36 Ok(Self {
37 ctx: WriteContext {
38 rts_array_length: None,
39 },
40 cursor,
41 })
42 }
43 }
44
45 #[inline]
46 pub fn advance(&mut self, amount: usize) {
47 self.cursor.advance(amount);
48 }
49
50 #[inline]
51 pub fn write<const N: usize>(&mut self, val: &[u8; N]) {
52 self.cursor.write(val);
53 }
54
55 #[inline]
56 pub fn write_slice(&mut self, val: &[u8]) {
57 self.cursor.write_slice(val)
58 }
59}
60
61pub struct ReadContext {
62 pub rts_array_max_el_to_read: Option<u32>,
66}
67
68pub struct Reader<B: BufferRef> {
69 pub ctx: ReadContext,
70 cursor: Cursor<B>,
71}
72
73impl<B: BufferRef> Reader<B> {
74 #[inline]
75 pub fn new<T: ?Sized + ShaderType>(buffer: B, offset: usize) -> Result<Self> {
76 let cursor = Cursor::new(buffer, offset);
77 if cursor.remaining() < T::min_size().get() as usize {
78 Err(Error::BufferTooSmall {
79 expected: T::min_size().get(),
80 found: cursor.remaining() as u64,
81 })
82 } else {
83 Ok(Self {
84 ctx: ReadContext {
85 rts_array_max_el_to_read: None,
86 },
87 cursor,
88 })
89 }
90 }
91
92 #[inline]
93 pub fn advance(&mut self, amount: usize) {
94 self.cursor.advance(amount);
95 }
96
97 #[inline]
98 pub fn read<const N: usize>(&mut self) -> &[u8; N] {
99 self.cursor.read()
100 }
101
102 #[inline]
103 pub fn read_slice(&mut self, val: &mut [u8]) {
104 self.cursor.read_slice(val)
105 }
106
107 #[inline]
108 pub fn remaining(&self) -> usize {
109 self.cursor.remaining()
110 }
111}
112
113struct Cursor<B> {
114 buffer: B,
115 pos: usize,
116}
117
118impl<B> Cursor<B> {
119 #[inline]
120 fn new(buffer: B, offset: usize) -> Self {
121 Self {
122 buffer,
123 pos: offset,
124 }
125 }
126 #[inline]
127 fn advance(&mut self, amount: usize) {
128 self.pos += amount;
129 }
130}
131
132impl<B: BufferRef> Cursor<B> {
133 #[inline]
134 fn remaining(&self) -> usize {
135 self.buffer.len().saturating_sub(self.pos)
136 }
137
138 #[inline]
139 fn read<const N: usize>(&mut self) -> &[u8; N] {
140 let res = self.buffer.read(self.pos);
141 self.pos += N;
142 res
143 }
144
145 #[inline]
146 fn read_slice(&mut self, val: &mut [u8]) {
147 self.buffer.read_slice(self.pos, val);
148 self.pos += val.len();
149 }
150}
151
152impl<B: BufferMut> Cursor<B> {
153 #[inline]
154 fn capacity(&self) -> usize {
155 self.buffer.capacity().saturating_sub(self.pos)
156 }
157
158 #[inline]
159 fn write<const N: usize>(&mut self, val: &[u8; N]) {
160 self.buffer.write(self.pos, val);
161 self.pos += N;
162 }
163
164 #[inline]
165 fn write_slice(&mut self, val: &[u8]) {
166 self.buffer.write_slice(self.pos, val);
167 self.pos += val.len();
168 }
169
170 #[inline]
171 fn try_enlarge(&mut self, wanted: usize) -> core::result::Result<(), EnlargeError> {
172 self.buffer.try_enlarge(wanted)
173 }
174}
175
176#[derive(Clone, Copy, Debug, Error)]
177#[error("could not enlarge buffer")]
178pub struct EnlargeError;
179
180impl From<std::collections::TryReserveError> for EnlargeError {
181 fn from(_: std::collections::TryReserveError) -> Self {
182 Self
183 }
184}
185
186#[allow(clippy::len_without_is_empty)]
187pub trait BufferRef {
188 fn len(&self) -> usize;
189
190 fn read<const N: usize>(&self, offset: usize) -> &[u8; N];
191
192 fn read_slice(&self, offset: usize, val: &mut [u8]);
193}
194
195pub trait BufferMut {
196 fn capacity(&self) -> usize;
197
198 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]);
199
200 fn write_slice(&mut self, offset: usize, val: &[u8]);
201
202 #[inline]
203 fn try_enlarge(&mut self, wanted: usize) -> core::result::Result<(), EnlargeError> {
204 if wanted > self.capacity() {
205 Err(EnlargeError)
206 } else {
207 Ok(())
208 }
209 }
210}
211
212impl BufferRef for [u8] {
213 fn len(&self) -> usize {
214 self.len()
215 }
216
217 #[inline]
218 fn read<const N: usize>(&self, offset: usize) -> &[u8; N] {
219 use crate::utils::SliceExt;
220 self.array(offset)
221 }
222
223 #[inline]
224 fn read_slice(&self, offset: usize, val: &mut [u8]) {
225 val.copy_from_slice(&self[offset..offset + val.len()])
226 }
227}
228
229impl<const LEN: usize> BufferRef for [u8; LEN] {
230 #[inline]
231 fn len(&self) -> usize {
232 <[u8] as BufferRef>::len(self)
233 }
234
235 #[inline]
236 fn read<const N: usize>(&self, offset: usize) -> &[u8; N] {
237 <[u8] as BufferRef>::read(self, offset)
238 }
239
240 #[inline]
241 fn read_slice(&self, offset: usize, val: &mut [u8]) {
242 <[u8] as BufferRef>::read_slice(self, offset, val)
243 }
244}
245
246impl BufferRef for Vec<u8> {
247 #[inline]
248 fn len(&self) -> usize {
249 <[u8] as BufferRef>::len(self)
250 }
251
252 #[inline]
253 fn read<const N: usize>(&self, offset: usize) -> &[u8; N] {
254 <[u8] as BufferRef>::read(self, offset)
255 }
256
257 #[inline]
258 fn read_slice(&self, offset: usize, val: &mut [u8]) {
259 <[u8] as BufferRef>::read_slice(self, offset, val)
260 }
261}
262
263impl BufferMut for [u8] {
264 #[inline]
265 fn capacity(&self) -> usize {
266 self.len()
267 }
268
269 #[inline]
270 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
271 use crate::utils::SliceExt;
272 *self.array_mut(offset) = *val;
273 }
274
275 #[inline]
276 fn write_slice(&mut self, offset: usize, val: &[u8]) {
277 self[offset..offset + val.len()].copy_from_slice(val);
278 }
279}
280
281impl BufferMut for [MaybeUninit<u8>] {
282 #[inline]
283 fn capacity(&self) -> usize {
284 self.len()
285 }
286
287 #[inline]
288 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
289 use crate::utils::SliceExt;
290 let val: &[MaybeUninit<u8>; N] = unsafe { core::mem::transmute(val) };
292 *self.array_mut(offset) = *val;
293 }
294
295 #[inline]
296 fn write_slice(&mut self, offset: usize, val: &[u8]) {
297 let val: &[MaybeUninit<u8>] = unsafe { core::mem::transmute(val) };
299 self[offset..offset + val.len()].copy_from_slice(val);
300 }
301}
302
303impl<const LEN: usize> BufferMut for [u8; LEN] {
304 #[inline]
305 fn capacity(&self) -> usize {
306 <[u8] as BufferMut>::capacity(self)
307 }
308
309 #[inline]
310 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
311 <[u8] as BufferMut>::write(self, offset, val);
312 }
313
314 #[inline]
315 fn write_slice(&mut self, offset: usize, val: &[u8]) {
316 <[u8] as BufferMut>::write_slice(self, offset, val)
317 }
318}
319
320impl<const LEN: usize> BufferMut for [MaybeUninit<u8>; LEN] {
321 #[inline]
322 fn capacity(&self) -> usize {
323 <[MaybeUninit<u8>] as BufferMut>::capacity(self)
324 }
325
326 #[inline]
327 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
328 <[MaybeUninit<u8>] as BufferMut>::write(self, offset, val)
329 }
330
331 #[inline]
332 fn write_slice(&mut self, offset: usize, val: &[u8]) {
333 <[MaybeUninit<u8>] as BufferMut>::write_slice(self, offset, val)
334 }
335}
336
337impl BufferMut for Vec<u8> {
338 #[inline]
339 fn capacity(&self) -> usize {
340 self.capacity()
341 }
342
343 #[inline]
344 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
345 <[u8] as BufferMut>::write(self, offset, val);
346 }
347
348 #[inline]
349 fn write_slice(&mut self, offset: usize, val: &[u8]) {
350 <[u8] as BufferMut>::write_slice(self, offset, val)
351 }
352
353 #[inline]
354 fn try_enlarge(&mut self, wanted: usize) -> core::result::Result<(), EnlargeError> {
355 use crate::utils::ByteVecExt;
356 self.try_extend(wanted).map_err(EnlargeError::from)
357 }
358}
359
360impl BufferMut for Vec<MaybeUninit<u8>> {
361 #[inline]
362 fn capacity(&self) -> usize {
363 self.capacity()
364 }
365
366 #[inline]
367 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
368 <[MaybeUninit<u8>] as BufferMut>::write(self, offset, val)
369 }
370
371 #[inline]
372 fn write_slice(&mut self, offset: usize, val: &[u8]) {
373 <[MaybeUninit<u8>] as BufferMut>::write_slice(self, offset, val)
374 }
375
376 #[inline]
377 fn try_enlarge(&mut self, wanted: usize) -> core::result::Result<(), EnlargeError> {
378 use crate::utils::ByteVecExt;
379 self.try_extend(wanted).map_err(EnlargeError::from)
380 }
381}
382
383macro_rules! impl_buffer_ref_for_wrappers {
384 ($($type:ty),*) => {$(
385 impl<T: ?Sized + BufferRef> BufferRef for $type {
386 #[inline]
387 fn len(&self) -> usize {
388 T::len(self)
389 }
390
391 #[inline]
392 fn read<const N: usize>(&self, offset: usize) -> &[u8; N] {
393 T::read(self, offset)
394 }
395
396 #[inline]
397 fn read_slice(&self, offset: usize, val: &mut [u8]) {
398 T::read_slice(self, offset, val)
399 }
400 }
401 )*};
402}
403
404impl_buffer_ref_for_wrappers!(&T, &mut T, Box<T>, std::rc::Rc<T>, std::sync::Arc<T>);
405
406macro_rules! impl_buffer_mut_for_wrappers {
407 ($($type:ty),*) => {$(
408 impl<T: ?Sized + BufferMut> BufferMut for $type {
409 #[inline]
410 fn capacity(&self) -> usize {
411 T::capacity(self)
412 }
413
414 #[inline]
415 fn write<const N: usize>(&mut self, offset: usize, val: &[u8; N]) {
416 T::write(self, offset, val)
417 }
418
419 #[inline]
420 fn write_slice(&mut self, offset: usize, val: &[u8]) {
421 T::write_slice(self, offset, val)
422 }
423
424 #[inline]
425 fn try_enlarge(&mut self, wanted: usize) -> core::result::Result<(), EnlargeError> {
426 T::try_enlarge(self, wanted)
427 }
428 }
429 )*};
430}
431
432impl_buffer_mut_for_wrappers!(&mut T, Box<T>);
433
434#[cfg(test)]
435mod buffer_ref {
436 use super::BufferRef;
437
438 #[test]
439 fn array() {
440 let arr = [0, 1, 2, 3, 4, 5];
441
442 assert_eq!(BufferRef::len(&arr), 6);
443 assert_eq!(BufferRef::read(&arr, 3), &[3, 4]);
444 }
445
446 #[test]
447 fn vec() {
448 let vec = Vec::from([0, 1, 2, 3, 4, 5]);
449
450 assert_eq!(BufferRef::len(&vec), 6);
451 assert_eq!(BufferRef::read(&vec, 3), &[3, 4]);
452 }
453}
454
455#[cfg(test)]
456mod buffer_mut {
457 use super::BufferMut;
458 use crate::core::EnlargeError;
459
460 #[test]
461 fn array() {
462 let mut arr = [0, 1, 2, 3, 4, 5];
463
464 assert_eq!(BufferMut::capacity(&arr), 6);
465
466 BufferMut::write(&mut arr, 3, &[9, 1]);
467 assert_eq!(arr, [0, 1, 2, 9, 1, 5]);
468
469 assert!(matches!(BufferMut::try_enlarge(&mut arr, 6), Ok(())));
470 assert!(matches!(
471 BufferMut::try_enlarge(&mut arr, 7),
472 Err(EnlargeError)
473 ));
474 }
475
476 #[test]
477 fn vec() {
478 let mut vec = Vec::from([0, 1, 2, 3, 4, 5]);
479
480 assert_eq!(BufferMut::capacity(&vec), vec.capacity());
481
482 BufferMut::write(&mut vec, 3, &[9, 1]);
483 assert_eq!(vec, Vec::from([0, 1, 2, 9, 1, 5]));
484
485 assert!(matches!(BufferMut::try_enlarge(&mut vec, 100), Ok(())));
486 assert!(matches!(
487 BufferMut::try_enlarge(&mut vec, usize::MAX),
488 Err(EnlargeError)
489 ));
490 }
491}
492
493#[cfg(test)]
494mod error {
495 use super::Error;
496
497 #[test]
498 fn derived_traits() {
499 let err = Error::BufferTooSmall {
500 expected: 4,
501 found: 2,
502 };
503
504 {
505 use std::error::Error;
506 assert!(err.source().is_none());
507 }
508
509 assert_eq!(
510 format!("{}", err.clone()),
511 "could not read/write 4 bytes from/into 2 byte sized buffer"
512 );
513
514 assert_eq!(
515 format!("{:?}", err.clone()),
516 "BufferTooSmall { expected: 4, found: 2 }"
517 );
518 }
519}
520
521#[cfg(test)]
522mod enlarge_error {
523 use super::EnlargeError;
524
525 #[test]
526 fn derived_traits() {
527 let try_reserve_error = {
529 let mut vec = Vec::<u8>::new();
530 vec.try_reserve(usize::MAX).err().unwrap()
531 };
532 let err = EnlargeError::from(try_reserve_error);
533
534 use std::error::Error;
535 assert!(err.source().is_none());
536
537 assert_eq!(format!("{}", err.clone()), "could not enlarge buffer");
538
539 assert_eq!(format!("{:?}", err.clone()), "EnlargeError");
540 }
541}