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: Option<DataType>,
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,
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(), &self.inner_dtype) {
63 (DataType::Null, _) => {},
64 (dt, None) => self.inner_dtype = Some(dt.clone()),
65 (dt, Some(set_dt)) => {
66 polars_bail!(ComputeError: "dtypes don't match, got {dt}, expected: {set_dt}")
67 },
68 }
69 if s.is_empty() {
70 self.append_empty();
71 } else {
72 self.builder.push_multiple(s.chunks());
73 }
74 Ok(())
75 }
76
77 pub fn finish(&mut self) -> ListChunked {
78 let slf = std::mem::take(self);
80 if slf.builder.is_empty() {
81 ListChunked::full_null_with_dtype(
82 slf.name.clone(),
83 0,
84 &slf.inner_dtype.unwrap_or(DataType::Null),
85 )
86 } else {
87 let inner_dtype_physical = self
88 .inner_dtype
89 .as_ref()
90 .map(|dt| dt.to_physical().to_arrow(CompatLevel::newest()));
91 let arr = slf.builder.finish(inner_dtype_physical.as_ref()).unwrap();
92
93 let list_dtype_logical = match &self.inner_dtype {
94 None => DataType::from_arrow_dtype(arr.dtype()),
95 Some(dt) => DataType::List(Box::new(dt.clone())),
96 };
97
98 let mut ca = ListChunked::with_chunk(PlSmallStr::EMPTY, arr);
99 if slf.fast_explode {
100 ca.set_fast_explode();
101 }
102 ca.field = Arc::new(Field::new(slf.name, list_dtype_logical));
103 ca
104 }
105 }
106}
107
108pub struct AnonymousOwnedListBuilder {
109 name: PlSmallStr,
110 builder: AnonymousBuilder<'static>,
111 owned: Vec<Series>,
112 inner_dtype: Option<DataType>,
113 fast_explode: bool,
114}
115
116impl Default for AnonymousOwnedListBuilder {
117 fn default() -> Self {
118 Self::new(PlSmallStr::EMPTY, 0, None)
119 }
120}
121
122impl ListBuilderTrait for AnonymousOwnedListBuilder {
123 fn append_series(&mut self, s: &Series) -> PolarsResult<()> {
124 match (s.dtype(), &self.inner_dtype) {
125 (DataType::Null, _) => {},
126 (dt, None) => self.inner_dtype = Some(dt.clone()),
127 (dt, Some(set_dt)) => {
128 polars_ensure!(dt == set_dt, ComputeError: "dtypes don't match, got {dt}, expected: {set_dt}")
129 },
130 }
131 if s.is_empty() {
132 self.append_empty();
133 } else {
134 unsafe {
135 self.builder
136 .push_multiple(&*(s.chunks().as_ref() as *const [ArrayRef]));
137 }
138 self.owned.push(s.clone());
140 }
141 Ok(())
142 }
143
144 #[inline]
145 fn append_null(&mut self) {
146 self.fast_explode = false;
147 self.builder.push_null()
148 }
149
150 fn finish(&mut self) -> ListChunked {
151 let inner_dtype = std::mem::take(&mut self.inner_dtype);
152 let slf = std::mem::take(self);
154 let inner_dtype_physical = inner_dtype
155 .as_ref()
156 .map(|dt| dt.to_physical().to_arrow(CompatLevel::newest()));
157 let arr = slf.builder.finish(inner_dtype_physical.as_ref()).unwrap();
158
159 let list_dtype_logical = match inner_dtype {
160 None => DataType::from_arrow_dtype(arr.dtype()),
161 Some(dt) => DataType::List(Box::new(dt)),
162 };
163
164 let mut ca = ListChunked::with_chunk(PlSmallStr::EMPTY, arr);
165 if slf.fast_explode {
166 ca.set_fast_explode();
167 }
168 ca.field = Arc::new(Field::new(slf.name, list_dtype_logical));
169 ca
170 }
171}
172
173impl AnonymousOwnedListBuilder {
174 pub fn new(name: PlSmallStr, capacity: usize, inner_dtype: Option<DataType>) -> Self {
175 Self {
176 name,
177 builder: AnonymousBuilder::new(capacity),
178 owned: Vec::with_capacity(capacity),
179 inner_dtype,
180 fast_explode: true,
181 }
182 }
183
184 #[inline]
185 pub fn append_empty(&mut self) {
186 self.fast_explode = false;
187 self.builder.push_empty()
188 }
189}