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