polars_core/chunked_array/builder/list/
anonymous.rs1use super::*;
2
3pub struct AnonymousListBuilder<'a> {
4 name: PlSmallStr,
5 builder: AnonymousBuilder<'a>,
6 fast_explode: bool,
7 inner_dtype: DtypeMerger,
8}
9
10impl Default for AnonymousListBuilder<'_> {
11 fn default() -> Self {
12 Self::new(PlSmallStr::EMPTY, 0, None)
13 }
14}
15
16impl<'a> AnonymousListBuilder<'a> {
17 pub fn new(name: PlSmallStr, capacity: usize, inner_dtype: Option<DataType>) -> Self {
18 Self {
19 name,
20 builder: AnonymousBuilder::new(capacity),
21 fast_explode: true,
22 inner_dtype: DtypeMerger::new(inner_dtype),
23 }
24 }
25
26 pub fn append_opt_series(&mut self, opt_s: Option<&'a Series>) -> PolarsResult<()> {
27 match opt_s {
28 Some(s) => return self.append_series(s),
29 None => {
30 self.append_null();
31 },
32 }
33 Ok(())
34 }
35
36 pub fn append_opt_array(&mut self, opt_s: Option<&'a dyn Array>) {
37 match opt_s {
38 Some(s) => self.append_array(s),
39 None => {
40 self.append_null();
41 },
42 }
43 }
44
45 pub fn append_array(&mut self, arr: &'a dyn Array) {
46 self.builder.push(arr)
47 }
48
49 #[inline]
50 pub fn append_null(&mut self) {
51 self.fast_explode = false;
52 self.builder.push_null();
53 }
54
55 #[inline]
56 pub fn append_empty(&mut self) {
57 self.fast_explode = false;
58 self.builder.push_empty()
59 }
60
61 pub fn append_series(&mut self, s: &'a Series) -> PolarsResult<()> {
62 match s.dtype() {
63 DataType::Null if s.is_empty() => self.append_empty(),
66 dt => self.inner_dtype.update(dt)?,
67 }
68 self.builder.push_multiple(s.chunks());
69 Ok(())
70 }
71
72 pub fn finish(&mut self) -> ListChunked {
73 let slf = std::mem::take(self);
75 if slf.builder.is_empty() {
76 ListChunked::full_null_with_dtype(
77 slf.name.clone(),
78 0,
79 &slf.inner_dtype.materialize().unwrap_or(DataType::Null),
80 )
81 } else {
82 let inner_dtype = slf.inner_dtype.materialize();
83
84 let inner_dtype_physical = inner_dtype
85 .as_ref()
86 .map(|dt| dt.to_physical().to_arrow(CompatLevel::newest()));
87 let arr = slf.builder.finish(inner_dtype_physical.as_ref()).unwrap();
88
89 let list_dtype_logical = match inner_dtype {
90 None => DataType::from_arrow_dtype(arr.dtype()),
91 Some(dt) => DataType::List(Box::new(dt)),
92 };
93
94 let mut ca = ListChunked::with_chunk(PlSmallStr::EMPTY, arr);
95 if slf.fast_explode {
96 ca.set_fast_explode();
97 }
98 ca.field = Arc::new(Field::new(slf.name.clone(), list_dtype_logical));
99 ca
100 }
101 }
102}
103
104pub struct AnonymousOwnedListBuilder {
105 name: PlSmallStr,
106 builder: AnonymousBuilder<'static>,
107 owned: Vec<Series>,
108 inner_dtype: DtypeMerger,
109 fast_explode: bool,
110}
111
112impl Default for AnonymousOwnedListBuilder {
113 fn default() -> Self {
114 Self::new(PlSmallStr::EMPTY, 0, None)
115 }
116}
117
118impl ListBuilderTrait for AnonymousOwnedListBuilder {
119 fn append_series(&mut self, s: &Series) -> PolarsResult<()> {
120 if s.is_empty() {
121 self.append_empty();
122 } else {
123 unsafe {
124 self.inner_dtype.update(s.dtype())?;
125 self.builder
126 .push_multiple(&*(s.chunks().as_ref() as *const [ArrayRef]));
127 }
128 self.owned.push(s.clone());
130 }
131 Ok(())
132 }
133
134 #[inline]
135 fn append_null(&mut self) {
136 self.fast_explode = false;
137 self.builder.push_null()
138 }
139
140 fn finish(&mut self) -> ListChunked {
141 let inner_dtype = std::mem::take(&mut self.inner_dtype).materialize();
142 let slf = std::mem::take(self);
144 let inner_dtype_physical = inner_dtype
145 .as_ref()
146 .map(|dt| dt.to_physical().to_arrow(CompatLevel::newest()));
147 let arr = slf.builder.finish(inner_dtype_physical.as_ref()).unwrap();
148
149 let list_dtype_logical = match inner_dtype {
150 None => DataType::from_arrow_dtype(arr.dtype()),
151 Some(dt) => DataType::List(Box::new(dt)),
152 };
153
154 let mut ca = ListChunked::with_chunk(PlSmallStr::EMPTY, arr);
155 if slf.fast_explode {
156 ca.set_fast_explode();
157 }
158 ca.field = Arc::new(Field::new(slf.name.clone(), list_dtype_logical));
159 ca
160 }
161}
162
163impl AnonymousOwnedListBuilder {
164 pub fn new(name: PlSmallStr, capacity: usize, inner_dtype: Option<DataType>) -> Self {
165 Self {
166 name,
167 builder: AnonymousBuilder::new(capacity),
168 owned: Vec::with_capacity(capacity),
169 inner_dtype: DtypeMerger::new(inner_dtype),
170 fast_explode: true,
171 }
172 }
173
174 #[inline]
175 pub fn append_empty(&mut self) {
176 self.fast_explode = false;
177 self.builder.push_empty()
178 }
179}