polars_ops/series/ops/
eager.rs1use polars_core::prelude::DataType;
2use polars_core::series::Series;
3use polars_error::PolarsResult;
4
5pub trait ShrinkType {
6 fn shrink_type(&self) -> PolarsResult<Series>;
7}
8
9impl ShrinkType for Series {
10 fn shrink_type(&self) -> PolarsResult<Series> {
11 if !self.dtype().is_primitive_numeric() {
12 return Ok(self.clone());
13 }
14
15 if self.dtype().is_float() {
16 return self.cast(&DataType::Float32);
17 }
18
19 if self.dtype().is_unsigned_integer() {
20 let max = self.max_reduce()?.value().extract::<u128>().unwrap_or(0);
21
22 if cfg!(feature = "dtype-u8") && max <= u8::MAX as u128 {
23 self.cast(&DataType::UInt8)
24 } else if cfg!(feature = "dtype-u16") && max <= u16::MAX as u128 {
25 self.cast(&DataType::UInt16)
26 } else if max <= u32::MAX as u128 {
27 self.cast(&DataType::UInt32)
28 } else if max <= u64::MAX as u128 {
29 self.cast(&DataType::UInt64)
30 } else {
31 Ok(self.clone())
32 }
33 } else {
34 let min = self.min_reduce()?.value().extract::<i128>().unwrap_or(0);
35 let max = self.max_reduce()?.value().extract::<i128>().unwrap_or(0);
36
37 if cfg!(feature = "dtype-i8") && min >= i8::MIN as i128 && max <= i8::MAX as i128 {
38 self.cast(&DataType::Int8)
39 } else if cfg!(feature = "dtype-i16")
40 && min >= i16::MIN as i128
41 && max <= i16::MAX as i128
42 {
43 self.cast(&DataType::Int16)
44 } else if min >= i32::MIN as i128 && max <= i32::MAX as i128 {
45 self.cast(&DataType::Int32)
46 } else if min >= i64::MIN as i128 && max <= i64::MAX as i128 {
47 self.cast(&DataType::Int64)
48 } else {
49 Ok(self.clone())
50 }
51 }
52 }
53}