planus/impls/
slice.rs

1use crate::{builder::Builder, traits::*, Cursor, Offset};
2use core::mem::MaybeUninit;
3
4impl<T, P: Primitive> WriteAsOffset<[P]> for [T]
5where
6    T: VectorWrite<P>,
7{
8    fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
9        let mut tmp: alloc::vec::Vec<T::Value> = alloc::vec::Vec::with_capacity(self.len());
10        for v in self.iter() {
11            tmp.push(v.prepare(builder));
12        }
13        // SAFETY: We need to make sure we always write the 4+stride*len bytes in the closure
14        unsafe {
15            // TODO: This will not be correctly aligned if P::ALIGNMENT_MASK is bigger than u32::ALIGNMENT_MASK
16            builder.write_with(
17                T::STRIDE
18                    .checked_mul(self.len())
19                    .unwrap()
20                    .checked_add(4)
21                    .unwrap(),
22                P::ALIGNMENT_MASK.max(u32::ALIGNMENT_MASK),
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> WriteAs<Offset<[P]>> for [T]
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> WriteAsDefault<Offset<[P]>, ()> for [T]
52where
53    P: Primitive,
54    T: VectorWrite<P>,
55{
56    type Prepared = Offset<[P]>;
57
58    fn prepare(&self, builder: &mut Builder, _default: &()) -> Option<Offset<[P]>> {
59        if self.is_empty() {
60            None
61        } else {
62            Some(WriteAsOffset::prepare(&self, builder))
63        }
64    }
65}
66
67impl<T, P> WriteAsOptional<Offset<[P]>> for [T]
68where
69    P: Primitive,
70    T: VectorWrite<P>,
71{
72    type Prepared = Offset<[P]>;
73
74    #[inline]
75    fn prepare(&self, builder: &mut Builder) -> Option<Offset<[P]>> {
76        Some(WriteAsOffset::prepare(self, builder))
77    }
78}