polars_utils/
enum_unit_vec.rs

1use either::Either;
2
3/// List of items where a single item is stored on the stack.
4/// Similar to UnitVec, but without size / alignment limitations.
5#[derive(Debug, Clone)]
6pub struct EnumUnitVec<T>(Either<[T; 1], Vec<T>>);
7
8impl<T> EnumUnitVec<T> {
9    pub const fn new() -> Self {
10        Self(Either::Right(Vec::new()))
11    }
12
13    pub const fn new_single(value: T) -> Self {
14        Self(Either::Left([value]))
15    }
16}
17
18impl<T> Default for EnumUnitVec<T> {
19    fn default() -> Self {
20        Self::new()
21    }
22}
23
24impl<T> std::ops::Deref for EnumUnitVec<T> {
25    type Target = [T];
26
27    fn deref(&self) -> &Self::Target {
28        AsRef::as_ref(&self.0)
29    }
30}
31
32impl<T> std::ops::DerefMut for EnumUnitVec<T> {
33    fn deref_mut(&mut self) -> &mut Self::Target {
34        AsMut::as_mut(&mut self.0)
35    }
36}
37
38impl<T> From<Vec<T>> for EnumUnitVec<T> {
39    fn from(value: Vec<T>) -> Self {
40        Self(Either::Right(value))
41    }
42}
43
44impl<T> IntoIterator for EnumUnitVec<T> {
45    type IntoIter = Either<<[T; 1] as IntoIterator>::IntoIter, <Vec<T> as IntoIterator>::IntoIter>;
46    type Item = T;
47
48    fn into_iter(self) -> Self::IntoIter {
49        match self.0 {
50            Either::Left(v) => Either::Left(v.into_iter()),
51            Either::Right(v) => Either::Right(v.into_iter()),
52        }
53    }
54}
55
56impl<T> FromIterator<T> for EnumUnitVec<T> {
57    fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
58        let mut iter = iter.into_iter();
59
60        let Some(first) = iter.next() else {
61            return Self::new();
62        };
63
64        let Some(second) = iter.next() else {
65            return Self::new_single(first);
66        };
67
68        let mut vec = Vec::with_capacity(iter.size_hint().0 + 2);
69        vec.push(first);
70        vec.push(second);
71        vec.extend(iter);
72        Self::from(vec)
73    }
74}