polars_arrow/scalar/
mod.rs1use std::any::Any;
4
5use crate::array::*;
6use crate::datatypes::*;
7
8mod dictionary;
9pub use dictionary::*;
10mod equal;
11mod primitive;
12pub use primitive::*;
13mod utf8;
14pub use utf8::*;
15mod binary;
16pub use binary::*;
17mod boolean;
18pub use boolean::*;
19mod list;
20pub use list::*;
21mod map;
22pub use map::*;
23mod null;
24pub use null::*;
25mod struct_;
26pub use struct_::*;
27mod fixed_size_list;
28pub use fixed_size_list::*;
29mod fixed_size_binary;
30pub use binview::*;
31pub use fixed_size_binary::*;
32mod binview;
33mod union;
34
35pub use union::UnionScalar;
36
37use crate::{match_integer_type, with_match_primitive_type_full};
38
39pub trait Scalar: std::fmt::Debug + Send + Sync + dyn_clone::DynClone + 'static {
42 fn as_any(&self) -> &dyn Any;
44
45 fn is_valid(&self) -> bool;
47
48 fn dtype(&self) -> &ArrowDataType;
50}
51
52dyn_clone::clone_trait_object!(Scalar);
53
54macro_rules! dyn_new_utf8 {
55 ($array:expr, $index:expr, $type:ty) => {{
56 let array = $array.as_any().downcast_ref::<Utf8Array<$type>>().unwrap();
57 let value = if array.is_valid($index) {
58 Some(array.value($index))
59 } else {
60 None
61 };
62 Box::new(Utf8Scalar::<$type>::new(value))
63 }};
64}
65
66macro_rules! dyn_new_binview {
67 ($array:expr, $index:expr, $type:ty) => {{
68 let array = $array
69 .as_any()
70 .downcast_ref::<BinaryViewArrayGeneric<$type>>()
71 .unwrap();
72 let value = if array.is_valid($index) {
73 Some(array.value($index))
74 } else {
75 None
76 };
77 Box::new(BinaryViewScalar::<$type>::new(value))
78 }};
79}
80
81macro_rules! dyn_new_binary {
82 ($array:expr, $index:expr, $type:ty) => {{
83 let array = $array
84 .as_any()
85 .downcast_ref::<BinaryArray<$type>>()
86 .unwrap();
87 let value = if array.is_valid($index) {
88 Some(array.value($index))
89 } else {
90 None
91 };
92 Box::new(BinaryScalar::<$type>::new(value))
93 }};
94}
95
96macro_rules! dyn_new_list {
97 ($array:expr, $index:expr, $type:ty) => {{
98 let array = $array.as_any().downcast_ref::<ListArray<$type>>().unwrap();
99 let value = if array.is_valid($index) {
100 Some(array.value($index).into())
101 } else {
102 None
103 };
104 Box::new(ListScalar::<$type>::new(array.dtype().clone(), value))
105 }};
106}
107
108pub fn new_scalar(array: &dyn Array, index: usize) -> Box<dyn Scalar> {
110 use PhysicalType::*;
111 match array.dtype().to_physical_type() {
112 Null => Box::new(NullScalar::new()),
113 Boolean => {
114 let array = array.as_any().downcast_ref::<BooleanArray>().unwrap();
115 let value = if array.is_valid(index) {
116 Some(array.value(index))
117 } else {
118 None
119 };
120 Box::new(BooleanScalar::new(value))
121 },
122 Primitive(primitive) => with_match_primitive_type_full!(primitive, |$T| {
123 let array = array
124 .as_any()
125 .downcast_ref::<PrimitiveArray<$T>>()
126 .unwrap();
127 let value = if array.is_valid(index) {
128 Some(array.value(index))
129 } else {
130 None
131 };
132 Box::new(PrimitiveScalar::new(array.dtype().clone(), value))
133 }),
134 BinaryView => dyn_new_binview!(array, index, [u8]),
135 Utf8View => dyn_new_binview!(array, index, str),
136 Utf8 => dyn_new_utf8!(array, index, i32),
137 LargeUtf8 => dyn_new_utf8!(array, index, i64),
138 Binary => dyn_new_binary!(array, index, i32),
139 LargeBinary => dyn_new_binary!(array, index, i64),
140 List => dyn_new_list!(array, index, i32),
141 LargeList => dyn_new_list!(array, index, i64),
142 Struct => {
143 let array = array.as_any().downcast_ref::<StructArray>().unwrap();
144 if array.is_valid(index) {
145 let values = array
146 .values()
147 .iter()
148 .map(|x| new_scalar(x.as_ref(), index))
149 .collect();
150 Box::new(StructScalar::new(array.dtype().clone(), Some(values)))
151 } else {
152 Box::new(StructScalar::new(array.dtype().clone(), None))
153 }
154 },
155 FixedSizeBinary => {
156 let array = array
157 .as_any()
158 .downcast_ref::<FixedSizeBinaryArray>()
159 .unwrap();
160 let value = if array.is_valid(index) {
161 Some(array.value(index))
162 } else {
163 None
164 };
165 Box::new(FixedSizeBinaryScalar::new(array.dtype().clone(), value))
166 },
167 FixedSizeList => {
168 let array = array.as_any().downcast_ref::<FixedSizeListArray>().unwrap();
169 let value = if array.is_valid(index) {
170 Some(array.value(index))
171 } else {
172 None
173 };
174 Box::new(FixedSizeListScalar::new(array.dtype().clone(), value))
175 },
176 Union => {
177 let array = array.as_any().downcast_ref::<UnionArray>().unwrap();
178 Box::new(UnionScalar::new(
179 array.dtype().clone(),
180 array.types()[index],
181 array.value(index),
182 ))
183 },
184 Map => {
185 let array = array.as_any().downcast_ref::<MapArray>().unwrap();
186 let value = if array.is_valid(index) {
187 Some(array.value(index))
188 } else {
189 None
190 };
191 Box::new(MapScalar::new(array.dtype().clone(), value))
192 },
193 Dictionary(key_type) => match_integer_type!(key_type, |$T| {
194 let array = array
195 .as_any()
196 .downcast_ref::<DictionaryArray<$T>>()
197 .unwrap();
198 let value = if array.is_valid(index) {
199 Some(array.value(index).into())
200 } else {
201 None
202 };
203 Box::new(DictionaryScalar::<$T>::new(
204 array.dtype().clone(),
205 value,
206 ))
207 }),
208 }
209}