flatbuffers/
array.rs
1use crate::follow::Follow;
18use crate::vector::VectorIter;
19use crate::EndianScalar;
20use core::fmt::{Debug, Formatter, Result};
21use core::marker::PhantomData;
22use core::mem::size_of;
23
24#[derive(Copy, Clone)]
25pub struct Array<'a, T: 'a, const N: usize>(&'a [u8], PhantomData<T>);
26
27impl<'a, T: 'a, const N: usize> Debug for Array<'a, T, N>
28where
29 T: 'a + Follow<'a>,
30 <T as Follow<'a>>::Inner: Debug,
31{
32 fn fmt(&self, f: &mut Formatter) -> Result {
33 f.debug_list().entries(self.iter()).finish()
34 }
35}
36
37#[allow(clippy::len_without_is_empty)]
38#[allow(clippy::from_over_into)] impl<'a, T: 'a, const N: usize> Array<'a, T, N> {
40 #[inline(always)]
48 pub unsafe fn new(buf: &'a [u8]) -> Self {
49 assert_eq!(size_of::<T>() * N, buf.len());
50
51 Array(buf, PhantomData)
52 }
53
54 #[inline(always)]
55 pub const fn len(&self) -> usize {
56 N
57 }
58 pub fn as_ptr(&self) -> *const u8 {
59 self.0.as_ptr()
60 }
61}
62
63impl<'a, T: Follow<'a> + 'a, const N: usize> Array<'a, T, N> {
64 #[inline(always)]
65 pub fn get(&self, idx: usize) -> T::Inner {
66 assert!(idx < N);
67 let sz = size_of::<T>();
68 unsafe { T::follow(self.0, sz * idx) }
71 }
72
73 #[inline(always)]
74 pub fn iter(&self) -> VectorIter<'a, T> {
75 unsafe { VectorIter::from_slice(self.0, self.len()) }
78 }
79}
80
81impl<'a, T: Follow<'a> + Debug, const N: usize> From<Array<'a, T, N>> for [T::Inner; N] {
82 fn from(array: Array<'a, T, N>) -> Self {
83 array_init(|i| array.get(i))
84 }
85}
86
87impl<'a, T: Follow<'a> + 'a, const N: usize> Follow<'a> for Array<'a, T, N> {
89 type Inner = Array<'a, T, N>;
90 #[inline(always)]
91 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
92 Array::new(&buf[loc..loc + N * size_of::<T>()])
93 }
94}
95
96pub unsafe fn emplace_scalar_array<T: EndianScalar, const N: usize>(
101 buf: &mut [u8],
102 loc: usize,
103 src: &[T; N],
104) {
105 let mut buf_ptr = buf[loc..].as_mut_ptr();
106 for item in src.iter() {
107 let item_le = item.to_little_endian();
108 core::ptr::copy_nonoverlapping(
109 &item_le as *const T::Scalar as *const u8,
110 buf_ptr,
111 size_of::<T::Scalar>(),
112 );
113 buf_ptr = buf_ptr.add(size_of::<T::Scalar>());
114 }
115}
116
117impl<'a, T: Follow<'a> + 'a, const N: usize> IntoIterator for Array<'a, T, N> {
118 type Item = T::Inner;
119 type IntoIter = VectorIter<'a, T>;
120 #[inline]
121 fn into_iter(self) -> Self::IntoIter {
122 self.iter()
123 }
124}
125
126#[inline]
127pub fn array_init<F, T, const N: usize>(mut initializer: F) -> [T; N]
128where
129 F: FnMut(usize) -> T,
130{
131 let mut array: core::mem::MaybeUninit<[T; N]> = core::mem::MaybeUninit::uninit();
132 let mut ptr_i = array.as_mut_ptr() as *mut T;
133
134 unsafe {
137 for i in 0..N {
138 let value_i = initializer(i);
139 ptr_i.write(value_i);
140 ptr_i = ptr_i.add(1);
141 }
142 array.assume_init()
143 }
144}
145
146#[cfg(feature = "serialize")]
147impl<'a, T: 'a, const N: usize> serde::ser::Serialize for Array<'a, T, N>
148where
149 T: 'a + Follow<'a>,
150 <T as Follow<'a>>::Inner: serde::ser::Serialize,
151{
152 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
153 where
154 S: serde::ser::Serializer,
155 {
156 use serde::ser::SerializeSeq;
157 let mut seq = serializer.serialize_seq(Some(self.len()))?;
158 for element in self.iter() {
159 seq.serialize_element(&element)?;
160 }
161 seq.end()
162 }
163}