forked from extern/nushell
Merged heterogeneous tables (#536)
* Merged heterogeneous tables * switch emoji
This commit is contained in:
parent
152467a858
commit
0571a6ee34
@ -148,7 +148,7 @@ pub fn write_xml_events<W: Write>(
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
let s = current.clone().into_abbreviated_string(config);
|
||||
let s = current.into_abbreviated_string(config);
|
||||
writer
|
||||
.write_event(Event::Text(BytesText::from_plain_str(s.as_str())))
|
||||
.expect("Couldn't write XML text");
|
||||
|
@ -52,7 +52,7 @@ impl Command for Table {
|
||||
|
||||
match input {
|
||||
PipelineData::Value(Value::List { vals, .. }, ..) => {
|
||||
let table = convert_to_table(0, vals, ctrlc, &config, call.head)?;
|
||||
let table = convert_to_table(0, &vals, ctrlc, &config, call.head)?;
|
||||
|
||||
if let Some(table) = table {
|
||||
let result = nu_table::draw_table(&table, term_width, &color_hm, &config);
|
||||
@ -215,20 +215,35 @@ impl Command for Table {
|
||||
}
|
||||
}
|
||||
|
||||
fn get_columns(input: &[Value]) -> Vec<String> {
|
||||
let mut columns = vec![];
|
||||
|
||||
for item in input {
|
||||
if let Value::Record { cols, vals: _, .. } = item {
|
||||
for col in cols {
|
||||
if !columns.contains(col) {
|
||||
columns.push(col.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
columns
|
||||
}
|
||||
|
||||
fn convert_to_table(
|
||||
row_offset: usize,
|
||||
iter: impl IntoIterator<Item = Value>,
|
||||
input: &[Value],
|
||||
ctrlc: Option<Arc<AtomicBool>>,
|
||||
config: &Config,
|
||||
head: Span,
|
||||
) -> Result<Option<nu_table::Table>, ShellError> {
|
||||
let mut iter = iter.into_iter().peekable();
|
||||
let mut headers = get_columns(input);
|
||||
let mut input = input.iter().peekable();
|
||||
let color_hm = get_color_config(config);
|
||||
let float_precision = config.float_precision as usize;
|
||||
|
||||
if let Some(first) = iter.peek() {
|
||||
let mut headers = first.columns();
|
||||
|
||||
if input.peek().is_some() {
|
||||
if !headers.is_empty() {
|
||||
headers.insert(0, "#".into());
|
||||
}
|
||||
@ -236,41 +251,34 @@ fn convert_to_table(
|
||||
// Vec of Vec of String1, String2 where String1 is datatype and String2 is value
|
||||
let mut data: Vec<Vec<(String, String)>> = Vec::new();
|
||||
|
||||
for (row_num, item) in iter.enumerate() {
|
||||
for (row_num, item) in input.enumerate() {
|
||||
if let Some(ctrlc) = &ctrlc {
|
||||
if ctrlc.load(Ordering::SeqCst) {
|
||||
return Ok(None);
|
||||
}
|
||||
}
|
||||
if let Value::Error { error } = item {
|
||||
return Err(error);
|
||||
return Err(error.clone());
|
||||
}
|
||||
// String1 = datatype, String2 = value as string
|
||||
let mut row: Vec<(String, String)> =
|
||||
vec![("string".to_string(), (row_num + row_offset).to_string())];
|
||||
|
||||
if headers.is_empty() {
|
||||
// if header row is empty, this is probably a list so format it that way
|
||||
row.push(("list".to_string(), item.into_abbreviated_string(config)))
|
||||
} else {
|
||||
for header in headers.iter().skip(1) {
|
||||
let result = match item {
|
||||
Value::Record { .. } => {
|
||||
item.clone().follow_cell_path(&[PathMember::String {
|
||||
val: header.into(),
|
||||
span: head,
|
||||
}])
|
||||
}
|
||||
_ => Ok(item.clone()),
|
||||
};
|
||||
for header in headers.iter().skip(1) {
|
||||
let result = match item {
|
||||
Value::Record { .. } => item.clone().follow_cell_path(&[PathMember::String {
|
||||
val: header.into(),
|
||||
span: head,
|
||||
}]),
|
||||
_ => Ok(item.clone()),
|
||||
};
|
||||
|
||||
match result {
|
||||
Ok(value) => row.push((
|
||||
(&value.get_type()).to_string(),
|
||||
value.into_abbreviated_string(config),
|
||||
)),
|
||||
Err(_) => row.push(("empty".to_string(), String::new())),
|
||||
}
|
||||
match result {
|
||||
Ok(value) => row.push((
|
||||
(&value.get_type()).to_string(),
|
||||
value.into_abbreviated_string(config),
|
||||
)),
|
||||
Err(_) => row.push(("empty".to_string(), "❎".into())),
|
||||
}
|
||||
}
|
||||
|
||||
@ -397,7 +405,7 @@ impl Iterator for PagingTableCreator {
|
||||
|
||||
let table = convert_to_table(
|
||||
self.row_offset,
|
||||
batch.into_iter(),
|
||||
&batch,
|
||||
self.ctrlc.clone(),
|
||||
&self.config,
|
||||
self.head,
|
||||
|
@ -386,22 +386,22 @@ impl Value {
|
||||
}
|
||||
|
||||
/// Convert Value into string. Note that Streams will be consumed.
|
||||
pub fn into_abbreviated_string(self, config: &Config) -> String {
|
||||
pub fn into_abbreviated_string(&self, config: &Config) -> String {
|
||||
match self {
|
||||
Value::Bool { val, .. } => val.to_string(),
|
||||
Value::Int { val, .. } => val.to_string(),
|
||||
Value::Float { val, .. } => val.to_string(),
|
||||
Value::Filesize { val, .. } => format_filesize(val, config),
|
||||
Value::Duration { val, .. } => format_duration(val),
|
||||
Value::Date { val, .. } => HumanTime::from(val).to_string(),
|
||||
Value::Filesize { val, .. } => format_filesize(*val, config),
|
||||
Value::Duration { val, .. } => format_duration(*val),
|
||||
Value::Date { val, .. } => HumanTime::from(*val).to_string(),
|
||||
Value::Range { val, .. } => {
|
||||
format!(
|
||||
"{}..{}",
|
||||
val.from.into_string(", ", config),
|
||||
val.to.into_string(", ", config)
|
||||
val.from.clone().into_string(", ", config),
|
||||
val.to.clone().into_string(", ", config)
|
||||
)
|
||||
}
|
||||
Value::String { val, .. } => val,
|
||||
Value::String { val, .. } => val.to_string(),
|
||||
Value::List { ref vals, .. } => match &vals[..] {
|
||||
[Value::Record { .. }, _end @ ..] => format!(
|
||||
"[table {} row{}]",
|
||||
|
Loading…
Reference in New Issue
Block a user