polars_ops/series/ops/
eager.rs

1use 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::<u64>().unwrap_or(0_u64);
21
22            if cfg!(feature = "dtype-u8") && max <= u8::MAX as u64 {
23                self.cast(&DataType::UInt8)
24            } else if cfg!(feature = "dtype-u16") && max <= u16::MAX as u64 {
25                self.cast(&DataType::UInt16)
26            } else if max <= u32::MAX as u64 {
27                self.cast(&DataType::UInt32)
28            } else {
29                Ok(self.clone())
30            }
31        } else {
32            let min = self.min_reduce()?.value().extract::<i64>().unwrap_or(0_i64);
33            let max = self.max_reduce()?.value().extract::<i64>().unwrap_or(0_i64);
34
35            if cfg!(feature = "dtype-i8") && min >= i8::MIN as i64 && max <= i8::MAX as i64 {
36                self.cast(&DataType::Int8)
37            } else if cfg!(feature = "dtype-i16")
38                && min >= i16::MIN as i64
39                && max <= i16::MAX as i64
40            {
41                self.cast(&DataType::Int16)
42            } else if min >= i32::MIN as i64 && max <= i32::MAX as i64 {
43                self.cast(&DataType::Int32)
44            } else {
45                Ok(self.clone())
46            }
47        }
48    }
49}