• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

vortex-data / vortex / 16272140851

14 Jul 2025 04:16PM UTC coverage: 81.537% (+0.06%) from 81.481%
16272140851

Pull #3866

github

web-flow
Merge a65e3902b into 0ade057ff
Pull Request #3866: feat: display

141 of 148 new or added lines in 2 files covered. (95.27%)

46270 of 56747 relevant lines covered (81.54%)

146701.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

92.47
/vortex-array/src/array/display/mod.rs
1
// SPDX-License-Identifier: Apache-2.0
2
// SPDX-FileCopyrightText: Copyright the Vortex contributors
3
//! Convert an array into a human-readable string representation.
4

5
mod tree;
6

7
use std::fmt::Display;
8

9
use itertools::Itertools as _;
10
use tree::TreeDisplayWrapper;
11
use vortex_error::VortexExpect as _;
12

13
use crate::Array;
14

15
/// A shim used to display the logical contents of an array.
16
///
17
/// For example, an `i16` typed array containing the first five non-negative integers is displayed
18
/// as: `[0i16, 1i16, 2i16, 3i16, 4i16]`.
19
///
20
/// # Examples
21
///
22
/// ```
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()),
28
///     "[0i16, 1i16, 2i16, 3i16, 4i16]",
29
/// )
30
/// ```
31
///
32
/// See also:
33
/// [Array::display](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display),
34
/// [Array::display_as](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display_as),
35
/// [DisplayArrayAs], and [DisplayOptions].
36
pub struct DisplayArray<'a>(pub &'a dyn Array);
37

38
impl Display for DisplayArray<'_> {
39
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150✔
40
        self.0.fmt_as(f, &DisplayOptions::default())
150✔
41
    }
150✔
42
}
43

44
/// Describe how to convert an array to a string.
45
///
46
/// See also:
47
/// [Array::display](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display),
48
/// [Array::display_as](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display_as),
49
/// [DisplayArray], and [DisplayArrayAs].
50
pub enum DisplayOptions {
51
    /// Only the top-level encoding id and limited metadata: `vortex.primitive(i16, len=5)`.
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 opts = DisplayOptions::MetadataOnly;
59
    /// assert_eq!(
60
    ///     format!("{}", array.display_as(&opts)),
61
    ///     "vortex.primitive(i16, len=5)",
62
    /// );
63
    /// ```
64
    MetadataOnly,
65
    /// Only the logical values of the array: `[0i16, 1i16, 2i16, 3i16, 4i16]`.
66
    ///
67
    /// ```
68
    /// # use vortex_array::display::DisplayOptions;
69
    /// # use vortex_array::IntoArray;
70
    /// # use vortex_buffer::buffer;
71
    /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
72
    /// let opts = DisplayOptions::default();
73
    /// assert_eq!(
74
    ///     format!("{}", array.display_as(&opts)),
75
    ///     "[0i16, 1i16, 2i16, 3i16, 4i16]",
76
    /// );
77
    /// assert_eq!(
78
    ///     format!("{}", array.display_as(&opts)),
79
    ///     format!("{}", array.display()),
80
    /// );
81
    /// ```
82
    CommaSeparatedScalars { space_after_comma: bool },
83
    /// The tree of encodings and all metadata but no values.
84
    ///
85
    /// ```
86
    /// # use vortex_array::display::DisplayOptions;
87
    /// # use vortex_array::IntoArray;
88
    /// # use vortex_buffer::buffer;
89
    /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
90
    /// let opts = DisplayOptions::TreeDisplay;
91
    /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
92
    ///   metadata: EmptyMetadata
93
    ///   buffer (align=2): 10 B (100.00%)
94
    /// ";
95
    /// assert_eq!(format!("{}", array.display_as(&opts)), expected);
96
    /// ```
97
    TreeDisplay,
98
}
99

100
impl Default for DisplayOptions {
101
    fn default() -> Self {
150✔
102
        Self::CommaSeparatedScalars {
150✔
103
            space_after_comma: true,
150✔
104
        }
150✔
105
    }
150✔
106
}
107

108
/// A shim used to display an array as specified in the options.
109
///
110
/// See also:
111
/// [Array::display](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display),
112
/// [Array::display_as](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display_as),
113
/// [DisplayArray], and [DisplayOptions].
114
pub struct DisplayArrayAs<'a>(pub &'a dyn Array, pub &'a DisplayOptions);
115

116
impl Display for DisplayArrayAs<'_> {
NEW
117
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
×
NEW
118
        self.0.fmt_as(f, self.1)
×
NEW
119
    }
×
120
}
121

122
/// Display the encoding and limited metadata of this array.
123
///
124
/// # Examples
125
/// ```
126
/// # use vortex_array::IntoArray;
127
/// # use vortex_buffer::buffer;
128
/// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
129
/// assert_eq!(
130
///     format!("{}", array),
131
///     "vortex.primitive(i16, len=5)",
132
/// );
133
/// ```
134
impl Display for dyn Array + '_ {
135
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
830✔
136
        self.fmt_as(f, &DisplayOptions::MetadataOnly)
830✔
137
    }
830✔
138
}
139

140
impl dyn Array + '_ {
141
    /// Display the logical values of the array.
142
    ///
143
    /// # Examples
144
    ///
145
    /// ```
146
    /// # use vortex_array::IntoArray;
147
    /// # use vortex_buffer::buffer;
148
    /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
149
    /// assert_eq!(
150
    ///     format!("{}", array.display()),
151
    ///     "[0i16, 1i16, 2i16, 3i16, 4i16]",
152
    /// )
153
    /// ```
154
    pub fn display(&self) -> DisplayArray {
150✔
155
        DisplayArray(self)
150✔
156
    }
150✔
157

158
    /// Display the array as specified by the options.
159
    ///
