Add metadata command (#569)

* Add metadata command

* Add string interpolation to testing
This commit is contained in:
JT 2021-12-24 11:16:50 +11:00 committed by GitHub
parent b719f8d4eb
commit 7f0921a14b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 135 additions and 20 deletions

View file

@ -168,24 +168,23 @@ impl Command for For {
span,
}),
},
// FIXME? Numbered `for` is kinda strange, but was supported in previous nushell
// Example {
// description: "Number each item and echo a message",
// example: "for $it in ['bob' 'fred'] --numbered { $\"($it.index) is ($it.item)\" }",
// result: Some(Value::List {
// vals: vec![
// Value::String {
// val: "0 is bob".into(),
// span,
// },
// Value::String {
// val: "0 is fred".into(),
// span,
// },
// ],
// span,
// }),
// },
Example {
description: "Number each item and echo a message",
example: "for $it in ['bob' 'fred'] --numbered { $\"($it.index) is ($it.item)\" }",
result: Some(Value::List {
vals: vec![
Value::String {
val: "0 is bob".into(),
span,
},
Value::String {
val: "1 is fred".into(),
span,
},
],
span,
}),
},
]
}
}

View file

@ -0,0 +1,103 @@
use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Category, DataSource, Example, PipelineData, PipelineMetadata, Signature, Value,
};
#[derive(Clone)]
pub struct Metadata;
impl Command for Metadata {
fn name(&self) -> &str {
"metadata"
}
fn usage(&self) -> &str {
"Get the metadata for items in the stream"
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("metadata").category(Category::Core)
}
fn run(
&self,
engine_state: &EngineState,
_stack: &mut Stack,
call: &Call,
input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let head = call.head;
let ctrlc = engine_state.ctrlc.clone();
let metadata = input.metadata();
input.map(
move |x| {
let span = x.span();
let mut cols = vec![];
let mut vals = vec![];
cols.push("span".into());
if let Ok(span) = span {
vals.push(Value::Record {
cols: vec!["start".into(), "end".into()],
vals: vec![
Value::Int {
val: span.start as i64,
span,
},
Value::Int {
val: span.end as i64,
span,
},
],
span: head,
});
}
if let Some(x) = &metadata {
match x {
PipelineMetadata {
data_source: DataSource::Ls,
} => {
cols.push("source".into());
vals.push(Value::String {
val: "ls".into(),
span: head,
})
}
}
}
Value::Record {
cols,
vals,
span: head,
}
},
ctrlc,
)
}
fn examples(&self) -> Vec<Example> {
vec![Example {
description: "Get the metadata of a value",
example: "3 | metadata",
result: None,
}]
}
}
#[cfg(test)]
mod test {
use super::*;
#[test]
fn test_examples() {
use crate::test_examples;
test_examples(Metadata {})
}
}

View file

@ -13,6 +13,7 @@ mod hide;
mod history;
mod if_;
mod let_;
mod metadata;
mod module;
mod source;
mod use_;
@ -33,6 +34,7 @@ pub use hide::Hide;
pub use history::History;
pub use if_::If;
pub use let_::Let;
pub use metadata::Metadata;
pub use module::Module;
pub use source::Source;
pub use use_::Use;

View file

@ -38,6 +38,7 @@ pub fn create_default_context() -> EngineState {
History,
If,
Let,
Metadata,
Module,
Source,
Use,

View file

@ -16,6 +16,8 @@ use super::{Ansi, Date, From, Into, Math, Path, Random, Split, Str, StrCollect,
#[cfg(test)]
pub fn test_examples(cmd: impl Command + 'static) {
use crate::BuildString;
let examples = cmd.examples();
let mut engine_state = Box::new(EngineState::new());
@ -25,6 +27,7 @@ pub fn test_examples(cmd: impl Command + 'static) {
let mut working_set = StateWorkingSet::new(&*engine_state);
working_set.add_decl(Box::new(Str));
working_set.add_decl(Box::new(StrCollect));
working_set.add_decl(Box::new(BuildString));
working_set.add_decl(Box::new(From));
working_set.add_decl(Box::new(To));
working_set.add_decl(Box::new(Into));

View file

@ -37,12 +37,12 @@ pub enum PipelineData {
Stream(ValueStream, Option<PipelineMetadata>),
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub struct PipelineMetadata {
pub data_source: DataSource,
}
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum DataSource {
Ls,
}
@ -52,6 +52,13 @@ impl PipelineData {
PipelineData::Value(Value::Nothing { span }, None)
}
pub fn metadata(&self) -> Option<PipelineMetadata> {
match self {
PipelineData::Stream(_, x) => x.clone(),
PipelineData::Value(_, x) => x.clone(),
}
}
pub fn into_value(self, span: Span) -> Value {
match self {
PipelineData::Value(Value::Nothing { .. }, ..) => Value::nothing(span),