Skip to main content

polars_core/chunked_array/builder/list/
anonymous.rs

1use super::*;
2
3pub struct AnonymousOwnedListBuilder {
4    name: PlSmallStr,
5    builder: AnonymousBuilder<'static>,
6    owned: Vec<Series>,
7    inner_dtype: Option<DataType>,
8    fast_explode: bool,
9}
10
11impl Default for AnonymousOwnedListBuilder {
12    fn default() -> Self {
13        Self::new(PlSmallStr::EMPTY, 0, None)
14    }
15}
16
17impl ListBuilderTrait for AnonymousOwnedListBuilder {
18    fn append_series(&mut self, s: &Series) -> PolarsResult<()> {
19        self.append_owned_series(s.clone())
20    }
21
22    fn append_owned_series(&mut self, s: Series) -> PolarsResult<()> {
23        match (s.dtype(), &self.inner_dtype) {
24            (DataType::Null, _) => {},
25            (dt, None) => self.inner_dtype = Some(dt.clone()),
26            (dt, Some(set_dt)) => {
27                polars_ensure!(dt == set_dt, ComputeError: "dtypes don't match, got {}, expected: {}", dt.pretty_format(), set_dt.pretty_format());
28            },
29        }
30        if s.is_empty() {
31            self.append_empty();
32        } else {
33            unsafe {
34                self.builder
35                    .push_multiple(&*(s.chunks().as_ref() as *const [ArrayRef]));
36            }
37            // This ensures that the underlying ArrayRef's are not dropped.
38            self.owned.push(s);
39        }
40        Ok(())
41    }
42
43    #[inline]
44    fn append_null(&mut self) {
45        self.fast_explode = false;
46        self.builder.push_null()
47    }
48
49    fn finish(&mut self) -> ListChunked {
50        let inner_dtype = std::mem::take(&mut self.inner_dtype);
51        // Don't use self from here on out.
52        let slf = std::mem::take(self);
53        let inner_dtype_physical = inner_dtype
54            .as_ref()
55            .map(|dt| dt.to_physical().to_arrow(CompatLevel::newest()));
56        let arr = slf.builder.finish(inner_dtype_physical.as_ref()).unwrap();
57
58        let list_dtype_logical = match inner_dtype {
59            None => DataType::from_arrow_dtype(arr.dtype()),
60            Some(dt) => DataType::List(Box::new(dt)),
61        };
62
63        let mut ca = ListChunked::with_chunk(PlSmallStr::EMPTY, arr);
64        if slf.fast_explode {
65            ca.set_fast_explode();
66        }
67        ca.field = Arc::new(Field::new(slf.name, list_dtype_logical));
68        ca
69    }
70}
71
72impl AnonymousOwnedListBuilder {
73    pub fn new(name: PlSmallStr, capacity: usize, inner_dtype: Option<DataType>) -> Self {
74        Self {
75            name,
76            builder: AnonymousBuilder::new(capacity),
77            owned: Vec::with_capacity(capacity),
78            inner_dtype,
79            fast_explode: true,
80        }
81    }
82
83    #[inline]
84    pub fn append_empty(&mut self) {
85        self.fast_explode = false;
86        self.builder.push_empty()
87    }
88}