diff --git a/crates/nu-command/src/debug/metadata.rs b/crates/nu-command/src/debug/metadata.rs index e65afd5d83..70bd699ba4 100644 --- a/crates/nu-command/src/debug/metadata.rs +++ b/crates/nu-command/src/debug/metadata.rs @@ -87,10 +87,9 @@ impl Command for Metadata { .into_pipeline_data(), ) } - None => Ok( - Value::record(build_metadata_record(input.metadata().as_ref(), head), head) - .into_pipeline_data(), - ), + None => { + Ok(Value::record(build_metadata_record(&input, head), head).into_pipeline_data()) + } } } @@ -116,19 +115,7 @@ fn build_metadata_record_value( head: Span, ) -> Value { let mut record = Record::new(); - - let span = arg.span(); - record.push( - "span", - Value::record( - record! { - "start" => Value::int(span.start as i64,span), - "end" => Value::int(span.end as i64, span), - }, - head, - ), - ); - + record.push("span", arg.span().into_value(head)); Value::record(extend_record_with_metadata(record, metadata, head), head) } diff --git a/crates/nu-command/src/debug/metadata_access.rs b/crates/nu-command/src/debug/metadata_access.rs index 297fc2e613..5aa16354f4 100644 --- a/crates/nu-command/src/debug/metadata_access.rs +++ b/crates/nu-command/src/debug/metadata_access.rs @@ -42,10 +42,7 @@ impl Command for MetadataAccess { // `ClosureEvalOnce` is not used as it uses `Stack::captures_to_stack` rather than // `Stack::captures_to_stack_preserve_out_dest`. This command shouldn't collect streams let mut callee_stack = caller_stack.captures_to_stack_preserve_out_dest(closure.captures); - let metadata_record = Value::record( - build_metadata_record(input.metadata().as_ref(), call.head), - call.head, - ); + let metadata_record = Value::record(build_metadata_record(&input, call.head), call.head); if let Some(var_id) = block.signature.get_positional(0).and_then(|var| var.var_id) { callee_stack.add_var(var_id, metadata_record) @@ -58,12 +55,10 @@ impl Command for MetadataAccess { fn examples(&self) -> Vec { vec![Example { description: "Access metadata and data from a stream together", - example: r#"{foo: bar} | to json --raw | metadata access {|meta| {in: $in, meta: $meta}}"#, + example: r#"{foo: bar} | to json --raw | metadata access {|meta| {in: $in, content: $meta.content_type}}"#, result: Some(Value::test_record(record! { "in" => Value::test_string(r#"{"foo":"bar"}"#), - "meta" => Value::test_record(record! { - "content_type" => Value::test_string(r#"application/json"#) - }) + "content" => Value::test_string(r#"application/json"#) })), }] } diff --git a/crates/nu-command/src/debug/metadata_set.rs b/crates/nu-command/src/debug/metadata_set.rs index 7b943f8c65..b5dd742ea3 100644 --- a/crates/nu-command/src/debug/metadata_set.rs +++ b/crates/nu-command/src/debug/metadata_set.rs @@ -79,15 +79,13 @@ impl Command for MetadataSet { }, Example { description: "Set the metadata of a file path", - example: "'crates' | metadata set --datasource-filepath $'(pwd)/crates' | metadata", + example: "'crates' | metadata set --datasource-filepath $'(pwd)/crates'", result: None, }, Example { description: "Set the metadata of a file path", - example: "'crates' | metadata set --content-type text/plain | metadata", - result: Some(Value::test_record(record! { - "content_type" => Value::test_string("text/plain"), - })), + example: "'crates' | metadata set --content-type text/plain | metadata | get content_type", + result: Some(Value::test_string("text/plain")), }, ] } diff --git a/crates/nu-command/src/debug/util.rs b/crates/nu-command/src/debug/util.rs index 07f5f38df9..a0a56560fa 100644 --- a/crates/nu-command/src/debug/util.rs +++ b/crates/nu-command/src/debug/util.rs @@ -1,4 +1,4 @@ -use nu_protocol::{DataSource, PipelineMetadata, Record, Span, Value}; +use nu_protocol::{DataSource, IntoValue, PipelineData, PipelineMetadata, Record, Span, Value}; pub fn extend_record_with_metadata( mut record: Record, @@ -29,6 +29,10 @@ pub fn extend_record_with_metadata( record } -pub fn build_metadata_record(metadata: Option<&PipelineMetadata>, head: Span) -> Record { - extend_record_with_metadata(Record::new(), metadata, head) +pub fn build_metadata_record(pipeline: &PipelineData, head: Span) -> Record { + let mut record = Record::new(); + if let Some(span) = pipeline.span() { + record.insert("span", span.into_value(head)); + } + extend_record_with_metadata(record, pipeline.metadata().as_ref(), head) } diff --git a/crates/nu-command/src/formats/from/csv.rs b/crates/nu-command/src/formats/from/csv.rs index d1cb497f83..f20dc4c7b0 100644 --- a/crates/nu-command/src/formats/from/csv.rs +++ b/crates/nu-command/src/formats/from/csv.rs @@ -203,6 +203,7 @@ mod test { use super::*; + use crate::Reject; use crate::{Metadata, MetadataSet}; #[test] @@ -221,6 +222,7 @@ mod test { working_set.add_decl(Box::new(FromCsv {})); working_set.add_decl(Box::new(Metadata {})); working_set.add_decl(Box::new(MetadataSet {})); + working_set.add_decl(Box::new(Reject {})); working_set.render() }; @@ -229,7 +231,7 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = r#""a,b\n1,2" | metadata set --content-type 'text/csv' --datasource-ls | from csv | metadata | $in"#; + let cmd = r#""a,b\n1,2" | metadata set --content-type 'text/csv' --datasource-ls | from csv | metadata | reject span | $in"#; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), diff --git a/crates/nu-command/src/formats/from/json.rs b/crates/nu-command/src/formats/from/json.rs index d76caacceb..e36b6b9bf9 100644 --- a/crates/nu-command/src/formats/from/json.rs +++ b/crates/nu-command/src/formats/from/json.rs @@ -248,6 +248,7 @@ fn convert_string_to_value_strict(string_input: &str, span: Span) -> Result Result<(), ShellError> { mod test { use nu_cmd_lang::eval_pipeline_without_terminal_expression; + use crate::Reject; use crate::{Metadata, MetadataSet, ToMsgpack}; use super::*; @@ -535,6 +536,7 @@ mod test { working_set.add_decl(Box::new(FromMsgpack {})); working_set.add_decl(Box::new(Metadata {})); working_set.add_decl(Box::new(MetadataSet {})); + working_set.add_decl(Box::new(Reject {})); working_set.render() }; @@ -543,7 +545,7 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = r#"{a: 1 b: 2} | to msgpack | metadata set --datasource-ls | from msgpack | metadata | $in"#; + let cmd = r#"{a: 1 b: 2} | to msgpack | metadata set --datasource-ls | from msgpack | metadata | reject span | $in"#; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), diff --git a/crates/nu-command/src/formats/from/nuon.rs b/crates/nu-command/src/formats/from/nuon.rs index 22df9569c2..ef3b398e99 100644 --- a/crates/nu-command/src/formats/from/nuon.rs +++ b/crates/nu-command/src/formats/from/nuon.rs @@ -74,6 +74,7 @@ impl Command for FromNuon { mod test { use nu_cmd_lang::eval_pipeline_without_terminal_expression; + use crate::Reject; use crate::{Metadata, MetadataSet}; use super::*; @@ -94,6 +95,7 @@ mod test { working_set.add_decl(Box::new(FromNuon {})); working_set.add_decl(Box::new(Metadata {})); working_set.add_decl(Box::new(MetadataSet {})); + working_set.add_decl(Box::new(Reject {})); working_set.render() }; @@ -102,7 +104,7 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = r#"'[[a, b]; [1, 2]]' | metadata set --content-type 'application/x-nuon' --datasource-ls | from nuon | metadata | $in"#; + let cmd = r#"'[[a, b]; [1, 2]]' | metadata set --content-type 'application/x-nuon' --datasource-ls | from nuon | metadata | reject span | $in"#; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), diff --git a/crates/nu-command/src/formats/from/toml.rs b/crates/nu-command/src/formats/from/toml.rs index 8f4242e5db..f6a772b0d6 100644 --- a/crates/nu-command/src/formats/from/toml.rs +++ b/crates/nu-command/src/formats/from/toml.rs @@ -145,6 +145,7 @@ pub fn convert_string_to_value(string_input: String, span: Span) -> Result, src: String, pos: TextPos) -> mod tests { use crate::Metadata; use crate::MetadataSet; + use crate::Reject; use super::*; @@ -541,6 +542,7 @@ mod tests { working_set.add_decl(Box::new(FromXml {})); working_set.add_decl(Box::new(Metadata {})); working_set.add_decl(Box::new(MetadataSet {})); + working_set.add_decl(Box::new(Reject {})); working_set.render() }; @@ -552,7 +554,7 @@ mod tests { let cmd = r#"' Event -' | metadata set --content-type 'application/xml' --datasource-ls | from xml | metadata | $in"#; +' | metadata set --content-type 'application/xml' --datasource-ls | from xml | metadata | reject span | $in"#; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), diff --git a/crates/nu-command/src/formats/from/yaml.rs b/crates/nu-command/src/formats/from/yaml.rs index 1fad95a52a..69617d7a01 100644 --- a/crates/nu-command/src/formats/from/yaml.rs +++ b/crates/nu-command/src/formats/from/yaml.rs @@ -243,6 +243,7 @@ fn from_yaml(input: PipelineData, head: Span) -> Result Value::test_string("text/csv"))), + Value::test_string("text/csv"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/json.rs b/crates/nu-command/src/formats/to/json.rs index 17918f63e7..4a481ecc32 100644 --- a/crates/nu-command/src/formats/to/json.rs +++ b/crates/nu-command/src/formats/to/json.rs @@ -229,14 +229,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to json | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to json | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record(record!("content_type" => Value::test_string("application/json"))), + Value::test_string("application/json"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/md.rs b/crates/nu-command/src/formats/to/md.rs index 0d12b38732..1aeaa82c4f 100644 --- a/crates/nu-command/src/formats/to/md.rs +++ b/crates/nu-command/src/formats/to/md.rs @@ -904,14 +904,14 @@ mod tests { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to md | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to md | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record(record!("content_type" => Value::test_string("text/markdown"))), + Value::test_string("text/markdown"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/msgpack.rs b/crates/nu-command/src/formats/to/msgpack.rs index cb99824107..be38a40739 100644 --- a/crates/nu-command/src/formats/to/msgpack.rs +++ b/crates/nu-command/src/formats/to/msgpack.rs @@ -348,16 +348,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to msgpack | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to msgpack | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record( - record!("content_type" => Value::test_string("application/x-msgpack")) - ), + Value::test_string("application/x-msgpack"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/nuon.rs b/crates/nu-command/src/formats/to/nuon.rs index 90fc14fe99..6e2a45a5f1 100644 --- a/crates/nu-command/src/formats/to/nuon.rs +++ b/crates/nu-command/src/formats/to/nuon.rs @@ -143,14 +143,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to nuon | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to nuon | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record(record!("content_type" => Value::test_string("application/x-nuon"))), + Value::test_string("application/x-nuon"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/text.rs b/crates/nu-command/src/formats/to/text.rs index 16a0d6f146..a9a9c77eb5 100644 --- a/crates/nu-command/src/formats/to/text.rs +++ b/crates/nu-command/src/formats/to/text.rs @@ -273,14 +273,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to text | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to text | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record(record!("content_type" => Value::test_string("text/plain"))), + Value::test_string("text/plain"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/tsv.rs b/crates/nu-command/src/formats/to/tsv.rs index c55428c5a0..ea0c221a19 100644 --- a/crates/nu-command/src/formats/to/tsv.rs +++ b/crates/nu-command/src/formats/to/tsv.rs @@ -132,16 +132,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to tsv | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to tsv | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record( - record!("content_type" => Value::test_string("text/tab-separated-values")) - ), + Value::test_string("text/tab-separated-values"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/xml.rs b/crates/nu-command/src/formats/to/xml.rs index 7a6e718e40..052435a9c7 100644 --- a/crates/nu-command/src/formats/to/xml.rs +++ b/crates/nu-command/src/formats/to/xml.rs @@ -538,14 +538,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{tag: note attributes: {} content : [{tag: remember attributes: {} content : [{tag: null attributes: null content : Event}]}]} | to xml | metadata | get content_type"; + let cmd = "{tag: note attributes: {} content : [{tag: remember attributes: {} content : [{tag: null attributes: null content : Event}]}]} | to xml | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record(record!("content_type" => Value::test_string("application/xml"))), + Value::test_string("application/xml"), result.expect("There should be a result") ); } diff --git a/crates/nu-command/src/formats/to/yaml.rs b/crates/nu-command/src/formats/to/yaml.rs index 7b6f99bb67..356d3e536e 100644 --- a/crates/nu-command/src/formats/to/yaml.rs +++ b/crates/nu-command/src/formats/to/yaml.rs @@ -233,14 +233,14 @@ mod test { .merge_delta(delta) .expect("Error merging delta"); - let cmd = "{a: 1 b: 2} | to yaml | metadata | get content_type"; + let cmd = "{a: 1 b: 2} | to yaml | metadata | get content_type | $in"; let result = eval_pipeline_without_terminal_expression( cmd, std::env::temp_dir().as_ref(), &mut engine_state, ); assert_eq!( - Value::test_record(record!("content_type" => Value::test_string("application/yaml"))), + Value::test_string("application/yaml"), result.expect("There should be a result") ); } diff --git a/crates/nu-protocol/src/span.rs b/crates/nu-protocol/src/span.rs index 6343d7dde0..9b96edf2e2 100644 --- a/crates/nu-protocol/src/span.rs +++ b/crates/nu-protocol/src/span.rs @@ -1,5 +1,5 @@ //! [`Span`] to point to sections of source code and the [`Spanned`] wrapper type -use crate::SpanId; +use crate::{IntoValue, SpanId, Value, record}; use miette::SourceSpan; use serde::{Deserialize, Serialize}; use std::ops::Deref; @@ -277,6 +277,16 @@ impl Span { } } +impl IntoValue for Span { + fn into_value(self, span: Span) -> Value { + let record = record! { + "start" => Value::int(self.start as i64, self), + "end" => Value::int(self.end as i64, self), + }; + record.into_value(span) + } +} + impl From for SourceSpan { fn from(s: Span) -> Self { Self::new(s.start.into(), s.end - s.start)