1use core::fmt;
11use core::mem::MaybeUninit;
12
13use crate::initializer::BufferInitializer;
14use crate::traits::{Initialize, TrustedDeref};
15use crate::wrappers::AsUninit;
16
17pub struct Buffer<T> {
18 pub(crate) initializer: BufferInitializer<T>,
19 pub(crate) items_filled: usize,
20}
21
22pub struct BufferRef<'buffer, T> {
28 inner: &'buffer mut Buffer<T>,
31}
32
33#[derive(Clone, Copy, Debug)]
34pub struct BufferParts<'a, I> {
35 pub filled_part: &'a [I],
36 pub unfilled_init_part: &'a [I],
37 pub unfilled_uninit_part: &'a [MaybeUninit<I>],
38}
39#[derive(Debug)]
40pub struct BufferPartsMut<'a, I> {
41 pub filled_part: &'a mut [I],
42 pub unfilled_init_part: &'a mut [I],
43 pub unfilled_uninit_part: &'a mut [MaybeUninit<I>],
44}
45
46impl<T> Buffer<T> {
47 #[inline]
49 pub const fn from_initializer(initializer: BufferInitializer<T>) -> Self {
50 Self {
51 initializer,
52 items_filled: 0,
53 }
54 }
55 pub const fn uninit(inner: T) -> Self {
58 Self::from_initializer(BufferInitializer::uninit(inner))
59 }
60 #[inline]
63 pub fn into_raw_parts(self) -> (BufferInitializer<T>, usize) {
64 let Self {
65 initializer,
66 items_filled,
67 } = self;
68
69 (initializer, items_filled)
70 }
71 #[inline]
72 pub fn into_initializer(self) -> BufferInitializer<T> {
73 self.initializer
74 }
75 #[inline]
82 pub fn into_inner(self) -> T {
83 self.into_initializer().into_inner()
84 }
85
86 #[inline]
91 pub const fn items_filled(&self) -> usize {
92 self.items_filled
93 }
94
95 #[inline]
96 pub fn by_ref(&mut self) -> BufferRef<'_, T> {
97 BufferRef { inner: self }
98 }
99
100 #[inline]
101 pub const fn initializer(&self) -> &BufferInitializer<T> {
102 &self.initializer
103 }
104
105 #[inline]
106 pub fn initializer_mut(&mut self) -> &mut BufferInitializer<T> {
107 &mut self.initializer
108 }
109}
110impl<T, Item> Buffer<AsUninit<T>>
111where
112 T: core::ops::Deref<Target = [Item]> + core::ops::DerefMut + TrustedDeref,
113{
114 pub fn new(init: T) -> Self {
115 Self::from_initializer(BufferInitializer::new(init))
116 }
117}
118
119impl<T> Buffer<T>
120where
121 T: Initialize,
122{
123 #[inline]
124 pub fn capacity(&self) -> usize {
125 self.initializer.capacity()
126 }
127
128 pub(crate) fn debug_assert_validity(&self) {
129 self.initializer.debug_assert_validity();
130 debug_assert!(self.items_filled() <= self.capacity());
131 debug_assert!(self.items_filled() <= self.initializer.items_initialized());
132 }
133 #[inline]
135 pub fn remaining(&self) -> usize {
136 debug_assert!(self.capacity() >= self.items_filled);
137 self.capacity().wrapping_sub(self.items_filled)
138 }
139 #[inline]
141 pub fn is_full(&self) -> bool {
142 self.items_filled() == self.capacity()
143 }
144 #[inline]
146 pub fn is_empty(&self) -> bool {
147 self.items_filled() == 0
148 }
149 #[inline]
151 pub fn filled_part(&self) -> &[T::Item] {
152 unsafe {
153 self.debug_assert_validity();
154
155 let ptr = self.initializer.all_uninit().as_ptr();
156 let len = self.items_filled;
157
158 core::slice::from_raw_parts(ptr as *const T::Item, len)
159 }
160 }
161 #[inline]
163 pub fn filled_part_mut(&mut self) -> &mut [T::Item] {
164 let orig_ptr = unsafe { self.initializer.all_uninit_mut().as_mut_ptr() };
165
166 unsafe {
167 self.debug_assert_validity();
168
169 let ptr = orig_ptr;
170 let len = self.items_filled;
171
172 core::slice::from_raw_parts_mut(ptr as *mut T::Item, len)
173 }
174 }
175 #[inline]
177 pub fn unfilled_part(&self) -> &[MaybeUninit<T::Item>] {
178 let (orig_ptr, orig_len) = {
179 let orig = self.initializer.all_uninit();
180
181 (orig.as_ptr(), orig.len())
182 };
183
184 unsafe {
185 self.debug_assert_validity();
186
187 let ptr = orig_ptr.add(self.items_filled);
188 let len = orig_len.wrapping_sub(self.items_filled);
189
190 core::slice::from_raw_parts(ptr, len)
191 }
192 }
193 #[inline]
210 pub unsafe fn unfilled_part_mut(&mut self) -> &mut [MaybeUninit<T::Item>] {
211 let (orig_ptr, orig_len) = {
212 let orig = self.initializer.all_uninit_mut();
213 (orig.as_mut_ptr(), orig.len())
214 };
215
216 self.debug_assert_validity();
217
218 let ptr = orig_ptr.add(self.items_filled);
219 let len = orig_len.wrapping_sub(self.items_filled);
220
221 core::slice::from_raw_parts_mut(ptr, len)
222 }
223 #[inline]
225 pub fn filled_unfilled_parts(&self) -> (&[T::Item], &[MaybeUninit<T::Item>]) {
226 (self.filled_part(), self.unfilled_part())
227 }
228 #[inline]
231 pub fn all_parts(&self) -> BufferParts<'_, T::Item> {
232 BufferParts {
233 filled_part: self.filled_part(),
234 unfilled_init_part: self.unfilled_init_part(),
235 unfilled_uninit_part: self.unfilled_uninit_part(),
236 }
237 }
238
239 #[inline]
240 pub fn all_parts_mut(&mut self) -> BufferPartsMut<'_, T::Item> {
241 let (all_ptr, all_len) = unsafe {
242 let all = self.initializer.all_uninit_mut();
243
244 (all.as_mut_ptr(), all.len())
245 };
246
247 unsafe {
248 self.debug_assert_validity();
249
250 let filled_base_ptr = all_ptr as *mut T::Item;
251 let filled_len = self.items_filled;
252
253 let unfilled_init_base_ptr = all_ptr.add(self.items_filled) as *mut T::Item;
254 let unfilled_init_len = self
255 .initializer
256 .items_initialized()
257 .wrapping_sub(self.items_filled);
258
259 let unfilled_uninit_base_ptr = all_ptr.add(self.initializer.items_initialized());
260 let unfilled_uninit_len = all_len.wrapping_sub(self.initializer.items_initialized());
261
262 let filled_part = core::slice::from_raw_parts_mut(filled_base_ptr, filled_len);
263 let unfilled_init_part =
264 core::slice::from_raw_parts_mut(unfilled_init_base_ptr, unfilled_init_len);
265 let unfilled_uninit_part =
266 core::slice::from_raw_parts_mut(unfilled_uninit_base_ptr, unfilled_uninit_len);
267
268 BufferPartsMut {
269 filled_part,
270 unfilled_init_part,
271 unfilled_uninit_part,
272 }
273 }
274 }
275
276 #[inline]
284 pub unsafe fn filled_unfilled_parts_mut(
285 &mut self,
286 ) -> (&mut [T::Item], &mut [MaybeUninit<T::Item>]) {
287 let (all_ptr, all_len) = {
288 let all = self.initializer.all_uninit_mut();
289
290 (all.as_mut_ptr(), all.len())
291 };
292
293 {
294 self.debug_assert_validity();
295
296 let filled_base_ptr = all_ptr as *mut T::Item;
297 let filled_len = self.items_filled;
298
299 let unfilled_base_ptr = all_ptr.add(self.items_filled);
300 let unfilled_len = all_len.wrapping_sub(self.items_filled);
301
302 let filled = core::slice::from_raw_parts_mut(filled_base_ptr, filled_len);
303 let unfilled = core::slice::from_raw_parts_mut(unfilled_base_ptr, unfilled_len);
304
305 (filled, unfilled)
306 }
307 }
308
309 #[inline]
310 pub fn unfilled_init_part(&self) -> &[T::Item] {
311 unsafe {
312 self.debug_assert_validity();
313
314 let all = self.initializer.all_uninit();
315 let all_ptr = all.as_ptr();
316
317 let unfilled_init_base_ptr = all_ptr.add(self.items_filled) as *const T::Item;
318 let unfilled_init_len = self
319 .initializer
320 .items_initialized()
321 .wrapping_sub(self.items_filled);
322
323 core::slice::from_raw_parts(unfilled_init_base_ptr, unfilled_init_len)
324 }
325 }
326
327 #[inline]
329 pub fn unfilled_init_part_mut(&mut self) -> &mut [T::Item] {
330 let BufferPartsMut {
331 unfilled_init_part, ..
332 } = self.all_parts_mut();
333
334 unfilled_init_part
335 }
336 #[inline]
337 pub fn unfilled_uninit_part(&self) -> &[MaybeUninit<T::Item>] {
338 self.initializer.uninit_part()
339 }
340 #[inline]
342 pub fn unfilled_uninit_part_mut(&mut self) -> &mut [MaybeUninit<T::Item>] {
343 self.initializer.uninit_part_mut()
344 }
345
346 #[inline]
347 pub fn unfilled_parts(&mut self) -> (&[T::Item], &[MaybeUninit<T::Item>]) {
348 let BufferParts {
349 unfilled_init_part,
350 unfilled_uninit_part,
351 ..
352 } = self.all_parts();
353
354 (unfilled_init_part, unfilled_uninit_part)
355 }
356 #[inline]
357 pub fn unfilled_parts_mut(&mut self) -> (&mut [T::Item], &mut [MaybeUninit<T::Item>]) {
358 let BufferPartsMut {
359 unfilled_init_part,
360 unfilled_uninit_part,
361 ..
362 } = self.all_parts_mut();
363
364 (unfilled_init_part, unfilled_uninit_part)
365 }
366
367 #[inline]
369 pub fn revert_to_start(&mut self) {
370 self.by_ref().revert_to_start()
371 }
372 #[inline]
373 pub fn append(&mut self, slice: &[T::Item])
374 where
375 T::Item: Copy,
376 {
377 unsafe {
378 let unfilled_part = self.unfilled_part_mut();
381 assert!(slice.len() <= unfilled_part.len());
382 unfilled_part[..slice.len()].copy_from_slice(crate::cast_init_to_uninit_slice(slice));
383
384 self.assume_init(slice.len())
385 }
386 }
387 #[inline]
388 pub fn advance(&mut self, count: usize) {
389 assert!(
390 self.initializer
391 .items_initialized()
392 .wrapping_sub(self.items_filled)
393 >= count,
394 "advancing filledness cursor beyond the initialized region ({} + {} = {} filled > {} init)",
395 self.items_filled,
396 count,
397 self.items_filled + count,
398 self.initializer.items_initialized,
399 );
400 self.items_filled = self.items_filled.wrapping_add(count);
401 }
402 #[inline]
403 pub fn advance_to_init_part(&mut self) {
404 self.items_filled = self.initializer.items_initialized;
405 }
406 pub unsafe fn assume_init(&mut self, count: usize) {
415 self.items_filled += count;
416 self.initializer.items_initialized =
417 core::cmp::max(self.items_filled, self.initializer.items_initialized);
418
419 self.debug_assert_validity();
420 }
421 #[inline]
428 pub unsafe fn assume_init_all(&mut self) {
429 self.items_filled = self.capacity();
430 self.initializer.items_initialized = self.capacity();
431 }
432 #[inline]
433 pub fn fill_by_repeating(&mut self, item: T::Item)
434 where
435 T::Item: Copy,
436 {
437 unsafe {
438 crate::fill_uninit_slice(self.unfilled_part_mut(), item);
439 self.assume_init_all();
440 }
441 }
442}
443impl<T> Buffer<T>
444where
445 T: Initialize<Item = u8>,
446{
447 #[inline]
448 pub fn fill_by_zeroing(&mut self) {
449 self.fill_by_repeating(0_u8);
450 }
451}
452impl<'a> Buffer<AsUninit<&'a mut [u8]>> {
453 #[inline]
455 pub fn from_slice_mut(slice: &'a mut [u8]) -> Self {
456 let mut initializer = BufferInitializer::new(slice);
457 unsafe {
458 initializer.advance_to_end();
459 }
460 Self::from_initializer(initializer)
461 }
462}
463impl<'a> Buffer<&'a mut [MaybeUninit<u8>]> {
464 #[inline]
465 pub fn from_uninit_slice_mut(slice: &'a mut [MaybeUninit<u8>]) -> Self {
466 Self::uninit(slice)
467 }
468}
469
470impl<'buffer, T> BufferRef<'buffer, T> {
471 #[inline]
472 pub fn items_filled(&self) -> usize {
473 self.inner.items_filled()
474 }
475
476 #[inline]
478 pub fn by_ref(&mut self) -> BufferRef<'_, T> {
479 BufferRef { inner: self.inner }
480 }
481}
482
483impl<'buffer, T> BufferRef<'buffer, T>
484where
485 T: Initialize,
486{
487 #[inline]
488 pub fn remaining(&self) -> usize {
489 self.inner.remaining()
490 }
491 #[inline]
492 pub fn unfilled_parts(&mut self) -> (&mut [T::Item], &mut [MaybeUninit<T::Item>]) {
493 self.inner.unfilled_parts_mut()
494 }
495 #[inline]
501 pub unsafe fn unfilled_mut(&mut self) -> &mut [MaybeUninit<T::Item>] {
502 self.inner.unfilled_part_mut()
503 }
504 #[inline]
513 pub unsafe fn advance(&mut self, count: usize) {
514 self.inner.assume_init(count)
515 }
516 #[inline]
523 pub unsafe fn advance_all(&mut self) {
524 self.inner.assume_init_all();
525 }
526 #[inline]
527 pub fn revert_to_start(&mut self) {
528 self.inner.revert_to_start()
529 }
530 #[inline]
531 pub fn fill_by_repeating(&mut self, item: T::Item)
532 where
533 T::Item: Copy,
534 {
535 self.inner.fill_by_repeating(item)
536 }
537 #[inline]
538 pub fn append(&mut self, slice: &[T::Item])
539 where
540 T::Item: Copy,
541 {
542 self.inner.append(slice)
543 }
544}
545impl<T> BufferRef<'_, T>
546where
547 T: Initialize<Item = u8>,
548{
549 #[inline]
550 pub fn fill_by_zeroing(&mut self) {
551 self.inner.fill_by_zeroing()
552 }
553}
554
555impl<T> fmt::Debug for Buffer<T>
556where
557 T: Initialize,
558{
559 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
560 let ptr = self.initializer().all_uninit().as_ptr();
561 let items_init = self.initializer().items_initialized();
562 let items_filled = self.items_filled();
563 let total = self.capacity();
564
565 if f.alternate() {
566 let init_percentage = items_init as f64 / total as f64 * 100.0;
567 let filled_percentage = items_filled as f64 / total as f64 * 100.0;
568 write!(
569 f,
570 "[buffer at {:?}, {} B filled ({:.1}%), {} B init ({:.1}%), {} B total]",
571 ptr, items_filled, filled_percentage, items_init, init_percentage, total
572 )
573 } else {
574 write!(
575 f,
576 "[buffer at {:?}, {}/{}/{}]",
577 ptr, items_filled, items_init, total
578 )
579 }
580 }
581}
582
583#[cfg(test)]
584mod tests {
585 use super::*;
586
587 #[test]
588 fn basic_buffer_ops() {
589 let mut buffer = Buffer::uninit([MaybeUninit::<u8>::uninit(); 32]);
590 assert_eq!(buffer.capacity(), 32);
591 assert_eq!(buffer.remaining(), 32);
592 assert!(buffer.is_empty());
593 assert!(!buffer.is_full());
594 assert!(buffer.initializer().is_completely_uninit());
595 assert!(!buffer.initializer().is_completely_init());
596 assert_eq!(buffer.initializer().items_initialized(), 0);
597 assert_eq!(buffer.initializer().remaining(), 32);
598 assert_eq!(buffer.filled_part(), &[]);
599 assert_eq!(buffer.unfilled_part().len(), 32);
600 assert_eq!(buffer.filled_part_mut(), &mut []);
601 assert_eq!(unsafe { buffer.unfilled_part_mut().len() }, 32);
602 let BufferParts {
605 filled_part,
606 unfilled_init_part,
607 unfilled_uninit_part,
608 } = buffer.all_parts();
609 assert_eq!(filled_part, &[]);
610 assert_eq!(unfilled_init_part, &[]);
611 assert_eq!(unfilled_uninit_part.len(), 32);
612
613 let BufferPartsMut {
614 filled_part,
615 unfilled_init_part,
616 unfilled_uninit_part,
617 } = buffer.all_parts_mut();
618 assert_eq!(filled_part, &mut []);
619 assert_eq!(unfilled_init_part, &mut []);
620 assert_eq!(unfilled_uninit_part.len(), 32);
621
622 let src = b"I am a really nice slice!";
623 let modified = b"I am a really wise slice!";
624
625 buffer.append(src);
626
627 assert!(!buffer.is_empty());
628 assert!(!buffer.is_full());
629 assert_eq!(buffer.filled_part(), src);
630 assert_eq!(buffer.filled_part_mut(), src);
631 assert!(!buffer.initializer().is_completely_init());
632 assert!(!buffer.initializer().is_completely_uninit());
633 assert_eq!(buffer.initializer().init_part(), src);
634 assert_eq!(buffer.initializer_mut().init_part_mut(), src);
635 assert_eq!(buffer.items_filled(), src.len());
636 assert_eq!(buffer.remaining(), 32 - src.len());
637
638 {
639 let slice_mut = buffer.filled_part_mut();
640 slice_mut[14] = b'w';
641 slice_mut[16] = b's';
642 }
643
644 assert!(!buffer.is_empty());
645 assert!(!buffer.is_full());
646 assert_eq!(buffer.filled_part(), modified);
647 assert_eq!(buffer.filled_part_mut(), modified);
648 assert_eq!(buffer.initializer().init_part(), modified);
649 assert_eq!(buffer.initializer_mut().init_part_mut(), modified);
650 assert_eq!(buffer.items_filled(), src.len());
651 assert_eq!(buffer.remaining(), 32 - src.len());
652 assert_eq!(buffer.unfilled_part().len(), 32 - src.len());
653 assert_eq!(unsafe { buffer.unfilled_part_mut().len() }, 32 - src.len());
654
655 let mut initializer = buffer.into_initializer();
656
657 assert_eq!(initializer.items_initialized(), modified.len());
658 assert_eq!(initializer.remaining(), 7);
659 initializer.partially_fill_uninit_part(3_usize, 0xFF_u8);
660 initializer.partially_zero_uninit_part(1_usize);
661 assert_eq!(initializer.remaining(), 3);
662
663 let modified_and_garbage_items = b"I am a really wise slice!\xFF\xFF\xFF\x00";
664 let (init, uninit) = initializer.init_uninit_parts();
665 assert_eq!(init, modified_and_garbage_items);
666 assert_eq!(uninit.len(), 3);
667
668 let (init, uninit) = initializer.init_uninit_parts_mut();
669 assert_eq!(init, modified_and_garbage_items);
670 init[2] = b'e';
671 assert_eq!(uninit.len(), 3);
672
673 let mut buffer = Buffer::from_initializer(initializer);
674 buffer.advance(modified.len());
675
676 let BufferParts {
677 filled_part,
678 unfilled_init_part,
679 unfilled_uninit_part,
680 } = buffer.all_parts();
681 let modified_again = b"I em a really wise slice!";
682 assert_eq!(filled_part, modified_again);
683 assert_eq!(unfilled_init_part, b"\xFF\xFF\xFF\x00");
684 assert_eq!(unfilled_uninit_part.len(), 3);
685
686 let BufferPartsMut {
687 filled_part,
688 unfilled_init_part,
689 unfilled_uninit_part,
690 } = buffer.all_parts_mut();
691 assert_eq!(filled_part, modified_again);
692 assert_eq!(unfilled_init_part, b"\xFF\xFF\xFF\x00");
693 unfilled_init_part[2] = b'\x13';
694 unfilled_init_part[3] = b'\x37';
695 assert_eq!(unfilled_init_part, b"\xFF\xFF\x13\x37");
696 assert_eq!(unfilled_uninit_part.len(), 3);
697
698 let rest = b" Right?";
699 buffer.append(rest);
700
701 assert_eq!(buffer.items_filled(), 32);
702 assert!(!buffer.is_empty());
703 assert!(buffer.is_full());
704 assert_eq!(buffer.remaining(), 0);
705
706 let total = b"I em a really wise slice! Right?";
707 assert_eq!(buffer.filled_part(), total);
708 assert_eq!(buffer.filled_part_mut(), total);
709 assert_eq!(buffer.initializer().remaining(), 0);
710 assert_eq!(buffer.initializer().items_initialized(), 32);
711 assert!(buffer.initializer().is_completely_init());
712 assert!(!buffer.initializer().is_completely_uninit());
713
714 buffer.advance_to_init_part();
715
716 let initialized: [u8; 32] = buffer.into_initializer().try_into_init().unwrap().into();
718 assert_eq!(&initialized, total);
719 }
720 #[test]
721 fn debug_impl() {
722 let array = [MaybeUninit::<u8>::uninit(); 32];
723 let mut buffer = Buffer::uninit(array);
724 buffer.append(b"Hello, world!");
725 buffer.initializer_mut().partially_zero_uninit_part(13);
726
727 assert_eq!(
728 format!("{:?}", buffer),
729 format!(
730 "[buffer at {:p}, 13/26/32]",
731 buffer.initializer().all_uninit().as_ptr()
732 )
733 );
734 assert_eq!(
735 format!("{:#?}", buffer),
736 format!(
737 "[buffer at {:p}, 13 B filled (40.6%), 26 B init (81.2%), 32 B total]",
738 buffer.initializer().all_uninit().as_ptr()
739 )
740 );
741 }
742}