vortex_array/display/mod.rs
1// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
4mod tree;
5
6use std::fmt::Display;
7
8use itertools::Itertools as _;
9use tree::TreeDisplayWrapper;
10
11use crate::Array;
12
13/// Describe how to convert an array to a string.
14///
15/// See also:
16/// [Array::display_as](../trait.Array.html#method.display_as)
17/// and [DisplayArrayAs].
18pub enum DisplayOptions {
19 /// Only the top-level encoding id and limited metadata: `vortex.primitive(i16, len=5)`.
20 ///
21 /// ```
22 /// # use vortex_array::display::DisplayOptions;
23 /// # use vortex_array::IntoArray;
24 /// # use vortex_buffer::buffer;
25 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
26 /// assert_eq!(
27 /// format!("{}", array.display_as(DisplayOptions::MetadataOnly)),
28 /// "vortex.primitive(i16, len=5)",
29 /// );
30 /// ```
31 MetadataOnly,
32 /// Only the logical values of the array: `[0i16, 1i16, 2i16, 3i16, 4i16]`.
33 ///
34 /// ```
35 /// # use vortex_array::display::DisplayOptions;
36 /// # use vortex_array::IntoArray;
37 /// # use vortex_buffer::buffer;
38 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
39 /// assert_eq!(
40 /// format!("{}", array.display_as(DisplayOptions::default())),
41 /// "[0i16, 1i16, 2i16, 3i16, 4i16]",
42 /// );
43 /// assert_eq!(
44 /// format!("{}", array.display_as(DisplayOptions::default())),
45 /// format!("{}", array.display_values()),
46 /// );
47 /// ```
48 CommaSeparatedScalars { omit_comma_after_space: bool },
49 /// The tree of encodings without any concrete values.
50 ///
51 /// With buffers, metadata, and stats:
52 ///
53 /// ```
54 /// # use vortex_array::display::DisplayOptions;
55 /// # use vortex_array::IntoArray;
56 /// # use vortex_buffer::buffer;
57 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
58 /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
59 /// metadata: EmptyMetadata
60 /// buffer: values host 10 B (align=2) (100.00%)
61 /// ";
62 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: true, stats: true })), expected);
63 ///
64 /// # use vortex_array::arrays::StructArray;
65 /// let array = StructArray::from_fields(&[
66 /// ("x", buffer![1, 2].into_array()),
67 /// ("y", buffer![3, 4].into_array()),
68 /// ]).unwrap().into_array();
69 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2) nbytes=16 B (100.00%)
70 /// metadata: EmptyMetadata
71 /// x: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
72 /// metadata: EmptyMetadata
73 /// buffer: values host 8 B (align=4) (100.00%)
74 /// y: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
75 /// metadata: EmptyMetadata
76 /// buffer: values host 8 B (align=4) (100.00%)
77 /// ";
78 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: true, stats: true })), expected);
79 /// ```
80 ///
81 /// With metadata and stats but no buffers:
82 ///
83 /// ```
84 /// # use vortex_array::display::DisplayOptions;
85 /// # use vortex_array::IntoArray;
86 /// # use vortex_buffer::buffer;
87 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
88 /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
89 /// metadata: EmptyMetadata
90 /// ";
91 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: true, stats: true })), expected);
92 ///
93 /// # use vortex_array::arrays::StructArray;
94 /// let array = StructArray::from_fields(&[
95 /// ("x", buffer![1, 2].into_array()),
96 /// ("y", buffer![3, 4].into_array()),
97 /// ]).unwrap().into_array();
98 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2) nbytes=16 B (100.00%)
99 /// metadata: EmptyMetadata
100 /// x: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
101 /// metadata: EmptyMetadata
102 /// y: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
103 /// metadata: EmptyMetadata
104 /// ";
105 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: true, stats: true })), expected);
106 /// ```
107 ///
108 /// With metadata and buffers but no stats:
109 ///
110 /// ```
111 /// # use vortex_array::display::DisplayOptions;
112 /// # use vortex_array::IntoArray;
113 /// # use vortex_buffer::buffer;
114 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
115 /// let expected = "root: vortex.primitive(i16, len=5)
116 /// metadata: EmptyMetadata
117 /// buffer: values host 10 B (align=2)
118 /// ";
119 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: true, stats: false })), expected);
120 ///
121 /// # use vortex_array::arrays::StructArray;
122 /// let array = StructArray::from_fields(&[
123 /// ("x", buffer![1, 2].into_array()),
124 /// ("y", buffer![3, 4].into_array()),
125 /// ]).unwrap().into_array();
126 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2)
127 /// metadata: EmptyMetadata
128 /// x: vortex.primitive(i32, len=2)
129 /// metadata: EmptyMetadata
130 /// buffer: values host 8 B (align=4)
131 /// y: vortex.primitive(i32, len=2)
132 /// metadata: EmptyMetadata
133 /// buffer: values host 8 B (align=4)
134 /// ";
135 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: true, stats: false })), expected);
136 /// ```
137 ///
138 /// With buffers and stats but no metadata:
139 ///
140 /// ```
141 /// # use vortex_array::display::DisplayOptions;
142 /// # use vortex_array::IntoArray;
143 /// # use vortex_buffer::buffer;
144 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
145 /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
146 /// buffer: values host 10 B (align=2) (100.00%)
147 /// ";
148 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: false, stats: true })), expected);
149 ///
150 /// # use vortex_array::arrays::StructArray;
151 /// let array = StructArray::from_fields(&[
152 /// ("x", buffer![1, 2].into_array()),
153 /// ("y", buffer![3, 4].into_array()),
154 /// ]).unwrap().into_array();
155 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2) nbytes=16 B (100.00%)
156 /// x: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
157 /// buffer: values host 8 B (align=4) (100.00%)
158 /// y: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
159 /// buffer: values host 8 B (align=4) (100.00%)
160 /// ";
161 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: false, stats: true })), expected);
162 /// ```
163 ///
164 /// With just buffers:
165 ///
166 /// ```
167 /// # use vortex_array::display::DisplayOptions;
168 /// # use vortex_array::IntoArray;
169 /// # use vortex_buffer::buffer;
170 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
171 /// let expected = "root: vortex.primitive(i16, len=5)
172 /// buffer: values host 10 B (align=2)
173 /// ";
174 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: false, stats: false })), expected);
175 ///
176 /// # use vortex_array::arrays::StructArray;
177 /// let array = StructArray::from_fields(&[
178 /// ("x", buffer![1, 2].into_array()),
179 /// ("y", buffer![3, 4].into_array()),
180 /// ]).unwrap().into_array();
181 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2)
182 /// x: vortex.primitive(i32, len=2)
183 /// buffer: values host 8 B (align=4)
184 /// y: vortex.primitive(i32, len=2)
185 /// buffer: values host 8 B (align=4)
186 /// ";
187 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: true, metadata: false, stats: false })), expected);
188 /// ```
189 ///
190 /// With just metadata:
191 ///
192 /// ```
193 /// # use vortex_array::display::DisplayOptions;
194 /// # use vortex_array::IntoArray;
195 /// # use vortex_buffer::buffer;
196 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
197 /// let expected = "root: vortex.primitive(i16, len=5)
198 /// metadata: EmptyMetadata
199 /// ";
200 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: true, stats: false })), expected);
201 ///
202 /// # use vortex_array::arrays::StructArray;
203 /// let array = StructArray::from_fields(&[
204 /// ("x", buffer![1, 2].into_array()),
205 /// ("y", buffer![3, 4].into_array()),
206 /// ]).unwrap().into_array();
207 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2)
208 /// metadata: EmptyMetadata
209 /// x: vortex.primitive(i32, len=2)
210 /// metadata: EmptyMetadata
211 /// y: vortex.primitive(i32, len=2)
212 /// metadata: EmptyMetadata
213 /// ";
214 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: true, stats: false })), expected);
215 /// ```
216 ///
217 /// With just stats:
218 ///
219 /// ```
220 /// # use vortex_array::display::DisplayOptions;
221 /// # use vortex_array::IntoArray;
222 /// # use vortex_buffer::buffer;
223 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
224 /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
225 /// ";
226 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: false, stats: true })), expected);
227 ///
228 /// # use vortex_array::arrays::StructArray;
229 /// let array = StructArray::from_fields(&[
230 /// ("x", buffer![1, 2].into_array()),
231 /// ("y", buffer![3, 4].into_array()),
232 /// ]).unwrap().into_array();
233 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2) nbytes=16 B (100.00%)
234 /// x: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
235 /// y: vortex.primitive(i32, len=2) nbytes=8 B (50.00%)
236 /// ";
237 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: false, stats: true })), expected);
238 /// ```
239 ///
240 /// With neither buffers, metadata, stats, nor values:
241 ///
242 /// ```
243 /// # use vortex_array::display::DisplayOptions;
244 /// # use vortex_array::IntoArray;
245 /// # use vortex_buffer::buffer;
246 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
247 /// let expected = "root: vortex.primitive(i16, len=5)\n";
248 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: false, stats: false })), expected);
249 ///
250 /// # use vortex_array::arrays::StructArray;
251 /// let array = StructArray::from_fields(&[
252 /// ("x", buffer![1, 2].into_array()),
253 /// ("y", buffer![3, 4].into_array()),
254 /// ]).unwrap().into_array();
255 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2)
256 /// x: vortex.primitive(i32, len=2)
257 /// y: vortex.primitive(i32, len=2)
258 /// ";
259 /// assert_eq!(format!("{}", array.display_as(DisplayOptions::TreeDisplay { buffers: false, metadata: false, stats: false })), expected);
260 /// ```
261 TreeDisplay {
262 buffers: bool,
263 metadata: bool,
264 stats: bool,
265 },
266 /// Display values in a formatted table with columns.
267 ///
268 /// For struct arrays, displays a column for each field in the struct.
269 /// For regular arrays, displays a single column with values.
270 ///
271 /// ```
272 /// # use vortex_array::display::DisplayOptions;
273 /// # use vortex_array::arrays::StructArray;
274 /// # use vortex_array::IntoArray;
275 /// # use vortex_buffer::buffer;
276 /// let s = StructArray::from_fields(&[
277 /// ("x", buffer![1, 2].into_array()),
278 /// ("y", buffer![3, 4].into_array()),
279 /// ]).unwrap().into_array();
280 /// let expected = "
281 /// ┌──────┬──────┐
282 /// │ x │ y │
283 /// ├──────┼──────┤
284 /// │ 1i32 │ 3i32 │
285 /// ├──────┼──────┤
286 /// │ 2i32 │ 4i32 │
287 /// └──────┴──────┘".trim();
288 /// assert_eq!(format!("{}", s.display_as(DisplayOptions::TableDisplay)), expected);
289 /// ```
290 #[cfg(feature = "table-display")]
291 TableDisplay,
292}
293
294impl Default for DisplayOptions {
295 fn default() -> Self {
296 Self::CommaSeparatedScalars {
297 omit_comma_after_space: false,
298 }
299 }
300}
301
302/// A shim used to display an array as specified in the options.
303///
304/// See also:
305/// [Array::display_as](../trait.Array.html#method.display_as)
306/// and [DisplayOptions].
307pub struct DisplayArrayAs<'a>(pub &'a dyn Array, pub DisplayOptions);
308
309impl Display for DisplayArrayAs<'_> {
310 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
311 self.0.fmt_as(f, &self.1)
312 }
313}
314
315/// Display the encoding and limited metadata of this array.
316///
317/// # Examples
318/// ```
319/// # use vortex_array::IntoArray;
320/// # use vortex_buffer::buffer;
321/// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
322/// assert_eq!(
323/// format!("{}", array),
324/// "vortex.primitive(i16, len=5)",
325/// );
326/// ```
327impl Display for dyn Array + '_ {
328 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
329 self.fmt_as(f, &DisplayOptions::MetadataOnly)
330 }
331}
332
333impl dyn Array + '_ {
334 /// Display logical values of the array
335 ///
336 /// For example, an `i16` typed array containing the first five non-negative integers is displayed
337 /// as: `[0i16, 1i16, 2i16, 3i16, 4i16]`.
338 ///
339 /// # Examples
340 ///
341 /// ```
342 /// # use vortex_array::IntoArray;
343 /// # use vortex_buffer::buffer;
344 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
345 /// assert_eq!(
346 /// format!("{}", array.display_values()),
347 /// "[0i16, 1i16, 2i16, 3i16, 4i16]",
348 /// )
349 /// ```
350 ///
351 /// See also:
352 /// [Array::display_as](..//trait.Array.html#method.display_as),
353 /// [DisplayArrayAs], and [DisplayOptions].
354 pub fn display_values(&self) -> impl Display {
355 DisplayArrayAs(
356 self,
357 DisplayOptions::CommaSeparatedScalars {
358 omit_comma_after_space: false,
359 },
360 )
361 }
362
363 /// Display the array as specified by the options.
364 ///
365 /// See [DisplayOptions] for examples.
366 pub fn display_as(&self, options: DisplayOptions) -> impl Display {
367 DisplayArrayAs(self, options)
368 }
369
370 /// Display the tree of array encodings and lengths without metadata, buffers, or stats.
371 ///
372 /// # Examples
373 /// ```
374 /// # use vortex_array::display::DisplayOptions;
375 /// # use vortex_array::IntoArray;
376 /// # use vortex_buffer::buffer;
377 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
378 /// let expected = "root: vortex.primitive(i16, len=5)\n";
379 /// assert_eq!(format!("{}", array.display_tree_encodings_only()), expected);
380 ///
381 /// # use vortex_array::arrays::StructArray;
382 /// let array = StructArray::from_fields(&[
383 /// ("x", buffer![1, 2].into_array()),
384 /// ("y", buffer![3, 4].into_array()),
385 /// ]).unwrap().into_array();
386 /// let expected = "root: vortex.struct({x=i32, y=i32}, len=2)
387 /// x: vortex.primitive(i32, len=2)
388 /// y: vortex.primitive(i32, len=2)
389 /// ";
390 /// assert_eq!(format!("{}", array.display_tree_encodings_only()), expected);
391 /// ```
392 pub fn display_tree_encodings_only(&self) -> impl Display {
393 DisplayArrayAs(
394 self,
395 DisplayOptions::TreeDisplay {
396 buffers: false,
397 metadata: false,
398 stats: false,
399 },
400 )
401 }
402
403 /// Display the tree of encodings of this array as an indented lists.
404 ///
405 /// While some metadata (such as length, bytes and validity-rate) are included, the logical
406 /// values of the array are not displayed. To view the logical values see
407 /// [Array::display_as](../trait.Array.html#method.display_as)
408 /// and [DisplayOptions].
409 ///
410 /// # Examples
411 /// ```
412 /// # use vortex_array::display::DisplayOptions;
413 /// # use vortex_array::IntoArray;
414 /// # use vortex_buffer::buffer;
415 /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
416 /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
417 /// metadata: EmptyMetadata
418 /// buffer: values host 10 B (align=2) (100.00%)
419 /// ";
420 /// assert_eq!(format!("{}", array.display_tree()), expected);
421 /// ```
422 pub fn display_tree(&self) -> impl Display {
423 DisplayArrayAs(
424 self,
425 DisplayOptions::TreeDisplay {
426 buffers: true,
427 metadata: true,
428 stats: true,
429 },
430 )
431 }
432
433 /// Display the array as a formatted table.
434 ///
435 /// For struct arrays, displays a column for each field in the struct.
436 /// For regular arrays, displays a single column with values.
437 ///
438 /// # Examples
439 /// ```
440 /// # #[cfg(feature = "table-display")]
441 /// # {
442 /// # use vortex_array::arrays::StructArray;
443 /// # use vortex_array::IntoArray;
444 /// # use vortex_buffer::buffer;
445 /// let s = StructArray::from_fields(&[
446 /// ("x", buffer![1, 2].into_array()),
447 /// ("y", buffer![3, 4].into_array()),
448 /// ]).unwrap().into_array();
449 /// let expected = "
450 /// ┌──────┬──────┐
451 /// │ x │ y │
452 /// ├──────┼──────┤
453 /// │ 1i32 │ 3i32 │
454 /// ├──────┼──────┤
455 /// │ 2i32 │ 4i32 │
456 /// └──────┴──────┘".trim();
457 /// assert_eq!(format!("{}", s.display_table()), expected);
458 /// # }
459 /// ```
460 #[cfg(feature = "table-display")]
461 pub fn display_table(&self) -> impl Display {
462 DisplayArrayAs(self, DisplayOptions::TableDisplay)
463 }
464
465 fn fmt_as(&self, f: &mut std::fmt::Formatter, options: &DisplayOptions) -> std::fmt::Result {
466 match options {
467 DisplayOptions::MetadataOnly => {
468 write!(
469 f,
470 "{}({}, len={})",
471 self.encoding_id(),
472 self.dtype(),
473 self.len()
474 )
475 }
476 DisplayOptions::CommaSeparatedScalars {
477 omit_comma_after_space,
478 } => {
479 write!(f, "[")?;
480 let sep = if *omit_comma_after_space { "," } else { ", " };
481 write!(
482 f,
483 "{}",
484 (0..self.len())
485 .map(|i| self
486 .scalar_at(i)
487 .map_or_else(|e| format!("<error: {e}>"), |s| s.to_string()))
488 .format(sep)
489 )?;
490 write!(f, "]")
491 }
492 DisplayOptions::TreeDisplay {
493 buffers,
494 metadata,
495 stats,
496 } => {
497 write!(
498 f,
499 "{}",
500 TreeDisplayWrapper {
501 array: self.to_array(),
502 buffers: *buffers,
503 metadata: *metadata,
504 stats: *stats
505 }
506 )
507 }
508 #[cfg(feature = "table-display")]
509 DisplayOptions::TableDisplay => {
510 use vortex_dtype::DType;
511
512 use crate::canonical::ToCanonical;
513
514 let mut builder = tabled::builder::Builder::default();
515
516 // Special logic for struct arrays.
517 let DType::Struct(sf, _) = self.dtype() else {
518 // For non-struct arrays, simply display a single column table without header.
519 for row_idx in 0..self.len() {
520 let value = self
521 .scalar_at(row_idx)
522 .map_or_else(|e| format!("<error: {e}>"), |s| s.to_string());
523 builder.push_record([value]);
524 }
525
526 let mut table = builder.build();
527 table.with(tabled::settings::Style::modern());
528
529 return write!(f, "{table}");
530 };
531
532 let struct_ = self.to_struct();
533 builder.push_record(sf.names().iter().map(|name| name.to_string()));
534
535 for row_idx in 0..self.len() {
536 if !self.is_valid(row_idx).unwrap_or(false) {
537 let null_row = vec!["null".to_string(); sf.names().len()];
538 builder.push_record(null_row);
539 } else {
540 let mut row = Vec::new();
541 for field_array in struct_.unmasked_fields().iter() {
542 let value = field_array
543 .scalar_at(row_idx)
544 .map_or_else(|e| format!("<error: {e}>"), |s| s.to_string());
545 row.push(value);
546 }
547 builder.push_record(row);
548 }
549 }
550
551 let mut table = builder.build();
552 table.with(tabled::settings::Style::modern());
553
554 // Center headers
555 for col_idx in 0..sf.names().len() {
556 table.modify((0, col_idx), tabled::settings::Alignment::center());
557 }
558
559 for row_idx in 0..self.len() {
560 if !self.is_valid(row_idx).unwrap_or(false) {
561 table.modify(
562 (1 + row_idx, 0),
563 tabled::settings::Span::column(sf.names().len() as isize),
564 );
565 table.modify((1 + row_idx, 0), tabled::settings::Alignment::center());
566 }
567 }
568
569 write!(f, "{table}")
570 }
571 }
572 }
573}
574
575#[cfg(test)]
576mod test {
577 use vortex_buffer::Buffer;
578 use vortex_buffer::buffer;
579 use vortex_dtype::FieldNames;
580
581 use crate::IntoArray as _;
582 use crate::arrays::BoolArray;
583 use crate::arrays::ListArray;
584 use crate::arrays::StructArray;
585 use crate::validity::Validity;
586
587 #[test]
588 fn test_primitive() {
589 let x = Buffer::<u32>::empty().into_array();
590 assert_eq!(x.display_values().to_string(), "[]");
591
592 let x = buffer![1].into_array();
593 assert_eq!(x.display_values().to_string(), "[1i32]");
594
595 let x = buffer![1, 2, 3, 4].into_array();
596 assert_eq!(x.display_values().to_string(), "[1i32, 2i32, 3i32, 4i32]");
597 }
598
599 #[test]
600 fn test_empty_struct() {
601 let s = StructArray::try_new(
602 FieldNames::empty(),
603 vec![],
604 3,
605 Validity::Array(BoolArray::from_iter([true, false, true]).into_array()),
606 )
607 .unwrap()
608 .into_array();
609 assert_eq!(s.display_values().to_string(), "[{}, null, {}]");
610 }
611
612 #[test]
613 fn test_simple_struct() {
614 let s = StructArray::from_fields(&[
615 ("x", buffer![1, 2, 3, 4].into_array()),
616 ("y", buffer![-1, -2, -3, -4].into_array()),
617 ])
618 .unwrap()
619 .into_array();
620 assert_eq!(
621 s.display_values().to_string(),
622 "[{x: 1i32, y: -1i32}, {x: 2i32, y: -2i32}, {x: 3i32, y: -3i32}, {x: 4i32, y: -4i32}]"
623 );
624 }
625
626 #[test]
627 fn test_list() {
628 let x = ListArray::try_new(
629 buffer![1, 2, 3, 4].into_array(),
630 buffer![0, 0, 1, 1, 2, 4].into_array(),
631 Validity::Array(BoolArray::from_iter([true, true, false, true, true]).into_array()),
632 )
633 .unwrap()
634 .into_array();
635 assert_eq!(
636 x.display_values().to_string(),
637 "[[], [1i32], null, [2i32], [3i32, 4i32]]"
638 );
639 }
640
641 #[test]
642 fn test_table_display_primitive() {
643 use crate::display::DisplayOptions;
644
645 let array = buffer![1, 2, 3, 4].into_array();
646 let table_display = array.display_as(DisplayOptions::TableDisplay);
647 assert_eq!(
648 table_display.to_string(),
649 r"
650┌──────┐
651│ 1i32 │
652├──────┤
653│ 2i32 │
654├──────┤
655│ 3i32 │
656├──────┤
657│ 4i32 │
658└──────┘"
659 .trim()
660 );
661 }
662
663 #[test]
664 fn test_table_display() {
665 use crate::display::DisplayOptions;
666
667 let array = crate::arrays::PrimitiveArray::from_option_iter(vec![
668 Some(-1),
669 Some(-2),
670 Some(-3),
671 None,
672 ])
673 .into_array();
674
675 let struct_ = StructArray::try_from_iter_with_validity(
676 [("x", buffer![1, 2, 3, 4].into_array()), ("y", array)],
677 Validity::Array(BoolArray::from_iter([true, false, true, true]).into_array()),
678 )
679 .unwrap()
680 .into_array();
681
682 let table_display = struct_.display_as(DisplayOptions::TableDisplay);
683 assert_eq!(
684 table_display.to_string(),
685 r"
686┌──────┬───────┐
687│ x │ y │
688├──────┼───────┤
689│ 1i32 │ -1i32 │
690├──────┼───────┤
691│ null │
692├──────┼───────┤
693│ 3i32 │ -3i32 │
694├──────┼───────┤
695│ 4i32 │ null │
696└──────┴───────┘"
697 .trim()
698 );
699 }
700}