1use core::borrow::{Borrow, BorrowMut};
4use core::convert::From;
5use core::hash::{Hash, Hasher};
6use core::iter::Extend;
7use core::mem::MaybeUninit;
8use core::ops::{Deref, DerefMut};
9
10pub struct FixedSliceVec<'a, T: Sized> {
15 storage: &'a mut [MaybeUninit<T>],
17 len: usize,
20}
21
22impl<'a, T: Sized> Drop for FixedSliceVec<'a, T> {
23 fn drop(&mut self) {
24 self.clear();
25 }
26}
27
28impl<'a, T: Sized> FixedSliceVec<'a, T> {
29 #[inline]
34 pub fn new(storage: &'a mut [MaybeUninit<T>]) -> Self {
35 FixedSliceVec { storage, len: 0 }
36 }
37
38 #[inline]
61 pub unsafe fn from_bytes(bytes: &'a mut [u8]) -> FixedSliceVec<'a, T> {
62 FixedSliceVec::align_from_bytes(bytes).1
63 }
64
65 #[inline]
73 pub fn from_uninit_bytes(bytes: &'a mut [MaybeUninit<u8>]) -> FixedSliceVec<'a, T> {
74 FixedSliceVec::align_from_uninit_bytes(bytes).1
75 }
76
77 #[inline]
98 pub unsafe fn align_from_bytes(
99 bytes: &'a mut [u8],
100 ) -> (&'a mut [u8], FixedSliceVec<'a, T>, &'a mut [u8]) {
101 let (prefix, storage, suffix) = bytes.align_to_mut();
102 (prefix, FixedSliceVec { storage, len: 0 }, suffix)
103 }
104
105 #[inline]
120 pub fn align_from_uninit_bytes(
121 bytes: &'a mut [MaybeUninit<u8>],
122 ) -> (
123 &'a mut [MaybeUninit<u8>],
124 FixedSliceVec<'a, T>,
125 &'a mut [MaybeUninit<u8>],
126 ) {
127 let (prefix, storage, suffix) = unsafe { bytes.align_to_mut() };
128 (prefix, FixedSliceVec { storage, len: 0 }, suffix)
129 }
130
131 #[inline]
159 pub fn as_mut_ptr(&mut self) -> *mut MaybeUninit<T> {
160 self.storage.as_mut_ptr()
161 }
162 #[inline]
194 pub fn as_ptr(&self) -> *const MaybeUninit<T> {
195 self.storage.as_ptr()
196 }
197
198 #[inline]
201 pub fn len(&self) -> usize {
202 self.len
203 }
204
205 #[inline]
207 pub fn capacity(&self) -> usize {
208 self.storage.len()
209 }
210
211 #[inline]
213 pub fn is_empty(&self) -> bool {
214 self.len == 0
215 }
216
217 #[inline]
219 pub fn is_full(&self) -> bool {
220 self.len == self.capacity()
221 }
222
223 #[inline]
227 pub fn try_push(&mut self, value: T) -> Result<(), StorageError<T>> {
228 if self.is_full() {
229 return Err(StorageError(value));
230 }
231 self.storage[self.len] = MaybeUninit::new(value);
232 self.len += 1;
233 Ok(())
234 }
235
236 #[inline]
242 pub fn push(&mut self, value: T) {
243 self.try_push(value).unwrap();
244 }
245
246 #[inline]
250 pub fn try_insert(&mut self, index: usize, value: T) -> Result<(), StorageError<T>> {
251 if index > self.len() {
252 return Err(StorageError(value));
253 }
254 self.try_push(value)?;
255 self.as_mut_slice()[index..].rotate_right(1);
256 Ok(())
257 }
258
259 #[inline]
265 pub fn insert(&mut self, index: usize, value: T) {
266 self.try_insert(index, value).unwrap()
267 }
268
269 #[inline]
275 pub fn try_extend(
276 &mut self,
277 iterable: impl IntoIterator<Item = T>,
278 ) -> Result<(), impl Iterator<Item = T>> {
279 let mut iter = iterable.into_iter().peekable();
280 loop {
281 if iter.peek().is_some() {
282 if self.is_full() {
283 return Err(iter);
284 } else if let Some(item) = iter.next() {
285 self.storage[self.len] = MaybeUninit::new(item);
286 self.len += 1;
287 } else {
288 unreachable!("`FixedSliceVec::try_extend` peeked above to ensure that `next` would return Some")
289 }
290 } else {
291 return Ok(());
292 }
293 }
294 }
295
296 #[inline]
298 pub fn pop(&mut self) -> Option<T> {
299 if self.len == 0 {
300 return None;
301 }
302 self.len -= 1;
303 Some(unsafe { self.storage[self.len].as_ptr().read() })
304 }
305
306 #[inline]
309 pub fn clear(&mut self) {
310 let original_len = self.len;
311 self.len = 0;
312 unsafe {
313 (core::slice::from_raw_parts_mut(self.storage.as_mut_ptr() as *mut T, original_len)
318 as *mut [T])
319 .drop_in_place();
320 }
321 }
322
323 #[inline]
328 pub fn truncate(&mut self, len: usize) {
329 let original_len = self.len;
330 if len > original_len {
331 return;
332 }
333 self.len = len;
334 unsafe {
335 (&mut core::slice::from_raw_parts_mut(self.storage.as_mut_ptr() as *mut T, original_len)[len..] as *mut [T]).drop_in_place();
340 }
341 }
342 pub fn remove(&mut self, index: usize) -> T {
349 if index >= self.len {
351 panic!(
352 "removal index (is {}) should be < len (is {})",
353 index, self.len
354 );
355 }
356 unsafe { self.unchecked_remove(index) }
357 }
358
359 pub fn try_remove(&mut self, index: usize) -> Result<T, IndexError> {
362 if index >= self.len {
363 return Err(IndexError);
364 }
365 Ok(unsafe { self.unchecked_remove(index) })
366 }
367
368 #[inline]
370 unsafe fn unchecked_remove(&mut self, index: usize) -> T {
371 let ptr = (self.as_mut_ptr() as *mut T).add(index);
372 let out = core::ptr::read(ptr);
373 core::ptr::copy(ptr.offset(1), ptr, self.len - index - 1);
374 self.len -= 1;
375 out
376 }
377 pub fn swap_remove(&mut self, index: usize) -> T {
387 if index >= self.len {
388 panic!(
389 "swap_remove index (is {}) should be < len (is {})",
390 index, self.len
391 );
392 }
393 unsafe { self.unchecked_swap_remove(index) }
394 }
395 pub fn try_swap_remove(&mut self, index: usize) -> Result<T, IndexError> {
401 if index >= self.len {
402 return Err(IndexError);
403 }
404 Ok(unsafe { self.unchecked_swap_remove(index) })
405 }
406
407 #[inline]
409 unsafe fn unchecked_swap_remove(&mut self, index: usize) -> T {
410 let target_ptr = (self.as_mut_ptr() as *mut T).add(index);
411 let end_ptr = (self.as_ptr() as *const T).add(self.len - 1);
412 let end_value = core::ptr::read(end_ptr);
413 self.len -= 1;
414 core::ptr::replace(target_ptr, end_value)
415 }
416
417 #[inline]
420 pub fn as_slice(&self) -> &[T] {
421 Deref::deref(self)
422 }
423
424 #[inline]
427 pub fn as_mut_slice(&mut self) -> &mut [T] {
428 DerefMut::deref_mut(self)
429 }
430}
431
432#[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
436pub struct StorageError<T>(pub T);
437
438impl<T> core::fmt::Debug for StorageError<T> {
439 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
440 f.write_str("Push failed because FixedSliceVec was full")
441 }
442}
443
444#[derive(Clone, PartialEq, PartialOrd, Eq, Ord)]
449pub struct IndexError;
450
451impl core::fmt::Debug for IndexError {
452 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> {
453 f.write_str(
454 "Access to the FixedSliceVec failed because an invalid index or length was provided",
455 )
456 }
457}
458
459impl<'a, T: Sized> From<&'a mut [MaybeUninit<T>]> for FixedSliceVec<'a, T> {
460 #[inline]
461 fn from(v: &'a mut [MaybeUninit<T>]) -> Self {
462 FixedSliceVec { storage: v, len: 0 }
463 }
464}
465
466impl<'a, T: Sized> Hash for FixedSliceVec<'a, T>
467where
468 T: Hash,
469{
470 #[inline]
471 fn hash<H: Hasher>(&self, state: &mut H) {
472 Hash::hash(&**self, state)
473 }
474}
475
476impl<'a, T: Sized> PartialEq for FixedSliceVec<'a, T>
477where
478 T: PartialEq,
479{
480 #[inline]
481 fn eq(&self, other: &Self) -> bool {
482 **self == **other
483 }
484}
485
486impl<'a, T: Sized> PartialEq<[T]> for FixedSliceVec<'a, T>
487where
488 T: PartialEq,
489{
490 #[inline]
491 fn eq(&self, other: &[T]) -> bool {
492 **self == *other
493 }
494}
495
496impl<'a, T: Sized> Eq for FixedSliceVec<'a, T> where T: Eq {}
497
498impl<'a, T: Sized> Borrow<[T]> for FixedSliceVec<'a, T> {
499 #[inline]
500 fn borrow(&self) -> &[T] {
501 self
502 }
503}
504
505impl<'a, T: Sized> BorrowMut<[T]> for FixedSliceVec<'a, T> {
506 #[inline]
507 fn borrow_mut(&mut self) -> &mut [T] {
508 self
509 }
510}
511
512impl<'a, T: Sized> AsRef<[T]> for FixedSliceVec<'a, T> {
513 #[inline]
514 fn as_ref(&self) -> &[T] {
515 self
516 }
517}
518
519impl<'a, T: Sized> AsMut<[T]> for FixedSliceVec<'a, T> {
520 #[inline]
521 fn as_mut(&mut self) -> &mut [T] {
522 self
523 }
524}
525
526impl<'a, T: Sized> core::fmt::Debug for FixedSliceVec<'a, T>
527where
528 T: core::fmt::Debug,
529{
530 #[inline]
531 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
532 (**self).fmt(f)
533 }
534}
535
536impl<'a, T: Sized> PartialOrd for FixedSliceVec<'a, T>
537where
538 T: PartialOrd,
539{
540 #[inline]
541 fn partial_cmp(&self, other: &FixedSliceVec<'a, T>) -> Option<core::cmp::Ordering> {
542 (**self).partial_cmp(other)
543 }
544
545 #[inline]
546 fn lt(&self, other: &Self) -> bool {
547 (**self).lt(other)
548 }
549
550 #[inline]
551 fn le(&self, other: &Self) -> bool {
552 (**self).le(other)
553 }
554
555 #[inline]
556 fn gt(&self, other: &Self) -> bool {
557 (**self).gt(other)
558 }
559
560 #[inline]
561 fn ge(&self, other: &Self) -> bool {
562 (**self).ge(other)
563 }
564}
565
566impl<'a, T: Sized> Deref for FixedSliceVec<'a, T> {
567 type Target = [T];
568 #[inline]
569 fn deref(&self) -> &Self::Target {
570 unsafe { core::slice::from_raw_parts(self.storage.as_ptr() as *const T, self.len) }
571 }
572}
573
574impl<'a, T: Sized> DerefMut for FixedSliceVec<'a, T> {
575 #[inline]
576 fn deref_mut(&mut self) -> &mut [T] {
577 unsafe { core::slice::from_raw_parts_mut(self.storage.as_mut_ptr() as *mut T, self.len) }
578 }
579}
580
581impl<'a, T: Sized> Extend<T> for FixedSliceVec<'a, T> {
589 fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
590 let _ = self.try_extend(iter);
591 }
592}
593
594#[cfg(test)]
595mod tests {
596 use super::*;
597
598 #[test]
599 fn from_uninit() {
600 let mut data: [MaybeUninit<u8>; 32] = unsafe { MaybeUninit::uninit().assume_init() };
601 let mut sv: FixedSliceVec<u8> = (&mut data[..]).into();
602 assert_eq!(0, sv.len());
603 assert_eq!(32, sv.capacity());
604 assert!(sv.is_empty());
605 let sv_as_slice: &[u8] = &sv;
606 let empty_slice: &[u8] = &[];
607 assert_eq!(empty_slice, sv_as_slice);
608 assert_eq!(Ok(()), sv.try_push(3));
609 assert_eq!(Ok(()), sv.try_push(1));
610 assert_eq!(Ok(()), sv.try_push(4));
611 let non_empty_slice: &[u8] = &[3u8, 1, 4];
612 assert_eq!(non_empty_slice, &sv as &[u8]);
613 let sv_as_mut_slice: &mut [u8] = &mut sv;
614 sv_as_mut_slice[1] = 2;
615 let non_empty_slice: &[u8] = &[3u8, 2, 4];
616 assert_eq!(non_empty_slice, &sv as &[u8]);
617
618 sv.clear();
619 assert_eq!(0, sv.len());
620 assert!(sv.is_empty());
621 }
622
623 #[test]
624 fn happy_path_from_bytes() {
625 let mut data = [0u8; 31];
626 let mut sv: FixedSliceVec<usize> = unsafe { FixedSliceVec::from_bytes(&mut data[..]) };
627 assert!(sv.is_empty());
628 if sv.capacity() > 0 {
630 for i in 0..sv.capacity() {
631 assert_eq!(Ok(()), sv.try_push(i));
632 }
633 }
634 assert!(sv.is_full());
635 }
636
637 #[test]
638 fn align_captures_suffix_and_prefix() {
639 let mut data = [
640 3u8, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5, 8, 9, 7, 9, 3, 2, 3, 8, 4, 6, 2, 6, 4, 3, 3,
641 ];
642 let original_len = data.len();
643 for i in 0..original_len {
644 for len in 0..original_len - i {
645 let storage = &mut data[i..i + len];
646 let storage_len = storage.len();
647 let (prefix, fixed_slice_vec, suffix): (_, FixedSliceVec<u16>, _) =
648 unsafe { FixedSliceVec::align_from_bytes(storage) };
649 assert_eq!(
650 storage_len,
651 prefix.len() + 2 * fixed_slice_vec.capacity() + suffix.len()
652 );
653 }
654 }
655 }
656 fn uninit_storage() -> [MaybeUninit<u8>; 4] {
657 unsafe { MaybeUninit::uninit().assume_init() }
658 }
659
660 #[test]
661 fn as_ptr_reveals_expected_internal_content() {
662 let expected = [0u8, 1, 2, 3];
663 let mut storage = uninit_storage();
664 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
665 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
666
667 let ptr = fsv.as_ptr();
668 for i in 0..fsv.len() {
669 assert_eq!(expected[i], unsafe { (*ptr.add(i)).assume_init() });
670 }
671
672 let mut fsv = fsv;
673 fsv[3] = 99;
674 assert_eq!(99, unsafe { (*fsv.as_ptr().add(3)).assume_init() })
675 }
676
677 #[test]
678 fn as_mut_ptr_allows_changes_to_internal_content() {
679 let expected = [0u8, 2, 4, 8];
680 let mut storage = uninit_storage();
681 let mut fsv: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
682 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
683
684 assert_eq!(8, unsafe { fsv.as_mut_ptr().add(3).read().assume_init() });
685 unsafe {
686 fsv.as_mut_ptr().add(3).write(MaybeUninit::new(99));
687 }
688 assert_eq!(99, fsv[3]);
689
690 fsv[1] = 200;
691 assert_eq!(200, unsafe { fsv.as_mut_ptr().add(1).read().assume_init() });
692 }
693
694 #[test]
695 fn manual_truncate() {
696 let expected = [0u8, 2, 4, 8];
697 let mut storage = uninit_storage();
698 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
699 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
700
701 fsv.truncate(100);
702 assert_eq!(&[0u8, 2, 4, 8], fsv.as_slice());
703 fsv.truncate(2);
704 assert_eq!(&[0u8, 2], fsv.as_slice());
705 fsv.truncate(2);
706 assert_eq!(&[0u8, 2], fsv.as_slice());
707 fsv.truncate(0);
708 assert!(fsv.is_empty());
709 }
710
711 #[test]
712 fn manual_try_remove() {
713 let expected = [0u8, 2, 4, 8];
714 let mut storage = uninit_storage();
715 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
716 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
717
718 assert_eq!(Err(IndexError), fsv.try_remove(100));
719 assert_eq!(Err(IndexError), fsv.try_remove(4));
720 assert_eq!(&[0u8, 2, 4, 8], fsv.as_slice());
721 assert_eq!(Ok(2), fsv.try_remove(1));
722 assert_eq!(&[0u8, 4, 8], fsv.as_slice());
723 }
724
725 #[test]
726 #[should_panic]
727 fn manual_swap_remove_outside_range() {
728 let mut storage = uninit_storage();
729 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
730 assert!(fsv.try_extend([0u8, 2, 4, 8].iter().copied()).is_ok());
731 fsv.swap_remove(100);
732 }
733
734 #[test]
735 #[should_panic]
736 fn manual_swap_remove_empty() {
737 let mut storage = uninit_storage();
738 let mut fsv: FixedSliceVec<u16> = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
739 assert!(fsv.capacity() > 0);
740 assert_eq!(0, fsv.len());
741 fsv.swap_remove(0);
742 }
743
744 #[test]
745 fn manual_swap_remove_inside_range() {
746 let mut storage = uninit_storage();
747 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
748 assert!(fsv.try_extend([0u8, 2, 4, 8].iter().copied()).is_ok());
749 assert_eq!(&[0u8, 2, 4, 8], fsv.as_slice());
750 assert_eq!(2, fsv.swap_remove(1));
751 assert_eq!(&[0u8, 8, 4], fsv.as_slice());
752 assert_eq!(0, fsv.swap_remove(0));
753 assert_eq!(&[4u8, 8], fsv.as_slice());
754 assert_eq!(4, fsv.swap_remove(0));
755 assert_eq!(&[8u8], fsv.as_slice());
756 assert_eq!(8, fsv.swap_remove(0));
757 assert!(fsv.as_slice().is_empty());
758 }
759
760 #[test]
761 fn manual_try_swap_remove() {
762 let expected = [0u8, 2, 4, 8];
763 let mut storage = uninit_storage();
764 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
765 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
766
767 assert_eq!(Err(IndexError), fsv.try_swap_remove(100));
768 assert_eq!(Err(IndexError), fsv.try_swap_remove(4));
769 assert_eq!(&[0u8, 2, 4, 8], fsv.as_slice());
770 assert_eq!(Ok(2), fsv.try_swap_remove(1));
771 assert_eq!(&[0u8, 8, 4], fsv.as_slice());
772 assert_eq!(Ok(0), fsv.try_swap_remove(0));
773 assert_eq!(&[4u8, 8], fsv.as_slice());
774 assert_eq!(Ok(4), fsv.try_swap_remove(0));
775 assert_eq!(&[8u8], fsv.as_slice());
776 assert_eq!(Ok(8), fsv.try_swap_remove(0));
777 assert!(fsv.as_slice().is_empty());
778 assert_eq!(Err(IndexError), fsv.try_swap_remove(0));
779 }
780
781 #[test]
782 fn try_extend_with_exactly_enough_room() {
783 let expected = [0u8, 2, 4, 8];
784 let mut storage = uninit_storage();
785 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
786 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
787 assert_eq!(&expected[..], &fsv[..]);
788 }
789
790 #[test]
791 fn try_extend_with_more_than_enough_room() {
792 let expected = [0u8, 2, 4, 8];
793 let mut storage: [MaybeUninit<u8>; 100] = unsafe { MaybeUninit::uninit().assume_init() };
794 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
795 assert!(fsv.try_extend(expected.iter().copied()).is_ok());
796 assert_eq!(&expected[..], &fsv[..]);
797 }
798
799 #[test]
800 fn try_extend_with_not_enough_room() {
801 let expected = [0u8, 2, 4, 8];
802 let mut storage: [MaybeUninit<u8>; 2] = unsafe { MaybeUninit::uninit().assume_init() };
803 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
804 let mut out_iter = fsv.try_extend(expected.iter().copied()).unwrap_err();
805 assert_eq!(Some(4), out_iter.next());
806 assert_eq!(Some(8), out_iter.next());
807 assert_eq!(None, out_iter.next());
808 assert_eq!(&expected[0..2], &fsv[..]);
809 }
810 #[test]
811 fn extend_with_exactly_enough_room() {
812 let expected = [0u8, 2, 4, 8];
813 let mut storage = uninit_storage();
814 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
815 fsv.extend(expected.iter().copied());
816 assert_eq!(&expected[..], &fsv[..]);
817 }
818
819 #[test]
820 fn extend_with_more_than_enough_room() {
821 let expected = [0u8, 2, 4, 8];
822 let mut storage: [MaybeUninit<u8>; 100] = unsafe { MaybeUninit::uninit().assume_init() };
823 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
824 fsv.extend(expected.iter().copied());
825 assert_eq!(&expected[..], &fsv[..]);
826 }
827
828 #[test]
829 fn extend_with_not_enough_room() {
830 let expected = [0u8, 2, 4, 8];
831 let mut storage: [MaybeUninit<u8>; 2] = unsafe { MaybeUninit::uninit().assume_init() };
832 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
833 fsv.extend(expected.iter().copied());
834 assert_eq!(&expected[0..2], &fsv[..]);
835 }
836
837 #[test]
838 fn from_uninit_bytes_empty_slice() {
839 let storage: &mut [MaybeUninit<u8>] = &mut [];
840 let mut fsv: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(storage);
841 assert_eq!(0, fsv.capacity());
842 assert_eq!(0, fsv.len());
843 assert!(fsv.try_push(31).is_err());
844 }
845 #[test]
846 fn from_uninit_bytes_smaller_than_item_slice() {
847 let mut storage: [MaybeUninit<u8>; 1] = unsafe { MaybeUninit::uninit().assume_init() };
848 let mut fsv: FixedSliceVec<u16> = FixedSliceVec::from_uninit_bytes(&mut storage);
849 assert_eq!(0, fsv.capacity());
850 assert_eq!(0, fsv.len());
851 assert!(fsv.try_push(31).is_err());
852 }
853 #[test]
854 fn from_uninit_bytes_larger_than_item_slice() {
855 let mut storage: [MaybeUninit<u8>; 9] = unsafe { MaybeUninit::uninit().assume_init() };
856 let mut fsv: FixedSliceVec<u16> = FixedSliceVec::from_uninit_bytes(&mut storage);
857 assert!(fsv.capacity() > 0);
858 assert_eq!(0, fsv.len());
859 assert!(fsv.try_push(31).is_ok());
860 assert_eq!(&[31], &fsv[..]);
861 }
862
863 #[test]
864 fn equality_sanity_checks() {
865 let mut storage_a: [MaybeUninit<u8>; 2] = unsafe { MaybeUninit::uninit().assume_init() };
866 let mut a: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_a);
867 let mut storage_b: [MaybeUninit<u8>; 2] = unsafe { MaybeUninit::uninit().assume_init() };
868 let mut b: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_b);
869
870 assert_eq!(a, b);
871 assert_eq!(&a, &b[..]);
872 assert_eq!(&b, &a[..]);
873 a.push(1u8);
874 assert_ne!(a, b);
875 assert_ne!(&a, &b[..]);
876 assert_ne!(&b, &a[..]);
877 b.push(1u8);
878 assert_eq!(a, b);
879 assert_eq!(&a, &b[..]);
880 assert_eq!(&b, &a[..]);
881 }
882
883 #[test]
884 fn borrow_ish_sanity_checks() {
885 let mut expected = [0u8, 2, 4, 8];
886 let mut storage: [MaybeUninit<u8>; 12] = unsafe { MaybeUninit::uninit().assume_init() };
887 let mut fsv = FixedSliceVec::from_uninit_bytes(&mut storage[..]);
888 fsv.extend(expected.iter().copied());
889
890 assert_eq!(&expected[..], Borrow::<[u8]>::borrow(&fsv));
891 assert_eq!(&mut expected[..], BorrowMut::<[u8]>::borrow_mut(&mut fsv));
892 assert_eq!(&expected[..], fsv.as_ref());
893 assert_eq!(&mut expected[..], fsv.as_mut());
894 }
895
896 #[test]
897 fn comparison_sanity_checks() {
898 let mut storage_a: [MaybeUninit<u8>; 2] = unsafe { MaybeUninit::uninit().assume_init() };
899 let mut a: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_a);
900 let mut storage_b: [MaybeUninit<u8>; 2] = unsafe { MaybeUninit::uninit().assume_init() };
901 let mut b: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_b);
902 use core::cmp::Ordering;
903 assert_eq!(Some(Ordering::Equal), a.partial_cmp(&b));
904 b.push(1);
905 assert!(a.lt(&b));
906 assert!(b.gt(&a));
907 a.push(1);
908 assert!(a.ge(&b));
909 assert!(a.le(&b));
910 a[0] = 2;
911 assert!(a.gt(&b));
912 assert!(b.lt(&a));
913 }
914
915 #[test]
916 fn insertion_sanity_checks() {
917 let mut storage_a: [MaybeUninit<u8>; 4] = unsafe { MaybeUninit::uninit().assume_init() };
919 let mut a: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_a);
920 let mut storage_b: [MaybeUninit<u8>; 4] = unsafe { MaybeUninit::uninit().assume_init() };
921 let mut b: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_b);
922 assert_eq!(a.as_slice(), b.as_slice(), "Equal sets of 0 elements");
923 a.insert(0usize, 1);
924 a.insert(0usize, 2);
925 a.insert(0usize, 3);
926 a.insert(0usize, 4);
927 b.push(4);
928 b.push(3);
929 b.push(2);
930 b.push(1);
931 assert_eq!(
932 a.as_slice(),
933 b.as_slice(),
934 "Equal sets of 4 elements, added in opposite order"
935 );
936 assert_eq!(a.try_insert(0, 0), b.try_push(0));
937 assert_eq!(
938 a.as_slice(),
939 &[4u8, 3u8, 2u8, 1u8],
940 "Insert should not modify until required capacity is verified."
941 );
942 assert_eq!(
943 b.as_slice(),
944 &[4u8, 3u8, 2u8, 1u8],
945 "Push should not modify until required capacity is verified."
946 );
947
948 a.clear();
950 assert!(
951 a.try_insert(1usize, 55).is_err(),
952 "Given `n` elements and index `0` to `n-1` the maximum insert index is `n` (push)"
953 );
954 a.insert(0usize, 4);
955 a.insert(1usize, 2);
956 a.insert(1usize, 3);
957 a.insert(3usize, 1);
958 assert_eq!(
959 a.as_slice(),
960 &[4u8, 3u8, 2u8, 1u8],
961 "Alternate insert order should yeild same result."
962 );
963
964 let mut storage_c: [MaybeUninit<u8>; 0] = unsafe { MaybeUninit::uninit().assume_init() };
966 let mut c: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_c);
967 assert!(
968 c.try_insert(0usize, 1).is_err(),
969 "Zero sized buffer should fail on insert"
970 );
971
972 let mut storage_d: [MaybeUninit<u8>; 1] = unsafe { MaybeUninit::uninit().assume_init() };
974 let mut d: FixedSliceVec<u8> = FixedSliceVec::from_uninit_bytes(&mut storage_d);
975 d.push(1);
976 assert!(
977 d.try_insert(0usize, 2).is_err(),
978 "Zero remaining capacity should fail an insert"
979 );
980 }
981}