use std::fmt;
use crate::ArrayRef;
use crate::arrays::Chunked;
use crate::display::extractor::IndentedFormatter;
use crate::display::extractor::TreeContext;
use crate::display::extractor::TreeExtractor;
use crate::display::extractors::BufferExtractor;
use crate::display::extractors::EncodingSummaryExtractor;
use crate::display::extractors::MetadataExtractor;
use crate::display::extractors::NbytesExtractor;
use crate::display::extractors::StatsExtractor;
pub struct TreeDisplay {
array: ArrayRef,
extractors: Vec<Box<dyn TreeExtractor>>,
}
impl TreeDisplay {
pub fn new(array: ArrayRef) -> Self {
Self {
array,
extractors: Vec::new(),
}
}
pub fn default_display(array: ArrayRef) -> Self {
Self::new(array)
.with(EncodingSummaryExtractor)
.with(NbytesExtractor)
.with(StatsExtractor)
.with(MetadataExtractor)
.with(BufferExtractor { show_percent: true })
}
pub fn with<E: TreeExtractor + 'static>(mut self, extractor: E) -> Self {
self.extractors.push(Box::new(extractor));
self
}
pub fn with_boxed(mut self, extractor: Box<dyn TreeExtractor>) -> Self {
self.extractors.push(extractor);
self
}
fn write_node(
&self,
name: &str,
array: &ArrayRef,
ctx: &mut TreeContext,
indent: &str,
f: &mut fmt::Formatter<'_>,
) -> fmt::Result {
write!(f, "{indent}{name}:")?;
for extractor in &self.extractors {
extractor.write_header(array, ctx, f)?;
}
writeln!(f)?;
let child_indent = format!("{indent} ");
{
let mut indented = IndentedFormatter::new(f, &child_indent);
for extractor in &self.extractors {
extractor.write_details(array, ctx, &mut indented)?;
}
}
let child_size = if array.is::<Chunked>() {
None
} else {
Some(array.nbytes())
};
ctx.push(child_size);
for (child_name, child) in array.children_names().into_iter().zip(array.children()) {
self.write_node(&child_name, &child, ctx, &child_indent, f)?;
}
ctx.pop();
Ok(())
}
}
impl fmt::Display for TreeDisplay {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut ctx = TreeContext::new();
self.write_node("root", &self.array, &mut ctx, "", f)
}
}