planus/impls/
array.rs

1use core::mem::MaybeUninit;
2
3use crate::{builder::Builder, traits::*, Cursor, Offset, UnionVectorOffset};
4
5impl<T, P, const N: usize> WriteAsOffset<[P]> for [T; N]
6where
7    P: Primitive,
8    T: VectorWrite<P>,
9{
10    fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
11        let mut tmp: [MaybeUninit<T::Value>; N] = unsafe { MaybeUninit::uninit().assume_init() };
12        for (t, v) in tmp.iter_mut().zip(self.iter()) {
13            t.write(v.prepare(builder));
14        }
15        // TODO: replace with std::mem::MaybeUninit::array_assume_init when it becomes stable
16        //       https://github.com/rust-lang/rust/issues/80908
17        let tmp =
18            unsafe { (&tmp as *const [MaybeUninit<T::Value>; N] as *const [T::Value; N]).read() };
19        unsafe {
20            builder.write_with(
21                4 + T::STRIDE.checked_mul(self.len()).unwrap(),
22                P::ALIGNMENT_MASK.max(3),
23                |buffer_position, bytes| {
24                    let bytes = bytes.as_mut_ptr();
25
26                    (self.len() as u32).write(
27                        Cursor::new(&mut *(bytes as *mut [MaybeUninit<u8>; 4])),
28                        buffer_position,
29                    );
30
31                    T::write_values(&tmp, bytes.add(4), buffer_position - 4);
32                },
33            )
34        };
35        builder.current_offset()
36    }
37}
38
39impl<T, P, const N: usize> WriteAs<Offset<[P]>> for [T; N]
40where
41    P: Primitive,
42    T: VectorWrite<P>,
43{
44    type Prepared = Offset<[P]>;
45
46    fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
47        WriteAsOffset::prepare(self, builder)
48    }
49}
50
51impl<T, P, const N: usize> WriteAsOptional<Offset<[P]>> for [T; N]
52where
53    P: Primitive,
54    T: VectorWrite<P>,
55{
56    type Prepared = Offset<[P]>;
57
58    #[inline]
59    fn prepare(&self, builder: &mut Builder) -> Option<Offset<[P]>> {
60        Some(WriteAsOffset::prepare(self, builder))
61    }
62}
63
64impl<T, P, const N: usize> WriteAsUnionVector<P> for [T; N]
65where
66    T: WriteAsUnion<P>,
67{
68    fn prepare(&self, builder: &mut Builder) -> UnionVectorOffset<P> {
69        WriteAsUnionVector::prepare(self.as_slice(), builder)
70    }
71}
72
73impl<T, P, const N: usize> WriteAsDefaultUnionVector<P> for [T; N]
74where
75    T: WriteAsUnion<P>,
76{
77    fn prepare(&self, builder: &mut Builder) -> Option<UnionVectorOffset<P>> {
78        if self.is_empty() {
79            None
80        } else {
81            Some(WriteAsUnionVector::prepare(self.as_slice(), builder))
82        }
83    }
84}
85
86impl<T, P, const N: usize> WriteAsOptionalUnionVector<P> for [T; N]
87where
88    T: WriteAsUnion<P>,
89{
90    #[inline]
91    fn prepare(&self, builder: &mut Builder) -> Option<UnionVectorOffset<P>> {
92        Some(WriteAsUnionVector::prepare(self.as_slice(), builder))
93    }
94}