From 6fcd09682cbaa1e2b2077e023c5ea351ab3a6f00 Mon Sep 17 00:00:00 2001 From: Ian Manske Date: Sun, 21 Jul 2024 21:15:36 +0000 Subject: [PATCH] Fix setting metadata on byte streams (#13416) # Description Setting metadata on a byte stream converts it to a list stream. This PR makes it so that `metadata set` does not alter its input besides the metadata. ```nushell open --raw test.json | metadata set --content-type application/json | http post https://httpbin.org/post ``` --- crates/nu-command/src/debug/metadata_set.rs | 40 +++++++++++---------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/crates/nu-command/src/debug/metadata_set.rs b/crates/nu-command/src/debug/metadata_set.rs index 96f50cfdba..c78a5df5c3 100644 --- a/crates/nu-command/src/debug/metadata_set.rs +++ b/crates/nu-command/src/debug/metadata_set.rs @@ -42,32 +42,32 @@ impl Command for MetadataSet { engine_state: &EngineState, stack: &mut Stack, call: &Call, - input: PipelineData, + mut input: PipelineData, ) -> Result { let head = call.head; let ds_fp: Option = call.get_flag(engine_state, stack, "datasource-filepath")?; let ds_ls = call.has_flag(engine_state, stack, "datasource-ls")?; let content_type: Option = call.get_flag(engine_state, stack, "content-type")?; - let signals = engine_state.signals().clone(); - let metadata = input - .metadata() - .clone() - .unwrap_or_default() - .with_content_type(content_type); + + let mut metadata = match &mut input { + PipelineData::Value(_, metadata) + | PipelineData::ListStream(_, metadata) + | PipelineData::ByteStream(_, metadata) => metadata.take().unwrap_or_default(), + PipelineData::Empty => return Err(ShellError::PipelineEmpty { dst_span: head }), + }; + + if let Some(content_type) = content_type { + metadata.content_type = Some(content_type); + } match (ds_fp, ds_ls) { - (Some(path), false) => Ok(input.into_pipeline_data_with_metadata( - head, - signals, - metadata.with_data_source(DataSource::FilePath(path.into())), - )), - (None, true) => Ok(input.into_pipeline_data_with_metadata( - head, - signals, - metadata.with_data_source(DataSource::Ls), - )), - _ => Ok(input.into_pipeline_data_with_metadata(head, signals, metadata)), + (Some(path), false) => metadata.data_source = DataSource::FilePath(path.into()), + (None, true) => metadata.data_source = DataSource::Ls, + (Some(_), true) => (), // TODO: error here + (None, false) => (), } + + Ok(input.set_metadata(Some(metadata))) } fn examples(&self) -> Vec { @@ -85,7 +85,9 @@ impl Command for MetadataSet { Example { description: "Set the metadata of a file path", example: "'crates' | metadata set --content-type text/plain | metadata", - result: Some(Value::record(record!("content_type" => Value::string("text/plain", Span::test_data())), Span::test_data())), + result: Some(Value::test_record(record! { + "content_type" => Value::test_string("text/plain"), + })), }, ] }