1use core::{marker::PhantomData, num::NonZeroUsize};
2
3use crate::{
4 errors::{self, ErrorKind},
5 impls::array_from_buffer,
6 slice_helpers::SliceWithStartOffset,
7 traits::VectorRead,
8 TableRead,
9};
10
11pub struct Vector<'buf, T: ?Sized> {
13 buffer: SliceWithStartOffset<'buf>,
14 len: usize,
15 _marker: PhantomData<&'buf T>,
16}
17
18impl<T: ?Sized> Copy for Vector<'_, T> {}
19impl<T: ?Sized> Clone for Vector<'_, T> {
20 #[inline]
21 fn clone(&self) -> Self {
22 *self
23 }
24}
25
26impl<'buf, T: ?Sized> Vector<'buf, T> {
27 #[inline]
32 #[must_use]
33 pub const fn new_empty() -> Vector<'buf, T> {
34 Self {
35 buffer: SliceWithStartOffset {
36 buffer: &[],
37 offset_from_start: 0,
38 },
39 len: 0,
40 _marker: PhantomData,
41 }
42 }
43
44 #[inline]
46 #[must_use]
47 pub fn is_empty(self) -> bool {
48 self.len == 0
49 }
50
51 #[inline]
53 #[must_use]
54 pub fn len(self) -> usize {
55 self.len
56 }
57}
58
59impl<'buf, T: VectorRead<'buf>> Vector<'buf, T> {
60 #[inline]
62 #[must_use]
63 pub fn first(self) -> Option<T> {
64 self.get(0)
65 }
66
67 #[inline]
69 #[must_use]
70 pub fn last(self) -> Option<T> {
71 self.get(self.len().checked_sub(1)?)
72 }
73
74 #[inline]
82 #[must_use]
83 pub fn get<I>(self, index: I) -> Option<I::Output>
84 where
85 I: VectorIndex<'buf, T>,
86 {
87 index.get(self)
88 }
89
90 #[inline]
102 #[must_use]
103 pub unsafe fn get_unchecked<I>(self, index: I) -> I::Output
104 where
105 I: VectorIndex<'buf, T>,
106 {
107 index.get_unchecked(self)
108 }
109
110 #[inline]
112 #[must_use]
113 pub fn iter(self) -> super::Iter<'buf, T> {
114 super::Iter::new(self)
115 }
116
117 #[inline]
134 #[must_use]
135 pub fn chunks(self, chunk_size: usize) -> super::Chunks<'buf, T> {
136 let chunk_size = NonZeroUsize::new(chunk_size).expect("chunks cannot have a size of zero");
137 super::Chunks::new(self, chunk_size)
138 }
139
140 #[inline]
157 #[must_use]
158 pub fn rchunks(self, chunk_size: usize) -> super::RChunks<'buf, T> {
159 let chunk_size = NonZeroUsize::new(chunk_size).expect("chunks cannot have a size of zero");
160 super::RChunks::new(self, chunk_size)
161 }
162
163 #[inline]
183 #[must_use]
184 pub fn chunks_exact(self, chunk_size: usize) -> super::ChunksExact<'buf, T> {
185 let chunk_size = NonZeroUsize::new(chunk_size).expect("chunks cannot have a size of zero");
186 super::ChunksExact::new(self, chunk_size)
187 }
188
189 #[inline]
210 #[must_use]
211 pub fn rchunks_exact(self, chunk_size: usize) -> super::RChunksExact<'buf, T> {
212 let chunk_size = NonZeroUsize::new(chunk_size).expect("chunks cannot have a size of zero");
213 super::RChunksExact::new(self, chunk_size)
214 }
215
216 #[inline]
224 #[must_use]
225 pub fn windows(self, size: usize) -> super::Windows<'buf, T> {
226 let size = NonZeroUsize::new(size).expect("windows cannot have a size of zero");
227 super::Windows::new(self, size)
228 }
229
230 #[inline]
232 #[must_use]
233 pub fn split_first(self) -> Option<(T, Vector<'buf, T>)> {
234 if self.is_empty() {
235 None
236 } else {
237 Some(unsafe { (self.get_unchecked(0), self.get_unchecked(1..)) })
238 }
239 }
240
241 #[inline]
243 #[must_use]
244 pub fn split_last(self) -> Option<(T, Vector<'buf, T>)> {
245 if self.is_empty() {
246 None
247 } else {
248 Some(unsafe {
249 (
250 self.get_unchecked(self.len - 1),
251 self.get_unchecked(..self.len - 1),
252 )
253 })
254 }
255 }
256
257 #[inline]
263 #[must_use]
264 pub fn split_at(self, mid: usize) -> Option<(Vector<'buf, T>, Vector<'buf, T>)> {
265 if mid <= self.len {
266 Some(unsafe { self.split_at_unchecked(mid) })
267 } else {
268 None
269 }
270 }
271
272 #[inline]
289 #[must_use]
290 pub unsafe fn split_at_unchecked(self, mid: usize) -> (Vector<'buf, T>, Vector<'buf, T>) {
291 (self.get_unchecked(..mid), self.get_unchecked(mid..))
292 }
293}
294
295impl<'buf, T: VectorRead<'buf>> Vector<'buf, T> {
296 pub fn to_vec<O>(self) -> crate::Result<alloc::vec::Vec<O>>
298 where
299 O: core::convert::TryFrom<T>,
300 crate::errors::Error: From<O::Error>,
301 {
302 self.iter()
303 .map(|v| O::try_from(v).map_err(crate::errors::Error::from))
304 .collect()
305 }
306}
307
308impl<'buf, T, E> Vector<'buf, core::result::Result<T, E>> {
309 pub fn to_vec_result<O>(self) -> crate::Result<alloc::vec::Vec<O>>
311 where
312 T: crate::traits::VectorReadInner<'buf>,
313 E: core::convert::From<T::Error>,
314 O: core::convert::TryFrom<T>,
315 crate::errors::Error: From<E> + From<O::Error>,
316 {
317 self.iter()
318 .map(|v| O::try_from(v?).map_err(|e| e.into()))
319 .collect()
320 }
321}
322
323impl<'buf, T: VectorRead<'buf>> IntoIterator for Vector<'buf, T> {
324 type Item = T;
325 type IntoIter = super::Iter<'buf, T>;
326
327 #[inline]
328 fn into_iter(self) -> Self::IntoIter {
329 self.iter()
330 }
331}
332
333impl<'buf, T: VectorRead<'buf> + core::fmt::Debug> core::fmt::Debug for Vector<'buf, T>
334where
335 T: core::fmt::Debug,
336{
337 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
338 f.debug_list().entries(*self).finish()
339 }
340}
341
342pub trait VectorIndex<'buf, T: VectorRead<'buf>>: private::Sealed {
344 type Output;
346
347 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output>;
349
350 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output;
357}
358
359fn into_range_unchecked(
361 len: usize,
362 (start, end): (core::ops::Bound<usize>, core::ops::Bound<usize>),
363) -> core::ops::Range<usize> {
364 use core::ops::Bound;
365 let start = match start {
366 Bound::Included(i) => i,
367 Bound::Excluded(i) => i + 1,
368 Bound::Unbounded => 0,
369 };
370 let end = match end {
371 Bound::Included(i) => i + 1,
372 Bound::Excluded(i) => i,
373 Bound::Unbounded => len,
374 };
375 start..end
376}
377
378fn into_range(
381 len: usize,
382 (start, end): (core::ops::Bound<usize>, core::ops::Bound<usize>),
383) -> Option<core::ops::Range<usize>> {
384 use core::ops::Bound;
385 let start = match start {
386 Bound::Included(start) => start,
387 Bound::Excluded(start) => start.checked_add(1)?,
388 Bound::Unbounded => 0,
389 };
390
391 let end = match end {
392 Bound::Included(end) => end.checked_add(1)?,
393 Bound::Excluded(end) => end,
394 Bound::Unbounded => len,
395 };
396
397 Some(start..end)
401}
402impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T>
403 for (core::ops::Bound<usize>, core::ops::Bound<usize>)
404{
405 type Output = Vector<'buf, T>;
406
407 #[inline]
408 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
409 into_range(vector.len, self)?.get(vector)
410 }
411
412 #[inline]
413 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
414 into_range_unchecked(vector.len, self).get_unchecked(vector)
415 }
416}
417
418impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for usize {
419 type Output = T;
420
421 #[inline]
422 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
423 if self < vector.len {
424 Some(unsafe { self.get_unchecked(vector) })
425 } else {
426 None
427 }
428 }
429
430 #[inline]
431 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
432 debug_assert!(self < vector.len);
433 debug_assert!(vector.len.checked_mul(T::STRIDE).unwrap() <= vector.buffer.len());
434 T::from_buffer(vector.buffer, T::STRIDE * self)
435 }
436}
437
438impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for core::ops::Range<usize> {
439 type Output = Vector<'buf, T>;
440
441 #[inline]
442 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
443 if self.start > self.end || self.end > vector.len {
444 None
445 } else {
446 unsafe { Some(self.get_unchecked(vector)) }
448 }
449 }
450
451 #[inline]
452 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
453 debug_assert!(self.start <= self.end);
454 debug_assert!(self.end <= vector.len);
455 Vector {
456 buffer: vector
457 .buffer
458 .advance(T::STRIDE * self.start)
459 .expect("IMPOSSIBLE: the length was checked on creation"),
460 len: self.end - self.start,
461 _marker: PhantomData,
462 }
463 }
464}
465
466impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for core::ops::RangeFrom<usize> {
467 type Output = Vector<'buf, T>;
468
469 #[inline]
470 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
471 (self.start..vector.len).get(vector)
472 }
473
474 #[inline]
475 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
476 (self.start..vector.len).get_unchecked(vector)
477 }
478}
479
480impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for core::ops::RangeFull {
481 type Output = Vector<'buf, T>;
482
483 #[inline]
484 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
485 Some(vector)
486 }
487
488 #[inline]
489 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
490 vector
491 }
492}
493
494impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for core::ops::RangeInclusive<usize> {
495 type Output = Vector<'buf, T>;
496
497 #[inline]
498 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
499 (*self.start()..self.end().checked_add(1)?).get(vector)
500 }
501
502 #[inline]
503 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
504 (*self.start()..self.end() + 1).get_unchecked(vector)
505 }
506}
507
508impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for core::ops::RangeTo<usize> {
509 type Output = Vector<'buf, T>;
510
511 #[inline]
512 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
513 (0..self.end).get(vector)
514 }
515
516 #[inline]
517 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
518 (0..self.end).get_unchecked(vector)
519 }
520}
521
522impl<'buf, T: VectorRead<'buf>> VectorIndex<'buf, T> for core::ops::RangeToInclusive<usize> {
523 type Output = Vector<'buf, T>;
524
525 #[inline]
526 fn get(self, vector: Vector<'buf, T>) -> Option<Self::Output> {
527 (0..=self.end).get(vector)
528 }
529
530 #[inline]
531 unsafe fn get_unchecked(self, vector: Vector<'buf, T>) -> Self::Output {
532 (0..=self.end).get_unchecked(vector)
533 }
534}
535
536impl<'buf, T: VectorRead<'buf>, O> TryFrom<Vector<'buf, T>> for alloc::vec::Vec<O>
537where
538 O: core::convert::TryFrom<T>,
539 errors::Error: From<O::Error>,
540{
541 type Error = crate::errors::Error;
542
543 fn try_from(value: Vector<'buf, T>) -> Result<Self, Self::Error> {
544 value
545 .iter()
546 .map(|v| O::try_from(v).map_err(errors::Error::from))
547 .collect()
548 }
549}
550
551impl<'buf, T: ?Sized + VectorRead<'buf>> TableRead<'buf> for Vector<'buf, T> {
552 fn from_buffer(
553 buffer: SliceWithStartOffset<'buf>,
554 offset: usize,
555 ) -> core::result::Result<Self, ErrorKind> {
556 let (buffer, len) = array_from_buffer(buffer, offset)?;
557 if len.checked_mul(T::STRIDE).ok_or(ErrorKind::InvalidLength)? <= buffer.len() {
558 Ok(Vector {
559 buffer,
560 len,
561 _marker: PhantomData,
562 })
563 } else {
564 Err(ErrorKind::InvalidLength)
565 }
566 }
567}
568
569mod private {
570 pub trait Sealed {}
571
572 impl Sealed for (core::ops::Bound<usize>, core::ops::Bound<usize>) {}
574 impl Sealed for usize {}
575 impl Sealed for core::ops::Range<usize> {}
576 impl Sealed for core::ops::RangeFrom<usize> {}
577 impl Sealed for core::ops::RangeFull {}
578 impl Sealed for core::ops::RangeInclusive<usize> {}
579 impl Sealed for core::ops::RangeTo<usize> {}
580 impl Sealed for core::ops::RangeToInclusive<usize> {}
581}