Added Decimal support to pretty-print display utility (#230) (#273)

* Added Decimal support to pretty-print display utility (#230)

* Applied cargo fmt to fix linting errors

* Added proper printing for decimals based on scale, moved tests to pretty.rs

* Applied cargo fmt on pretty test

Co-authored-by: Manish Gill <manish.gill@tomtom.com>
diff --git a/arrow/src/util/display.rs b/arrow/src/util/display.rs
index e40abab..61f549a 100644
--- a/arrow/src/util/display.rs
+++ b/arrow/src/util/display.rs
@@ -192,6 +192,20 @@
     }};
 }
 
+macro_rules! make_string_from_decimal {
+    ($array_type: ty, $column: ident, $row: ident, $scale: ident) => {{
+        let array = $column.as_any().downcast_ref::<$array_type>().unwrap();
+        let decimal_string = array.value($row).to_string();
+        let formatted_decimal = if *$scale == 0 {
+            decimal_string
+        } else {
+            let splits = decimal_string.split_at(decimal_string.len() - *$scale);
+            format!("{}.{}", splits.0, splits.1)
+        };
+        Ok(formatted_decimal)
+    }};
+}
+
 /// Get the value at the given row in an array as a String.
 ///
 /// Note this function is quite inefficient and is unlikely to be
@@ -217,6 +231,9 @@
         DataType::Float16 => make_string!(array::Float32Array, column, row),
         DataType::Float32 => make_string!(array::Float32Array, column, row),
         DataType::Float64 => make_string!(array::Float64Array, column, row),
+        DataType::Decimal(_, scale) => {
+            make_string_from_decimal!(array::DecimalArray, column, row, scale)
+        }
         DataType::Timestamp(unit, _) if *unit == TimeUnit::Second => {
             make_string_datetime!(array::TimestampSecondArray, column, row)
         }
diff --git a/arrow/src/util/pretty.rs b/arrow/src/util/pretty.rs
index f354899..d307406 100644
--- a/arrow/src/util/pretty.rs
+++ b/arrow/src/util/pretty.rs
@@ -115,6 +115,7 @@
     };
 
     use super::*;
+    use crate::array::{DecimalBuilder, Int32Array};
     use std::sync::Arc;
 
     #[test]
@@ -418,4 +419,92 @@
         ];
         check_datetime!(Time64NanosecondArray, 11111111, expected);
     }
+
+    #[test]
+    fn test_int_display() -> Result<()> {
+        let array = Arc::new(Int32Array::from(vec![6, 3])) as ArrayRef;
+        let actual_one = array_value_to_string(&array, 0).unwrap();
+        let expected_one = "6";
+
+        let actual_two = array_value_to_string(&array, 1).unwrap();
+        let expected_two = "3";
+        assert_eq!(actual_one, expected_one);
+        assert_eq!(actual_two, expected_two);
+        Ok(())
+    }
+
+    #[test]
+    fn test_decimal_display() -> Result<()> {
+        let capacity = 10;
+        let precision = 10;
+        let scale = 2;
+
+        let mut builder = DecimalBuilder::new(capacity, precision, scale);
+        builder.append_value(101).unwrap();
+        builder.append_null().unwrap();
+        builder.append_value(200).unwrap();
+        builder.append_value(3040).unwrap();
+
+        let dm = Arc::new(builder.finish()) as ArrayRef;
+
+        let schema = Arc::new(Schema::new(vec![Field::new(
+            "f",
+            dm.data_type().clone(),
+            true,
+        )]));
+
+        let batch = RecordBatch::try_new(schema, vec![dm])?;
+
+        let table = pretty_format_batches(&[batch])?;
+
+        let expected = vec![
+            "+-------+",
+            "| f     |",
+            "+-------+",
+            "| 1.01  |",
+            "|       |",
+            "| 2.00  |",
+            "| 30.40 |",
+            "+-------+",
+        ];
+
+        let actual: Vec<&str> = table.lines().collect();
+        assert_eq!(expected, actual, "Actual result:\n{}", table);
+
+        Ok(())
+    }
+
+    #[test]
+    fn test_decimal_display_zero_scale() -> Result<()> {
+        let capacity = 10;
+        let precision = 5;
+        let scale = 0;
+
+        let mut builder = DecimalBuilder::new(capacity, precision, scale);
+        builder.append_value(101).unwrap();
+        builder.append_null().unwrap();
+        builder.append_value(200).unwrap();
+        builder.append_value(3040).unwrap();
+
+        let dm = Arc::new(builder.finish()) as ArrayRef;
+
+        let schema = Arc::new(Schema::new(vec![Field::new(
+            "f",
+            dm.data_type().clone(),
+            true,
+        )]));
+
+        let batch = RecordBatch::try_new(schema, vec![dm])?;
+
+        let table = pretty_format_batches(&[batch])?;
+        let expected = vec![
+            "+------+", "| f    |", "+------+", "| 101  |", "|      |", "| 200  |",
+            "| 3040 |", "+------+",
+        ];
+
+        let actual: Vec<&str> = table.lines().collect();
+        assert_eq!(expected, actual, "Actual result:\n{}", table);
+
+        Ok(())
+    }
 }