From 6805821f078d1dc9bf294bcdb1d82706cc08858b Mon Sep 17 00:00:00 2001 From: "Jorge C. Leitao" Date: Tue, 15 Feb 2022 14:43:23 +0000 Subject: [PATCH] Refactored fmt --- src/array/binary/fmt.rs | 26 +++ src/array/binary/mod.rs | 17 +- src/array/boolean/fmt.rs | 17 ++ src/array/boolean/mod.rs | 9 +- src/array/dictionary/fmt.rs | 32 ++++ src/array/dictionary/mod.rs | 19 +- src/array/display.rs | 224 ------------------------ src/array/fixed_size_binary/fmt.rs | 20 +++ src/array/fixed_size_binary/mod.rs | 10 +- src/array/fixed_size_list/fmt.rs | 24 +++ src/array/fixed_size_list/mod.rs | 9 +- src/array/fmt.rs | 180 +++++++++++++++++++ src/array/list/fmt.rs | 31 ++++ src/array/list/mod.rs | 14 +- src/array/mod.rs | 51 +----- src/array/primitive/display.rs | 15 -- src/array/primitive/fmt.rs | 128 ++++++++++++++ src/array/primitive/mod.rs | 2 +- src/array/struct_/fmt.rs | 34 ++++ src/array/struct_/mod.rs | 11 +- src/array/union/fmt.rs | 24 +++ src/array/union/mod.rs | 17 +- src/array/utf8/fmt.rs | 23 +++ src/array/utf8/mod.rs | 8 +- src/io/print.rs | 7 +- tests/it/array/boolean/mod.rs | 2 +- tests/it/array/fixed_size_binary/mod.rs | 4 +- tests/it/array/list/mod.rs | 9 +- tests/it/array/primitive/mod.rs | 42 ++--- tests/it/array/struct_/mod.rs | 26 +++ 30 files changed, 617 insertions(+), 418 deletions(-) create mode 100644 src/array/binary/fmt.rs create mode 100644 src/array/boolean/fmt.rs create mode 100644 src/array/dictionary/fmt.rs delete mode 100644 src/array/display.rs create mode 100644 src/array/fixed_size_binary/fmt.rs create mode 100644 src/array/fixed_size_list/fmt.rs create mode 100644 src/array/fmt.rs create mode 100644 src/array/list/fmt.rs delete mode 100644 src/array/primitive/display.rs create mode 100644 src/array/primitive/fmt.rs create mode 100644 src/array/struct_/fmt.rs create mode 100644 src/array/union/fmt.rs create mode 100644 src/array/utf8/fmt.rs diff --git a/src/array/binary/fmt.rs b/src/array/binary/fmt.rs new file mode 100644 index 00000000000..1d82f2c979e --- /dev/null +++ b/src/array/binary/fmt.rs @@ -0,0 +1,26 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::write_vec; +use super::super::Offset; +use super::BinaryArray; + +pub fn write_value(array: &BinaryArray, index: usize, f: &mut W) -> Result { + let bytes = array.value(index); + let writer = |f: &mut W, index| write!(f, "{}", bytes[index]); + + write_vec(f, writer, None, bytes.len(), "None", false) +} + +impl Debug for BinaryArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, f); + + let head = if O::is_large() { + "LargeBinaryArray" + } else { + "BinaryArray" + }; + write!(f, "{}", head)?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/binary/mod.rs b/src/array/binary/mod.rs index e071ceea719..437854eba4c 100644 --- a/src/array/binary/mod.rs +++ b/src/array/binary/mod.rs @@ -6,12 +6,12 @@ use crate::{ }; use super::{ - display_fmt, display_helper, specification::{check_offsets_minimal, try_check_offsets}, Array, GenericBinaryArray, Offset, }; mod ffi; +pub(super) mod fmt; mod iterator; pub use iterator::*; mod from; @@ -23,7 +23,7 @@ pub use mutable::*; /// The following invariants hold: /// * Two consecutives `offsets` casted (`as`) to `usize` are valid slices of `values`. /// * `len` is equal to `validity.len()`, when defined. -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct BinaryArray { data_type: DataType, offsets: Buffer, @@ -274,19 +274,6 @@ impl Array for BinaryArray { } } -impl std::fmt::Display for BinaryArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let a = |x: &[u8]| display_helper(x.iter().map(|x| Some(format!("{:b}", x)))).join(" "); - let iter = self.iter().map(|x| x.map(a)); - let head = if O::is_large() { - "LargeBinaryArray" - } else { - "BinaryArray" - }; - display_fmt(iter, head, f, false) - } -} - unsafe impl GenericBinaryArray for BinaryArray { #[inline] fn values(&self) -> &[u8] { diff --git a/src/array/boolean/fmt.rs b/src/array/boolean/fmt.rs new file mode 100644 index 00000000000..229a01cd3e0 --- /dev/null +++ b/src/array/boolean/fmt.rs @@ -0,0 +1,17 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::write_vec; +use super::BooleanArray; + +pub fn write_value(array: &BooleanArray, index: usize, f: &mut W) -> Result { + write!(f, "{}", array.value(index)) +} + +impl Debug for BooleanArray { + fn fmt(&self, f: &mut Formatter) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, f); + + write!(f, "BooleanArray")?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/boolean/mod.rs b/src/array/boolean/mod.rs index 17b8b5dc6c8..0c5126a2707 100644 --- a/src/array/boolean/mod.rs +++ b/src/array/boolean/mod.rs @@ -4,9 +4,10 @@ use crate::{ }; use either::Either; -use super::{display_fmt, Array}; +use super::Array; mod ffi; +pub(super) mod fmt; mod from; mod iterator; mod mutable; @@ -204,9 +205,3 @@ impl Array for BooleanArray { Box::new(self.with_validity(validity)) } } - -impl std::fmt::Debug for BooleanArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - display_fmt(self.iter(), "BooleanArray", f, false) - } -} diff --git a/src/array/dictionary/fmt.rs b/src/array/dictionary/fmt.rs new file mode 100644 index 00000000000..e3e3b475d8f --- /dev/null +++ b/src/array/dictionary/fmt.rs @@ -0,0 +1,32 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use crate::array::Array; + +use super::super::fmt::{get_display, write_vec}; +use super::{DictionaryArray, DictionaryKey}; + +pub fn write_value( + array: &DictionaryArray, + index: usize, + null: &'static str, + f: &mut W, +) -> Result { + let keys = array.keys(); + let values = array.values(); + + if keys.is_valid(index) { + let key = keys.value(index).to_usize().unwrap(); + get_display(values.as_ref(), null)(f, key) + } else { + write!(f, "{}", null) + } +} + +impl Debug for DictionaryArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, "None", f); + + write!(f, "DictionaryArray")?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/dictionary/mod.rs b/src/array/dictionary/mod.rs index bd9514bcab4..49d3af6ae21 100644 --- a/src/array/dictionary/mod.rs +++ b/src/array/dictionary/mod.rs @@ -8,13 +8,13 @@ use crate::{ }; mod ffi; +pub(super) mod fmt; mod iterator; mod mutable; pub use iterator::*; pub use mutable::*; -use super::display::get_value_display; -use super::{display_fmt, new_empty_array, primitive::PrimitiveArray, Array}; +use super::{new_empty_array, primitive::PrimitiveArray, Array}; use crate::scalar::NullScalar; /// Trait denoting [`NativeType`]s that can be used as keys of a dictionary. @@ -50,7 +50,7 @@ impl DictionaryKey for u64 { /// An [`Array`] whose values are encoded by keys. This [`Array`] is useful when the cardinality of /// values is low compared to the length of the [`Array`]. -#[derive(Debug, Clone)] +#[derive(Clone)] pub struct DictionaryArray { data_type: DataType, keys: PrimitiveArray, @@ -203,16 +203,3 @@ impl Array for DictionaryArray { Box::new(self.with_validity(validity)) } } - -impl std::fmt::Display for DictionaryArray -where - PrimitiveArray: std::fmt::Display, -{ - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let display = get_value_display(self); - let new_lines = false; - let head = &format!("{:?}", self.data_type()); - let iter = self.iter().enumerate().map(|(i, x)| x.map(|_| display(i))); - display_fmt(iter, head, f, new_lines) - } -} diff --git a/src/array/display.rs b/src/array/display.rs deleted file mode 100644 index de7314927c8..00000000000 --- a/src/array/display.rs +++ /dev/null @@ -1,224 +0,0 @@ -use crate::{ - array::*, - datatypes::{DataType, IntervalUnit, TimeUnit}, - temporal_conversions, -}; - -macro_rules! dyn_display { - ($array:expr, $ty:ty, $expr:expr) => {{ - let a = $array.as_any().downcast_ref::<$ty>().unwrap(); - Box::new(move |row: usize| format!("{}", $expr(a.value(row)))) - }}; -} - -macro_rules! dyn_primitive { - ($array:expr, $ty:ty, $expr:expr) => {{ - dyn_display!($array, PrimitiveArray<$ty>, $expr) - }}; -} - -/// Returns a function of index returning the string representation of the _value_ of `array`. -/// This does not take nulls into account. -pub fn get_value_display<'a>(array: &'a dyn Array) -> Box String + 'a> { - use DataType::*; - match array.data_type() { - Null => Box::new(|_: usize| "".to_string()), - Boolean => { - let a = array.as_any().downcast_ref::().unwrap(); - Box::new(move |row: usize| format!("{}", a.value(row))) - } - Int8 => dyn_primitive!(array, i8, |x| x), - Int16 => dyn_primitive!(array, i16, |x| x), - Int32 => dyn_primitive!(array, i32, |x| x), - Int64 => dyn_primitive!(array, i64, |x| x), - UInt8 => dyn_primitive!(array, u8, |x| x), - UInt16 => dyn_primitive!(array, u16, |x| x), - UInt32 => dyn_primitive!(array, u32, |x| x), - UInt64 => dyn_primitive!(array, u64, |x| x), - Float16 => unreachable!(), - Float32 => dyn_primitive!(array, f32, |x| x), - Float64 => dyn_primitive!(array, f64, |x| x), - Date32 => dyn_primitive!(array, i32, temporal_conversions::date32_to_date), - Date64 => dyn_primitive!(array, i64, temporal_conversions::date64_to_date), - Time32(TimeUnit::Second) => { - dyn_primitive!(array, i32, temporal_conversions::time32s_to_time) - } - Time32(TimeUnit::Millisecond) => { - dyn_primitive!(array, i32, temporal_conversions::time32ms_to_time) - } - Time32(_) => unreachable!(), // remaining are not valid - Time64(TimeUnit::Microsecond) => { - dyn_primitive!(array, i64, temporal_conversions::time64us_to_time) - } - Time64(TimeUnit::Nanosecond) => { - dyn_primitive!(array, i64, temporal_conversions::time64ns_to_time) - } - Time64(_) => unreachable!(), // remaining are not valid - Timestamp(time_unit, tz) => { - if let Some(tz) = tz { - let timezone = temporal_conversions::parse_offset(tz); - match timezone { - Ok(timezone) => { - dyn_primitive!(array, i64, |time| { - temporal_conversions::timestamp_to_datetime(time, *time_unit, &timezone) - }) - } - #[cfg(feature = "chrono-tz")] - Err(_) => { - let timezone = temporal_conversions::parse_offset_tz(tz).unwrap(); - dyn_primitive!(array, i64, |time| { - temporal_conversions::timestamp_to_datetime(time, *time_unit, &timezone) - }) - } - #[cfg(not(feature = "chrono-tz"))] - _ => panic!( - "Invalid Offset format (must be [-]00:00) or chrono-tz feature not active" - ), - } - } else { - dyn_primitive!(array, i64, |time| { - temporal_conversions::timestamp_to_naive_datetime(time, *time_unit) - }) - } - } - Interval(IntervalUnit::YearMonth) => { - dyn_primitive!(array, i32, |x| format!("{}m", x)) - } - Interval(IntervalUnit::DayTime) => { - dyn_primitive!(array, days_ms, |x: days_ms| format!( - "{}d{}ms", - x.days(), - x.milliseconds() - )) - } - - Interval(IntervalUnit::MonthDayNano) => { - dyn_primitive!(array, months_days_ns, |x: months_days_ns| format!( - "{}m{}d{}ns", - x.months(), - x.days(), - x.ns() - )) - } - Duration(TimeUnit::Second) => dyn_primitive!(array, i64, |x| format!("{}s", x)), - Duration(TimeUnit::Millisecond) => dyn_primitive!(array, i64, |x| format!("{}ms", x)), - Duration(TimeUnit::Microsecond) => dyn_primitive!(array, i64, |x| format!("{}us", x)), - Duration(TimeUnit::Nanosecond) => dyn_primitive!(array, i64, |x| format!("{}ns", x)), - Binary => dyn_display!(array, BinaryArray, |x: &[u8]| { - x.iter().fold("".to_string(), |mut acc, x| { - acc.push_str(&format!("{:#010b}", x)); - acc - }) - }), - LargeBinary => dyn_display!(array, BinaryArray, |x: &[u8]| { - x.iter().fold("".to_string(), |mut acc, x| { - acc.push_str(&format!("{:#010b}", x)); - acc - }) - }), - FixedSizeBinary(_) => dyn_display!(array, FixedSizeBinaryArray, |x: &[u8]| { - x.iter().fold("".to_string(), |mut acc, x| { - acc.push_str(&format!("{:#010b}", x)); - acc - }) - }), - Utf8 => dyn_display!(array, Utf8Array, |x| x), - LargeUtf8 => dyn_display!(array, Utf8Array, |x| x), - Decimal(_, scale) => { - // The number 999.99 has a precision of 5 and scale of 2 - let scale = *scale as u32; - let display = move |x| { - let base = x / 10i128.pow(scale); - let decimals = x - base * 10i128.pow(scale); - format!("{}.{}", base, decimals) - }; - dyn_primitive!(array, i128, display) - } - List(_) => { - let f = |x: Box| { - let display = get_value_display(x.as_ref()); - let string_values = (0..x.len()).map(display).collect::>(); - format!("[{}]", string_values.join(", ")) - }; - dyn_display!(array, ListArray, f) - } - FixedSizeList(_, _) => { - let f = |x: Box| { - let display = get_value_display(x.as_ref()); - let string_values = (0..x.len()).map(display).collect::>(); - format!("[{}]", string_values.join(", ")) - }; - dyn_display!(array, FixedSizeListArray, f) - } - LargeList(_) => { - let f = |x: Box| { - let display = get_value_display(x.as_ref()); - let string_values = (0..x.len()).map(display).collect::>(); - format!("[{}]", string_values.join(", ")) - }; - dyn_display!(array, ListArray, f) - } - Dictionary(key_type, ..) => match_integer_type!(key_type, |$T| { - let a = array - .as_any() - .downcast_ref::>() - .unwrap(); - let keys = a.keys(); - let display = get_display(a.values().as_ref()); - Box::new(move |row: usize| { - if keys.is_null(row) { - "".to_string() - }else { - display(keys.value(row) as usize) - } - }) - }), - Map(_, _) => todo!(), - Struct(_) => { - let a = array.as_any().downcast_ref::().unwrap(); - let displays = a - .values() - .iter() - .map(|x| get_value_display(x.as_ref())) - .collect::>(); - Box::new(move |row: usize| { - let mut string = displays - .iter() - .zip(a.fields().iter().map(|f| &f.name)) - .map(|(f, name)| (f(row), name)) - .fold("{".to_string(), |mut acc, (v, name)| { - acc.push_str(&format!("{}: {}, ", name, v)); - acc - }); - if string.len() > 1 { - // remove last ", " - string.pop(); - string.pop(); - } - string.push('}'); - string - }) - } - Union(_, _, _) => { - let array = array.as_any().downcast_ref::().unwrap(); - Box::new(move |row: usize| { - let (field, index) = array.index(row); - get_display(array.fields()[field].as_ref())(index) - }) - } - Extension(_, _, _) => todo!(), - } -} - -/// Returns a function of index returning the string representation of the item of `array`. -/// This outputs an empty string on nulls. -pub fn get_display<'a>(array: &'a dyn Array) -> Box String + 'a> { - let value_display = get_value_display(array); - Box::new(move |row| { - if array.is_null(row) { - "".to_string() - } else { - value_display(row) - } - }) -} diff --git a/src/array/fixed_size_binary/fmt.rs b/src/array/fixed_size_binary/fmt.rs new file mode 100644 index 00000000000..c5f9e2dd329 --- /dev/null +++ b/src/array/fixed_size_binary/fmt.rs @@ -0,0 +1,20 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::write_vec; +use super::FixedSizeBinaryArray; + +pub fn write_value(array: &FixedSizeBinaryArray, index: usize, f: &mut W) -> Result { + let values = array.value(index); + let writer = |f: &mut W, index| write!(f, "{}", values[index]); + + write_vec(f, writer, None, values.len(), "None", false) +} + +impl Debug for FixedSizeBinaryArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, f); + + write!(f, "{:?}", self.data_type)?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/fixed_size_binary/mod.rs b/src/array/fixed_size_binary/mod.rs index d68c484d45c..f796340c93a 100644 --- a/src/array/fixed_size_binary/mod.rs +++ b/src/array/fixed_size_binary/mod.rs @@ -1,8 +1,9 @@ use crate::{bitmap::Bitmap, buffer::Buffer, datatypes::DataType, error::Result}; -use super::{display_fmt, Array}; +use super::Array; mod ffi; +pub(super) mod fmt; mod iterator; mod mutable; pub use mutable::*; @@ -205,13 +206,6 @@ impl Array for FixedSizeBinaryArray { } } -impl std::fmt::Debug for FixedSizeBinaryArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let iter = self.iter().map(|x| x.map(|x| format!("{:?}", x))); - display_fmt(iter, "FixedSizeBinaryArray", f, false) - } -} - impl FixedSizeBinaryArray { /// Creates a [`FixedSizeBinaryArray`] from an fallible iterator of optional `[u8]`. pub fn try_from_iter, I: IntoIterator>>( diff --git a/src/array/fixed_size_list/fmt.rs b/src/array/fixed_size_list/fmt.rs new file mode 100644 index 00000000000..ee7d86115a1 --- /dev/null +++ b/src/array/fixed_size_list/fmt.rs @@ -0,0 +1,24 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::{get_display, write_vec}; +use super::FixedSizeListArray; + +pub fn write_value( + array: &FixedSizeListArray, + index: usize, + null: &'static str, + f: &mut W, +) -> Result { + let values = array.value(index); + let writer = |f: &mut W, index| get_display(values.as_ref(), null)(f, index); + write_vec(f, writer, None, values.len(), null, false) +} + +impl Debug for FixedSizeListArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, "None", f); + + write!(f, "FixedSizeListArray")?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/fixed_size_list/mod.rs b/src/array/fixed_size_list/mod.rs index 79554f54910..197bad87d5e 100644 --- a/src/array/fixed_size_list/mod.rs +++ b/src/array/fixed_size_list/mod.rs @@ -5,9 +5,10 @@ use crate::{ datatypes::{DataType, Field}, }; -use super::{debug_fmt, new_empty_array, new_null_array, Array}; +use super::{new_empty_array, new_null_array, Array}; mod ffi; +pub(super) mod fmt; mod iterator; pub use iterator::*; mod mutable; @@ -195,9 +196,3 @@ impl Array for FixedSizeListArray { Box::new(self.with_validity(validity)) } } - -impl std::fmt::Debug for FixedSizeListArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - debug_fmt(self.iter(), "FixedSizeListArray", f, true) - } -} diff --git a/src/array/fmt.rs b/src/array/fmt.rs new file mode 100644 index 00000000000..39f4f8b1603 --- /dev/null +++ b/src/array/fmt.rs @@ -0,0 +1,180 @@ +use std::fmt::{Result, Write}; + +use crate::bitmap::Bitmap; + +use super::Array; + +/// Returns a function that writes the value of the element of `array` +/// at position `index` to a [`Write`], +/// writing `null` in the null slots. +pub fn get_value_display<'a, F: Write + 'a>( + array: &'a dyn Array, + null: &'static str, +) -> Box Result + 'a> { + use crate::datatypes::PhysicalType::*; + match array.data_type().to_physical_type() { + Null => Box::new(move |f, _| write!(f, "{}", null)), + Boolean => Box::new(|f, index| { + super::boolean::fmt::write_value(array.as_any().downcast_ref().unwrap(), index, f) + }), + Primitive(primitive) => with_match_primitive_type!(primitive, |$T| { + let writer = super::primitive::fmt::get_write_value::<$T, _>( + array.as_any().downcast_ref().unwrap(), + ); + Box::new(move |f, index| writer(f, index)) + }), + Binary => Box::new(|f, index| { + super::binary::fmt::write_value::( + array.as_any().downcast_ref().unwrap(), + index, + f, + ) + }), + FixedSizeBinary => Box::new(|f, index| { + super::fixed_size_binary::fmt::write_value( + array.as_any().downcast_ref().unwrap(), + index, + f, + ) + }), + LargeBinary => Box::new(|f, index| { + super::binary::fmt::write_value::( + array.as_any().downcast_ref().unwrap(), + index, + f, + ) + }), + Utf8 => Box::new(|f, index| { + super::utf8::fmt::write_value::( + array.as_any().downcast_ref().unwrap(), + index, + f, + ) + }), + LargeUtf8 => Box::new(|f, index| { + super::utf8::fmt::write_value::( + array.as_any().downcast_ref().unwrap(), + index, + f, + ) + }), + List => Box::new(move |f, index| { + super::list::fmt::write_value::( + array.as_any().downcast_ref().unwrap(), + index, + null, + f, + ) + }), + FixedSizeList => Box::new(move |f, index| { + super::fixed_size_list::fmt::write_value( + array.as_any().downcast_ref().unwrap(), + index, + null, + f, + ) + }), + LargeList => Box::new(move |f, index| { + super::list::fmt::write_value::( + array.as_any().downcast_ref().unwrap(), + index, + null, + f, + ) + }), + Struct => Box::new(move |f, index| { + super::struct_::fmt::write_value(array.as_any().downcast_ref().unwrap(), index, null, f) + }), + Union => Box::new(move |f, index| { + super::union::fmt::write_value(array.as_any().downcast_ref().unwrap(), index, null, f) + }), + Map => todo!(), + Dictionary(key_type) => match_integer_type!(key_type, |$T| { + Box::new(move |f, index| { + super::dictionary::fmt::write_value::<$T,_>(array.as_any().downcast_ref().unwrap(), index, null, f) + }) + }), + } +} + +/// Returns a function that writes the element of `array` +/// at position `index` to a [`Write`], writing `null` to the null slots. +pub fn get_display<'a, F: Write + 'a>( + array: &'a dyn Array, + null: &'static str, +) -> Box Result + 'a> { + let value_display = get_value_display(array, null); + Box::new(move |f, row| { + if array.is_null(row) { + f.write_str(null) + } else { + value_display(f, row) + } + }) +} + +pub fn write_vec( + f: &mut F, + d: D, + validity: Option<&Bitmap>, + len: usize, + null: &'static str, + new_lines: bool, +) -> Result +where + D: Fn(&mut F, usize) -> Result, + F: Write, +{ + f.write_char('[')?; + write_list(f, d, validity, len, null, new_lines)?; + f.write_char(']')?; + Ok(()) +} + +fn write_list( + f: &mut F, + d: D, + validity: Option<&Bitmap>, + len: usize, + null: &'static str, + new_lines: bool, +) -> Result +where + D: Fn(&mut F, usize) -> Result, + F: Write, +{ + for index in 0..len { + if index != 0 { + f.write_char(',')?; + f.write_char(if new_lines { '\n' } else { ' ' })?; + } + if let Some(val) = validity { + if val.get_bit(index) { + d(f, index) + } else { + write!(f, "{}", null) + } + } else { + d(f, index) + }?; + } + Ok(()) +} + +pub fn write_map( + f: &mut F, + d: D, + validity: Option<&Bitmap>, + len: usize, + null: &'static str, + new_lines: bool, +) -> Result +where + D: Fn(&mut F, usize) -> Result, + F: Write, +{ + f.write_char('{')?; + write_list(f, d, validity, len, null, new_lines)?; + f.write_char('}')?; + Ok(()) +} diff --git a/src/array/list/fmt.rs b/src/array/list/fmt.rs new file mode 100644 index 00000000000..868689a3827 --- /dev/null +++ b/src/array/list/fmt.rs @@ -0,0 +1,31 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use crate::array::Offset; + +use super::super::fmt::{get_display, write_vec}; +use super::ListArray; + +pub fn write_value( + array: &ListArray, + index: usize, + null: &'static str, + f: &mut W, +) -> Result { + let values = array.value(index); + let writer = |f: &mut W, index| get_display(values.as_ref(), null)(f, index); + write_vec(f, writer, None, values.len(), null, false) +} + +impl Debug for ListArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, "None", f); + + let head = if O::is_large() { + "LargeListArray" + } else { + "ListArray" + }; + write!(f, "{}", head)?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/list/mod.rs b/src/array/list/mod.rs index f355285e195..4da1c2835af 100644 --- a/src/array/list/mod.rs +++ b/src/array/list/mod.rs @@ -6,9 +6,10 @@ use crate::{ datatypes::{DataType, Field}, }; -use super::{debug_fmt, new_empty_array, specification::check_offsets, Array, Offset}; +use super::{new_empty_array, specification::check_offsets, Array, Offset}; mod ffi; +pub(super) mod fmt; mod iterator; pub use iterator::*; mod mutable; @@ -236,14 +237,3 @@ impl Array for ListArray { Box::new(self.with_validity(validity)) } } - -impl std::fmt::Debug for ListArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let head = if O::is_large() { - "LargeListArray" - } else { - "ListArray" - }; - debug_fmt(self.iter(), head, f, true) - } -} diff --git a/src/array/mod.rs b/src/array/mod.rs index ff3a26c735b..bff8effb0a6 100644 --- a/src/array/mod.rs +++ b/src/array/mod.rs @@ -19,7 +19,6 @@ use std::any::Any; use crate::error::Result; -use crate::types::{days_ms, months_days_ns}; use crate::{ bitmap::{Bitmap, MutableBitmap}, datatypes::DataType, @@ -350,7 +349,6 @@ impl<'a> AsRef<(dyn Array + 'a)> for dyn Array { mod binary; mod boolean; mod dictionary; -mod display; mod fixed_size_binary; mod fixed_size_list; mod list; @@ -364,11 +362,12 @@ mod utf8; mod equal; mod ffi; +mod fmt; pub mod growable; pub mod ord; -pub use display::get_display; pub use equal::equal; +pub use fmt::{get_display, get_value_display}; pub use crate::types::Offset; pub use binary::{BinaryArray, BinaryValueIter, MutableBinaryArray}; @@ -401,52 +400,6 @@ pub trait TryPush { fn try_push(&mut self, item: A) -> Result<()>; } -fn display_helper>>(iter: I) -> Vec { - iter.into_iter() - .map(|x| match x { - Some(x) => x.to_string(), - None => "None".to_string(), - }) - .collect::>() -} - -fn debug_helper>>(iter: I) -> Vec { - iter.into_iter() - .map(|x| match x { - Some(x) => format!("{:?}", x), - None => "None".to_string(), - }) - .collect::>() -} - -fn debug_fmt>>( - iter: I, - head: &str, - f: &mut std::fmt::Formatter<'_>, - new_lines: bool, -) -> std::fmt::Result { - let result = debug_helper(iter); - if new_lines { - write!(f, "{}[\n{}\n]", head, result.join(",\n")) - } else { - write!(f, "{}[{}]", head, result.join(", ")) - } -} - -fn display_fmt>>( - iter: I, - head: &str, - f: &mut std::fmt::Formatter<'_>, - new_lines: bool, -) -> std::fmt::Result { - let result = display_helper(iter); - if new_lines { - write!(f, "{}[\n{}\n]", head, result.join(",\n")) - } else { - write!(f, "{}[{}]", head, result.join(", ")) - } -} - /// Trait that list arrays implement for the purposes of DRY. pub trait IterableListArray: Array { /// # Safety diff --git a/src/array/primitive/display.rs b/src/array/primitive/display.rs deleted file mode 100644 index c0d33fc4d01..00000000000 --- a/src/array/primitive/display.rs +++ /dev/null @@ -1,15 +0,0 @@ -use crate::types::NativeType; - -use super::super::display::get_value_display; -use super::super::display_fmt; -use super::PrimitiveArray; - -impl std::fmt::Debug for PrimitiveArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let display = get_value_display(self); - let new_lines = false; - let head = &format!("{:?}", self.data_type()); - let iter = self.iter().enumerate().map(|(i, x)| x.map(|_| display(i))); - display_fmt(iter, head, f, new_lines) - } -} diff --git a/src/array/primitive/fmt.rs b/src/array/primitive/fmt.rs new file mode 100644 index 00000000000..5a94b399424 --- /dev/null +++ b/src/array/primitive/fmt.rs @@ -0,0 +1,128 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use crate::array::Array; +use crate::datatypes::{IntervalUnit, TimeUnit}; +use crate::types::{days_ms, months_days_ns}; + +use super::super::super::temporal_conversions; +use super::super::super::types::NativeType; +use super::super::fmt::write_vec; +use super::PrimitiveArray; + +macro_rules! dyn_primitive { + ($array:expr, $ty:ty, $expr:expr) => {{ + let array = ($array as &dyn Array) + .as_any() + .downcast_ref::>() + .unwrap(); + Box::new(move |f, index| write!(f, "{}", $expr(array.value(index)))) + }}; +} + +pub fn get_write_value<'a, T: NativeType, F: Write>( + array: &'a PrimitiveArray, +) -> Box Result + 'a> { + use crate::datatypes::DataType::*; + match array.data_type().to_logical_type() { + Int8 => Box::new(|f, index| write!(f, "{}", array.value(index))), + Int16 => Box::new(|f, index| write!(f, "{}", array.value(index))), + Int32 => Box::new(|f, index| write!(f, "{}", array.value(index))), + Int64 => Box::new(|f, index| write!(f, "{}", array.value(index))), + UInt8 => Box::new(|f, index| write!(f, "{}", array.value(index))), + UInt16 => Box::new(|f, index| write!(f, "{}", array.value(index))), + UInt32 => Box::new(|f, index| write!(f, "{}", array.value(index))), + UInt64 => Box::new(|f, index| write!(f, "{}", array.value(index))), + Float16 => unreachable!(), + Float32 => Box::new(|f, index| write!(f, "{}", array.value(index))), + Float64 => Box::new(|f, index| write!(f, "{}", array.value(index))), + Date32 => { + dyn_primitive!(array, i32, temporal_conversions::date32_to_date) + } + Date64 => { + dyn_primitive!(array, i64, temporal_conversions::date64_to_date) + } + Time32(TimeUnit::Second) => { + dyn_primitive!(array, i32, temporal_conversions::time32s_to_time) + } + Time32(TimeUnit::Millisecond) => { + dyn_primitive!(array, i32, temporal_conversions::time32ms_to_time) + } + Time32(_) => unreachable!(), // remaining are not valid + Time64(TimeUnit::Microsecond) => { + dyn_primitive!(array, i64, temporal_conversions::time64us_to_time) + } + Time64(TimeUnit::Nanosecond) => { + dyn_primitive!(array, i64, temporal_conversions::time64ns_to_time) + } + Time64(_) => unreachable!(), // remaining are not valid + Timestamp(time_unit, tz) => { + if let Some(tz) = tz { + let timezone = temporal_conversions::parse_offset(tz); + match timezone { + Ok(timezone) => { + dyn_primitive!(array, i64, |time| { + temporal_conversions::timestamp_to_datetime(time, *time_unit, &timezone) + }) + } + #[cfg(feature = "chrono-tz")] + Err(_) => { + let timezone = temporal_conversions::parse_offset_tz(tz).unwrap(); + dyn_primitive!(array, i64, |time| { + temporal_conversions::timestamp_to_datetime(time, *time_unit, &timezone) + }) + } + #[cfg(not(feature = "chrono-tz"))] + _ => panic!( + "Invalid Offset format (must be [-]00:00) or chrono-tz feature not active" + ), + } + } else { + dyn_primitive!(array, i64, |time| { + temporal_conversions::timestamp_to_naive_datetime(time, *time_unit) + }) + } + } + Interval(IntervalUnit::YearMonth) => { + dyn_primitive!(array, i32, |x| format!("{}m", x)) + } + Interval(IntervalUnit::DayTime) => { + dyn_primitive!(array, days_ms, |x: days_ms| format!( + "{}d{}ms", + x.days(), + x.milliseconds() + )) + } + Interval(IntervalUnit::MonthDayNano) => { + dyn_primitive!(array, months_days_ns, |x: months_days_ns| format!( + "{}m{}d{}ns", + x.months(), + x.days(), + x.ns() + )) + } + Duration(TimeUnit::Second) => dyn_primitive!(array, i64, |x| format!("{}s", x)), + Duration(TimeUnit::Millisecond) => dyn_primitive!(array, i64, |x| format!("{}ms", x)), + Duration(TimeUnit::Microsecond) => dyn_primitive!(array, i64, |x| format!("{}us", x)), + Duration(TimeUnit::Nanosecond) => dyn_primitive!(array, i64, |x| format!("{}ns", x)), + Decimal(_, scale) => { + // The number 999.99 has a precision of 5 and scale of 2 + let scale = *scale as u32; + let display = move |x| { + let base = x / 10i128.pow(scale); + let decimals = x - base * 10i128.pow(scale); + format!("{}.{}", base, decimals) + }; + dyn_primitive!(array, i128, display) + } + _ => unreachable!(), + } +} + +impl Debug for PrimitiveArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = get_write_value(self); + + write!(f, "{:?}", self.data_type())?; + write_vec(f, &*writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/primitive/mod.rs b/src/array/primitive/mod.rs index 1c2563e3e02..988fad952a9 100644 --- a/src/array/primitive/mod.rs +++ b/src/array/primitive/mod.rs @@ -9,8 +9,8 @@ use crate::{ use super::Array; use either::Either; -mod display; mod ffi; +pub(super) mod fmt; mod from_natural; mod iterator; pub use iterator::*; diff --git a/src/array/struct_/fmt.rs b/src/array/struct_/fmt.rs new file mode 100644 index 00000000000..999cd8b67e0 --- /dev/null +++ b/src/array/struct_/fmt.rs @@ -0,0 +1,34 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::{get_display, write_map, write_vec}; +use super::StructArray; + +pub fn write_value( + array: &StructArray, + index: usize, + null: &'static str, + f: &mut W, +) -> Result { + let writer = |f: &mut W, _index| { + for (i, (field, column)) in array.fields().iter().zip(array.values()).enumerate() { + if i != 0 { + write!(f, ", ")?; + } + let writer = get_display(column.as_ref(), null); + write!(f, "{}: ", field.name)?; + writer(f, index)?; + } + Ok(()) + }; + + write_map(f, writer, None, 1, null, false) +} + +impl Debug for StructArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, "None", f); + + write!(f, "StructArray")?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/struct_/mod.rs b/src/array/struct_/mod.rs index be59347c3bb..d4ae90e3fb4 100644 --- a/src/array/struct_/mod.rs +++ b/src/array/struct_/mod.rs @@ -8,6 +8,7 @@ use crate::{ use super::{new_empty_array, new_null_array, Array}; mod ffi; +pub(super) mod fmt; mod iterator; /// A [`StructArray`] is a nested [`Array`] with an optional validity representing @@ -220,13 +221,3 @@ impl Array for StructArray { Box::new(self.with_validity(validity)) } } - -impl std::fmt::Debug for StructArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - writeln!(f, "StructArray{{")?; - for (field, column) in self.fields().iter().zip(self.values()) { - writeln!(f, "{}: {:?},", field.name, column)?; - } - write!(f, "}}") - } -} diff --git a/src/array/union/fmt.rs b/src/array/union/fmt.rs new file mode 100644 index 00000000000..521201fffd6 --- /dev/null +++ b/src/array/union/fmt.rs @@ -0,0 +1,24 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::{get_display, write_vec}; +use super::UnionArray; + +pub fn write_value( + array: &UnionArray, + index: usize, + null: &'static str, + f: &mut W, +) -> Result { + let (field, index) = array.index(index); + + get_display(array.fields()[field].as_ref(), null)(f, index) +} + +impl Debug for UnionArray { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, "None", f); + + write!(f, "UnionArray")?; + write_vec(f, writer, None, self.len(), "None", false) + } +} diff --git a/src/array/union/mod.rs b/src/array/union/mod.rs index 5ef0ff9d86d..4cbc51d6edf 100644 --- a/src/array/union/mod.rs +++ b/src/array/union/mod.rs @@ -1,14 +1,16 @@ use std::{collections::HashMap, sync::Arc}; use crate::{ - array::{display::get_value_display, display_fmt, new_empty_array, new_null_array, Array}, bitmap::Bitmap, buffer::Buffer, datatypes::{DataType, Field, UnionMode}, scalar::{new_scalar, Scalar}, }; +use super::{new_empty_array, new_null_array, Array}; + mod ffi; +pub(super) mod fmt; mod iterator; type FieldEntry = (usize, Arc); @@ -273,16 +275,3 @@ impl UnionArray { Self::get_all(data_type).2.is_sparse() } } - -impl std::fmt::Debug for UnionArray { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let display = get_value_display(self); - let new_lines = false; - let head = "UnionArray"; - let iter = self - .iter() - .enumerate() - .map(|(i, x)| if x.is_valid() { Some(display(i)) } else { None }); - display_fmt(iter, head, f, new_lines) - } -} diff --git a/src/array/utf8/fmt.rs b/src/array/utf8/fmt.rs new file mode 100644 index 00000000000..3752e2bfbda --- /dev/null +++ b/src/array/utf8/fmt.rs @@ -0,0 +1,23 @@ +use std::fmt::{Debug, Formatter, Result, Write}; + +use super::super::fmt::write_vec; +use super::super::Offset; +use super::Utf8Array; + +pub fn write_value(array: &Utf8Array, index: usize, f: &mut W) -> Result { + write!(f, "{}", array.value(index)) +} + +impl Debug for Utf8Array { + fn fmt(&self, f: &mut Formatter<'_>) -> Result { + let writer = |f: &mut Formatter, index| write_value(self, index, f); + + let head = if O::is_large() { + "LargeUtf8Array" + } else { + "Utf8Array" + }; + write!(f, "{}", head)?; + write_vec(f, writer, self.validity(), self.len(), "None", false) + } +} diff --git a/src/array/utf8/mod.rs b/src/array/utf8/mod.rs index 015941325ef..84ad09548bf 100644 --- a/src/array/utf8/mod.rs +++ b/src/array/utf8/mod.rs @@ -7,12 +7,12 @@ use crate::{ use either::Either; use super::{ - display_fmt, specification::{check_offsets_minimal, try_check_offsets_and_utf8}, Array, GenericBinaryArray, Offset, }; mod ffi; +pub(super) mod fmt; mod from; mod iterator; mod mutable; @@ -367,12 +367,6 @@ impl Array for Utf8Array { } } -impl std::fmt::Debug for Utf8Array { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - display_fmt(self.iter(), &format!("{:?}", self.data_type()), f, false) - } -} - unsafe impl GenericBinaryArray for Utf8Array { #[inline] fn values(&self) -> &[u8] { diff --git a/src/io/print.rs b/src/io/print.rs index 1f5e8c1b9c3..08cc3e3efb8 100644 --- a/src/io/print.rs +++ b/src/io/print.rs @@ -23,14 +23,15 @@ pub fn write, N: AsRef>(batches: &[Chunk], names: &[ let displayes = batch .arrays() .iter() - .map(|array| get_display(array.as_ref())) + .map(|array| get_display(array.as_ref(), "")) .collect::>(); for row in 0..batch.len() { let mut cells = Vec::new(); (0..batch.arrays().len()).for_each(|col| { - let string = displayes[col](row); - cells.push(Cell::new(&string)); + let mut string = String::new(); + displayes[col](&mut string, row).unwrap(); + cells.push(Cell::new(string)); }); table.add_row(cells); } diff --git a/tests/it/array/boolean/mod.rs b/tests/it/array/boolean/mod.rs index 2e97cc6f360..9b9ee57bd28 100644 --- a/tests/it/array/boolean/mod.rs +++ b/tests/it/array/boolean/mod.rs @@ -48,7 +48,7 @@ fn with_validity() { } #[test] -fn display() { +fn debug() { let array = BooleanArray::from([Some(true), None, Some(false)]); assert_eq!(format!("{:?}", array), "BooleanArray[true, None, false]"); } diff --git a/tests/it/array/fixed_size_binary/mod.rs b/tests/it/array/fixed_size_binary/mod.rs index 036ff136171..9d8c2cd728a 100644 --- a/tests/it/array/fixed_size_binary/mod.rs +++ b/tests/it/array/fixed_size_binary/mod.rs @@ -30,7 +30,7 @@ fn with_validity() { } #[test] -fn display() { +fn debug() { let values = Buffer::from_slice([1, 2, 3, 4, 5, 6]); let a = FixedSizeBinaryArray::from_data( DataType::FixedSizeBinary(2), @@ -39,7 +39,7 @@ fn display() { ); assert_eq!( format!("{:?}", a), - "FixedSizeBinaryArray[[1, 2], None, [5, 6]]" + "FixedSizeBinary(2)[[1, 2], None, [5, 6]]" ); } diff --git a/tests/it/array/list/mod.rs b/tests/it/array/list/mod.rs index 431459c1ba7..78bc8dcd719 100644 --- a/tests/it/array/list/mod.rs +++ b/tests/it/array/list/mod.rs @@ -7,7 +7,7 @@ use arrow2::datatypes::DataType; mod mutable; #[test] -fn display() { +fn debug() { let values = Buffer::from_slice([1, 2, 3, 4, 5]); let values = PrimitiveArray::::from_data(DataType::Int32, values, None); @@ -19,10 +19,7 @@ fn display() { None, ); - assert_eq!( - format!("{:?}", array), - "ListArray[\nInt32[1, 2],\nInt32[],\nInt32[3],\nInt32[4, 5]\n]" - ); + assert_eq!(format!("{:?}", array), "ListArray[[1, 2], [], [3], [4, 5]]"); } #[test] @@ -70,6 +67,6 @@ fn test_nested_display() { None, ); - let expected = "ListArray[\nListArray[\nInt32[1, 2],\nInt32[3, 4]\n],\nListArray[\nInt32[5, 6, 7],\nInt32[],\nInt32[8]\n],\nListArray[\nInt32[9, 10]\n]\n]"; + let expected = "ListArray[[[1, 2], [3, 4]], [[5, 6, 7], [], [8]], [[9, 10]]]"; assert_eq!(format!("{:?}", nested), expected); } diff --git a/tests/it/array/primitive/mod.rs b/tests/it/array/primitive/mod.rs index 341cc0615de..b2080577eae 100644 --- a/tests/it/array/primitive/mod.rs +++ b/tests/it/array/primitive/mod.rs @@ -77,13 +77,13 @@ fn from() { } #[test] -fn display_int32() { +fn debug_int32() { let array = Int32Array::from(&[Some(1), None, Some(2)]); assert_eq!(format!("{:?}", array), "Int32[1, None, 2]"); } #[test] -fn display_date32() { +fn debug_date32() { let array = Int32Array::from(&[Some(1), None, Some(2)]).to(DataType::Date32); assert_eq!( format!("{:?}", array), @@ -92,7 +92,7 @@ fn display_date32() { } #[test] -fn display_time32s() { +fn debug_time32s() { let array = Int32Array::from(&[Some(1), None, Some(2)]).to(DataType::Time32(TimeUnit::Second)); assert_eq!( format!("{:?}", array), @@ -101,7 +101,7 @@ fn display_time32s() { } #[test] -fn display_time32ms() { +fn debug_time32ms() { let array = Int32Array::from(&[Some(1), None, Some(2)]).to(DataType::Time32(TimeUnit::Millisecond)); assert_eq!( @@ -111,20 +111,20 @@ fn display_time32ms() { } #[test] -fn display_interval_d() { +fn debug_interval_d() { let array = Int32Array::from(&[Some(1), None, Some(2)]).to(DataType::Interval(IntervalUnit::YearMonth)); assert_eq!(format!("{:?}", array), "Interval(YearMonth)[1m, None, 2m]"); } #[test] -fn display_int64() { +fn debug_int64() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Int64); assert_eq!(format!("{:?}", array), "Int64[1, None, 2]"); } #[test] -fn display_date64() { +fn debug_date64() { let array = Int64Array::from(&[Some(1), None, Some(86400000)]).to(DataType::Date64); assert_eq!( format!("{:?}", array), @@ -133,7 +133,7 @@ fn display_date64() { } #[test] -fn display_time64us() { +fn debug_time64us() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Time64(TimeUnit::Microsecond)); assert_eq!( @@ -143,7 +143,7 @@ fn display_time64us() { } #[test] -fn display_time64ns() { +fn debug_time64ns() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Time64(TimeUnit::Nanosecond)); assert_eq!( @@ -153,7 +153,7 @@ fn display_time64ns() { } #[test] -fn display_timestamp_s() { +fn debug_timestamp_s() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Timestamp(TimeUnit::Second, None)); assert_eq!( @@ -163,7 +163,7 @@ fn display_timestamp_s() { } #[test] -fn display_timestamp_ms() { +fn debug_timestamp_ms() { let array = Int64Array::from(&[Some(1), None, Some(2)]) .to(DataType::Timestamp(TimeUnit::Millisecond, None)); assert_eq!( @@ -173,7 +173,7 @@ fn display_timestamp_ms() { } #[test] -fn display_timestamp_us() { +fn debug_timestamp_us() { let array = Int64Array::from(&[Some(1), None, Some(2)]) .to(DataType::Timestamp(TimeUnit::Microsecond, None)); assert_eq!( @@ -183,7 +183,7 @@ fn display_timestamp_us() { } #[test] -fn display_timestamp_ns() { +fn debug_timestamp_ns() { let array = Int64Array::from(&[Some(1), None, Some(2)]) .to(DataType::Timestamp(TimeUnit::Nanosecond, None)); assert_eq!( @@ -193,7 +193,7 @@ fn display_timestamp_ns() { } #[test] -fn display_timestamp_tz_ns() { +fn debug_timestamp_tz_ns() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Timestamp( TimeUnit::Nanosecond, Some("+02:00".to_string()), @@ -205,7 +205,7 @@ fn display_timestamp_tz_ns() { } #[test] -fn display_duration_ms() { +fn debug_duration_ms() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Duration(TimeUnit::Millisecond)); assert_eq!( @@ -215,14 +215,14 @@ fn display_duration_ms() { } #[test] -fn display_duration_s() { +fn debug_duration_s() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Duration(TimeUnit::Second)); assert_eq!(format!("{:?}", array), "Duration(Second)[1s, None, 2s]"); } #[test] -fn display_duration_us() { +fn debug_duration_us() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Duration(TimeUnit::Microsecond)); assert_eq!( @@ -232,7 +232,7 @@ fn display_duration_us() { } #[test] -fn display_duration_ns() { +fn debug_duration_ns() { let array = Int64Array::from(&[Some(1), None, Some(2)]).to(DataType::Duration(TimeUnit::Nanosecond)); assert_eq!( @@ -242,7 +242,7 @@ fn display_duration_ns() { } #[test] -fn display_decimal() { +fn debug_decimal() { let array = Int128Array::from(&[Some(12345), None, Some(23456)]).to(DataType::Decimal(5, 2)); assert_eq!( format!("{:?}", array), @@ -251,7 +251,7 @@ fn display_decimal() { } #[test] -fn display_decimal1() { +fn debug_decimal1() { let array = Int128Array::from(&[Some(12345), None, Some(23456)]).to(DataType::Decimal(5, 1)); assert_eq!( format!("{:?}", array), @@ -260,7 +260,7 @@ fn display_decimal1() { } #[test] -fn display_interval_days_ms() { +fn debug_interval_days_ms() { let array = DaysMsArray::from(&[Some(days_ms::new(1, 1)), None, Some(days_ms::new(2, 2))]); assert_eq!( format!("{:?}", array), diff --git a/tests/it/array/struct_/mod.rs b/tests/it/array/struct_/mod.rs index 27325c6a68f..cd88fb8933e 100644 --- a/tests/it/array/struct_/mod.rs +++ b/tests/it/array/struct_/mod.rs @@ -1 +1,27 @@ mod iterator; + +use arrow2::array::*; +use arrow2::bitmap::Bitmap; +use arrow2::datatypes::*; + +#[test] +fn debug() { + use std::sync::Arc; + let boolean = Arc::new(BooleanArray::from_slice(&[false, false, true, true])) as Arc; + let int = Arc::new(Int32Array::from_slice(&[42, 28, 19, 31])) as Arc; + + let fields = vec![ + Field::new("b", DataType::Boolean, false), + Field::new("c", DataType::Int32, false), + ]; + + let array = StructArray::from_data( + DataType::Struct(fields), + vec![boolean.clone(), int.clone()], + Some(Bitmap::from([true, true, false, true])), + ); + assert_eq!( + format!("{:?}", array), + "StructArray[{b: false, c: 42}, {b: false, c: 28}, None, {b: true, c: 31}]" + ); +}