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-time")]
26mod time;
27use std::marker::PhantomData;
28
29#[cfg(feature = "dtype-time")]
30pub use time::*;
31
32use crate::chunked_array::cast::CastOptions;
33use crate::prelude::*;
34
35pub struct Logical<Logical: PolarsDataType, Physical: PolarsDataType> {
38 pub phys: ChunkedArray<Physical>,
39 pub dtype: DataType,
40 _phantom: PhantomData<Logical>,
41}
42
43impl<K: PolarsDataType, T: PolarsDataType> Clone for Logical<K, T> {
44 fn clone(&self) -> Self {
45 Self {
46 phys: self.phys.clone(),
47 dtype: self.dtype.clone(),
48 _phantom: PhantomData,
49 }
50 }
51}
52
53impl<K: PolarsDataType, T: PolarsDataType> Logical<K, T> {
54 pub unsafe fn new_logical(phys: ChunkedArray<T>, dtype: DataType) -> Logical<K, T> {
57 Logical {
58 phys,
59 dtype,
60 _phantom: PhantomData,
61 }
62 }
63}
64
65pub trait LogicalType {
66 fn dtype(&self) -> &DataType;
68
69 fn get_any_value(&self, _i: usize) -> PolarsResult<AnyValue<'_>> {
71 unimplemented!()
72 }
73
74 unsafe fn get_any_value_unchecked(&self, _i: usize) -> AnyValue<'_> {
77 unimplemented!()
78 }
79
80 fn cast_with_options(&self, dtype: &DataType, options: CastOptions) -> PolarsResult<Series>;
81
82 fn cast(&self, dtype: &DataType) -> PolarsResult<Series> {
83 self.cast_with_options(dtype, CastOptions::NonStrict)
84 }
85}
86
87impl<K: PolarsDataType, T: PolarsDataType> Logical<K, T>
88where
89 Self: LogicalType,
90{
91 #[inline(always)]
92 pub fn name(&self) -> &PlSmallStr {
93 self.phys.name()
94 }
95
96 #[inline(always)]
97 pub fn rename(&mut self, name: PlSmallStr) {
98 self.phys.rename(name)
99 }
100
101 #[inline(always)]
102 pub fn len(&self) -> usize {
103 self.phys.len()
104 }
105
106 #[inline(always)]
107 pub fn is_empty(&self) -> bool {
108 self.len() == 0
109 }
110
111 #[inline(always)]
112 pub fn null_count(&self) -> usize {
113 self.phys.null_count()
114 }
115
116 #[inline(always)]
117 pub fn has_nulls(&self) -> bool {
118 self.phys.has_nulls()
119 }
120
121 #[inline(always)]
122 pub fn is_null(&self) -> BooleanChunked {
123 self.phys.is_null()
124 }
125
126 #[inline(always)]
127 pub fn is_not_null(&self) -> BooleanChunked {
128 self.phys.is_not_null()
129 }
130
131 #[inline(always)]
132 pub fn split_at(&self, offset: i64) -> (Self, Self) {
133 let (left, right) = self.phys.split_at(offset);
134 unsafe {
135 (
136 Self::new_logical(left, self.dtype.clone()),
137 Self::new_logical(right, self.dtype.clone()),
138 )
139 }
140 }
141
142 #[inline(always)]
143 pub fn slice(&self, offset: i64, length: usize) -> Self {
144 unsafe { Self::new_logical(self.phys.slice(offset, length), self.dtype.clone()) }
145 }
146
147 #[inline(always)]
148 pub fn field(&self) -> Field {
149 let name = self.phys.ref_field().name();
150 Field::new(name.clone(), LogicalType::dtype(self).clone())
151 }
152
153 #[inline(always)]
154 pub fn physical(&self) -> &ChunkedArray<T> {
155 &self.phys
156 }
157
158 #[inline(always)]
159 pub fn physical_mut(&mut self) -> &mut ChunkedArray<T> {
160 &mut self.phys
161 }
162
163 #[inline(always)]
164 pub fn into_physical(self) -> ChunkedArray<T> {
165 self.phys
166 }
167}