1use std::hint::unreachable_unchecked;
2
3use arrow::bitmap::BitmapBuilder;
4#[cfg(feature = "dtype-struct")]
5use polars_utils::pl_str::PlSmallStr;
6
7use super::*;
8use crate::chunked_array::builder::NullChunkedBuilder;
9#[cfg(feature = "dtype-struct")]
10use crate::prelude::any_value::arr_to_any_value;
11
12#[derive(Clone)]
13pub enum AnyValueBuffer<'a> {
14 Boolean(BooleanChunkedBuilder),
15 #[cfg(feature = "dtype-i8")]
16 Int8(PrimitiveChunkedBuilder<Int8Type>),
17 #[cfg(feature = "dtype-i16")]
18 Int16(PrimitiveChunkedBuilder<Int16Type>),
19 Int32(PrimitiveChunkedBuilder<Int32Type>),
20 Int64(PrimitiveChunkedBuilder<Int64Type>),
21 #[cfg(feature = "dtype-u8")]
22 UInt8(PrimitiveChunkedBuilder<UInt8Type>),
23 #[cfg(feature = "dtype-u16")]
24 UInt16(PrimitiveChunkedBuilder<UInt16Type>),
25 UInt32(PrimitiveChunkedBuilder<UInt32Type>),
26 UInt64(PrimitiveChunkedBuilder<UInt64Type>),
27 #[cfg(feature = "dtype-date")]
28 Date(PrimitiveChunkedBuilder<Int32Type>),
29 #[cfg(feature = "dtype-datetime")]
30 Datetime(
31 PrimitiveChunkedBuilder<Int64Type>,
32 TimeUnit,
33 Option<TimeZone>,
34 ),
35 #[cfg(feature = "dtype-duration")]
36 Duration(PrimitiveChunkedBuilder<Int64Type>, TimeUnit),
37 #[cfg(feature = "dtype-time")]
38 Time(PrimitiveChunkedBuilder<Int64Type>),
39 Float32(PrimitiveChunkedBuilder<Float32Type>),
40 Float64(PrimitiveChunkedBuilder<Float64Type>),
41 String(StringChunkedBuilder),
42 Null(NullChunkedBuilder),
43 All(DataType, Vec<AnyValue<'a>>),
44}
45
46impl<'a> AnyValueBuffer<'a> {
47 #[inline]
48 pub fn add(&mut self, val: AnyValue<'a>) -> Option<()> {
49 use AnyValueBuffer::*;
50 match (self, val) {
51 (Boolean(builder), AnyValue::Null) => builder.append_null(),
52 (Boolean(builder), AnyValue::Boolean(v)) => builder.append_value(v),
53 (Boolean(builder), val) => {
54 let v = val.extract::<u8>()?;
55 builder.append_value(v == 1)
56 },
57 (Int32(builder), AnyValue::Null) => builder.append_null(),
58 (Int32(builder), val) => builder.append_value(val.extract()?),
59 (Int64(builder), AnyValue::Null) => builder.append_null(),
60 (Int64(builder), val) => builder.append_value(val.extract()?),
61 (UInt32(builder), AnyValue::Null) => builder.append_null(),
62 (UInt32(builder), val) => builder.append_value(val.extract()?),
63 (UInt64(builder), AnyValue::Null) => builder.append_null(),
64 (UInt64(builder), val) => builder.append_value(val.extract()?),
65 (Float32(builder), AnyValue::Null) => builder.append_null(),
66 (Float64(builder), AnyValue::Null) => builder.append_null(),
67 (Float32(builder), val) => builder.append_value(val.extract()?),
68 (Float64(builder), val) => builder.append_value(val.extract()?),
69 (String(builder), AnyValue::String(v)) => builder.append_value(v),
70 (String(builder), AnyValue::StringOwned(v)) => builder.append_value(v.as_str()),
71 (String(builder), AnyValue::Null) => builder.append_null(),
72 #[cfg(feature = "dtype-i8")]
73 (Int8(builder), AnyValue::Null) => builder.append_null(),
74 #[cfg(feature = "dtype-i8")]
75 (Int8(builder), val) => builder.append_value(val.extract()?),
76 #[cfg(feature = "dtype-i16")]
77 (Int16(builder), AnyValue::Null) => builder.append_null(),
78 #[cfg(feature = "dtype-i16")]
79 (Int16(builder), val) => builder.append_value(val.extract()?),
80 #[cfg(feature = "dtype-u8")]
81 (UInt8(builder), AnyValue::Null) => builder.append_null(),
82 #[cfg(feature = "dtype-u8")]
83 (UInt8(builder), val) => builder.append_value(val.extract()?),
84 #[cfg(feature = "dtype-u16")]
85 (UInt16(builder), AnyValue::Null) => builder.append_null(),
86 #[cfg(feature = "dtype-u16")]
87 (UInt16(builder), val) => builder.append_value(val.extract()?),
88 #[cfg(feature = "dtype-date")]
89 (Date(builder), AnyValue::Null) => builder.append_null(),
90 #[cfg(feature = "dtype-date")]
91 (Date(builder), AnyValue::Date(v)) => builder.append_value(v),
92 #[cfg(feature = "dtype-date")]
93 (Date(builder), val) if val.is_primitive_numeric() => {
94 builder.append_value(val.extract()?)
95 },
96 #[cfg(feature = "dtype-datetime")]
97 (Datetime(builder, _, _), AnyValue::Null) => builder.append_null(),
98 #[cfg(feature = "dtype-datetime")]
99 (
100 Datetime(builder, tu_l, _),
101 AnyValue::Datetime(v, tu_r, _) | AnyValue::DatetimeOwned(v, tu_r, _),
102 ) => {
103 let v = convert_time_units(v, tu_r, *tu_l);
106 builder.append_value(v)
107 },
108 #[cfg(feature = "dtype-datetime")]
109 (Datetime(builder, _, _), val) if val.is_primitive_numeric() => {
110 builder.append_value(val.extract()?)
111 },
112 #[cfg(feature = "dtype-duration")]
113 (Duration(builder, _), AnyValue::Null) => builder.append_null(),
114 #[cfg(feature = "dtype-duration")]
115 (Duration(builder, tu_l), AnyValue::Duration(v, tu_r)) => {
116 let v = convert_time_units(v, tu_r, *tu_l);
117 builder.append_value(v)
118 },
119 #[cfg(feature = "dtype-duration")]
120 (Duration(builder, _), val) if val.is_primitive_numeric() => {
121 builder.append_value(val.extract()?)
122 },
123 #[cfg(feature = "dtype-time")]
124 (Time(builder), AnyValue::Time(v)) => builder.append_value(v),
125 #[cfg(feature = "dtype-time")]
126 (Time(builder), AnyValue::Null) => builder.append_null(),
127 #[cfg(feature = "dtype-time")]
128 (Time(builder), val) if val.is_primitive_numeric() => {
129 builder.append_value(val.extract()?)
130 },
131 (Null(builder), AnyValue::Null) => builder.append_null(),
132 (All(_, vals), v) => vals.push(v.into_static()),
134
135 (String(builder), av) => match av {
137 AnyValue::Int64(v) => builder.append_value(format!("{v}")),
138 AnyValue::Float64(v) => builder.append_value(format!("{v}")),
139 AnyValue::Boolean(true) => builder.append_value("true"),
140 AnyValue::Boolean(false) => builder.append_value("false"),
141 _ => return None,
142 },
143 _ => return None,
144 };
145 Some(())
146 }
147
148 pub(crate) fn add_fallible(&mut self, val: &AnyValue<'a>) -> PolarsResult<()> {
149 self.add(val.clone()).ok_or_else(|| {
150 polars_err!(
151 ComputeError: "could not append value: {} of type: {} to the builder; make sure that all rows \
152 have the same schema or consider increasing `infer_schema_length`\n\
153 \n\
154 it might also be that a value overflows the data-type's capacity", val, val.dtype()
155 )
156 })
157 }
158
159 pub fn reset(&mut self, capacity: usize, strict: bool) -> PolarsResult<Series> {
160 use AnyValueBuffer::*;
161 let out = match self {
162 Boolean(b) => {
163 let mut new = BooleanChunkedBuilder::new(b.field.name().clone(), capacity);
164 std::mem::swap(&mut new, b);
165 new.finish().into_series()
166 },
167 Int32(b) => {
168 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
169 std::mem::swap(&mut new, b);
170 new.finish().into_series()
171 },
172 Int64(b) => {
173 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
174 std::mem::swap(&mut new, b);
175 new.finish().into_series()
176 },
177 UInt32(b) => {
178 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
179 std::mem::swap(&mut new, b);
180 new.finish().into_series()
181 },
182 UInt64(b) => {
183 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
184 std::mem::swap(&mut new, b);
185 new.finish().into_series()
186 },
187 #[cfg(feature = "dtype-date")]
188 Date(b) => {
189 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
190 std::mem::swap(&mut new, b);
191 new.finish().into_date().into_series()
192 },
193 #[cfg(feature = "dtype-datetime")]
194 Datetime(b, tu, tz) => {
195 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
196 std::mem::swap(&mut new, b);
197 let tz = if capacity > 0 {
198 tz.clone()
199 } else {
200 std::mem::take(tz)
201 };
202 new.finish().into_datetime(*tu, tz).into_series()
203 },
204 #[cfg(feature = "dtype-duration")]
205 Duration(b, tu) => {
206 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
207 std::mem::swap(&mut new, b);
208 new.finish().into_duration(*tu).into_series()
209 },
210 #[cfg(feature = "dtype-time")]
211 Time(b) => {
212 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
213 std::mem::swap(&mut new, b);
214 new.finish().into_time().into_series()
215 },
216 Float32(b) => {
217 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
218 std::mem::swap(&mut new, b);
219 new.finish().into_series()
220 },
221 Float64(b) => {
222 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
223 std::mem::swap(&mut new, b);
224 new.finish().into_series()
225 },
226 String(b) => {
227 let mut new = StringChunkedBuilder::new(b.field.name().clone(), capacity);
228 std::mem::swap(&mut new, b);
229 new.finish().into_series()
230 },
231 #[cfg(feature = "dtype-i8")]
232 Int8(b) => {
233 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
234 std::mem::swap(&mut new, b);
235 new.finish().into_series()
236 },
237 #[cfg(feature = "dtype-i16")]
238 Int16(b) => {
239 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
240 std::mem::swap(&mut new, b);
241 new.finish().into_series()
242 },
243 #[cfg(feature = "dtype-u8")]
244 UInt8(b) => {
245 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
246 std::mem::swap(&mut new, b);
247 new.finish().into_series()
248 },
249 #[cfg(feature = "dtype-u16")]
250 UInt16(b) => {
251 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
252 std::mem::swap(&mut new, b);
253 new.finish().into_series()
254 },
255 Null(b) => {
256 let mut new = NullChunkedBuilder::new(b.field.name().clone(), 0);
257 std::mem::swap(&mut new, b);
258 new.finish().into_series()
259 },
260 All(dtype, vals) => {
261 let out =
262 Series::from_any_values_and_dtype(PlSmallStr::EMPTY, vals, dtype, strict)?;
263 let mut new = Vec::with_capacity(capacity);
264 std::mem::swap(&mut new, vals);
265 out
266 },
267 };
268 Ok(out)
269 }
270
271 pub fn into_series(mut self) -> Series {
272 self.reset(0, false).unwrap()
273 }
274
275 pub fn new(dtype: &DataType, capacity: usize) -> AnyValueBuffer<'a> {
276 (dtype, capacity).into()
277 }
278}
279
280impl From<(&DataType, usize)> for AnyValueBuffer<'_> {
282 fn from(a: (&DataType, usize)) -> Self {
283 let (dt, len) = a;
284 use DataType::*;
285 match dt {
286 Boolean => AnyValueBuffer::Boolean(BooleanChunkedBuilder::new(PlSmallStr::EMPTY, len)),
287 Int32 => AnyValueBuffer::Int32(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
288 Int64 => AnyValueBuffer::Int64(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
289 UInt32 => AnyValueBuffer::UInt32(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
290 UInt64 => AnyValueBuffer::UInt64(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
291 #[cfg(feature = "dtype-i8")]
292 Int8 => AnyValueBuffer::Int8(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
293 #[cfg(feature = "dtype-i16")]
294 Int16 => AnyValueBuffer::Int16(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
295 #[cfg(feature = "dtype-u8")]
296 UInt8 => AnyValueBuffer::UInt8(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
297 #[cfg(feature = "dtype-u16")]
298 UInt16 => AnyValueBuffer::UInt16(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
299 #[cfg(feature = "dtype-date")]
300 Date => AnyValueBuffer::Date(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
301 #[cfg(feature = "dtype-datetime")]
302 Datetime(tu, tz) => AnyValueBuffer::Datetime(
303 PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len),
304 *tu,
305 tz.clone(),
306 ),
307 #[cfg(feature = "dtype-duration")]
308 Duration(tu) => {
309 AnyValueBuffer::Duration(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len), *tu)
310 },
311 #[cfg(feature = "dtype-time")]
312 Time => AnyValueBuffer::Time(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len)),
313 Float32 => {
314 AnyValueBuffer::Float32(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
315 },
316 Float64 => {
317 AnyValueBuffer::Float64(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
318 },
319 String => AnyValueBuffer::String(StringChunkedBuilder::new(PlSmallStr::EMPTY, len)),
320 Null => AnyValueBuffer::Null(NullChunkedBuilder::new(PlSmallStr::EMPTY, 0)),
321 dt => AnyValueBuffer::All(dt.clone(), Vec::with_capacity(len)),
323 }
324 }
325}
326
327#[derive(Clone)]
329pub enum AnyValueBufferTrusted<'a> {
330 Boolean(BooleanChunkedBuilder),
331 #[cfg(feature = "dtype-i8")]
332 Int8(PrimitiveChunkedBuilder<Int8Type>),
333 #[cfg(feature = "dtype-i16")]
334 Int16(PrimitiveChunkedBuilder<Int16Type>),
335 Int32(PrimitiveChunkedBuilder<Int32Type>),
336 Int64(PrimitiveChunkedBuilder<Int64Type>),
337 #[cfg(feature = "dtype-u8")]
338 UInt8(PrimitiveChunkedBuilder<UInt8Type>),
339 #[cfg(feature = "dtype-u16")]
340 UInt16(PrimitiveChunkedBuilder<UInt16Type>),
341 UInt32(PrimitiveChunkedBuilder<UInt32Type>),
342 UInt64(PrimitiveChunkedBuilder<UInt64Type>),
343 Float32(PrimitiveChunkedBuilder<Float32Type>),
344 Float64(PrimitiveChunkedBuilder<Float64Type>),
345 String(StringChunkedBuilder),
346 #[cfg(feature = "dtype-struct")]
347 Struct(BitmapBuilder, Vec<(AnyValueBuffer<'a>, PlSmallStr)>),
349 Null(NullChunkedBuilder),
350 All(DataType, Vec<AnyValue<'a>>),
351}
352
353impl<'a> AnyValueBufferTrusted<'a> {
354 pub fn new(dtype: &DataType, len: usize) -> Self {
355 (dtype, len).into()
356 }
357
358 #[inline]
359 unsafe fn add_null(&mut self) {
360 use AnyValueBufferTrusted::*;
361 match self {
362 Boolean(builder) => builder.append_null(),
363 #[cfg(feature = "dtype-i8")]
364 Int8(builder) => builder.append_null(),
365 #[cfg(feature = "dtype-i16")]
366 Int16(builder) => builder.append_null(),
367 Int32(builder) => builder.append_null(),
368 Int64(builder) => builder.append_null(),
369 #[cfg(feature = "dtype-u8")]
370 UInt8(builder) => builder.append_null(),
371 #[cfg(feature = "dtype-u16")]
372 UInt16(builder) => builder.append_null(),
373 UInt32(builder) => builder.append_null(),
374 UInt64(builder) => builder.append_null(),
375 Float32(builder) => builder.append_null(),
376 Float64(builder) => builder.append_null(),
377 String(builder) => builder.append_null(),
378 #[cfg(feature = "dtype-struct")]
379 Struct(outer_validity, builders) => {
380 outer_validity.push(false);
381 for (b, _) in builders.iter_mut() {
382 b.add(AnyValue::Null);
383 }
384 },
385 Null(builder) => builder.append_null(),
386 All(_, vals) => vals.push(AnyValue::Null),
387 }
388 }
389
390 #[inline]
391 unsafe fn add_physical(&mut self, val: &AnyValue<'_>) {
392 use AnyValueBufferTrusted::*;
393 match self {
394 Boolean(builder) => {
395 let AnyValue::Boolean(v) = val else {
396 unreachable_unchecked()
397 };
398 builder.append_value(*v)
399 },
400 #[cfg(feature = "dtype-i8")]
401 Int8(builder) => {
402 let AnyValue::Int8(v) = val else {
403 unreachable_unchecked()
404 };
405 builder.append_value(*v)
406 },
407 #[cfg(feature = "dtype-i16")]
408 Int16(builder) => {
409 let AnyValue::Int16(v) = val else {
410 unreachable_unchecked()
411 };
412 builder.append_value(*v)
413 },
414 Int32(builder) => {
415 let AnyValue::Int32(v) = val else {
416 unreachable_unchecked()
417 };
418 builder.append_value(*v)
419 },
420 Int64(builder) => {
421 let AnyValue::Int64(v) = val else {
422 unreachable_unchecked()
423 };
424 builder.append_value(*v)
425 },
426 #[cfg(feature = "dtype-u8")]
427 UInt8(builder) => {
428 let AnyValue::UInt8(v) = val else {
429 unreachable_unchecked()
430 };
431 builder.append_value(*v)
432 },
433 #[cfg(feature = "dtype-u16")]
434 UInt16(builder) => {
435 let AnyValue::UInt16(v) = val else {
436 unreachable_unchecked()
437 };
438 builder.append_value(*v)
439 },
440 UInt32(builder) => {
441 let AnyValue::UInt32(v) = val else {
442 unreachable_unchecked()
443 };
444 builder.append_value(*v)
445 },
446 UInt64(builder) => {
447 let AnyValue::UInt64(v) = val else {
448 unreachable_unchecked()
449 };
450 builder.append_value(*v)
451 },
452 Float32(builder) => {
453 let AnyValue::Float32(v) = val else {
454 unreachable_unchecked()
455 };
456 builder.append_value(*v)
457 },
458 Float64(builder) => {
459 let AnyValue::Float64(v) = val else {
460 unreachable_unchecked()
461 };
462 builder.append_value(*v)
463 },
464 Null(builder) => {
465 let AnyValue::Null = val else {
466 unreachable_unchecked()
467 };
468 builder.append_null()
469 },
470 _ => unreachable_unchecked(),
471 }
472 }
473
474 #[inline]
482 pub unsafe fn add_unchecked_owned_physical(&mut self, val: &AnyValue<'_>) {
483 use AnyValueBufferTrusted::*;
484 match val {
485 AnyValue::Null => self.add_null(),
486 _ => {
487 match self {
488 String(builder) => {
489 let AnyValue::StringOwned(v) = val else {
490 unreachable_unchecked()
491 };
492 builder.append_value(v.as_str())
493 },
494 #[cfg(feature = "dtype-struct")]
495 Struct(outer_validity, builders) => {
496 let AnyValue::StructOwned(payload) = val else {
497 unreachable_unchecked()
498 };
499 let avs = &*payload.0;
500 for i in 0..avs.len() {
502 unsafe {
503 let (builder, _) = builders.get_unchecked_mut(i);
504 let av = avs.get_unchecked(i).clone();
505 let av = std::mem::transmute::<AnyValue<'_>, AnyValue<'a>>(av);
507 builder.add(av.clone());
508 }
509 }
510 outer_validity.push(true);
511 },
512 All(_, vals) => vals.push(val.clone().into_static()),
513 _ => self.add_physical(val),
514 }
515 },
516 }
517 }
518
519 #[inline]
522 pub unsafe fn add_unchecked_borrowed_physical(&mut self, val: &AnyValue<'_>) {
523 use AnyValueBufferTrusted::*;
524 match val {
525 AnyValue::Null => self.add_null(),
526 _ => {
527 match self {
528 String(builder) => {
529 let AnyValue::String(v) = val else {
530 unreachable_unchecked()
531 };
532 builder.append_value(v)
533 },
534 #[cfg(feature = "dtype-struct")]
535 Struct(outer_validity, builders) => {
536 let AnyValue::Struct(idx, arr, fields) = val else {
537 unreachable_unchecked()
538 };
539 let arrays = arr.values();
540 for i in 0..fields.len() {
542 unsafe {
543 let array = arrays.get_unchecked(i);
544 let field = fields.get_unchecked(i);
545 let (builder, _) = builders.get_unchecked_mut(i);
546 let av = arr_to_any_value(&**array, *idx, &field.dtype);
547 let av = std::mem::transmute::<AnyValue<'_>, AnyValue<'a>>(av);
549 builder.add(av);
550 }
551 }
552 outer_validity.push(true);
553 },
554 All(_, vals) => vals.push(val.clone().into_static()),
555 _ => self.add_physical(val),
556 }
557 },
558 }
559 }
560
561 pub fn reset(&mut self, capacity: usize, strict: bool) -> PolarsResult<Series> {
563 use AnyValueBufferTrusted::*;
564 let out = match self {
565 Boolean(b) => {
566 let mut new = BooleanChunkedBuilder::new(b.field.name().clone(), capacity);
567 std::mem::swap(&mut new, b);
568 new.finish().into_series()
569 },
570 Int32(b) => {
571 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
572 std::mem::swap(&mut new, b);
573 new.finish().into_series()
574 },
575 Int64(b) => {
576 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
577 std::mem::swap(&mut new, b);
578 new.finish().into_series()
579 },
580 UInt32(b) => {
581 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
582 std::mem::swap(&mut new, b);
583 new.finish().into_series()
584 },
585 UInt64(b) => {
586 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
587 std::mem::swap(&mut new, b);
588 new.finish().into_series()
589 },
590 Float32(b) => {
591 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
592 std::mem::swap(&mut new, b);
593 new.finish().into_series()
594 },
595 Float64(b) => {
596 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
597 std::mem::swap(&mut new, b);
598 new.finish().into_series()
599 },
600 String(b) => {
601 let mut new = StringChunkedBuilder::new(b.field.name().clone(), capacity);
602 std::mem::swap(&mut new, b);
603 new.finish().into_series()
604 },
605 #[cfg(feature = "dtype-i8")]
606 Int8(b) => {
607 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
608 std::mem::swap(&mut new, b);
609 new.finish().into_series()
610 },
611 #[cfg(feature = "dtype-i16")]
612 Int16(b) => {
613 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
614 std::mem::swap(&mut new, b);
615 new.finish().into_series()
616 },
617 #[cfg(feature = "dtype-u8")]
618 UInt8(b) => {
619 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
620 std::mem::swap(&mut new, b);
621 new.finish().into_series()
622 },
623 #[cfg(feature = "dtype-u16")]
624 UInt16(b) => {
625 let mut new = PrimitiveChunkedBuilder::new(b.field.name().clone(), capacity);
626 std::mem::swap(&mut new, b);
627 new.finish().into_series()
628 },
629 #[cfg(feature = "dtype-struct")]
630 Struct(outer_validity, b) => {
631 if b.is_empty() {
634 return Ok(
635 StructChunked::from_series(PlSmallStr::EMPTY, 0, [].iter())?.into_series()
636 );
637 }
638
639 let mut min_len = usize::MAX;
640 let mut max_len = usize::MIN;
641
642 let v = b
643 .iter_mut()
644 .map(|(b, name)| {
645 let mut s = b.reset(capacity, strict)?;
646
647 min_len = min_len.min(s.len());
648 max_len = max_len.max(s.len());
649
650 s.rename(name.clone());
651 Ok(s)
652 })
653 .collect::<PolarsResult<Vec<_>>>()?;
654
655 let length = if min_len == 0 { 0 } else { max_len };
656
657 let old_outer_validity = core::mem::take(outer_validity);
658 outer_validity.reserve(capacity);
659
660 StructChunked::from_series(PlSmallStr::EMPTY, length, v.iter())
661 .unwrap()
662 .with_outer_validity(Some(old_outer_validity.freeze()))
663 .into_series()
664 },
665 Null(b) => {
666 let mut new = NullChunkedBuilder::new(b.field.name().clone(), 0);
667 std::mem::swap(&mut new, b);
668 new.finish().into_series()
669 },
670 All(dtype, vals) => {
671 let mut swap_vals = Vec::with_capacity(capacity);
672 std::mem::swap(vals, &mut swap_vals);
673 Series::from_any_values_and_dtype(PlSmallStr::EMPTY, &swap_vals, dtype, false)
674 .unwrap()
675 },
676 };
677
678 Ok(out)
679 }
680
681 pub fn into_series(mut self) -> Series {
682 self.reset(0, false).unwrap()
684 }
685}
686
687impl From<(&DataType, usize)> for AnyValueBufferTrusted<'_> {
688 fn from(a: (&DataType, usize)) -> Self {
689 let (dt, len) = a;
690 use DataType::*;
691 match dt {
692 Boolean => {
693 AnyValueBufferTrusted::Boolean(BooleanChunkedBuilder::new(PlSmallStr::EMPTY, len))
694 },
695 Int32 => {
696 AnyValueBufferTrusted::Int32(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
697 },
698 Int64 => {
699 AnyValueBufferTrusted::Int64(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
700 },
701 UInt32 => {
702 AnyValueBufferTrusted::UInt32(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
703 },
704 UInt64 => {
705 AnyValueBufferTrusted::UInt64(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
706 },
707 #[cfg(feature = "dtype-i8")]
708 Int8 => {
709 AnyValueBufferTrusted::Int8(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
710 },
711 #[cfg(feature = "dtype-i16")]
712 Int16 => {
713 AnyValueBufferTrusted::Int16(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
714 },
715 #[cfg(feature = "dtype-u8")]
716 UInt8 => {
717 AnyValueBufferTrusted::UInt8(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
718 },
719 #[cfg(feature = "dtype-u16")]
720 UInt16 => {
721 AnyValueBufferTrusted::UInt16(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
722 },
723 Float32 => {
724 AnyValueBufferTrusted::Float32(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
725 },
726 Float64 => {
727 AnyValueBufferTrusted::Float64(PrimitiveChunkedBuilder::new(PlSmallStr::EMPTY, len))
728 },
729 String => {
730 AnyValueBufferTrusted::String(StringChunkedBuilder::new(PlSmallStr::EMPTY, len))
731 },
732 #[cfg(feature = "dtype-struct")]
733 Struct(fields) => {
734 let outer_validity = BitmapBuilder::with_capacity(len);
735 let buffers = fields
736 .iter()
737 .map(|field| {
738 let dtype = field.dtype().to_physical();
739 let buffer: AnyValueBuffer = (&dtype, len).into();
740 (buffer, field.name.clone())
741 })
742 .collect::<Vec<_>>();
743 AnyValueBufferTrusted::Struct(outer_validity, buffers)
744 },
745 dt => AnyValueBufferTrusted::All(dt.clone(), Vec::with_capacity(len)),
747 }
748 }
749}