1use std::{
2 fmt::{Debug, Display},
3 marker::PhantomData,
4 mem::{ManuallyDrop, MaybeUninit},
5 ops::{Add, Mul, Sub},
6 sync::Arc,
7 vec,
8};
9
10use bytemuck::{box_bytes_of, from_box_bytes, BoxBytes, Pod};
11use derive_more::derive::{AsMut, AsRef, Deref, DerefMut, IntoIterator};
12use hybrid_array::{Array, ArraySize};
13use rayon::iter::{FromParallelIterator, IntoParallelIterator, ParallelIterator};
14use serde::{Deserialize, Serialize};
15use typenum::{Diff, Prod, Sum, Unsigned, U1, U2, U3, U5};
16use wincode::{
17 io::{Reader, Writer},
18 ReadResult,
19 SchemaRead,
20 SchemaWrite,
21 TypeMeta,
22 WriteResult,
23};
24
25use crate::{errors::PrimitiveError, types::Positive};
26
27#[derive(Deref, DerefMut, Clone, IntoIterator, AsRef, AsMut, Eq)]
29#[into_iterator(owned, ref, ref_mut)]
30pub struct HeapArray<T: Sized, M: Positive> {
31 #[deref]
32 #[deref_mut]
33 #[as_ref(forward)]
34 #[as_mut(forward)]
35 pub(super) data: Box<[T]>,
36 #[into_iterator(ignore)]
37 pub(super) _len: PhantomData<fn() -> M>,
40}
41
42impl<T: Sized, M: Positive> HeapArray<T, M> {
43 pub(super) fn new(data: Box<[T]>) -> Self {
44 Self {
45 data,
46 _len: PhantomData,
47 }
48 }
49}
50
51impl<T: Sized, M: Positive> HeapArray<T, M> {
52 pub fn peel_transparent<U>(self) -> HeapArray<U, M>
54 where
55 T: bytemuck::TransparentWrapper<U>,
56 {
57 use bytemuck::allocation::TransparentWrapperAlloc;
58 HeapArray::new(T::peel_vec(self.data.into_vec()).into_boxed_slice())
59 }
60
61 pub fn wrap_transparent<W>(self) -> HeapArray<W, M>
63 where
64 W: bytemuck::TransparentWrapper<T>,
65 {
66 use bytemuck::allocation::TransparentWrapperAlloc;
67 HeapArray::new(W::wrap_vec(self.data.into_vec()).into_boxed_slice())
68 }
69}
70
71impl<T: Pod, M: Positive> HeapArray<T, M> {
73 pub fn into_box_bytes(self) -> BoxBytes {
74 box_bytes_of(self.data)
75 }
76
77 pub fn from_box_bytes(buf: BoxBytes) -> Self {
78 Self {
79 data: from_box_bytes(buf),
80 _len: PhantomData,
81 }
82 }
83}
84
85impl<T: Sized, M: Positive> HeapArray<T, M> {
86 pub fn map<F, U>(self, f: F) -> HeapArray<U, M>
87 where
88 F: FnMut(T) -> U,
89 {
90 self.into_iter().map(f).collect()
91 }
92
93 pub fn into_array<const K: usize>(self) -> [T; K] {
99 const {
100 assert!(
101 M::USIZE == K,
102 "HeapArray length does not match destructured array length",
103 );
104 }
105 let raw: *mut [T] = Box::into_raw(self.data);
108 unsafe { *Box::from_raw(raw.cast::<[T; K]>()) }
109 }
110}
111
112impl<T: Sized + Default, M: Positive> HeapArray<T, M> {
113 pub fn from_single_value(val: T) -> Self {
114 Self {
115 data: vec![val].into_boxed_slice(),
116 _len: PhantomData,
117 }
118 }
119}
120
121impl<T: Sized + Default, M: Positive> Default for HeapArray<T, M> {
122 fn default() -> Self {
123 Self {
124 data: (0..M::USIZE).map(|_| T::default()).collect(),
125 _len: PhantomData,
126 }
127 }
128}
129
130impl<T: Sized + Debug, M: Positive> Debug for HeapArray<T, M> {
131 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
132 f.debug_struct(format!("HeapArray<{}>", M::USIZE).as_str())
133 .field("data", &self.data)
134 .finish()
135 }
136}
137
138impl<T: Sized + Serialize, M: Positive> Serialize for HeapArray<T, M> {
139 fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
140 use serde::ser::SerializeTuple;
141 let mut tuple = serializer.serialize_tuple(M::USIZE)?;
142 for element in self.data.iter() {
143 tuple.serialize_element(element)?;
144 }
145 tuple.end()
146 }
147}
148
149impl<'de, T: Sized + Deserialize<'de>, M: Positive> Deserialize<'de> for HeapArray<T, M> {
150 fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
151 struct HeapArrayVisitor<T, M: Positive> {
152 _phantom: PhantomData<(T, M)>,
153 }
154
155 impl<'de, T: Deserialize<'de>, M: Positive> serde::de::Visitor<'de> for HeapArrayVisitor<T, M> {
156 type Value = HeapArray<T, M>;
157
158 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
159 write!(formatter, "a tuple of {} elements", M::USIZE)
160 }
161
162 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
163 where
164 A: serde::de::SeqAccess<'de>,
165 {
166 let mut data = Vec::with_capacity(M::USIZE);
167 for i in 0..M::USIZE {
168 let element = seq
169 .next_element()?
170 .ok_or_else(|| serde::de::Error::invalid_length(i, &self))?;
171 data.push(element);
172 }
173
174 Ok(HeapArray {
175 data: data.into_boxed_slice(),
176 _len: PhantomData,
177 })
178 }
179 }
180
181 deserializer.deserialize_tuple(
182 M::USIZE,
183 HeapArrayVisitor {
184 _phantom: PhantomData,
185 },
186 )
187 }
188}
189
190impl<T: Sized + SchemaWrite<Src = T>, M: Positive> SchemaWrite for HeapArray<T, M> {
191 type Src = HeapArray<T, M>;
192
193 const TYPE_META: wincode::TypeMeta = match <T as SchemaWrite>::TYPE_META {
194 TypeMeta::Static { size, zero_copy } => TypeMeta::Static {
195 size: size * M::USIZE,
196 zero_copy,
197 },
198 TypeMeta::Dynamic => TypeMeta::Dynamic,
199 };
200
201 #[inline]
202 fn size_of(src: &Self::Src) -> WriteResult<usize> {
203 if let TypeMeta::Static { size, .. } = <Self as SchemaWrite>::TYPE_META {
204 return Ok(size);
205 }
206
207 src.iter()
209 .map(T::size_of)
210 .try_fold(0usize, |acc, x| x.map(|x| acc + x))
211 }
212
213 #[inline]
214 fn write(writer: &mut impl Writer, src: &Self::Src) -> WriteResult<()> {
215 if let TypeMeta::Static {
216 size,
217 zero_copy: true,
218 } = <Self as SchemaWrite>::TYPE_META
219 {
220 let writer = &mut unsafe { writer.as_trusted_for(size) }?;
223 unsafe { writer.write_slice_t(&src.data)? };
226 writer.finish()?;
227 } else if let TypeMeta::Static { size, .. } = <Self as SchemaWrite>::TYPE_META {
228 #[allow(clippy::arithmetic_side_effects)]
229 let mut writer = unsafe { writer.as_trusted_for(size) }?;
233 for item in src {
234 T::write(&mut writer, item)?;
235 }
236 writer.finish()?;
237 } else {
238 for item in src {
239 T::write(writer, item)?;
240 }
241 }
242
243 Ok(())
244 }
245}
246
247pub(crate) struct SliceDropGuard<T> {
248 ptr: *mut MaybeUninit<T>,
249 initialized_len: usize,
250}
251
252impl<T> SliceDropGuard<T> {
253 pub(crate) fn new(ptr: *mut MaybeUninit<T>) -> Self {
254 Self {
255 ptr,
256 initialized_len: 0,
257 }
258 }
259
260 #[inline(always)]
261 #[allow(clippy::arithmetic_side_effects)]
262 pub(crate) fn inc_len(&mut self) {
263 self.initialized_len += 1;
264 }
265}
266
267impl<T> Drop for SliceDropGuard<T> {
268 #[inline(always)]
269 fn drop(&mut self) {
270 unsafe {
271 std::ptr::drop_in_place(std::ptr::slice_from_raw_parts_mut(
272 self.ptr.cast::<T>(),
273 self.initialized_len,
274 ));
275 }
276 }
277}
278
279impl<'de, T: Sized + SchemaRead<'de, Dst = T>, M: Positive> SchemaRead<'de> for HeapArray<T, M> {
280 type Dst = HeapArray<T::Dst, M>;
281
282 const TYPE_META: TypeMeta = const {
283 match T::TYPE_META {
284 TypeMeta::Static { size, zero_copy } => TypeMeta::Static {
285 size: M::USIZE * size,
286 zero_copy,
287 },
288 TypeMeta::Dynamic => TypeMeta::Dynamic,
289 }
290 };
291
292 #[inline]
293 fn read(reader: &mut impl Reader<'de>, dst: &mut MaybeUninit<Self::Dst>) -> ReadResult<()> {
294 struct DropGuardRawCopy<T>(*mut [MaybeUninit<T>]);
299 impl<T> Drop for DropGuardRawCopy<T> {
300 #[inline]
301 fn drop(&mut self) {
302 let container = unsafe { Box::from_raw(self.0) };
303 drop(container);
304 }
305 }
306 struct DropGuardElemCopy<T> {
311 inner: ManuallyDrop<SliceDropGuard<T>>,
312 fat: *mut [MaybeUninit<T>],
313 }
314 impl<T> DropGuardElemCopy<T> {
315 #[inline(always)]
316 fn new(fat: *mut [MaybeUninit<T>], raw: *mut MaybeUninit<T>) -> Self {
317 Self {
318 inner: ManuallyDrop::new(SliceDropGuard::new(raw)),
319 fat,
320 }
321 }
322 }
323 impl<T> Drop for DropGuardElemCopy<T> {
324 #[inline]
325 fn drop(&mut self) {
326 unsafe {
327 ManuallyDrop::drop(&mut self.inner);
328 }
329 let container = unsafe { Box::from_raw(self.fat) };
330 drop(container);
331 }
332 }
333 let mem = Box::<[T::Dst]>::new_uninit_slice(M::USIZE);
334 let fat = Box::into_raw(mem);
335 match T::TYPE_META {
336 TypeMeta::Static {
337 zero_copy: true, ..
338 } => {
339 let guard = DropGuardRawCopy(fat);
340 let dst = unsafe { &mut *fat };
341 unsafe { reader.copy_into_slice_t(dst)? };
342 std::mem::forget(guard);
343 }
344 TypeMeta::Static {
345 size,
346 zero_copy: false,
347 } => {
348 let raw_base = unsafe { (*fat).as_mut_ptr() };
349 let mut guard: DropGuardElemCopy<T::Dst> = DropGuardElemCopy::new(fat, raw_base);
350 #[allow(clippy::arithmetic_side_effects)]
351 let reader = &mut unsafe { reader.as_trusted_for(size * M::USIZE) }?;
352 for i in 0..M::USIZE {
353 let slot = unsafe { &mut *raw_base.add(i) };
354 T::read(reader, slot)?;
355 guard.inner.inc_len();
356 }
357 std::mem::forget(guard);
358 }
359 TypeMeta::Dynamic => {
360 let raw_base = unsafe { (*fat).as_mut_ptr() };
361 let mut guard: DropGuardElemCopy<T::Dst> = DropGuardElemCopy::new(fat, raw_base);
362 for i in 0..M::USIZE {
363 let slot = unsafe { &mut *raw_base.add(i) };
364 T::read(reader, slot)?;
365 guard.inner.inc_len();
366 }
367 std::mem::forget(guard);
368 }
369 }
370 let container = unsafe { Box::from_raw(fat) };
371 let container = unsafe { container.assume_init().try_into().unwrap() };
372 dst.write(container);
373 Ok(())
374 }
375}
376
377impl<T: Sized, M: Positive> FromIterator<T> for HeapArray<T, M> {
378 fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
379 let data = iter.into_iter().collect::<Box<_>>();
380 assert_eq!(data.len(), M::USIZE,);
381 Self {
382 data,
383 _len: PhantomData,
384 }
385 }
386}
387
388impl<T: Sized + Send, M: Positive> IntoParallelIterator for HeapArray<T, M> {
389 type Item = T;
390 type Iter = rayon::vec::IntoIter<T>;
391
392 fn into_par_iter(self) -> Self::Iter {
393 self.data.into_par_iter()
394 }
395}
396
397impl<T: Sized + Send, M: Positive> FromParallelIterator<T> for HeapArray<T, M> {
398 fn from_par_iter<I: IntoParallelIterator<Item = T>>(par_iter: I) -> Self {
399 let data: Box<[T]> = par_iter.into_par_iter().collect::<Vec<T>>().into();
400 assert_eq!(data.len(), M::USIZE);
401 Self {
402 data,
403 _len: PhantomData,
404 }
405 }
406}
407
408impl<T: Sized + Copy, M: Positive> HeapArray<T, M> {
413 pub fn split<M1, M2>(&self) -> (HeapArray<T, M1>, HeapArray<T, M2>)
414 where
415 M1: Positive,
416 M2: Positive + Add<M1, Output = M>,
417 {
418 let (m1, m2) = self.split_at(M1::USIZE);
419 (
420 HeapArray::<T, M1> {
421 data: m1.into(),
422 _len: PhantomData,
423 },
424 HeapArray::<T, M2> {
425 data: m2.into(),
426 _len: PhantomData,
427 },
428 )
429 }
430
431 pub fn split_last_pos<M1>(self) -> (HeapArray<T, M1>, T)
432 where
433 M1: Positive + Add<typenum::B1, Output = M>,
434 {
435 let Self { data, .. } = self;
436 let mut data = data.into_vec();
437 let last = data.pop().expect("HeapArray is empty");
438 (
439 HeapArray::<T, M1> {
440 data: data.into_boxed_slice(),
441 _len: PhantomData,
442 },
443 last,
444 )
445 }
446
447 pub fn split_halves<MDiv2>(&self) -> (HeapArray<T, MDiv2>, HeapArray<T, MDiv2>)
448 where
449 MDiv2: Positive + Mul<U2, Output = M>,
450 {
451 let (m1, m2) = self.split_at(MDiv2::USIZE);
452 (
453 HeapArray::<T, MDiv2> {
454 data: m1.into(),
455 _len: PhantomData,
456 },
457 HeapArray::<T, MDiv2> {
458 data: m2.into(),
459 _len: PhantomData,
460 },
461 )
462 }
463
464 pub fn merge_halves(this: Self, other: Self) -> HeapArray<T, Prod<M, U2>>
465 where
466 M: Mul<U2, Output: Positive>,
467 {
468 let mut vec = this.data.into_vec();
469 vec.extend(other.data.into_vec());
470 HeapArray::<T, Prod<M, U2>> {
471 data: vec.into_boxed_slice(),
472 _len: PhantomData,
473 }
474 }
475
476 pub fn split3<M1, M2, M3>(&self) -> (HeapArray<T, M1>, HeapArray<T, M2>, HeapArray<T, M3>)
477 where
478 M1: Positive,
479 M2: Positive + Add<M1>,
480 M3: Positive + Add<Sum<M2, M1>, Output = M>,
481 {
482 let (m1, m_rest) = self.split_at(M1::USIZE);
483 let (m2, m3) = m_rest.split_at(M2::USIZE);
484 (
485 HeapArray::<T, M1> {
486 data: m1.into(),
487 _len: PhantomData,
488 },
489 HeapArray::<T, M2> {
490 data: m2.into(),
491 _len: PhantomData,
492 },
493 HeapArray::<T, M3> {
494 data: m3.into(),
495 _len: PhantomData,
496 },
497 )
498 }
499
500 pub fn split_thirds<MDiv3>(
501 &self,
502 ) -> (
503 HeapArray<T, MDiv3>,
504 HeapArray<T, MDiv3>,
505 HeapArray<T, MDiv3>,
506 )
507 where
508 MDiv3: Positive + Mul<U3, Output = M>,
509 {
510 let (m1, m_rest) = self.split_at(MDiv3::USIZE);
511 let (m2, m3) = m_rest.split_at(MDiv3::USIZE);
512 (
513 HeapArray::<T, MDiv3> {
514 data: m1.into(),
515 _len: PhantomData,
516 },
517 HeapArray::<T, MDiv3> {
518 data: m2.into(),
519 _len: PhantomData,
520 },
521 HeapArray::<T, MDiv3> {
522 data: m3.into(),
523 _len: PhantomData,
524 },
525 )
526 }
527
528 pub fn merge_thirds(first: Self, second: Self, third: Self) -> HeapArray<T, Prod<M, U3>>
529 where
530 M: Mul<U3, Output: Positive>,
531 {
532 let mut vec = first.data.into_vec();
533 vec.extend(second.data.into_vec());
534 vec.extend(third.data.into_vec());
535 HeapArray::<T, Prod<M, U3>> {
536 data: vec.into_boxed_slice(),
537 _len: PhantomData,
538 }
539 }
540
541 pub fn merge_fifths(
542 first: Self,
543 second: Self,
544 third: Self,
545 fourth: Self,
546 fifth: Self,
547 ) -> HeapArray<T, Prod<M, U5>>
548 where
549 M: Mul<U5, Output: Positive>,
550 {
551 let mut vec = first.data.into_vec();
552 vec.reserve_exact(M::USIZE * 4);
553 vec.extend(second.data.into_vec());
554 vec.extend(third.data.into_vec());
555 vec.extend(fourth.data.into_vec());
556 vec.extend(fifth.data.into_vec());
557 HeapArray::<T, Prod<M, U5>> {
558 data: vec.into_boxed_slice(),
559 _len: PhantomData,
560 }
561 }
562}
563
564pub struct HeapArrayTuple<T1: Sized, T2: Sized, M: Positive>(
565 pub HeapArray<T1, M>,
566 pub HeapArray<T2, M>,
567);
568
569impl<T1: Sized, T2: Sized, M: Positive> FromIterator<(T1, T2)> for HeapArrayTuple<T1, T2, M> {
570 fn from_iter<I: IntoIterator<Item = (T1, T2)>>(iter: I) -> Self {
571 let (data1, data2): (Vec<_>, Vec<_>) = iter.into_iter().unzip();
572
573 assert_eq!(data1.len(), M::USIZE);
574 assert_eq!(data2.len(), M::USIZE);
575 HeapArrayTuple(
576 HeapArray::<T1, M> {
577 data: data1.into_boxed_slice(),
578 _len: PhantomData,
579 },
580 HeapArray::<T2, M> {
581 data: data2.into_boxed_slice(),
582 _len: PhantomData,
583 },
584 )
585 }
586}
587
588impl<T: Sized, M: Positive> TryFrom<Vec<T>> for HeapArray<T, M> {
589 type Error = PrimitiveError;
590
591 fn try_from(data: Vec<T>) -> Result<Self, PrimitiveError> {
592 if data.len() == M::USIZE {
593 Ok(Self {
594 data: data.into_boxed_slice(),
595 _len: PhantomData,
596 })
597 } else {
598 Err(PrimitiveError::InvalidSize(M::USIZE, data.len()))
599 }
600 }
601}
602
603impl<T: Sized, M: Positive> TryFrom<Box<[T]>> for HeapArray<T, M> {
604 type Error = PrimitiveError;
605
606 fn try_from(data: Box<[T]>) -> Result<Self, PrimitiveError> {
607 if data.len() == M::USIZE {
608 Ok(Self {
609 data,
610 _len: PhantomData,
611 })
612 } else {
613 Err(PrimitiveError::InvalidSize(M::USIZE, data.len()))
614 }
615 }
616}
617
618impl<T: Sized + Clone, M: Positive> TryFrom<Arc<[T]>> for HeapArray<T, M> {
619 type Error = PrimitiveError;
620
621 fn try_from(data: Arc<[T]>) -> Result<Self, PrimitiveError> {
622 if data.len() != M::USIZE {
623 return Err(PrimitiveError::InvalidSize(M::USIZE, data.len()));
624 }
625 Ok(Self {
626 data: data.to_vec().into_boxed_slice(),
627 _len: PhantomData,
628 })
629 }
630}
631
632impl<T: Sized> From<T> for HeapArray<T, U1> {
633 fn from(element: T) -> Self {
634 Self {
635 data: Box::new([element]),
636 _len: PhantomData,
637 }
638 }
639}
640
641impl<T: Sized, M: Positive> From<HeapArray<T, M>> for Vec<T> {
642 fn from(array: HeapArray<T, M>) -> Self {
643 array.data.into_vec()
644 }
645}
646
647impl<T: Sized + Clone, M: Positive + ArraySize> From<Array<T, M>> for HeapArray<T, M> {
648 fn from(array: Array<T, M>) -> Self {
649 Self {
650 data: array.to_vec().into_boxed_slice(),
651 _len: PhantomData,
652 }
653 }
654}
655
656impl<T: Sized, M: Positive> HeapArray<T, M> {
657 pub fn truncate<N>(self) -> HeapArray<T, N>
660 where
661 N: Positive,
662 M: Sub<N, Output: Unsigned>,
663 {
664 let mut vec = self.data.into_vec();
665 vec.truncate(N::USIZE);
666 HeapArray {
667 data: vec.into_boxed_slice(),
668 _len: PhantomData,
669 }
670 }
671
672 pub fn split_last<N: Positive>(self) -> (HeapArray<T, Diff<M, N>>, HeapArray<T, N>)
673 where
674 M: Sub<N, Output: Positive>,
675 {
676 let mut vec = self.data.into_vec();
677 let last_n = vec.split_off(M::USIZE - N::USIZE);
678
679 (
680 HeapArray {
681 data: vec.into_boxed_slice(),
682 _len: PhantomData,
683 },
684 HeapArray {
685 data: last_n.into_boxed_slice(),
686 _len: PhantomData,
687 },
688 )
689 }
690
691 pub fn from_fn(f: impl FnMut(usize) -> T) -> Self {
692 Self {
693 data: (0..M::USIZE).map(f).collect::<Box<_>>(),
694 _len: PhantomData,
695 }
696 }
697
698 pub fn from_constant(c: T) -> Self
699 where
700 T: Copy,
701 {
702 Self {
703 data: (0..M::USIZE).map(|_| c).collect::<Box<_>>(),
704 _len: PhantomData,
705 }
706 }
707}
708
709impl<T: Sized, M: Positive> Display for HeapArray<T, M>
710where
711 T: Display,
712{
713 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
714 write!(f, "[")?;
715 for (i, item) in self.data.iter().enumerate() {
716 if i != 0 {
717 write!(f, ", ")?;
718 }
719 write!(f, "{item}")?;
720 }
721 write!(f, "]")
722 }
723}
724
725#[cfg(test)]
726pub mod tests {
727 use hybrid_array::sizes::{U2, U3, U6};
728 use typenum::{U1, U4};
729
730 use super::*;
731
732 #[test]
733 fn test_heap_array() {
734 let array = HeapArray::<_, U3>::from_fn(|i| i);
735 assert_eq!(array.into_iter().collect::<Vec<_>>(), vec![0, 1, 2]);
736 }
737
738 #[test]
739 fn test_default() {
740 let array = HeapArray::<usize, U3>::default();
741 assert_eq!(array.len(), 3);
742 }
743
744 #[test]
745 fn test_heap_array_split_last() {
746 let array = HeapArray::<_, U6>::from_fn(|i| i);
747 let (first, last) = array.split_last::<U2>();
748 assert_eq!(first.into_iter().collect::<Vec<_>>(), vec![0, 1, 2, 3]);
749 assert_eq!(last.into_iter().collect::<Vec<_>>(), vec![4, 5]);
750 }
751
752 #[test]
753 fn test_heap_array_from_array() {
754 let array = Array::<_, U3>::from_fn(|i| i);
755 let heap_array = HeapArray::<_, U3>::from(array);
756 assert_eq!(heap_array.into_iter().collect::<Vec<_>>(), vec![0, 1, 2]);
757 }
758
759 #[test]
760 fn test_heap_array_from_vec() {
761 let vec = vec![0, 1, 2];
762 let heap_array = HeapArray::<_, U3>::try_from(vec).unwrap();
763 assert_eq!(heap_array.into_iter().collect::<Vec<_>>(), vec![0, 1, 2]);
764
765 let vec = vec![0, 1];
766 let heap_array = HeapArray::<_, U3>::try_from(vec);
767 assert!(heap_array.is_err());
768 }
769
770 #[test]
771 fn test_heap_array_from_iter() {
772 let heap_array = HeapArray::<_, U3>::from_fn(|i| i);
773 assert_eq!(heap_array.into_iter().collect::<Vec<_>>(), vec![0, 1, 2]);
774 }
775
776 #[test]
777 #[should_panic]
778 fn test_heap_array_from_iter_wrong_size() {
779 HeapArray::<_, U2>::from_iter(0..3);
780 }
781
782 #[test]
783 fn test_heap_array_deserialize() {
784 let array = HeapArray::<usize, U6>::from_fn(|i| i);
785 let serialized = bincode::serialize(&array).unwrap();
786 bincode::deserialize::<HeapArray<usize, U6>>(&serialized).unwrap();
787
788 use bincode::Options;
792 let config = bincode::DefaultOptions::new()
793 .with_fixint_encoding()
794 .reject_trailing_bytes();
795
796 let wrong_deserialize = config.deserialize::<HeapArray<usize, U3>>(&serialized);
797 assert!(wrong_deserialize.is_err());
798 }
799
800 #[test]
801 fn test_heap_array_split() {
802 let array = HeapArray::<_, U6>::from_fn(|i| i);
803 let (first, second) = array.split::<U4, U2>();
804 assert_eq!(first.into_iter().collect::<Vec<_>>(), vec![0, 1, 2, 3]);
805 assert_eq!(second.into_iter().collect::<Vec<_>>(), vec![4, 5]);
806
807 let (first, second) = array.split_halves::<U3>();
808 assert_eq!(first.into_iter().collect::<Vec<_>>(), vec![0, 1, 2]);
809 assert_eq!(second.into_iter().collect::<Vec<_>>(), vec![3, 4, 5]);
810
811 }
815
816 #[test]
817 fn test_heap_array_split3() {
818 let array = HeapArray::<_, U6>::from_fn(|i| i);
819 let (first, second, third) = array.split3::<U3, U2, U1>();
820 assert_eq!(first.into_iter().collect::<Vec<_>>(), vec![0, 1, 2]);
821 assert_eq!(second.into_iter().collect::<Vec<_>>(), vec![3, 4]);
822 assert_eq!(third.into_iter().collect::<Vec<_>>(), vec![5]);
823
824 let (first, second, third) = array.split_thirds::<U2>();
825 assert_eq!(first.into_iter().collect::<Vec<_>>(), vec![0, 1]);
826 assert_eq!(second.into_iter().collect::<Vec<_>>(), vec![2, 3]);
827 assert_eq!(third.into_iter().collect::<Vec<_>>(), vec![4, 5]);
828
829 }
833
834 #[test]
835 fn test_heap_array_wrap_transparent() {
836 #[repr(transparent)]
837 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
838 struct Wrap(u32);
839 unsafe impl bytemuck::TransparentWrapper<u32> for Wrap {}
841
842 let array = HeapArray::<u32, U3>::from_fn(|i| (i as u32) * 10);
843 let wrapped: HeapArray<Wrap, U3> = array.wrap_transparent();
844 assert_eq!(
845 wrapped.into_iter().collect::<Vec<_>>(),
846 vec![Wrap(0), Wrap(10), Wrap(20)],
847 );
848 }
849
850 #[test]
851 fn test_heap_array_peel_transparent() {
852 #[repr(transparent)]
853 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
854 struct Wrap(u32);
855 unsafe impl bytemuck::TransparentWrapper<u32> for Wrap {}
857
858 let array = HeapArray::<Wrap, U3>::from_fn(|i| Wrap((i as u32) * 10));
859 let peeled: HeapArray<u32, U3> = array.peel_transparent();
860 assert_eq!(peeled.into_iter().collect::<Vec<_>>(), vec![0, 10, 20]);
861 }
862
863 #[test]
864 fn test_heap_array_wrap_peel_roundtrip() {
865 #[repr(transparent)]
866 #[derive(Clone, Copy, Debug, PartialEq, Eq)]
867 struct Wrap(u32);
868 unsafe impl bytemuck::TransparentWrapper<u32> for Wrap {}
870
871 let original = HeapArray::<u32, U4>::from_fn(|i| i as u32 + 1);
872 let expected = original.clone().into_iter().collect::<Vec<_>>();
873 let roundtripped: HeapArray<u32, U4> =
874 original.wrap_transparent::<Wrap>().peel_transparent();
875 assert_eq!(roundtripped.into_iter().collect::<Vec<_>>(), expected);
876 }
877
878 #[test]
879 fn test_heap_array_wincode_roundtrip() {
880 let array = HeapArray::<u32, U4>::from_fn(|i| (i * 10) as u32);
882 let ser = wincode::serialize(&array).unwrap();
883 let bin_ser = bincode::serialize(&array).unwrap();
884 let deserialized: HeapArray<u32, U4> = wincode::deserialize(&ser).unwrap();
885
886 assert_eq!(ser, bin_ser);
887 assert_eq!(deserialized, array);
888
889 #[derive(
891 Debug, Copy, Clone, PartialEq, SchemaRead, SchemaWrite, Serialize, Deserialize,
892 )]
893 struct NonZeroCopy {
894 a: u8,
895 b: u16,
896 }
897 let array = HeapArray::<NonZeroCopy, U3>::from_fn(|i| NonZeroCopy {
898 a: i as u8,
899 b: (i * 100) as u16,
900 });
901 let ser = wincode::serialize(&array).unwrap();
902 let bin_ser = bincode::serialize(&array).unwrap();
903 let deserialized: HeapArray<NonZeroCopy, U3> = wincode::deserialize(&ser).unwrap();
904 assert_eq!(ser, bin_ser);
905 assert_eq!(deserialized, array);
906
907 let array = HeapArray::<String, U2>::from_fn(|i| format!("String {i}"));
909 let ser = wincode::serialize(&array).unwrap();
910 let bin_ser = bincode::serialize(&array).unwrap();
911 let deserialized: HeapArray<String, U2> = wincode::deserialize(&ser).unwrap();
912 assert_eq!(ser, bin_ser);
913 assert_eq!(deserialized, array);
914 }
915}