Path: blob/main/crates/polars-arrow/src/array/primitive/fmt.rs
8406 views
#![allow(clippy::redundant_closure_call)]1use std::fmt::{Debug, Formatter, Result, Write};23use super::PrimitiveArray;4use crate::array::Array;5use crate::array::fmt::write_vec;6use crate::datatypes::{IntervalUnit, TimeUnit};7use crate::temporal_conversions;8use crate::types::{NativeType, days_ms, i256, months_days_ns};910macro_rules! dyn_primitive {11($array:expr, $ty:ty, $expr:expr) => {{12let array = ($array as &dyn Array)13.as_any()14.downcast_ref::<PrimitiveArray<$ty>>()15.unwrap();16Box::new(move |f, index| write!(f, "{}", $expr(array.value(index))))17}};18}1920pub fn get_write_value<'a, T: NativeType, F: Write>(21array: &'a PrimitiveArray<T>,22) -> Box<dyn Fn(&mut F, usize) -> Result + 'a> {23use crate::datatypes::ArrowDataType::*;24match array.dtype().to_storage() {25Int8 => Box::new(|f, index| write!(f, "{}", array.value(index))),26Int16 => Box::new(|f, index| write!(f, "{}", array.value(index))),27Int32 => Box::new(|f, index| write!(f, "{}", array.value(index))),28Int64 => Box::new(|f, index| write!(f, "{}", array.value(index))),29Int128 => Box::new(|f, index| write!(f, "{}", array.value(index))),30UInt8 => Box::new(|f, index| write!(f, "{}", array.value(index))),31UInt16 => Box::new(|f, index| write!(f, "{}", array.value(index))),32UInt32 => Box::new(|f, index| write!(f, "{}", array.value(index))),33UInt64 => Box::new(|f, index| write!(f, "{}", array.value(index))),34UInt128 => Box::new(|f, index| write!(f, "{}", array.value(index))),35Float16 => Box::new(|f, index| write!(f, "{}", array.value(index))),36Float32 => Box::new(|f, index| write!(f, "{}", array.value(index))),37Float64 => Box::new(|f, index| write!(f, "{}", array.value(index))),38Date32 => {39dyn_primitive!(array, i32, temporal_conversions::date32_to_date)40},41Date64 => {42dyn_primitive!(array, i64, temporal_conversions::date64_to_date)43},44Time32(TimeUnit::Second) => {45dyn_primitive!(array, i32, temporal_conversions::time32s_to_time)46},47Time32(TimeUnit::Millisecond) => {48dyn_primitive!(array, i32, temporal_conversions::time32ms_to_time)49},50Time32(_) => unreachable!(), // remaining are not valid51Time64(TimeUnit::Microsecond) => {52dyn_primitive!(array, i64, temporal_conversions::time64us_to_time)53},54Time64(TimeUnit::Nanosecond) => {55dyn_primitive!(array, i64, temporal_conversions::time64ns_to_time)56},57Time64(_) => unreachable!(), // remaining are not valid58Timestamp(time_unit, tz) => {59if let Some(tz) = tz {60let timezone = temporal_conversions::parse_offset(tz.as_str());61match timezone {62Ok(timezone) => {63dyn_primitive!(array, i64, |time| {64temporal_conversions::timestamp_to_datetime(time, *time_unit, &timezone)65})66},67#[cfg(feature = "chrono-tz")]68Err(_) => {69let timezone = temporal_conversions::parse_offset_tz(tz.as_str());70match timezone {71Ok(timezone) => dyn_primitive!(array, i64, |time| {72temporal_conversions::timestamp_to_datetime(73time, *time_unit, &timezone,74)75}),76Err(_) => {77let tz = tz.clone();78Box::new(move |f, index| {79write!(f, "{} ({})", array.value(index), tz)80})81},82}83},84#[cfg(not(feature = "chrono-tz"))]85_ => {86let tz = tz.clone();87Box::new(move |f, index| write!(f, "{} ({})", array.value(index), tz))88},89}90} else {91dyn_primitive!(array, i64, |time| {92temporal_conversions::timestamp_to_naive_datetime(time, *time_unit)93})94}95},96Interval(IntervalUnit::YearMonth) => {97dyn_primitive!(array, i32, |x| format!("{x}m"))98},99Interval(IntervalUnit::DayTime) => {100dyn_primitive!(array, days_ms, |x: days_ms| format!(101"{}d{}ms",102x.days(),103x.milliseconds()104))105},106Interval(IntervalUnit::MonthDayNano) => {107dyn_primitive!(array, months_days_ns, |x: months_days_ns| format!(108"{}m{}d{}ns",109x.months(),110x.days(),111x.ns()112))113},114Duration(TimeUnit::Second) => dyn_primitive!(array, i64, |x| format!("{x}s")),115Duration(TimeUnit::Millisecond) => dyn_primitive!(array, i64, |x| format!("{x}ms")),116Duration(TimeUnit::Microsecond) => dyn_primitive!(array, i64, |x| format!("{x}us")),117Duration(TimeUnit::Nanosecond) => dyn_primitive!(array, i64, |x| format!("{x}ns")),118Decimal(_, scale) => {119// The number 999.99 has a precision of 5 and scale of 2120let scale = *scale as u32;121let factor = 10i128.pow(scale);122let display = move |x: i128| {123let base = x / factor;124let decimals = (x - base * factor).abs();125format!("{base}.{decimals}")126};127dyn_primitive!(array, i128, display)128},129Decimal32(_, scale) => {130let scale = *scale as u32;131let factor = 10i32.pow(scale);132let display = move |x: i32| {133let base = x / factor;134let decimals = (x - base * factor).abs();135format!("{base}.{decimals}")136};137dyn_primitive!(array, i32, display)138},139Decimal64(_, scale) => {140let scale = *scale as u32;141let factor = 10i64.pow(scale);142let display = move |x: i64| {143let base = x / factor;144let decimals = (x - base * factor).abs();145format!("{base}.{decimals}")146};147dyn_primitive!(array, i64, display)148},149Decimal256(_, scale) => {150let scale = *scale as u32;151let factor = (ethnum::I256::ONE * 10).pow(scale);152let display = move |x: i256| {153let base = x.0 / factor;154let decimals = (x.0 - base * factor).abs();155format!("{base}.{decimals}")156};157dyn_primitive!(array, i256, display)158},159_ => unreachable!(),160}161}162163impl<T: NativeType> Debug for PrimitiveArray<T> {164fn fmt(&self, f: &mut Formatter<'_>) -> Result {165let writer = get_write_value(self);166167write!(f, "{:?}", self.dtype())?;168write_vec(f, &*writer, self.validity(), self.len(), "None", false)169}170}171172173