Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 75 additions & 0 deletions rust/arrow/src/array.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@

use std::any::Any;
use std::convert::From;
use std::fmt;
use std::io::Write;
use std::mem;
use std::sync::Arc;
Expand Down Expand Up @@ -248,6 +249,20 @@ impl<T: ArrowNumericType> PrimitiveArray<T> {
}
}

impl<T: ArrowNumericType> fmt::Debug for PrimitiveArray<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PrimitiveArray<{:?}>\n[\n", T::get_data_type())?;
for i in 0..self.len() {
if self.is_null(i) {
write!(f, " null,\n")?;
} else {
write!(f, " {:?},\n", self.value(i))?;
}
}
write!(f, "]")
}
}

/// Specific implementation for Boolean arrays due to bit-packing
impl PrimitiveArray<BooleanType> {
pub fn new(length: usize, values: Buffer, null_count: usize, offset: usize) -> Self {
Expand Down Expand Up @@ -280,6 +295,20 @@ impl PrimitiveArray<BooleanType> {
}
}

impl fmt::Debug for PrimitiveArray<BooleanType> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "PrimitiveArray<{:?}>\n[\n", BooleanType::get_data_type())?;
for i in 0..self.len() {
if self.is_null(i) {
write!(f, " null,\n")?
} else {
write!(f, " {:?},\n", self.value(i))?
}
}
write!(f, "]")
}
}

// TODO: the macro is needed here because we'd get "conflicting implementations" error
// otherwise with both `From<Vec<T::Native>>` and `From<Vec<Option<T::Native>>>`.
// We should revisit this in future.
Expand Down Expand Up @@ -761,6 +790,52 @@ mod tests {
let _slice = arr.value_slice(0, 4);
}

#[test]
fn test_int32_fmt_debug() {
let buf = Buffer::from(&[0, 1, 2, 3, 4].to_byte_slice());
let arr = Int32Array::new(5, buf, 0, 0);
assert_eq!(
"PrimitiveArray<Int32>\n[\n 0,\n 1,\n 2,\n 3,\n 4,\n]",
format!("{:?}", arr)
);
}

#[test]
fn test_int32_with_null_fmt_debug() {
let mut builder = Int32Array::builder(3);
builder.append_slice(&[0, 1]).unwrap();
builder.append_null().unwrap();
builder.append_slice(&[3, 4]).unwrap();
let arr = builder.finish();
assert_eq!(
"PrimitiveArray<Int32>\n[\n 0,\n 1,\n null,\n 3,\n 4,\n]",
format!("{:?}", arr)
);
}

#[test]
fn test_boolean_fmt_debug() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May you please add tests for null values, I don't think you handle them because getting a null value returns invalid data.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will do! Thanks

let buf = Buffer::from(&[true, false, false].to_byte_slice());
let arr = BooleanArray::new(3, buf, 0, 0);
assert_eq!(
"PrimitiveArray<Boolean>\n[\n true,\n false,\n false,\n]",
format!("{:?}", arr)
);
}

#[test]
fn test_boolean_with_null_fmt_debug() {
let mut builder = BooleanArray::builder(3);
builder.append_value(true).unwrap();
builder.append_null().unwrap();
builder.append_value(false).unwrap();
let arr = builder.finish();
assert_eq!(
"PrimitiveArray<Boolean>\n[\n true,\n null,\n false,\n]",
format!("{:?}", arr)
);
}

#[test]
fn test_primitive_array_builder() {
// Test building an primitive array with ArrayData builder and offset
Expand Down
5 changes: 4 additions & 1 deletion rust/arrow/src/datatypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ pub struct Field {
nullable: bool,
}

pub trait ArrowNativeType: Send + Sync + Copy + PartialOrd + FromStr + 'static {}
pub trait ArrowNativeType:
fmt::Debug + Send + Sync + Copy + PartialOrd + FromStr + 'static
{
}

/// Trait indicating a primitive fixed-width type (bool, ints and floats).
pub trait ArrowPrimitiveType: 'static {
Expand Down