use std::sync::Arc;
use crate::console::{Justify, Overflow};
use crate::highlighter::ReprHighlighter;
use crate::panel::Panel;
use crate::pretty::{Pretty, PrettyValue};
use crate::table::{Cell, Table};
use crate::text::Text;
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ScopeOptions {
pub title: Option<String>,
pub sort_keys: bool,
pub indent_guides: bool,
pub max_length: Option<usize>,
pub max_string: Option<usize>,
pub max_depth: Option<usize>,
pub overflow: Option<Overflow>,
}
impl Default for ScopeOptions {
fn default() -> Self {
ScopeOptions {
title: None,
sort_keys: true,
indent_guides: false,
max_length: None,
max_string: None,
max_depth: None,
overflow: None,
}
}
}
pub fn render_scope<K: Into<String>>(
scope: impl IntoIterator<Item = (K, PrettyValue)>,
options: &ScopeOptions,
) -> Panel {
let mut items_table = Table::grid().padding(0, 1, 0, 1).expand(false);
items_table.add_column_justify("", Justify::Right);
let mut items: Vec<(String, PrettyValue)> = scope
.into_iter()
.map(|(key, value)| (key.into(), value))
.collect();
if options.sort_keys {
items.sort_by_cached_key(|(key, _)| (!key.starts_with("__"), key.to_lowercase()));
}
for (key, value) in items {
let key_style = if key.starts_with("__") {
"scope.key.special"
} else {
"scope.key"
};
let mut key_text = Text::new("");
key_text.append(&key, Some(key_style.into()));
key_text.append(" =", Some("scope.equals".into()));
let pretty = Pretty::from_value(value)
.highlighter(ReprHighlighter::new())
.indent_guides(options.indent_guides)
.max_length(options.max_length)
.max_string(options.max_string)
.max_depth(options.max_depth)
.overflow(options.overflow);
items_table.add_row_cells(vec![
Cell::Text(key_text),
Cell::Renderable(Arc::new(pretty)),
]);
}
let mut panel = Panel::fit(Box::new(items_table))
.border_style("scope.border")
.padding((0, 1, 0, 1));
if let Some(title) = &options.title {
panel = panel.title(title.clone());
}
panel
}