polars_core/chunked_array/logical/
mod.rs1#[cfg(feature = "dtype-date")]
2mod date;
3#[cfg(feature = "dtype-date")]
4pub use date::*;
5#[cfg(feature = "dtype-categorical")]
6pub mod categorical;
7#[cfg(feature = "dtype-categorical")]
8pub use categorical::*;
9#[cfg(feature = "dtype-datetime")]
10mod datetime;
11#[cfg(feature = "dtype-datetime")]
12pub use datetime::*;
13#[cfg(feature = "dtype-decimal")]
14mod decimal;
15#[cfg(feature = "dtype-decimal")]
16pub use decimal::*;
17#[cfg(feature = "dtype-duration")]
18mod duration;
19#[cfg(feature = "dtype-duration")]
20pub use duration::*;
21#[cfg(feature = "dtype-extension")]
22mod extension;
23#[cfg(feature = "dtype-extension")]
24pub use extension::*;
25#[cfg(feature = "dtype-map")]
26mod map;
27#[cfg(feature = "dtype-map")]
28pub use map::*;
29#[cfg(feature = "dtype-time")]
30mod time;
31use std::marker::PhantomData;
32
33#[cfg(feature = "dtype-time")]
34pub use time::*;
35
36use crate::chunked_array::cast::CastOptions;
37use crate::prelude::*;
38
39pub struct Logical<Logical: PolarsDataType, Physical: PolarsDataType> {
42 pub phys: ChunkedArray<Physical>,
43 pub dtype: DataType,
44 _phantom: PhantomData<Logical>,
45}
46
47impl<K: PolarsDataType, T: PolarsDataType> Clone for Logical<K, T> {
48 fn clone(&self) -> Self {
49 Self {
50 phys: self.phys.clone(),
51 dtype: self.dtype.clone(),
52 _phantom: PhantomData,
53 }
54 }
55}
56
57impl<K: PolarsDataType, T: PolarsDataType> Logical<K, T> {
58 pub unsafe fn new_logical(phys: ChunkedArray<T>, dtype: DataType) -> Logical<K, T> {
61 Logical {
62 phys,
63 dtype,
64 _phantom: PhantomData,
65 }
66 }
67}
68
69pub trait LogicalType {
70 fn dtype(&self) -> &DataType;
72
73 fn get_any_value(&self, _i: usize) -> PolarsResult<AnyValue<'_>> {
75 unimplemented!()
76 }
77
78 unsafe fn get_any_value_unchecked(&self, _i: usize) -> AnyValue<'_> {
81 unimplemented!()
82 }
83
84 fn cast_with_options(&self, dtype: &DataType, options: CastOptions) -> PolarsResult<Series>;
85
86 fn cast(&self, dtype: &DataType) -> PolarsResult<Series> {
87 self.cast_with_options(dtype, CastOptions::NonStrict)
88 }
89}
90
91impl<K: PolarsDataType, T: PolarsDataType> Logical<K, T>
92where
93 Self: LogicalType,
94{
95 #[inline(always)]
96 pub fn name(&self) -> &PlSmallStr {
97 self.phys.name()
98 }
99
100 #[inline(always)]
101 pub fn rename(&mut self, name: PlSmallStr) {
102 self.phys.rename(name)
103 }
104
105 #[inline(always)]
106 pub fn len(&self) -> usize {
107 self.phys.len()
108 }
109
110 #[inline(always)]
111 pub fn is_empty(&self) -> bool {
112 self.len() == 0
113 }
114
115 #[inline(always)]
116 pub fn null_count(&self) -> usize {
117 self.phys.null_count()
118 }
119
120 #[inline(always)]
121 pub fn has_nulls(&self) -> bool {
122 self.phys.has_nulls()
123 }
124
125 #[inline(always)]
126 pub fn is_null(&self) -> BooleanChunked {
127 self.phys.is_null()
128 }
129
130 #[inline(always)]
131 pub fn is_not_null(&self) -> BooleanChunked {
132 self.phys.is_not_null()
133 }
134
135 #[inline(always)]
136 pub fn split_at(&self, offset: i64) -> (Self, Self) {
137 let (left, right) = self.phys.split_at(offset);
138 unsafe {
139 (
140 Self::new_logical(left, self.dtype.clone()),
141 Self::new_logical(right, self.dtype.clone()),
142 )
143 }
144 }
145
146 #[inline(always)]
147 pub fn slice(&self, offset: i64, length: usize) -> Self {
148 unsafe { Self::new_logical(self.phys.slice(offset, length), self.dtype.clone()) }
149 }
150
151 #[inline(always)]
152 pub fn field(&self) -> Field {
153 let name = self.phys.ref_field().name();
154 Field::new(name.clone(), LogicalType::dtype(self).clone())
155 }
156
157 #[inline(always)]
158 pub fn physical(&self) -> &ChunkedArray<T> {
159 &self.phys
160 }
161
162 #[inline(always)]
163 pub fn physical_mut(&mut self) -> &mut ChunkedArray<T> {
164 &mut self.phys
165 }
166
167 #[inline(always)]
168 pub fn into_physical(self) -> ChunkedArray<T> {
169 self.phys
170 }
171}