1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
use itertools::Itertools;
use re_chunk_store::external::arrow2;
use re_chunk_store::external::arrow2::array::Utf8Array;
use re_types::SizeBytes as _;
use re_ui::UiExt;
// Note: this is copied and heavily modified from `re_data_ui`. We don't want to unify them because
// that would likely introduce an undesired dependency (`re_chunk_store_ui` should remain as
// independent as possible from the viewer, so it may be split off one day).
pub(crate) fn arrow_ui(ui: &mut egui::Ui, array: &dyn arrow2::array::Array) {
ui.scope(|ui| {
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Truncate);
// Special-treat text.
// Note: we match on the raw data here, so this works for any component containing text.
if let Some(utf8) = array.as_any().downcast_ref::<Utf8Array<i32>>() {
if utf8.len() == 1 {
let string = utf8.value(0);
ui.monospace(string);
return;
}
}
if let Some(utf8) = array.as_any().downcast_ref::<Utf8Array<i64>>() {
if utf8.len() == 1 {
let string = utf8.value(0);
ui.monospace(string);
return;
}
}
let num_bytes = array.total_size_bytes();
if num_bytes < 3000 {
if array.is_empty() {
ui.monospace("[]");
return;
}
let instance_count = array.len();
let display = arrow2::array::get_display(array, "null");
if instance_count == 1 {
let mut string = String::new();
match display(&mut string, 0) {
Ok(_) => ui.monospace(&string),
Err(err) => ui.error_with_details_on_hover(&err.to_string()),
};
return;
} else {
ui.label(format!("{instance_count} items"))
.on_hover_ui(|ui| {
ui.style_mut().wrap_mode = Some(egui::TextWrapMode::Wrap);
ui.monospace(format!(
"[{}]",
(0..instance_count)
.filter_map(|index| {
let mut s = String::new();
//TODO(ab): should we care about errors here?
display(&mut s, index).ok().map(|_| s)
})
.join(", ")
));
});
}
return;
}
// Fallback:
let bytes = re_format::format_bytes(num_bytes as _);
let data_type_formatted = format!("{:?}", array.data_type());
if data_type_formatted.len() < 20 {
// e.g. "4.2 KiB of Float32"
ui.label(&format!("{bytes} of {data_type_formatted}"));
} else {
// Huge datatype, probably a union horror show
ui.label(format!("{bytes} of data"));
}
});
}