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