160
    /// See [DisplayOptions] for examples.
NEW
161
    pub fn display_as<'a>(&'a self, options: &'a DisplayOptions) -> DisplayArrayAs<'a> {
×
NEW
162
        DisplayArrayAs(self, options)
×
NEW
163
    }
×
164

165
    /// Display the tree of encodings of this array as an indented lists.
166
    ///
167
    /// While some metadata (such as length, bytes and validity-rate) are included, the logical
168
    /// values of the array are not displayed. To view the logical values see
169
    /// [Array::display](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display),
170
    /// [Array::display_as](http://localhost:8000/doc/vortex_array/trait.Array.html#method.display_as),
171
    /// and [DisplayOptions].
172
    ///
173
    /// # Examples
174
    /// ```
175
    /// # use vortex_array::display::DisplayOptions;
176
    /// # use vortex_array::IntoArray;
177
    /// # use vortex_buffer::buffer;
178
    /// let array = buffer![0_i16, 1, 2, 3, 4].into_array();
179
    /// let opts = DisplayOptions::TreeDisplay;
180
    /// let expected = "root: vortex.primitive(i16, len=5) nbytes=10 B (100.00%)
181
    ///   metadata: EmptyMetadata
182
    ///   buffer (align=2): 10 B (100.00%)
183
    /// ";
184
    /// assert_eq!(format!("{}", array.display_as(&opts)), expected);
185
    /// ```
186
    pub fn tree_display(&self) -> impl Display {
361✔
187
        TreeDisplayWrapper(self.to_array())
361✔
188
    }
361✔
189

190
    /// Format an array as specified by the options.
191
    ///
192
    /// See [DisplayOptions] for examples.
193
    pub fn fmt_as(
980✔
194
        &self,
980✔
195
        f: &mut std::fmt::Formatter,
980✔
196
        options: &DisplayOptions,
980✔
197
    ) -> std::fmt::Result {
980✔
198
        match options {
980✔
199
            DisplayOptions::MetadataOnly => {
200
                write!(
830✔
201
                    f,
830✔
202
                    "{}({}, len={})",
830✔
203
                    self.encoding_id(),
830✔
204
                    self.dtype(),
830✔
205
                    self.len()
830✔
206
                )
830✔
207
            }
208
            DisplayOptions::CommaSeparatedScalars { space_after_comma } => {
150✔
209
                write!(f, "[")?;
150✔
210
                let sep = if *space_after_comma { ", " } else { "," };
150✔
211
                write!(
150✔
212
                    f,
150✔
213
                    "{}",
150✔
214
                    (0..self.len())
150✔
215
                        .map(|i| self.scalar_at(i).vortex_expect("index is in bounds"))
989✔
216
                        .format(sep)
150✔
217
                )?;
150✔
218
                write!(f, "]")
150✔
219
            }
NEW
220
            DisplayOptions::TreeDisplay => write!(f, "{}", TreeDisplayWrapper(self.to_array())),
×
221
        }
222
    }
980✔
223
}
224

225
#[cfg(test)]
226
mod test {
227
    use vortex_buffer::{Buffer, buffer};
228
    use vortex_dtype::FieldNames;
229

230
    use crate::IntoArray as _;
231
    use crate::arrays::{BoolArray, ListArray, StructArray};
232
    use crate::validity::Validity;
233

234
    #[test]
235
    fn test_primitive() {
1✔
236
        let x = Buffer::<u32>::empty().into_array();
1✔
237
        assert_eq!(x.display().to_string(), "[]");
1✔
238

239
        let x = buffer![1].into_array();
1✔
240
        assert_eq!(x.display().to_string(), "[1i32]");
1✔
241

242
        let x = buffer![1, 2, 3, 4].into_array();
1✔
243
        assert_eq!(x.display().to_string(), "[1i32, 2i32, 3i32, 4i32]");
1✔
244
    }
1✔
245

246
    #[test]
247
    fn test_empty_struct() {
1✔
248
        let s = StructArray::try_new(
1✔
249
            FieldNames::from(vec![]),
1✔
250
            vec![],
1✔
251
            3,
1✔
252
            Validity::Array(BoolArray::from_iter([true, false, true]).into_array()),
1✔
253
        )
1✔
254
        .unwrap()
1✔
255
        .into_array();
1✔
256
        assert_eq!(s.display().to_string(), "[{}, null, {}]");
1✔
257
    }
1✔
258

259
    #[test]
260
    fn test_simple_struct() {
1✔
261
        let s = StructArray::from_fields(&[
1✔
262
            ("x", buffer![1, 2, 3, 4].into_array()),
1✔
263
            ("y", buffer![-1, -2, -3, -4].into_array()),
1✔
264
        ])
1✔
265
        .unwrap()
1✔
266
        .into_array();
1✔
267
        assert_eq!(
1✔
268
            s.display().to_string(),
1✔
269
            "[{x: 1i32, y: -1i32}, {x: 2i32, y: -2i32}, {x: 3i32, y: -3i32}, {x: 4i32, y: -4i32}]"
1✔
270
        );
1✔
271
    }
1✔
272

273
    #[test]
274
    fn test_list() {
1✔
275
        let x = ListArray::try_new(
1✔
276
            buffer![1, 2, 3, 4].into_array(),
1✔
277
            buffer![0, 0, 1, 1, 2, 4].into_array(),
1✔
278
            Validity::Array(BoolArray::from_iter([true, true, false, true, true]).into_array()),
1✔
279
        )
1✔
280
        .unwrap()
1✔
281
        .into_array();
1✔
282
        assert_eq!(
1✔
283
            x.display().to_string(),
1✔
284
            "[[], [1i32], null, [2i32], [3i32, 4i32]]"
1✔
285
        );
1✔
286
    }
1✔
287
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc