1use arrow::{
6 array::{
7 Array, BinaryArray, BooleanArray, Date32Array, Date64Array, Float32Array, Float64Array,
8 Int16Array, Int32Array, Int64Array, Int8Array, LargeBinaryArray, LargeStringArray,
9 StringArray, TimestampMicrosecondArray, TimestampMillisecondArray,
10 TimestampNanosecondArray, TimestampSecondArray, UInt16Array, UInt32Array, UInt64Array,
11 UInt8Array,
12 },
13 datatypes::DataType,
14};
15
16use super::error::TuiResult;
17
18pub fn format_array_value(array: &dyn Array, row: usize) -> TuiResult<Option<String>> {
34 if row >= array.len() {
36 return Ok(None);
37 }
38
39 if array.is_null(row) {
41 return Ok(Some("NULL".to_string()));
42 }
43
44 let formatted = match array.data_type() {
45 DataType::Utf8 => format_utf8(array, row),
47 DataType::LargeUtf8 => format_large_utf8(array, row),
48
49 DataType::Int8 => format_int8(array, row),
51 DataType::Int16 => format_int16(array, row),
52 DataType::Int32 => format_int32(array, row),
53 DataType::Int64 => format_int64(array, row),
54 DataType::UInt8 => format_uint8(array, row),
55 DataType::UInt16 => format_uint16(array, row),
56 DataType::UInt32 => format_uint32(array, row),
57 DataType::UInt64 => format_uint64(array, row),
58
59 DataType::Float32 => format_float32(array, row),
61 DataType::Float64 => format_float64(array, row),
62
63 DataType::Boolean => format_boolean(array, row),
65
66 DataType::Binary => format_binary(array, row),
68 DataType::LargeBinary => format_large_binary(array, row),
69
70 DataType::Date32 => format_date32(array, row),
72 DataType::Date64 => format_date64(array, row),
73
74 DataType::Timestamp(unit, _) => format_timestamp(array, row, *unit),
76
77 DataType::Null => Some("NULL".to_string()),
79
80 other => Some(format!("<{}>", type_name(other))),
82 };
83
84 Ok(formatted)
85}
86
87fn type_name(dt: &DataType) -> &'static str {
89 match dt {
90 DataType::Null => "null",
91 DataType::Boolean => "bool",
92 DataType::Int8 => "i8",
93 DataType::Int16 => "i16",
94 DataType::Int32 => "i32",
95 DataType::Int64 => "i64",
96 DataType::UInt8 => "u8",
97 DataType::UInt16 => "u16",
98 DataType::UInt32 => "u32",
99 DataType::UInt64 => "u64",
100 DataType::Float32 => "f32",
101 DataType::Float64 => "f64",
102 DataType::Utf8 => "string",
103 DataType::LargeUtf8 => "large_string",
104 DataType::Binary => "binary",
105 DataType::LargeBinary => "large_binary",
106 DataType::Date32 => "date32",
107 DataType::Date64 => "date64",
108 DataType::Timestamp(_, _) => "timestamp",
109 DataType::List(_) => "list",
110 DataType::LargeList(_) => "large_list",
111 DataType::Struct(_) => "struct",
112 DataType::Map(_, _) => "map",
113 DataType::Dictionary(_, _) => "dict",
114 _ => "unknown",
115 }
116}
117
118fn format_utf8(array: &dyn Array, row: usize) -> Option<String> {
121 array
122 .as_any()
123 .downcast_ref::<StringArray>()
124 .map(|arr| arr.value(row).to_string())
125}
126
127fn format_large_utf8(array: &dyn Array, row: usize) -> Option<String> {
128 array
129 .as_any()
130 .downcast_ref::<LargeStringArray>()
131 .map(|arr| arr.value(row).to_string())
132}
133
134fn format_int8(array: &dyn Array, row: usize) -> Option<String> {
135 array
136 .as_any()
137 .downcast_ref::<Int8Array>()
138 .map(|arr| arr.value(row).to_string())
139}
140
141fn format_int16(array: &dyn Array, row: usize) -> Option<String> {
142 array
143 .as_any()
144 .downcast_ref::<Int16Array>()
145 .map(|arr| arr.value(row).to_string())
146}
147
148fn format_int32(array: &dyn Array, row: usize) -> Option<String> {
149 array
150 .as_any()
151 .downcast_ref::<Int32Array>()
152 .map(|arr| arr.value(row).to_string())
153}
154
155fn format_int64(array: &dyn Array, row: usize) -> Option<String> {
156 array
157 .as_any()
158 .downcast_ref::<Int64Array>()
159 .map(|arr| arr.value(row).to_string())
160}
161
162fn format_uint8(array: &dyn Array, row: usize) -> Option<String> {
163 array
164 .as_any()
165 .downcast_ref::<UInt8Array>()
166 .map(|arr| arr.value(row).to_string())
167}
168
169fn format_uint16(array: &dyn Array, row: usize) -> Option<String> {
170 array
171 .as_any()
172 .downcast_ref::<UInt16Array>()
173 .map(|arr| arr.value(row).to_string())
174}
175
176fn format_uint32(array: &dyn Array, row: usize) -> Option<String> {
177 array
178 .as_any()
179 .downcast_ref::<UInt32Array>()
180 .map(|arr| arr.value(row).to_string())
181}
182
183fn format_uint64(array: &dyn Array, row: usize) -> Option<String> {
184 array
185 .as_any()
186 .downcast_ref::<UInt64Array>()
187 .map(|arr| arr.value(row).to_string())
188}
189
190fn format_float32(array: &dyn Array, row: usize) -> Option<String> {
191 array
192 .as_any()
193 .downcast_ref::<Float32Array>()
194 .map(|arr| format!("{:.2}", arr.value(row)))
195}
196
197fn format_float64(array: &dyn Array, row: usize) -> Option<String> {
198 array
199 .as_any()
200 .downcast_ref::<Float64Array>()
201 .map(|arr| format!("{:.4}", arr.value(row)))
202}
203
204fn format_boolean(array: &dyn Array, row: usize) -> Option<String> {
205 array
206 .as_any()
207 .downcast_ref::<BooleanArray>()
208 .map(|arr| if arr.value(row) { "true" } else { "false" }.to_string())
209}
210
211fn format_binary(array: &dyn Array, row: usize) -> Option<String> {
212 array.as_any().downcast_ref::<BinaryArray>().map(|arr| {
213 let bytes = arr.value(row);
214 format_bytes_preview(bytes)
215 })
216}
217
218fn format_large_binary(array: &dyn Array, row: usize) -> Option<String> {
219 array
220 .as_any()
221 .downcast_ref::<LargeBinaryArray>()
222 .map(|arr| {
223 let bytes = arr.value(row);
224 format_bytes_preview(bytes)
225 })
226}
227
228fn format_bytes_preview(bytes: &[u8]) -> String {
230 if bytes.len() <= 8 {
231 format!("0x{}", hex_encode(bytes))
232 } else {
233 format!("0x{}... ({} bytes)", hex_encode(&bytes[..8]), bytes.len())
234 }
235}
236
237fn hex_encode(bytes: &[u8]) -> String {
239 use std::fmt::Write;
240 let mut result = String::with_capacity(bytes.len() * 2);
241 for b in bytes {
242 let _ = write!(result, "{b:02x}");
243 }
244 result
245}
246
247fn format_date32(array: &dyn Array, row: usize) -> Option<String> {
248 array.as_any().downcast_ref::<Date32Array>().map(|arr| {
249 let days = arr.value(row);
250 format!("date:{days}")
252 })
253}
254
255fn format_date64(array: &dyn Array, row: usize) -> Option<String> {
256 array.as_any().downcast_ref::<Date64Array>().map(|arr| {
257 let millis = arr.value(row);
258 format!("date64:{millis}")
259 })
260}
261
262fn format_timestamp(
263 array: &dyn Array,
264 row: usize,
265 unit: arrow::datatypes::TimeUnit,
266) -> Option<String> {
267 use arrow::datatypes::TimeUnit;
268
269 match unit {
270 TimeUnit::Second => array
271 .as_any()
272 .downcast_ref::<TimestampSecondArray>()
273 .map(|arr| format!("ts:{}", arr.value(row))),
274 TimeUnit::Millisecond => array
275 .as_any()
276 .downcast_ref::<TimestampMillisecondArray>()
277 .map(|arr| format!("ts:{}", arr.value(row))),
278 TimeUnit::Microsecond => array
279 .as_any()
280 .downcast_ref::<TimestampMicrosecondArray>()
281 .map(|arr| format!("ts:{}", arr.value(row))),
282 TimeUnit::Nanosecond => array
283 .as_any()
284 .downcast_ref::<TimestampNanosecondArray>()
285 .map(|arr| format!("ts:{}", arr.value(row))),
286 }
287}
288
289pub fn truncate_string(s: &str, max_width: usize) -> String {
301 if max_width < 3 {
302 return s.chars().take(max_width).collect();
303 }
304
305 let char_count = s.chars().count();
306 if char_count <= max_width {
307 return s.to_string();
308 }
309
310 let truncate_at = max_width.saturating_sub(2);
312 let mut result: String = s.chars().take(truncate_at).collect();
313 result.push_str("..");
314 result
315}
316
317pub fn display_width(s: &str) -> usize {
322 s.chars().count()
323}
324
325#[cfg(test)]
326mod tests {
327 use std::sync::Arc;
328
329 use arrow::array::{
330 ArrayRef, BinaryArray, BooleanArray, Date32Array, Date64Array, Float32Array, Float64Array,
331 Int16Array, Int32Array, Int64Array, Int8Array, LargeBinaryArray, LargeStringArray,
332 NullArray, StringArray, TimestampMillisecondArray, UInt16Array, UInt32Array, UInt64Array,
333 UInt8Array,
334 };
335
336 use super::*;
337
338 fn make_string_array(values: Vec<Option<&str>>) -> ArrayRef {
339 Arc::new(StringArray::from(values))
340 }
341
342 fn make_int32_array(values: Vec<Option<i32>>) -> ArrayRef {
343 Arc::new(Int32Array::from(values))
344 }
345
346 fn make_float32_array(values: Vec<Option<f32>>) -> ArrayRef {
347 Arc::new(Float32Array::from(values))
348 }
349
350 fn make_int8_array(values: Vec<Option<i8>>) -> ArrayRef {
351 Arc::new(Int8Array::from(values))
352 }
353
354 fn make_int16_array(values: Vec<Option<i16>>) -> ArrayRef {
355 Arc::new(Int16Array::from(values))
356 }
357
358 fn make_int64_array(values: Vec<Option<i64>>) -> ArrayRef {
359 Arc::new(Int64Array::from(values))
360 }
361
362 fn make_uint8_array(values: Vec<Option<u8>>) -> ArrayRef {
363 Arc::new(UInt8Array::from(values))
364 }
365
366 fn make_uint16_array(values: Vec<Option<u16>>) -> ArrayRef {
367 Arc::new(UInt16Array::from(values))
368 }
369
370 fn make_uint32_array(values: Vec<Option<u32>>) -> ArrayRef {
371 Arc::new(UInt32Array::from(values))
372 }
373
374 fn make_uint64_array(values: Vec<Option<u64>>) -> ArrayRef {
375 Arc::new(UInt64Array::from(values))
376 }
377
378 fn make_float64_array(values: Vec<Option<f64>>) -> ArrayRef {
379 Arc::new(Float64Array::from(values))
380 }
381
382 fn make_boolean_array(values: Vec<Option<bool>>) -> ArrayRef {
383 Arc::new(BooleanArray::from(values))
384 }
385
386 #[test]
387 fn f_format_utf8_string() {
388 let array = make_string_array(vec![Some("hello"), Some("world")]);
389 let result = format_array_value(array.as_ref(), 0).unwrap();
390 assert_eq!(result, Some("hello".to_string()));
391 }
392
393 #[test]
394 fn f_format_utf8_null() {
395 let array = make_string_array(vec![None, Some("world")]);
396 let result = format_array_value(array.as_ref(), 0).unwrap();
397 assert_eq!(result, Some("NULL".to_string()));
398 }
399
400 #[test]
401 fn f_format_int32() {
402 let array = make_int32_array(vec![Some(42), Some(-100)]);
403 let result = format_array_value(array.as_ref(), 0).unwrap();
404 assert_eq!(result, Some("42".to_string()));
405
406 let result_neg = format_array_value(array.as_ref(), 1).unwrap();
407 assert_eq!(result_neg, Some("-100".to_string()));
408 }
409
410 #[test]
411 fn f_format_float32() {
412 let array = make_float32_array(vec![Some(2.71), Some(2.0)]);
413 let result = format_array_value(array.as_ref(), 0).unwrap();
414 assert_eq!(result, Some("2.71".to_string()));
415 }
416
417 #[test]
418 fn f_format_out_of_bounds() {
419 let array = make_string_array(vec![Some("hello")]);
420 let result = format_array_value(array.as_ref(), 10).unwrap();
421 assert_eq!(result, None);
422 }
423
424 #[test]
425 fn f_truncate_string_short() {
426 let s = "hello";
427 assert_eq!(truncate_string(s, 10), "hello");
428 }
429
430 #[test]
431 fn f_truncate_string_exact() {
432 let s = "hello";
433 assert_eq!(truncate_string(s, 5), "hello");
434 }
435
436 #[test]
437 fn f_truncate_string_long() {
438 let s = "hello world this is a long string";
439 let result = truncate_string(s, 10);
440 assert!(result.ends_with(".."));
441 assert!(result.chars().count() <= 10);
442 }
443
444 #[test]
445 fn f_truncate_string_very_short_max() {
446 let s = "hello";
447 let result = truncate_string(s, 2);
448 assert_eq!(result.chars().count(), 2);
449 }
450
451 #[test]
452 fn f_display_width_ascii() {
453 assert_eq!(display_width("hello"), 5);
454 }
455
456 #[test]
457 fn f_display_width_unicode() {
458 assert_eq!(display_width("日本語"), 3);
459 }
460
461 #[test]
462 fn f_display_width_empty() {
463 assert_eq!(display_width(""), 0);
464 }
465
466 #[test]
467 fn f_hex_encode_empty() {
468 assert_eq!(hex_encode(&[]), "");
469 }
470
471 #[test]
472 fn f_hex_encode_bytes() {
473 assert_eq!(hex_encode(&[0xde, 0xad, 0xbe, 0xef]), "deadbeef");
474 }
475
476 #[test]
477 fn f_format_bytes_preview_short() {
478 let bytes = vec![0x01, 0x02, 0x03];
479 let result = format_bytes_preview(&bytes);
480 assert!(result.starts_with("0x"));
481 assert!(result.contains("010203"));
482 }
483
484 #[test]
485 fn f_format_bytes_preview_long() {
486 let bytes = vec![0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a];
487 let result = format_bytes_preview(&bytes);
488 assert!(result.contains("..."));
489 assert!(result.contains("10 bytes"));
490 }
491
492 #[test]
493 fn f_type_name_string() {
494 assert_eq!(type_name(&DataType::Utf8), "string");
495 }
496
497 #[test]
498 fn f_type_name_int32() {
499 assert_eq!(type_name(&DataType::Int32), "i32");
500 }
501
502 #[test]
503 fn f_type_name_float32() {
504 assert_eq!(type_name(&DataType::Float32), "f32");
505 }
506
507 #[test]
510 fn f_format_int8() {
511 let array = make_int8_array(vec![Some(42), Some(-100)]);
512 let result = format_array_value(array.as_ref(), 0).unwrap();
513 assert_eq!(result, Some("42".to_string()));
514 }
515
516 #[test]
517 fn f_format_int16() {
518 let array = make_int16_array(vec![Some(1234), Some(-5678)]);
519 let result = format_array_value(array.as_ref(), 0).unwrap();
520 assert_eq!(result, Some("1234".to_string()));
521 }
522
523 #[test]
524 fn f_format_int64() {
525 let array = make_int64_array(vec![Some(1_000_000_000_000), Some(-1)]);
526 let result = format_array_value(array.as_ref(), 0).unwrap();
527 assert_eq!(result, Some("1000000000000".to_string()));
528 }
529
530 #[test]
531 fn f_format_uint8() {
532 let array = make_uint8_array(vec![Some(255), Some(0)]);
533 let result = format_array_value(array.as_ref(), 0).unwrap();
534 assert_eq!(result, Some("255".to_string()));
535 }
536
537 #[test]
538 fn f_format_uint16() {
539 let array = make_uint16_array(vec![Some(65535), Some(0)]);
540 let result = format_array_value(array.as_ref(), 0).unwrap();
541 assert_eq!(result, Some("65535".to_string()));
542 }
543
544 #[test]
545 fn f_format_uint32() {
546 let array = make_uint32_array(vec![Some(4_000_000_000), Some(0)]);
547 let result = format_array_value(array.as_ref(), 0).unwrap();
548 assert_eq!(result, Some("4000000000".to_string()));
549 }
550
551 #[test]
552 fn f_format_uint64() {
553 let array = make_uint64_array(vec![Some(18_446_744_073_709_551_615), Some(0)]);
554 let result = format_array_value(array.as_ref(), 0).unwrap();
555 assert_eq!(result, Some("18446744073709551615".to_string()));
556 }
557
558 #[test]
559 fn f_format_float64() {
560 let array = make_float64_array(vec![Some(2.718281828), Some(1.0)]);
561 let result = format_array_value(array.as_ref(), 0).unwrap();
562 assert_eq!(result, Some("2.7183".to_string()));
563 }
564
565 #[test]
566 fn f_format_boolean_true() {
567 let array = make_boolean_array(vec![Some(true), Some(false)]);
568 let result = format_array_value(array.as_ref(), 0).unwrap();
569 assert_eq!(result, Some("true".to_string()));
570 }
571
572 #[test]
573 fn f_format_boolean_false() {
574 let array = make_boolean_array(vec![Some(false), Some(true)]);
575 let result = format_array_value(array.as_ref(), 0).unwrap();
576 assert_eq!(result, Some("false".to_string()));
577 }
578
579 #[test]
580 fn f_format_large_string() {
581 let array: ArrayRef = Arc::new(LargeStringArray::from(vec!["large_text", "another"]));
582 let result = format_array_value(array.as_ref(), 0).unwrap();
583 assert_eq!(result, Some("large_text".to_string()));
584 }
585
586 #[test]
587 fn f_format_binary() {
588 let array: ArrayRef = Arc::new(BinaryArray::from_vec(vec![&[0x01, 0x02, 0x03]]));
589 let result = format_array_value(array.as_ref(), 0).unwrap();
590 assert!(result.is_some());
591 assert!(result.unwrap().starts_with("0x"));
592 }
593
594 #[test]
595 fn f_format_large_binary() {
596 let array: ArrayRef = Arc::new(LargeBinaryArray::from_vec(vec![&[0xde, 0xad, 0xbe, 0xef]]));
597 let result = format_array_value(array.as_ref(), 0).unwrap();
598 assert!(result.is_some());
599 assert!(result.unwrap().contains("deadbeef"));
600 }
601
602 #[test]
603 fn f_format_date32() {
604 let array: ArrayRef = Arc::new(Date32Array::from(vec![Some(19000), None]));
605 let result = format_array_value(array.as_ref(), 0).unwrap();
606 assert!(result.is_some());
607 assert!(result.unwrap().contains("date:"));
608 }
609
610 #[test]
611 fn f_format_date64() {
612 let array: ArrayRef = Arc::new(Date64Array::from(vec![Some(1_640_000_000_000), None]));
613 let result = format_array_value(array.as_ref(), 0).unwrap();
614 assert!(result.is_some());
615 assert!(result.unwrap().contains("date64:"));
616 }
617
618 #[test]
619 fn f_format_timestamp_ms() {
620 let array: ArrayRef = Arc::new(TimestampMillisecondArray::from(vec![
621 Some(1_640_000_000_000),
622 None,
623 ]));
624 let result = format_array_value(array.as_ref(), 0).unwrap();
625 assert!(result.is_some());
626 assert!(result.unwrap().contains("ts:"));
627 }
628
629 #[test]
630 fn f_format_null_type() {
631 let array: ArrayRef = Arc::new(NullArray::new(3));
632 let result = format_array_value(array.as_ref(), 0).unwrap();
633 assert_eq!(result, Some("NULL".to_string()));
634 }
635
636 #[test]
637 fn f_type_name_null() {
638 assert_eq!(type_name(&DataType::Null), "null");
639 }
640
641 #[test]
642 fn f_type_name_bool() {
643 assert_eq!(type_name(&DataType::Boolean), "bool");
644 }
645
646 #[test]
647 fn f_type_name_int8() {
648 assert_eq!(type_name(&DataType::Int8), "i8");
649 }
650
651 #[test]
652 fn f_type_name_int16() {
653 assert_eq!(type_name(&DataType::Int16), "i16");
654 }
655
656 #[test]
657 fn f_type_name_int64() {
658 assert_eq!(type_name(&DataType::Int64), "i64");
659 }
660
661 #[test]
662 fn f_type_name_uint8() {
663 assert_eq!(type_name(&DataType::UInt8), "u8");
664 }
665
666 #[test]
667 fn f_type_name_uint16() {
668 assert_eq!(type_name(&DataType::UInt16), "u16");
669 }
670
671 #[test]
672 fn f_type_name_uint32() {
673 assert_eq!(type_name(&DataType::UInt32), "u32");
674 }
675
676 #[test]
677 fn f_type_name_uint64() {
678 assert_eq!(type_name(&DataType::UInt64), "u64");
679 }
680
681 #[test]
682 fn f_type_name_float64() {
683 assert_eq!(type_name(&DataType::Float64), "f64");
684 }
685
686 #[test]
687 fn f_type_name_large_string() {
688 assert_eq!(type_name(&DataType::LargeUtf8), "large_string");
689 }
690
691 #[test]
692 fn f_type_name_binary() {
693 assert_eq!(type_name(&DataType::Binary), "binary");
694 }
695
696 #[test]
697 fn f_type_name_large_binary() {
698 assert_eq!(type_name(&DataType::LargeBinary), "large_binary");
699 }
700
701 #[test]
702 fn f_type_name_date32() {
703 assert_eq!(type_name(&DataType::Date32), "date32");
704 }
705
706 #[test]
707 fn f_type_name_date64() {
708 assert_eq!(type_name(&DataType::Date64), "date64");
709 }
710
711 #[test]
712 fn f_type_name_timestamp() {
713 let ts_type = DataType::Timestamp(arrow::datatypes::TimeUnit::Millisecond, None);
714 assert_eq!(type_name(&ts_type), "timestamp");
715 }
716
717 #[test]
718 fn f_type_name_list() {
719 use arrow::datatypes::Field;
720 let list_type = DataType::List(Arc::new(Field::new("item", DataType::Int32, true)));
721 assert_eq!(type_name(&list_type), "list");
722 }
723
724 #[test]
725 fn f_type_name_large_list() {
726 use arrow::datatypes::Field;
727 let list_type = DataType::LargeList(Arc::new(Field::new("item", DataType::Int32, true)));
728 assert_eq!(type_name(&list_type), "large_list");
729 }
730
731 #[test]
732 fn f_type_name_struct() {
733 use arrow::datatypes::{Field, Fields};
734 let fields = Fields::from(vec![Field::new("a", DataType::Int32, false)]);
735 let struct_type = DataType::Struct(fields);
736 assert_eq!(type_name(&struct_type), "struct");
737 }
738
739 #[test]
740 fn f_type_name_map() {
741 use arrow::datatypes::Field;
742 let entries = Field::new(
743 "entries",
744 DataType::Struct(
745 vec![
746 Field::new("key", DataType::Utf8, false),
747 Field::new("value", DataType::Int32, true),
748 ]
749 .into(),
750 ),
751 false,
752 );
753 let map_type = DataType::Map(Arc::new(entries), false);
754 assert_eq!(type_name(&map_type), "map");
755 }
756
757 #[test]
758 fn f_type_name_dict() {
759 let dict_type = DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Utf8));
760 assert_eq!(type_name(&dict_type), "dict");
761 }
762
763 #[test]
764 fn f_type_name_unknown() {
765 let interval_type = DataType::Interval(arrow::datatypes::IntervalUnit::DayTime);
767 assert_eq!(type_name(&interval_type), "unknown");
768 }
769
770 #[test]
771 fn f_format_timestamp_second() {
772 use arrow::array::TimestampSecondArray;
773 let array: ArrayRef = Arc::new(TimestampSecondArray::from(vec![Some(1_640_000_000), None]));
774 let result = format_array_value(array.as_ref(), 0).unwrap();
775 assert!(result.is_some());
776 assert!(result.unwrap().contains("ts:"));
777 }
778
779 #[test]
780 fn f_format_timestamp_microsecond() {
781 use arrow::array::TimestampMicrosecondArray;
782 let array: ArrayRef = Arc::new(TimestampMicrosecondArray::from(vec![
783 Some(1_640_000_000_000_000),
784 None,
785 ]));
786 let result = format_array_value(array.as_ref(), 0).unwrap();
787 assert!(result.is_some());
788 assert!(result.unwrap().contains("ts:"));
789 }
790
791 #[test]
792 fn f_format_timestamp_nanosecond() {
793 use arrow::array::TimestampNanosecondArray;
794 let array: ArrayRef = Arc::new(TimestampNanosecondArray::from(vec![
795 Some(1_640_000_000_000_000_000),
796 None,
797 ]));
798 let result = format_array_value(array.as_ref(), 0).unwrap();
799 assert!(result.is_some());
800 assert!(result.unwrap().contains("ts:"));
801 }
802
803 #[test]
804 fn f_format_unsupported_type() {
805 use arrow::{array::ListArray, buffer::OffsetBuffer, datatypes::Field};
807
808 let values = Int32Array::from(vec![1, 2, 3, 4, 5]);
809 let offsets = OffsetBuffer::new(vec![0, 2, 5].into());
810 let field = Arc::new(Field::new("item", DataType::Int32, true));
811 let array: ArrayRef = Arc::new(ListArray::new(field, offsets, Arc::new(values), None));
812
813 let result = format_array_value(array.as_ref(), 0).unwrap();
814 assert!(result.is_some());
815 assert!(result.unwrap().contains("list"));
817 }
818}