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 #[inline]
61 pub unsafe fn new_logical(phys: ChunkedArray<T>, dtype: DataType) -> Logical<K, T> {
62 Logical {
63 phys,
64 dtype,
65 _phantom: PhantomData,
66 }
67 }
68}
69
70pub trait LogicalType {
71 fn dtype(&self) -> &DataType;
73
74 fn get_any_value(&self, _i: usize) -> PolarsResult<AnyValue<'_>> {
76 unimplemented!()
77 }
78
79 unsafe fn get_any_value_unchecked(&self, _i: usize) -> AnyValue<'_> {
82 unimplemented!()
83 }
84
85 fn cast_with_options(&self, dtype: &DataType, options: CastOptions) -> PolarsResult<Series>;
86
87 fn cast(&self, dtype: &DataType) -> PolarsResult<Series> {
88 self.cast_with_options(dtype, CastOptions::NonStrict)
89 }
90}
91
92impl<K: PolarsDataType, T: PolarsDataType> Logical<K, T>
93where
94 Self: LogicalType,
95{
96 #[inline(always)]
97 pub fn name(&self) -> &PlSmallStr {
98 self.phys.name()
99 }
100
101 #[inline(always)]
102 pub fn rename(&mut self, name: PlSmallStr) {
103 self.phys.rename(name)
104 }
105
106 #[inline(always)]
107 pub fn len(&self) -> usize {
108 self.phys.len()
109 }
110
111 #[inline(always)]
112 pub fn is_empty(&self) -> bool {
113 self.len() == 0
114 }
115
116 #[inline(always)]
117 pub fn null_count(&self) -> usize {
118 self.phys.null_count()
119 }
120
121 #[inline(always)]
122 pub fn has_nulls(&self) -> bool {
123 self.phys.has_nulls()
124 }
125
126 #[inline(always)]
127 pub fn is_null(&self) -> BooleanChunked {
128 self.phys.is_null()
129 }
130
131 #[inline(always)]
132 pub fn is_not_null(&self) -> BooleanChunked {
133 self.phys.is_not_null()
134 }
135
136 #[inline(always)]
137 pub fn split_at(&self, offset: i64) -> (Self, Self) {
138 let (left, right) = self.phys.split_at(offset);
139 unsafe {
140 (
141 Self::new_logical(left, self.dtype.clone()),
142 Self::new_logical(right, self.dtype.clone()),
143 )
144 }
145 }
146
147 #[inline(always)]
148 pub fn slice(&self, offset: i64, length: usize) -> Self {
149 unsafe { Self::new_logical(self.phys.slice(offset, length), self.dtype.clone()) }
150 }
151
152 #[inline(always)]
153 pub fn field(&self) -> Field {
154 let name = self.phys.ref_field().name();
155 Field::new(name.clone(), LogicalType::dtype(self).clone())
156 }
157
158 #[inline(always)]
159 pub fn physical(&self) -> &ChunkedArray<T> {
160 &self.phys
161 }
162
163 #[inline(always)]
164 pub fn physical_mut(&mut self) -> &mut ChunkedArray<T> {
165 &mut self.phys
166 }
167
168 #[inline(always)]
169 pub fn into_physical(self) -> ChunkedArray<T> {
170 self.phys
171 }
172}