1use core::fmt::{Debug, Formatter, Result};
18use core::iter::{DoubleEndedIterator, ExactSizeIterator, FusedIterator};
19use core::marker::PhantomData;
20use core::mem::{align_of, size_of};
21use core::str::from_utf8_unchecked;
22
23use crate::endian_scalar::read_scalar_at;
24use crate::follow::Follow;
25use crate::primitives::*;
26
27pub struct Vector<'a, T: 'a>(&'a [u8], usize, PhantomData<T>);
28
29impl<'a, T: 'a> Default for Vector<'a, T> {
30 fn default() -> Self {
31 Self(
34 &[0; core::mem::size_of::<UOffsetT>()],
35 0,
36 Default::default(),
37 )
38 }
39}
40
41impl<'a, T> Debug for Vector<'a, T>
42where
43 T: 'a + Follow<'a>,
44 <T as Follow<'a>>::Inner: Debug,
45{
46 fn fmt(&self, f: &mut Formatter) -> Result {
47 f.debug_list().entries(self.iter()).finish()
48 }
49}
50
51impl<'a, T> Copy for Vector<'a, T> {}
55
56impl<'a, T> Clone for Vector<'a, T> {
57 fn clone(&self) -> Self {
58 *self
59 }
60}
61
62impl<'a, T: 'a> Vector<'a, T> {
63 #[inline(always)]
70 pub unsafe fn new(buf: &'a [u8], loc: usize) -> Self {
71 Vector(buf, loc, PhantomData)
72 }
73
74 #[inline(always)]
75 pub fn len(&self) -> usize {
76 unsafe { read_scalar_at::<UOffsetT>(self.0, self.1) as usize }
79 }
80
81 #[inline(always)]
82 pub fn is_empty(&self) -> bool {
83 self.len() == 0
84 }
85
86 #[inline(always)]
87 pub fn bytes(&self) -> &'a [u8] {
88 let sz = size_of::<T>();
89 let len = self.len();
90 &self.0[self.1 + SIZE_UOFFSET..self.1 + SIZE_UOFFSET + sz * len]
91 }
92}
93
94impl<'a, T: Follow<'a> + 'a> Vector<'a, T> {
95 #[inline(always)]
96 pub fn get(&self, idx: usize) -> T::Inner {
97 assert!(idx < self.len());
98 let sz = size_of::<T>();
99 debug_assert!(sz > 0);
100 unsafe { T::follow(self.0, self.1 as usize + SIZE_UOFFSET + sz * idx) }
103 }
104
105 #[inline(always)]
106 pub fn iter(&self) -> VectorIter<'a, T> {
107 VectorIter::from_vector(*self)
108 }
109}
110
111pub unsafe fn follow_cast_ref<'a, T: Sized + 'a>(buf: &'a [u8], loc: usize) -> &'a T {
115 assert_eq!(align_of::<T>(), 1);
116 let sz = size_of::<T>();
117 let buf = &buf[loc..loc + sz];
118 let ptr = buf.as_ptr() as *const T;
119 &*ptr
122}
123
124impl<'a> Follow<'a> for &'a str {
125 type Inner = &'a str;
126 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
127 let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
128 let slice = &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len];
129 from_utf8_unchecked(slice)
130 }
131}
132
133impl<'a> Follow<'a> for &'a [u8] {
134 type Inner = &'a [u8];
135 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
136 let len = read_scalar_at::<UOffsetT>(buf, loc) as usize;
137 &buf[loc + SIZE_UOFFSET..loc + SIZE_UOFFSET + len]
138 }
139}
140
141impl<'a, T: Follow<'a> + 'a> Follow<'a> for Vector<'a, T> {
143 type Inner = Vector<'a, T>;
144 unsafe fn follow(buf: &'a [u8], loc: usize) -> Self::Inner {
145 Vector::new(buf, loc)
146 }
147}
148
149#[derive(Debug)]
151pub struct VectorIter<'a, T: 'a> {
152 buf: &'a [u8],
153 loc: usize,
154 remaining: usize,
155 phantom: PhantomData<T>,
156}
157
158impl<'a, T: 'a> VectorIter<'a, T> {
159 #[inline]
160 pub fn from_vector(inner: Vector<'a, T>) -> Self {
161 VectorIter {
162 buf: inner.0,
163 loc: inner.1 + SIZE_UOFFSET,
167 remaining: inner.len(),
168 phantom: PhantomData,
169 }
170 }
171
172 #[inline]
179 pub unsafe fn from_slice(buf: &'a [u8], items_num: usize) -> Self {
180 VectorIter {
181 buf,
182 loc: 0,
183 remaining: items_num,
184 phantom: PhantomData,
185 }
186 }
187}
188
189impl<'a, T: Follow<'a> + 'a> Clone for VectorIter<'a, T> {
190 #[inline]
191 fn clone(&self) -> Self {
192 VectorIter {
193 buf: self.buf,
194 loc: self.loc,
195 remaining: self.remaining,
196 phantom: self.phantom,
197 }
198 }
199}
200
201impl<'a, T: Follow<'a> + 'a> Iterator for VectorIter<'a, T> {
202 type Item = T::Inner;
203
204 #[inline]
205 fn next(&mut self) -> Option<T::Inner> {
206 let sz = size_of::<T>();
207 debug_assert!(sz > 0);
208
209 if self.remaining == 0 {
210 None
211 } else {
212 let result = unsafe { T::follow(self.buf, self.loc) };
216 self.loc += sz;
217 self.remaining -= 1;
218 Some(result)
219 }
220 }
221
222 #[inline]
223 fn nth(&mut self, n: usize) -> Option<T::Inner> {
224 let sz = size_of::<T>();
225 debug_assert!(sz > 0);
226
227 self.remaining = self.remaining.saturating_sub(n);
228
229 self.loc = self.loc.wrapping_add(sz * n);
232
233 self.next()
234 }
235
236 #[inline]
237 fn size_hint(&self) -> (usize, Option<usize>) {
238 (self.remaining, Some(self.remaining))
239 }
240}
241
242impl<'a, T: Follow<'a> + 'a> DoubleEndedIterator for VectorIter<'a, T> {
243 #[inline]
244 fn next_back(&mut self) -> Option<T::Inner> {
245 let sz = size_of::<T>();
246 debug_assert!(sz > 0);
247
248 if self.remaining == 0 {
249 None
250 } else {
251 self.remaining -= 1;
252 Some(unsafe { T::follow(self.buf, self.loc + sz * self.remaining) })
256 }
257 }
258
259 #[inline]
260 fn nth_back(&mut self, n: usize) -> Option<T::Inner> {
261 self.remaining = self.remaining.saturating_sub(n);
262 self.next_back()
263 }
264}
265
266impl<'a, T: 'a + Follow<'a>> ExactSizeIterator for VectorIter<'a, T> {
267 #[inline]
268 fn len(&self) -> usize {
269 self.remaining
270 }
271}
272
273impl<'a, T: 'a + Follow<'a>> FusedIterator for VectorIter<'a, T> {}
274
275impl<'a, T: Follow<'a> + 'a> IntoIterator for Vector<'a, T> {
276 type Item = T::Inner;
277 type IntoIter = VectorIter<'a, T>;
278 #[inline]
279 fn into_iter(self) -> Self::IntoIter {
280 self.iter()
281 }
282}
283
284impl<'a, 'b, T: Follow<'a> + 'a> IntoIterator for &'b Vector<'a, T> {
285 type Item = T::Inner;
286 type IntoIter = VectorIter<'a, T>;
287 fn into_iter(self) -> Self::IntoIter {
288 self.iter()
289 }
290}
291
292#[cfg(feature = "serialize")]
293impl<'a, T> serde::ser::Serialize for Vector<'a, T>
294where
295 T: 'a + Follow<'a>,
296 <T as Follow<'a>>::Inner: serde::ser::Serialize,
297{
298 fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
299 where
300 S: serde::ser::Serializer,
301 {
302 use serde::ser::SerializeSeq;
303 let mut seq = serializer.serialize_seq(Some(self.len()))?;
304 for element in self {
305 seq.serialize_element(&element)?;
306 }
307 seq.end()
308 }
309}