polars_core/chunked_array/ops/
full.rs

1use arrow::bitmap::Bitmap;
2
3use crate::chunked_array::builder::get_list_builder;
4use crate::prelude::*;
5use crate::series::IsSorted;
6
7impl<T> ChunkFull<T::Native> for ChunkedArray<T>
8where
9    T: PolarsNumericType,
10{
11    fn full(name: PlSmallStr, value: T::Native, length: usize) -> Self {
12        let data = vec![value; length];
13        let mut out = ChunkedArray::from_vec(name, data);
14        out.set_sorted_flag(IsSorted::Ascending);
15        out
16    }
17}
18
19impl<T> ChunkFullNull for ChunkedArray<T>
20where
21    T: PolarsNumericType,
22{
23    fn full_null(name: PlSmallStr, length: usize) -> Self {
24        let arr = PrimitiveArray::new_null(T::get_dtype().to_arrow(CompatLevel::newest()), length);
25        ChunkedArray::with_chunk(name, arr)
26    }
27}
28impl ChunkFull<bool> for BooleanChunked {
29    fn full(name: PlSmallStr, value: bool, length: usize) -> Self {
30        let bits = Bitmap::new_with_value(value, length);
31        let arr = BooleanArray::from_data_default(bits, None);
32        let mut out = BooleanChunked::with_chunk(name, arr);
33        out.set_sorted_flag(IsSorted::Ascending);
34        out
35    }
36}
37
38impl ChunkFullNull for BooleanChunked {
39    fn full_null(name: PlSmallStr, length: usize) -> Self {
40        let arr = BooleanArray::new_null(ArrowDataType::Boolean, length);
41        ChunkedArray::with_chunk(name, arr)
42    }
43}
44
45impl<'a> ChunkFull<&'a str> for StringChunked {
46    fn full(name: PlSmallStr, value: &'a str, length: usize) -> Self {
47        let mut builder = StringChunkedBuilder::new(name, length);
48        builder.chunk_builder.extend_constant(length, Some(value));
49        let mut out = builder.finish();
50        out.set_sorted_flag(IsSorted::Ascending);
51        out
52    }
53}
54
55impl ChunkFullNull for StringChunked {
56    fn full_null(name: PlSmallStr, length: usize) -> Self {
57        let arr = Utf8ViewArray::new_null(DataType::String.to_arrow(CompatLevel::newest()), length);
58        ChunkedArray::with_chunk(name, arr)
59    }
60}
61
62impl<'a> ChunkFull<&'a [u8]> for BinaryChunked {
63    fn full(name: PlSmallStr, value: &'a [u8], length: usize) -> Self {
64        let mut builder = BinaryChunkedBuilder::new(name, length);
65        builder.chunk_builder.extend_constant(length, Some(value));
66        let mut out = builder.finish();
67        out.set_sorted_flag(IsSorted::Ascending);
68        out
69    }
70}
71
72impl ChunkFullNull for BinaryChunked {
73    fn full_null(name: PlSmallStr, length: usize) -> Self {
74        let arr =
75            BinaryViewArray::new_null(DataType::Binary.to_arrow(CompatLevel::newest()), length);
76        ChunkedArray::with_chunk(name, arr)
77    }
78}
79
80impl<'a> ChunkFull<&'a [u8]> for BinaryOffsetChunked {
81    fn full(name: PlSmallStr, value: &'a [u8], length: usize) -> Self {
82        let mut mutable = MutableBinaryArray::with_capacities(length, length * value.len());
83        mutable.extend_values(std::iter::repeat_n(value, length));
84        let arr: BinaryArray<i64> = mutable.into();
85        let mut out = ChunkedArray::with_chunk(name, arr);
86        out.set_sorted_flag(IsSorted::Ascending);
87        out
88    }
89}
90
91impl ChunkFullNull for BinaryOffsetChunked {
92    fn full_null(name: PlSmallStr, length: usize) -> Self {
93        let arr = BinaryArray::<i64>::new_null(
94            DataType::BinaryOffset.to_arrow(CompatLevel::newest()),
95            length,
96        );
97        ChunkedArray::with_chunk(name, arr)
98    }
99}
100
101impl ChunkFull<&Series> for ListChunked {
102    fn full(name: PlSmallStr, value: &Series, length: usize) -> ListChunked {
103        let mut builder = get_list_builder(value.dtype(), value.len() * length, length, name);
104        for _ in 0..length {
105            builder.append_series(value).unwrap();
106        }
107        builder.finish()
108    }
109}
110
111impl ChunkFullNull for ListChunked {
112    fn full_null(name: PlSmallStr, length: usize) -> ListChunked {
113        ListChunked::full_null_with_dtype(name, length, &DataType::Null)
114    }
115}
116
117#[cfg(feature = "dtype-array")]
118impl ArrayChunked {
119    pub fn full_null_with_dtype(
120        name: PlSmallStr,
121        length: usize,
122        inner_dtype: &DataType,
123        width: usize,
124    ) -> ArrayChunked {
125        let arr = FixedSizeListArray::new_null(
126            ArrowDataType::FixedSizeList(
127                Box::new(ArrowField::new(
128                    PlSmallStr::from_static("item"),
129                    inner_dtype.to_physical().to_arrow(CompatLevel::newest()),
130                    true,
131                )),
132                width,
133            ),
134            length,
135        );
136        // SAFETY: physical type matches the logical.
137        unsafe {
138            ChunkedArray::from_chunks_and_dtype(
139                name,
140                vec![Box::new(arr)],
141                DataType::Array(Box::new(inner_dtype.clone()), width),
142            )
143        }
144    }
145}
146
147#[cfg(feature = "dtype-array")]
148impl ChunkFull<&Series> for ArrayChunked {
149    fn full(name: PlSmallStr, value: &Series, length: usize) -> ArrayChunked {
150        let width = value.len();
151        let dtype = value.dtype();
152        let arrow_dtype = ArrowDataType::FixedSizeList(
153            Box::new(ArrowField::new(
154                PlSmallStr::from_static("item"),
155                dtype.to_physical().to_arrow(CompatLevel::newest()),
156                true,
157            )),
158            width,
159        );
160        let value = value.rechunk().chunks()[0].clone();
161        let arr = FixedSizeListArray::full(length, value, arrow_dtype);
162
163        // SAFETY: physical type matches the logical.
164        unsafe {
165            ChunkedArray::from_chunks_and_dtype(
166                name,
167                vec![Box::new(arr)],
168                DataType::Array(Box::new(dtype.clone()), width),
169            )
170        }
171    }
172}
173
174#[cfg(feature = "dtype-array")]
175impl ChunkFullNull for ArrayChunked {
176    fn full_null(name: PlSmallStr, length: usize) -> ArrayChunked {
177        ArrayChunked::full_null_with_dtype(name, length, &DataType::Null, 0)
178    }
179}
180
181impl ListChunked {
182    pub fn full_null_with_dtype(
183        name: PlSmallStr,
184        length: usize,
185        inner_dtype: &DataType,
186    ) -> ListChunked {
187        let arr: ListArray<i64> = ListArray::new_null(
188            ArrowDataType::LargeList(Box::new(ArrowField::new(
189                PlSmallStr::from_static("item"),
190                inner_dtype.to_physical().to_arrow(CompatLevel::newest()),
191                true,
192            ))),
193            length,
194        );
195        // SAFETY: physical type matches the logical.
196        unsafe {
197            ChunkedArray::from_chunks_and_dtype(
198                name,
199                vec![Box::new(arr)],
200                DataType::List(Box::new(inner_dtype.clone())),
201            )
202        }
203    }
204}
205#[cfg(feature = "dtype-struct")]
206impl ChunkFullNull for StructChunked {
207    fn full_null(name: PlSmallStr, length: usize) -> StructChunked {
208        StructChunked::from_series(name, length, [].iter())
209            .unwrap()
210            .with_outer_validity(Some(Bitmap::new_zeroed(length)))
211    }
212}
213
214#[cfg(feature = "object")]
215impl<T: PolarsObject> ChunkFull<T> for ObjectChunked<T> {
216    fn full(name: PlSmallStr, value: T, length: usize) -> Self
217    where
218        Self: Sized,
219    {
220        let mut ca: Self = (0..length).map(|_| Some(value.clone())).collect();
221        ca.rename(name);
222        ca
223    }
224}
225
226#[cfg(feature = "object")]
227impl<T: PolarsObject> ChunkFullNull for ObjectChunked<T> {
228    fn full_null(name: PlSmallStr, length: usize) -> ObjectChunked<T> {
229        let mut ca: Self = (0..length).map(|_| None).collect();
230        ca.rename(name);
231        ca
232    }
233}