diff --git a/crates/nu-command/src/filters/columns.rs b/crates/nu-command/src/filters/columns.rs index 2349ab9683..47ed1c88f8 100644 --- a/crates/nu-command/src/filters/columns.rs +++ b/crates/nu-command/src/filters/columns.rs @@ -2,8 +2,8 @@ use nu_engine::column::get_columns; use nu_protocol::ast::Call; use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::{ - Category, Example, IntoInterruptiblePipelineData, IntoPipelineData, PipelineData, ShellError, - Signature, Span, Type, Value, + Category, Example, IntoInterruptiblePipelineData, PipelineData, ShellError, Signature, Span, + Type, Value, }; #[derive(Clone)] @@ -80,9 +80,11 @@ impl Command for Columns { fn getcol( engine_state: &EngineState, - span: Span, + head: Span, input: PipelineData, ) -> Result { + let ctrlc = engine_state.ctrlc.clone(); + let metadata = input.metadata(); match input { PipelineData::Empty => Ok(PipelineData::Empty), PipelineData::Value( @@ -96,7 +98,8 @@ fn getcol( Ok(input_cols .into_iter() .map(move |x| Value::String { val: x, span }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) } PipelineData::Value(Value::CustomValue { val, span }, ..) => { // TODO: should we get CustomValue to expose columns in a more efficient way? @@ -106,7 +109,8 @@ fn getcol( Ok(input_cols .into_iter() .map(move |x| Value::String { val: x, span }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) } PipelineData::ListStream(stream, ..) => { let v: Vec<_> = stream.into_iter().collect(); @@ -114,17 +118,36 @@ fn getcol( Ok(input_cols .into_iter() - .map(move |x| Value::String { val: x, span }) - .into_pipeline_data(engine_state.ctrlc.clone())) + .map(move |x| Value::String { val: x, span: head }) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)) } PipelineData::Value(Value::Record { cols, .. }, ..) => Ok(cols .into_iter() - .map(move |x| Value::String { val: x, span }) - .into_pipeline_data(engine_state.ctrlc.clone())), - PipelineData::Value(..) | PipelineData::ExternalStream { .. } => { - let cols = vec![]; - let vals = vec![]; - Ok(Value::Record { cols, vals, span }.into_pipeline_data()) + .map(move |x| Value::String { val: x, span: head }) + .into_pipeline_data(ctrlc) + .set_metadata(metadata)), + // Propagate errors + PipelineData::Value(Value::Error { error }, ..) => Err(error), + PipelineData::Value(other, ..) => { + Err(ShellError::OnlySupportsThisInputType( + "record or table".into(), + other.get_type().to_string(), + head, + // This line requires the Value::Error match above. + other.expect_span(), + )) + } + PipelineData::ExternalStream { .. } => { + Err(ShellError::OnlySupportsThisInputType( + "record or table".into(), + "raw data".into(), + head, + // This line requires the PipelineData::Empty and PipelineData::ListStream matches above. + input + .span() + .expect("PipelineData::ExternalStream had no span"), + )) } } } diff --git a/crates/nu-command/src/filters/values.rs b/crates/nu-command/src/filters/values.rs index 70984d56fe..42e4c33675 100644 --- a/crates/nu-command/src/filters/values.rs +++ b/crates/nu-command/src/filters/values.rs @@ -176,7 +176,7 @@ fn values( Ok(vals.into_pipeline_data(ctrlc).set_metadata(metadata)) } // Propagate errors - PipelineData::Value(Value::Error { error: _ }, ..) => Ok(input), + PipelineData::Value(Value::Error { error }, ..) => Err(error), PipelineData::Value(other, ..) => { Err(ShellError::OnlySupportsThisInputType( "record or table".into(),