Path: blob/main/crates/polars-arrow/src/array/primitive/fmt.rs
6939 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_logical_type() {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))),34Float16 => unreachable!(),35Float32 => Box::new(|f, index| write!(f, "{}", array.value(index))),36Float64 => Box::new(|f, index| write!(f, "{}", array.value(index))),37Date32 => {38dyn_primitive!(array, i32, temporal_conversions::date32_to_date)39},40Date64 => {41dyn_primitive!(array, i64, temporal_conversions::date64_to_date)42},43Time32(TimeUnit::Second) => {44dyn_primitive!(array, i32, temporal_conversions::time32s_to_time)45},46Time32(TimeUnit::Millisecond) => {47dyn_primitive!(array, i32, temporal_conversions::time32ms_to_time)48},49Time32(_) => unreachable!(), // remaining are not valid50Time64(TimeUnit::Microsecond) => {51dyn_primitive!(array, i64, temporal_conversions::time64us_to_time)52},53Time64(TimeUnit::Nanosecond) => {54dyn_primitive!(array, i64, temporal_conversions::time64ns_to_time)55},56Time64(_) => unreachable!(), // remaining are not valid57Timestamp(time_unit, tz) => {58if let Some(tz) = tz {59let timezone = temporal_conversions::parse_offset(tz.as_str());60match timezone {61Ok(timezone) => {62dyn_primitive!(array, i64, |time| {63temporal_conversions::timestamp_to_datetime(time, *time_unit, &timezone)64})65},66#[cfg(feature = "chrono-tz")]67Err(_) => {68let timezone = temporal_conversions::parse_offset_tz(tz.as_str());69match timezone {70Ok(timezone) => dyn_primitive!(array, i64, |time| {71temporal_conversions::timestamp_to_datetime(72time, *time_unit, &timezone,73)74}),75Err(_) => {76let tz = tz.clone();77Box::new(move |f, index| {78write!(f, "{} ({})", array.value(index), tz)79})80},81}82},83#[cfg(not(feature = "chrono-tz"))]84_ => {85let tz = tz.clone();86Box::new(move |f, index| write!(f, "{} ({})", array.value(index), tz))87},88}89} else {90dyn_primitive!(array, i64, |time| {91temporal_conversions::timestamp_to_naive_datetime(time, *time_unit)92})93}94},95Interval(IntervalUnit::YearMonth) => {96dyn_primitive!(array, i32, |x| format!("{x}m"))97},98Interval(IntervalUnit::DayTime) => {99dyn_primitive!(array, days_ms, |x: days_ms| format!(100"{}d{}ms",101x.days(),102x.milliseconds()103))104},105Interval(IntervalUnit::MonthDayNano) => {106dyn_primitive!(array, months_days_ns, |x: months_days_ns| format!(107"{}m{}d{}ns",108x.months(),109x.days(),110x.ns()111))112},113Duration(TimeUnit::Second) => dyn_primitive!(array, i64, |x| format!("{x}s")),114Duration(TimeUnit::Millisecond) => dyn_primitive!(array, i64, |x| format!("{x}ms")),115Duration(TimeUnit::Microsecond) => dyn_primitive!(array, i64, |x| format!("{x}us")),116Duration(TimeUnit::Nanosecond) => dyn_primitive!(array, i64, |x| format!("{x}ns")),117Decimal(_, scale) => {118// The number 999.99 has a precision of 5 and scale of 2119let scale = *scale as u32;120let factor = 10i128.pow(scale);121let display = move |x: i128| {122let base = x / factor;123let decimals = (x - base * factor).abs();124format!("{base}.{decimals}")125};126dyn_primitive!(array, i128, display)127},128Decimal32(_, scale) => {129let scale = *scale as u32;130let factor = 10i32.pow(scale);131let display = move |x: i32| {132let base = x / factor;133let decimals = (x - base * factor).abs();134format!("{base}.{decimals}")135};136dyn_primitive!(array, i32, display)137},138Decimal64(_, scale) => {139let scale = *scale as u32;140let factor = 10i64.pow(scale);141let display = move |x: i64| {142let base = x / factor;143let decimals = (x - base * factor).abs();144format!("{base}.{decimals}")145};146dyn_primitive!(array, i64, display)147},148Decimal256(_, scale) => {149let scale = *scale as u32;150let factor = (ethnum::I256::ONE * 10).pow(scale);151let display = move |x: i256| {152let base = x.0 / factor;153let decimals = (x.0 - base * factor).abs();154format!("{base}.{decimals}")155};156dyn_primitive!(array, i256, display)157},158_ => unreachable!(),159}160}161162impl<T: NativeType> Debug for PrimitiveArray<T> {163fn fmt(&self, f: &mut Formatter<'_>) -> Result {164let writer = get_write_value(self);165166write!(f, "{:?}", self.dtype())?;167write_vec(f, &*writer, self.validity(), self.len(), "None", false)168}169}170171172