Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-utils/src/enum_unit_vec.rs
6939 views
1
use 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)]
6
pub struct EnumUnitVec<T>(Either<[T; 1], Vec<T>>);
7
8
impl<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
18
impl<T> Default for EnumUnitVec<T> {
19
fn default() -> Self {
20
Self::new()
21
}
22
}
23
24
impl<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
32
impl<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
38
impl<T> From<Vec<T>> for EnumUnitVec<T> {
39
fn from(value: Vec<T>) -> Self {
40
Self(Either::Right(value))
41
}
42
}
43
44
impl<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
56
impl<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
}
75
76