1use core::mem::MaybeUninit;
2
3use crate::{builder::Builder, traits::*, Offset, UnionVectorOffset};
4
5impl<T, P: Primitive> WriteAsOffset<[P]> for [T]
6where
7 T: VectorWrite<P>,
8{
9 fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
10 let mut tmp: alloc::vec::Vec<T::Value> = alloc::vec::Vec::with_capacity(self.len());
11 for v in self.iter() {
12 tmp.push(v.prepare(builder));
13 }
14 unsafe {
16 builder.write_with(
17 T::STRIDE.checked_mul(tmp.len()).unwrap(),
18 P::ALIGNMENT_MASK.max(u32::ALIGNMENT_MASK),
19 |buffer_position, bytes| {
20 let bytes = bytes.as_mut_ptr();
21
22 T::write_values(&tmp, bytes, buffer_position);
23 },
24 );
25 }
26
27 unsafe {
29 builder.write_with(4, 0, |_buffer_position, bytes| {
30 let len = (self.len() as u32).to_le_bytes().map(MaybeUninit::new);
31 bytes.copy_from_slice(&len);
32 });
33 }
34 builder.current_offset()
35 }
36}
37
38impl<T, P> WriteAs<Offset<[P]>> for [T]
39where
40 [T]: WriteAsOffset<[P]>,
41{
42 type Prepared = Offset<[P]>;
43
44 fn prepare(&self, builder: &mut Builder) -> Offset<[P]> {
45 WriteAsOffset::prepare(&self, builder)
46 }
47}
48
49impl<T, P> WriteAsDefault<Offset<[P]>, ()> for [T]
50where
51 [T]: WriteAsOffset<[P]>,
52{
53 type Prepared = Offset<[P]>;
54
55 fn prepare(&self, builder: &mut Builder, _default: &()) -> Option<Offset<[P]>> {
56 if self.is_empty() {
57 None
58 } else {
59 Some(WriteAsOffset::prepare(&self, builder))
60 }
61 }
62}
63
64impl<T, P> WriteAsOptional<Offset<[P]>> for [T]
65where
66 [T]: WriteAsOffset<[P]>,
67{
68 type Prepared = Offset<[P]>;
69
70 #[inline]
71 fn prepare(&self, builder: &mut Builder) -> Option<Offset<[P]>> {
72 Some(WriteAsOffset::prepare(self, builder))
73 }
74}
75
76impl<T, P> WriteAsUnionVector<P> for [T]
77where
78 T: WriteAsUnion<P>,
79{
80 fn prepare(&self, builder: &mut Builder) -> UnionVectorOffset<P> {
81 let mut tmp_tags: alloc::vec::Vec<MaybeUninit<u8>> =
82 alloc::vec::Vec::with_capacity(self.len());
83 let mut tmp_values: alloc::vec::Vec<Offset<()>> =
84 alloc::vec::Vec::with_capacity(self.len());
85 for v in self.iter() {
86 let union_offset = v.prepare(builder);
87 tmp_tags.push(MaybeUninit::new(union_offset.tag));
88 tmp_values.push(union_offset.offset());
89 }
90
91 unsafe {
93 builder.write_with(
94 Offset::<()>::STRIDE.checked_mul(self.len()).unwrap(),
95 Offset::<()>::ALIGNMENT_MASK,
96 |buffer_position, bytes| {
97 let bytes = bytes.as_mut_ptr();
98
99 Offset::<()>::write_values(&tmp_values, bytes, buffer_position);
100 },
101 );
102 }
103
104 unsafe {
106 builder.write_with(4, 0, |_buffer_position, bytes| {
107 let len = (self.len() as u32).to_le_bytes().map(MaybeUninit::new);
108 bytes.copy_from_slice(&len);
109 });
110 }
111 let values_offset = builder.current_offset();
112
113 unsafe {
115 builder.write_with(
116 tmp_tags.len(),
117 u32::ALIGNMENT_MASK,
118 |_buffer_position, bytes| {
119 bytes.copy_from_slice(&tmp_tags);
120 },
121 );
122 }
123
124 unsafe {
126 builder.write_with(4, 0, |_buffer_position, bytes| {
127 let len = (self.len() as u32).to_le_bytes().map(MaybeUninit::new);
128 bytes.copy_from_slice(&len);
129 });
130 }
131
132 let tags_offset = builder.current_offset();
133 crate::UnionVectorOffset {
134 tags_offset,
135 values_offset,
136 phantom: core::marker::PhantomData,
137 }
138 }
139}
140
141impl<T, P> WriteAsDefaultUnionVector<P> for [T]
142where
143 T: WriteAsUnion<P>,
144{
145 fn prepare(&self, builder: &mut Builder) -> Option<UnionVectorOffset<P>> {
146 if self.is_empty() {
147 None
148 } else {
149 Some(WriteAsUnionVector::prepare(self, builder))
150 }
151 }
152}
153
154impl<T, P> WriteAsOptionalUnionVector<P> for [T]
155where
156 T: WriteAsUnion<P>,
157{
158 #[inline]
159 fn prepare(&self, builder: &mut Builder) -> Option<UnionVectorOffset<P>> {
160 Some(WriteAsUnionVector::prepare(self, builder))
161 }
162}