Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-arrow/src/scalar/mod.rs
6939 views
1
//! contains the [`Scalar`] trait object representing individual items of [`Array`](crate::array::Array)s,
2
//! as well as concrete implementations such as [`BooleanScalar`].
3
use std::any::Any;
4
5
use crate::array::*;
6
use crate::datatypes::*;
7
8
mod dictionary;
9
pub use dictionary::*;
10
mod equal;
11
mod primitive;
12
pub use primitive::*;
13
mod utf8;
14
pub use utf8::*;
15
mod binary;
16
pub use binary::*;
17
mod boolean;
18
pub use boolean::*;
19
mod list;
20
pub use list::*;
21
mod map;
22
pub use map::*;
23
mod null;
24
pub use null::*;
25
mod struct_;
26
pub use struct_::*;
27
mod fixed_size_list;
28
pub use fixed_size_list::*;
29
mod fixed_size_binary;
30
pub use binview::*;
31
pub use fixed_size_binary::*;
32
mod binview;
33
mod union;
34
35
pub use union::UnionScalar;
36
37
use crate::{match_integer_type, with_match_primitive_type_full};
38
39
/// Trait object declaring an optional value with a [`ArrowDataType`].
40
/// This strait is often used in APIs that accept multiple scalar types.
41
pub trait Scalar: std::fmt::Debug + Send + Sync + dyn_clone::DynClone + 'static {
42
/// convert itself to
43
fn as_any(&self) -> &dyn Any;
44
45
/// whether it is valid
46
fn is_valid(&self) -> bool;
47
48
/// the logical type.
49
fn dtype(&self) -> &ArrowDataType;
50
}
51
52
dyn_clone::clone_trait_object!(Scalar);
53
54
macro_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
66
macro_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
81
macro_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
96
macro_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
108
/// creates a new [`Scalar`] from an [`Array`].
109
pub 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
}
210
211