mirror of
https://github.com/nushell/nushell.git
synced 2024-11-25 01:43:47 +01:00
ListStream
touchup (#12524)
# Description Does some misc changes to `ListStream`: - Moves it into its own module/file separate from `RawStream`. - `ListStream`s now have an associated `Span`. - This required changes to `ListStreamInfo` in `nu-plugin`. Note sure if this is a breaking change for the plugin protocol. - Hides the internals of `ListStream` but also adds a few more methods. - This includes two functions to more easily alter a stream (these take a `ListStream` and return a `ListStream` instead of having to go through the whole `into_pipeline_data(..)` route). - `map`: takes a `FnMut(Value) -> Value` - `modify`: takes a function to modify the inner stream.
This commit is contained in:
parent
3143ded374
commit
e879d4ecaf
@ -107,7 +107,7 @@ impl Command for History {
|
|||||||
file: history_path.display().to_string(),
|
file: history_path.display().to_string(),
|
||||||
span: head,
|
span: head,
|
||||||
})?
|
})?
|
||||||
.into_pipeline_data(ctrlc)),
|
.into_pipeline_data(head, ctrlc)),
|
||||||
HistoryFileFormat::Sqlite => Ok(history_reader
|
HistoryFileFormat::Sqlite => Ok(history_reader
|
||||||
.and_then(|h| {
|
.and_then(|h| {
|
||||||
h.search(SearchQuery::everything(SearchDirection::Forward, None))
|
h.search(SearchQuery::everything(SearchDirection::Forward, None))
|
||||||
@ -122,7 +122,7 @@ impl Command for History {
|
|||||||
file: history_path.display().to_string(),
|
file: history_path.display().to_string(),
|
||||||
span: head,
|
span: head,
|
||||||
})?
|
})?
|
||||||
.into_pipeline_data(ctrlc)),
|
.into_pipeline_data(head, ctrlc)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -87,7 +87,7 @@ impl Command for EachWhile {
|
|||||||
Err(_) => None,
|
Err(_) => None,
|
||||||
})
|
})
|
||||||
.fuse()
|
.fuse()
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
||||||
PipelineData::ExternalStream {
|
PipelineData::ExternalStream {
|
||||||
@ -108,7 +108,7 @@ impl Command for EachWhile {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.fuse()
|
.fuse()
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
// This match allows non-iterables to be accepted,
|
// This match allows non-iterables to be accepted,
|
||||||
// which is currently considered undesirable (Nov 2022).
|
// which is currently considered undesirable (Nov 2022).
|
||||||
|
@ -108,7 +108,7 @@ impl Command for UpdateCells {
|
|||||||
columns,
|
columns,
|
||||||
span: head,
|
span: head,
|
||||||
}
|
}
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone())
|
.into_pipeline_data(head, engine_state.ctrlc.clone())
|
||||||
.set_metadata(metadata))
|
.set_metadata(metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -238,10 +238,7 @@ fn format(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(PipelineData::ListStream(
|
Ok(ListStream::new(list.into_iter(), head_span, engine_state.ctrlc.clone()).into())
|
||||||
ListStream::from_stream(list.into_iter(), None),
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
// Unwrapping this ShellError is a bit unfortunate.
|
// Unwrapping this ShellError is a bit unfortunate.
|
||||||
// Ideally, its Span would be preserved.
|
// Ideally, its Span would be preserved.
|
||||||
|
@ -62,6 +62,7 @@ impl Command for Do {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let block: Closure = call.req(engine_state, caller_stack, 0)?;
|
let block: Closure = call.req(engine_state, caller_stack, 0)?;
|
||||||
let rest: Vec<Value> = call.rest(engine_state, caller_stack, 1)?;
|
let rest: Vec<Value> = call.rest(engine_state, caller_stack, 1)?;
|
||||||
let ignore_all_errors = call.has_flag(engine_state, caller_stack, "ignore-errors")?;
|
let ignore_all_errors = call.has_flag(engine_state, caller_stack, "ignore-errors")?;
|
||||||
@ -75,7 +76,7 @@ impl Command for Do {
|
|||||||
let mut callee_stack = caller_stack.captures_to_stack_preserve_out_dest(block.captures);
|
let mut callee_stack = caller_stack.captures_to_stack_preserve_out_dest(block.captures);
|
||||||
let block = engine_state.get_block(block.block_id);
|
let block = engine_state.get_block(block.block_id);
|
||||||
|
|
||||||
bind_args_to(&mut callee_stack, &block.signature, rest, call.head)?;
|
bind_args_to(&mut callee_stack, &block.signature, rest, head)?;
|
||||||
let eval_block_with_early_return = get_eval_block_with_early_return(engine_state);
|
let eval_block_with_early_return = get_eval_block_with_early_return(engine_state);
|
||||||
let result = eval_block_with_early_return(engine_state, &mut callee_stack, block, input);
|
let result = eval_block_with_early_return(engine_state, &mut callee_stack, block, input);
|
||||||
|
|
||||||
@ -117,7 +118,7 @@ impl Command for Do {
|
|||||||
None,
|
None,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.err_span(call.head)
|
.err_span(head)
|
||||||
})
|
})
|
||||||
.transpose()?;
|
.transpose()?;
|
||||||
|
|
||||||
@ -148,13 +149,9 @@ impl Command for Do {
|
|||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut exit_code_ctrlc = None;
|
|
||||||
let exit_code: Vec<Value> = match exit_code {
|
let exit_code: Vec<Value> = match exit_code {
|
||||||
None => vec![],
|
None => vec![],
|
||||||
Some(exit_code_stream) => {
|
Some(exit_code_stream) => exit_code_stream.into_iter().collect(),
|
||||||
exit_code_ctrlc.clone_from(&exit_code_stream.ctrlc);
|
|
||||||
exit_code_stream.into_iter().collect()
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
if let Some(Value::Int { val: code, .. }) = exit_code.last() {
|
if let Some(Value::Int { val: code, .. }) = exit_code.last() {
|
||||||
if *code != 0 {
|
if *code != 0 {
|
||||||
@ -174,10 +171,7 @@ impl Command for Do {
|
|||||||
span,
|
span,
|
||||||
None,
|
None,
|
||||||
)),
|
)),
|
||||||
exit_code: Some(ListStream::from_stream(
|
exit_code: Some(ListStream::new(exit_code.into_iter(), span, None)),
|
||||||
exit_code.into_iter(),
|
|
||||||
exit_code_ctrlc,
|
|
||||||
)),
|
|
||||||
span,
|
span,
|
||||||
metadata,
|
metadata,
|
||||||
trim_end_newline,
|
trim_end_newline,
|
||||||
@ -205,21 +199,15 @@ impl Command for Do {
|
|||||||
Ok(PipelineData::Value(Value::Error { .. }, ..)) | Err(_) if ignore_shell_errors => {
|
Ok(PipelineData::Value(Value::Error { .. }, ..)) | Err(_) if ignore_shell_errors => {
|
||||||
Ok(PipelineData::empty())
|
Ok(PipelineData::empty())
|
||||||
}
|
}
|
||||||
Ok(PipelineData::ListStream(ls, metadata)) if ignore_shell_errors => {
|
Ok(PipelineData::ListStream(stream, metadata)) if ignore_shell_errors => {
|
||||||
// check if there is a `Value::Error` in given list stream first.
|
let stream = stream.map(move |value| {
|
||||||
let mut values = vec![];
|
if let Value::Error { .. } = value {
|
||||||
let ctrlc = ls.ctrlc.clone();
|
Value::nothing(head)
|
||||||
for v in ls {
|
|
||||||
if let Value::Error { .. } = v {
|
|
||||||
values.push(Value::nothing(call.head));
|
|
||||||
} else {
|
} else {
|
||||||
values.push(v)
|
value
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
Ok(PipelineData::ListStream(
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
ListStream::from_stream(values.into_iter(), ctrlc),
|
|
||||||
metadata,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
r => r,
|
r => r,
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
|
use nu_engine::{command_prelude::*, get_eval_block, get_eval_expression};
|
||||||
use nu_protocol::ListStream;
|
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct For;
|
pub struct For;
|
||||||
@ -88,7 +87,11 @@ impl Command for For {
|
|||||||
let span = value.span();
|
let span = value.span();
|
||||||
match value {
|
match value {
|
||||||
Value::List { vals, .. } => {
|
Value::List { vals, .. } => {
|
||||||
for (idx, x) in ListStream::from_stream(vals.into_iter(), ctrlc).enumerate() {
|
for (idx, x) in vals.into_iter().enumerate() {
|
||||||
|
if nu_utils::ctrl_c::was_pressed(&ctrlc) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// with_env() is used here to ensure that each iteration uses
|
// with_env() is used here to ensure that each iteration uses
|
||||||
// a different set of environment variables.
|
// a different set of environment variables.
|
||||||
// Hence, a 'cd' in the first loop won't affect the next loop.
|
// Hence, a 'cd' in the first loop won't affect the next loop.
|
||||||
|
@ -26,13 +26,10 @@ impl Command for ScopeAliases {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let head = call.head;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
|
|
||||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||||
scope_data.populate_decls();
|
scope_data.populate_decls();
|
||||||
|
Ok(Value::list(scope_data.collect_aliases(head), head).into_pipeline_data())
|
||||||
Ok(scope_data.collect_aliases(span).into_pipeline_data(ctrlc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -26,13 +26,10 @@ impl Command for ScopeCommands {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let head = call.head;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
|
|
||||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||||
scope_data.populate_decls();
|
scope_data.populate_decls();
|
||||||
|
Ok(Value::list(scope_data.collect_commands(head), head).into_pipeline_data())
|
||||||
Ok(scope_data.collect_commands(span).into_pipeline_data(ctrlc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -26,13 +26,10 @@ impl Command for ScopeExterns {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let head = call.head;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
|
|
||||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||||
scope_data.populate_decls();
|
scope_data.populate_decls();
|
||||||
|
Ok(Value::list(scope_data.collect_externs(head), head).into_pipeline_data())
|
||||||
Ok(scope_data.collect_externs(span).into_pipeline_data(ctrlc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -26,13 +26,10 @@ impl Command for ScopeModules {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let head = call.head;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
|
|
||||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||||
scope_data.populate_modules();
|
scope_data.populate_modules();
|
||||||
|
Ok(Value::list(scope_data.collect_modules(head), head).into_pipeline_data())
|
||||||
Ok(scope_data.collect_modules(span).into_pipeline_data(ctrlc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -26,13 +26,10 @@ impl Command for ScopeVariables {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let head = call.head;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
|
|
||||||
let mut scope_data = ScopeData::new(engine_state, stack);
|
let mut scope_data = ScopeData::new(engine_state, stack);
|
||||||
scope_data.populate_vars();
|
scope_data.populate_vars();
|
||||||
|
Ok(Value::list(scope_data.collect_vars(head), head).into_pipeline_data())
|
||||||
Ok(scope_data.collect_vars(span).into_pipeline_data(ctrlc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -69,35 +69,47 @@ impl Command for PluginList {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.span();
|
let head = call.head;
|
||||||
|
|
||||||
// Group plugin decls by plugin identity
|
// Group plugin decls by plugin identity
|
||||||
let decls = engine_state.plugin_decls().into_group_map_by(|decl| {
|
let decls = engine_state.plugin_decls().into_group_map_by(|decl| {
|
||||||
decl.plugin_identity()
|
decl.plugin_identity()
|
||||||
.expect("plugin decl should have identity")
|
.expect("plugin decl should have identity")
|
||||||
});
|
});
|
||||||
|
|
||||||
// Build plugins list
|
// Build plugins list
|
||||||
let list = engine_state.plugins().iter().map(|plugin| {
|
let list = engine_state.plugins().iter().map(|plugin| {
|
||||||
// Find commands that belong to the plugin
|
// Find commands that belong to the plugin
|
||||||
let commands = decls.get(plugin.identity())
|
let commands = decls.get(plugin.identity())
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flat_map(|decls| {
|
.flat_map(|decls| {
|
||||||
decls.iter().map(|decl| Value::string(decl.name(), span))
|
decls.iter().map(|decl| Value::string(decl.name(), head))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Value::record(record! {
|
let pid = plugin
|
||||||
"name" => Value::string(plugin.identity().name(), span),
|
.pid()
|
||||||
"is_running" => Value::bool(plugin.is_running(), span),
|
.map(|p| Value::int(p as i64, head))
|
||||||
"pid" => plugin.pid()
|
.unwrap_or(Value::nothing(head));
|
||||||
.map(|p| Value::int(p as i64, span))
|
|
||||||
.unwrap_or(Value::nothing(span)),
|
let shell = plugin
|
||||||
"filename" => Value::string(plugin.identity().filename().to_string_lossy(), span),
|
.identity()
|
||||||
"shell" => plugin.identity().shell()
|
.shell()
|
||||||
.map(|s| Value::string(s.to_string_lossy(), span))
|
.map(|s| Value::string(s.to_string_lossy(), head))
|
||||||
.unwrap_or(Value::nothing(span)),
|
.unwrap_or(Value::nothing(head));
|
||||||
"commands" => Value::list(commands, span),
|
|
||||||
}, span)
|
let record = record! {
|
||||||
}).collect::<Vec<Value>>();
|
"name" => Value::string(plugin.identity().name(), head),
|
||||||
Ok(list.into_pipeline_data(engine_state.ctrlc.clone()))
|
"is_running" => Value::bool(plugin.is_running(), head),
|
||||||
|
"pid" => pid,
|
||||||
|
"filename" => Value::string(plugin.identity().filename().to_string_lossy(), head),
|
||||||
|
"shell" => shell,
|
||||||
|
"commands" => Value::list(commands, head),
|
||||||
|
};
|
||||||
|
|
||||||
|
Value::record(record, head)
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
Ok(Value::list(list, head).into_pipeline_data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +98,7 @@ fn into_cell_path(call: &Call, input: PipelineData) -> Result<PipelineData, Shel
|
|||||||
match input {
|
match input {
|
||||||
PipelineData::Value(value, _) => Ok(value_to_cell_path(&value, head)?.into_pipeline_data()),
|
PipelineData::Value(value, _) => Ok(value_to_cell_path(&value, head)?.into_pipeline_data()),
|
||||||
PipelineData::ListStream(stream, ..) => {
|
PipelineData::ListStream(stream, ..) => {
|
||||||
let list: Vec<_> = stream.collect();
|
let list: Vec<_> = stream.into_iter().collect();
|
||||||
Ok(list_to_cell_path(&list, head)?.into_pipeline_data())
|
Ok(list_to_cell_path(&list, head)?.into_pipeline_data())
|
||||||
}
|
}
|
||||||
PipelineData::ExternalStream { span, .. } => Err(ShellError::OnlySupportsThisInputType {
|
PipelineData::ExternalStream { span, .. } => Err(ShellError::OnlySupportsThisInputType {
|
||||||
|
@ -81,7 +81,7 @@ impl Command for IntoValue {
|
|||||||
display_as_filesizes,
|
display_as_filesizes,
|
||||||
span,
|
span,
|
||||||
}
|
}
|
||||||
.into_pipeline_data(ctrlc)
|
.into_pipeline_data(span, ctrlc)
|
||||||
.set_metadata(metadata))
|
.set_metadata(metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,8 +203,8 @@ fn action(
|
|||||||
ctrl_c: Option<Arc<AtomicBool>>,
|
ctrl_c: Option<Arc<AtomicBool>>,
|
||||||
) -> Result<Value, ShellError> {
|
) -> Result<Value, ShellError> {
|
||||||
match input {
|
match input {
|
||||||
PipelineData::ListStream(list_stream, _) => {
|
PipelineData::ListStream(stream, _) => {
|
||||||
insert_in_transaction(list_stream.stream, span, table, ctrl_c)
|
insert_in_transaction(stream.into_iter(), span, table, ctrl_c)
|
||||||
}
|
}
|
||||||
PipelineData::Value(
|
PipelineData::Value(
|
||||||
Value::List {
|
Value::List {
|
||||||
|
@ -30,17 +30,17 @@ impl Command for SubCommand {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
let head = call.head;
|
||||||
|
|
||||||
Ok(TZ_VARIANTS
|
Ok(TZ_VARIANTS
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |x| {
|
.map(move |x| {
|
||||||
Value::record(
|
Value::record(
|
||||||
record! { "timezone" => Value::string(x.name(), span) },
|
record! { "timezone" => Value::string(x.name(), head) },
|
||||||
span,
|
head,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -34,16 +34,14 @@ impl Command for Explain {
|
|||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
// This was all delightfully stolen from benchmark :)
|
// This was all delightfully stolen from benchmark :)
|
||||||
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
let capture_block: Closure = call.req(engine_state, stack, 0)?;
|
||||||
let block = engine_state.get_block(capture_block.block_id);
|
let block = engine_state.get_block(capture_block.block_id);
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
let mut stack = stack.captures_to_stack(capture_block.captures);
|
let mut stack = stack.captures_to_stack(capture_block.captures);
|
||||||
|
let elements = get_pipeline_elements(engine_state, &mut stack, block, head);
|
||||||
let elements = get_pipeline_elements(engine_state, &mut stack, block, call.head);
|
Ok(Value::list(elements, head).into_pipeline_data())
|
||||||
|
|
||||||
Ok(elements.into_pipeline_data(ctrlc))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -47,13 +47,21 @@ impl Command for MetadataSet {
|
|||||||
let metadata = PipelineMetadata {
|
let metadata = PipelineMetadata {
|
||||||
data_source: DataSource::FilePath(path.into()),
|
data_source: DataSource::FilePath(path.into()),
|
||||||
};
|
};
|
||||||
Ok(input.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(input.into_pipeline_data_with_metadata(
|
||||||
|
head,
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
(None, true) => {
|
(None, true) => {
|
||||||
let metadata = PipelineMetadata {
|
let metadata = PipelineMetadata {
|
||||||
data_source: DataSource::Ls,
|
data_source: DataSource::Ls,
|
||||||
};
|
};
|
||||||
Ok(input.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(input.into_pipeline_data_with_metadata(
|
||||||
|
head,
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::IncorrectValue {
|
_ => Err(ShellError::IncorrectValue {
|
||||||
msg: "Expected either --datasource-ls(-l) or --datasource-filepath(-f)".to_string(),
|
msg: "Expected either --datasource-ls(-l) or --datasource-filepath(-f)".to_string(),
|
||||||
|
@ -121,7 +121,7 @@ impl Command for Du {
|
|||||||
};
|
};
|
||||||
Ok(
|
Ok(
|
||||||
du_for_one_pattern(args, ¤t_dir, tag, engine_state.ctrlc.clone())?
|
du_for_one_pattern(args, ¤t_dir, tag, engine_state.ctrlc.clone())?
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()),
|
.into_pipeline_data(tag, engine_state.ctrlc.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Some(paths) => {
|
Some(paths) => {
|
||||||
@ -147,7 +147,7 @@ impl Command for Du {
|
|||||||
Ok(result_iters
|
Ok(result_iters
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(tag, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ impl Command for Glob {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(if !not_patterns.is_empty() {
|
let result = if !not_patterns.is_empty() {
|
||||||
let np: Vec<&str> = not_patterns.iter().map(|s| s as &str).collect();
|
let np: Vec<&str> = not_patterns.iter().map(|s| s as &str).collect();
|
||||||
let glob_results = glob
|
let glob_results = glob
|
||||||
.walk_with_behavior(
|
.walk_with_behavior(
|
||||||
@ -218,10 +218,7 @@ impl Command for Glob {
|
|||||||
inner: vec![],
|
inner: vec![],
|
||||||
})?
|
})?
|
||||||
.flatten();
|
.flatten();
|
||||||
let result = glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span)?;
|
glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span)
|
||||||
result
|
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone())
|
|
||||||
} else {
|
} else {
|
||||||
let glob_results = glob
|
let glob_results = glob
|
||||||
.walk_with_behavior(
|
.walk_with_behavior(
|
||||||
@ -232,11 +229,12 @@ impl Command for Glob {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.flatten();
|
.flatten();
|
||||||
let result = glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span)?;
|
glob_to_value(ctrlc, glob_results, no_dirs, no_files, no_symlinks, span)
|
||||||
result
|
}?;
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone())
|
Ok(result
|
||||||
})
|
.into_iter()
|
||||||
|
.into_pipeline_data(span, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,10 +115,11 @@ impl Command for Ls {
|
|||||||
match input_pattern_arg {
|
match input_pattern_arg {
|
||||||
None => Ok(ls_for_one_pattern(None, args, ctrl_c.clone(), cwd)?
|
None => Ok(ls_for_one_pattern(None, args, ctrl_c.clone(), cwd)?
|
||||||
.into_pipeline_data_with_metadata(
|
.into_pipeline_data_with_metadata(
|
||||||
|
call_span,
|
||||||
|
ctrl_c,
|
||||||
PipelineMetadata {
|
PipelineMetadata {
|
||||||
data_source: DataSource::Ls,
|
data_source: DataSource::Ls,
|
||||||
},
|
},
|
||||||
ctrl_c,
|
|
||||||
)),
|
)),
|
||||||
Some(pattern) => {
|
Some(pattern) => {
|
||||||
let mut result_iters = vec![];
|
let mut result_iters = vec![];
|
||||||
@ -137,10 +138,11 @@ impl Command for Ls {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.flatten()
|
.flatten()
|
||||||
.into_pipeline_data_with_metadata(
|
.into_pipeline_data_with_metadata(
|
||||||
|
call_span,
|
||||||
|
ctrl_c,
|
||||||
PipelineMetadata {
|
PipelineMetadata {
|
||||||
data_source: DataSource::Ls,
|
data_source: DataSource::Ls,
|
||||||
},
|
},
|
||||||
ctrl_c,
|
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,10 @@ impl Command for Open {
|
|||||||
} else if output.len() == 1 {
|
} else if output.len() == 1 {
|
||||||
Ok(output.remove(0))
|
Ok(output.remove(0))
|
||||||
} else {
|
} else {
|
||||||
Ok(output.into_iter().flatten().into_pipeline_data(ctrlc))
|
Ok(output
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.into_pipeline_data(call_span, ctrlc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,7 +465,7 @@ fn rm(
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.filter(|x| !matches!(x.get_type(), Type::Nothing))
|
.filter(|x| !matches!(x.get_type(), Type::Nothing))
|
||||||
.into_pipeline_data(ctrlc)
|
.into_pipeline_data(span, ctrlc)
|
||||||
.print_not_formatted(engine_state, false, true)?;
|
.print_not_formatted(engine_state, false, true)?;
|
||||||
|
|
||||||
Ok(PipelineData::empty())
|
Ok(PipelineData::empty())
|
||||||
|
@ -116,7 +116,7 @@ only unwrap the outer list, and leave the variable's contents untouched."#
|
|||||||
Ok(input
|
Ok(input
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(other.into_pipeline_data())
|
.chain(other.into_pipeline_data())
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,73 +62,68 @@ impl Command for Columns {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
_engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = call.head;
|
getcol(call.head, input)
|
||||||
getcol(engine_state, span, input)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn getcol(
|
fn getcol(head: Span, input: PipelineData) -> Result<PipelineData, ShellError> {
|
||||||
engine_state: &EngineState,
|
|
||||||
head: Span,
|
|
||||||
input: PipelineData,
|
|
||||||
) -> Result<PipelineData, ShellError> {
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
match input {
|
match input {
|
||||||
PipelineData::Empty => Ok(PipelineData::Empty),
|
PipelineData::Empty => Ok(PipelineData::Empty),
|
||||||
PipelineData::Value(v, ..) => {
|
PipelineData::Value(v, ..) => {
|
||||||
let span = v.span();
|
let span = v.span();
|
||||||
match v {
|
let cols = match v {
|
||||||
Value::List {
|
Value::List {
|
||||||
vals: input_vals, ..
|
vals: input_vals, ..
|
||||||
} => {
|
} => get_columns(&input_vals)
|
||||||
let input_cols = get_columns(&input_vals);
|
.into_iter()
|
||||||
Ok(input_cols
|
.map(move |x| Value::string(x, span))
|
||||||
.into_iter()
|
.collect(),
|
||||||
.map(move |x| Value::string(x, span))
|
|
||||||
.into_pipeline_data(ctrlc)
|
|
||||||
.set_metadata(metadata))
|
|
||||||
}
|
|
||||||
Value::Custom { val, .. } => {
|
Value::Custom { val, .. } => {
|
||||||
// TODO: should we get CustomValue to expose columns in a more efficient way?
|
// TODO: should we get CustomValue to expose columns in a more efficient way?
|
||||||
// Would be nice to be able to get columns without generating the whole value
|
// Would be nice to be able to get columns without generating the whole value
|
||||||
let input_as_base_value = val.to_base_value(span)?;
|
let input_as_base_value = val.to_base_value(span)?;
|
||||||
let input_cols = get_columns(&[input_as_base_value]);
|
get_columns(&[input_as_base_value])
|
||||||
Ok(input_cols
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |x| Value::string(x, span))
|
.map(move |x| Value::string(x, span))
|
||||||
.into_pipeline_data(ctrlc)
|
.collect()
|
||||||
.set_metadata(metadata))
|
|
||||||
}
|
}
|
||||||
Value::Record { val, .. } => Ok(val
|
Value::Record { val, .. } => val
|
||||||
.into_owned()
|
.into_owned()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |(x, _)| Value::string(x, head))
|
.map(move |(x, _)| Value::string(x, head))
|
||||||
.into_pipeline_data(ctrlc)
|
.collect(),
|
||||||
.set_metadata(metadata)),
|
|
||||||
// Propagate errors
|
// Propagate errors
|
||||||
Value::Error { error, .. } => Err(*error),
|
Value::Error { error, .. } => return Err(*error),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => {
|
||||||
exp_input_type: "record or table".into(),
|
return Err(ShellError::OnlySupportsThisInputType {
|
||||||
wrong_type: other.get_type().to_string(),
|
exp_input_type: "record or table".into(),
|
||||||
dst_span: head,
|
wrong_type: other.get_type().to_string(),
|
||||||
src_span: other.span(),
|
dst_span: head,
|
||||||
}),
|
src_span: other.span(),
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(Value::list(cols, head)
|
||||||
|
.into_pipeline_data()
|
||||||
|
.set_metadata(metadata))
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(stream, ..) => {
|
PipelineData::ListStream(stream, ..) => {
|
||||||
let v: Vec<_> = stream.into_iter().collect();
|
let values = stream.into_iter().collect::<Vec<_>>();
|
||||||
let input_cols = get_columns(&v);
|
let cols = get_columns(&values)
|
||||||
|
|
||||||
Ok(input_cols
|
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |x| Value::string(x, head))
|
.map(|s| Value::string(s, head))
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc))
|
.collect();
|
||||||
|
|
||||||
|
Ok(Value::list(cols, head)
|
||||||
|
.into_pipeline_data()
|
||||||
|
.set_metadata(metadata))
|
||||||
}
|
}
|
||||||
PipelineData::ExternalStream { .. } => Err(ShellError::OnlySupportsThisInputType {
|
PipelineData::ExternalStream { .. } => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "record or table".into(),
|
exp_input_type: "record or table".into(),
|
||||||
|
@ -90,7 +90,8 @@ fn drop_cols(
|
|||||||
// is displayed farther to the right.
|
// is displayed farther to the right.
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
match input {
|
match input {
|
||||||
PipelineData::ListStream(mut stream, ..) => {
|
PipelineData::ListStream(stream, ..) => {
|
||||||
|
let mut stream = stream.into_iter();
|
||||||
if let Some(mut first) = stream.next() {
|
if let Some(mut first) = stream.next() {
|
||||||
let drop_cols = drop_cols_set(&mut first, head, columns)?;
|
let drop_cols = drop_cols_set(&mut first, head, columns)?;
|
||||||
|
|
||||||
@ -101,7 +102,7 @@ fn drop_cols(
|
|||||||
Err(e) => Value::error(e, head),
|
Err(e) => Value::error(e, head),
|
||||||
}
|
}
|
||||||
}))
|
}))
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
} else {
|
} else {
|
||||||
Ok(PipelineData::Empty)
|
Ok(PipelineData::Empty)
|
||||||
}
|
}
|
||||||
|
@ -100,6 +100,7 @@ impl Command for DropNth {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let number_or_range = extract_int_or_range(engine_state, stack, call)?;
|
let number_or_range = extract_int_or_range(engine_state, stack, call)?;
|
||||||
|
|
||||||
@ -115,7 +116,7 @@ impl Command for DropNth {
|
|||||||
return Err(ShellError::UnsupportedInput {
|
return Err(ShellError::UnsupportedInput {
|
||||||
msg: "float range".into(),
|
msg: "float range".into(),
|
||||||
input: "value originates from here".into(),
|
input: "value originates from here".into(),
|
||||||
msg_span: call.head,
|
msg_span: head,
|
||||||
input_span: number_or_range.span,
|
input_span: number_or_range.span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -129,7 +130,7 @@ impl Command for DropNth {
|
|||||||
return Err(ShellError::UnsupportedInput {
|
return Err(ShellError::UnsupportedInput {
|
||||||
msg: "drop nth accepts only positive ints".into(),
|
msg: "drop nth accepts only positive ints".into(),
|
||||||
input: "value originates from here".into(),
|
input: "value originates from here".into(),
|
||||||
msg_span: call.head,
|
msg_span: head,
|
||||||
input_span: number_or_range.span,
|
input_span: number_or_range.span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -139,7 +140,7 @@ impl Command for DropNth {
|
|||||||
msg: "The upper bound needs to be equal or larger to the lower bound"
|
msg: "The upper bound needs to be equal or larger to the lower bound"
|
||||||
.into(),
|
.into(),
|
||||||
input: "value originates from here".into(),
|
input: "value originates from here".into(),
|
||||||
msg_span: call.head,
|
msg_span: head,
|
||||||
input_span: number_or_range.span,
|
input_span: number_or_range.span,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -154,8 +155,9 @@ impl Command for DropNth {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.take(start)
|
.take(start)
|
||||||
.into_pipeline_data_with_metadata(
|
.into_pipeline_data_with_metadata(
|
||||||
metadata,
|
head,
|
||||||
engine_state.ctrlc.clone(),
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -175,7 +177,7 @@ impl Command for DropNth {
|
|||||||
rows,
|
rows,
|
||||||
current: 0,
|
current: 0,
|
||||||
}
|
}
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ with 'transpose' first."#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
||||||
PipelineData::ExternalStream {
|
PipelineData::ExternalStream {
|
||||||
@ -170,7 +170,7 @@ with 'transpose' first."#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
// This match allows non-iterables to be accepted,
|
// This match allows non-iterables to be accepted,
|
||||||
// which is currently considered undesirable (Nov 2022).
|
// which is currently considered undesirable (Nov 2022).
|
||||||
|
@ -60,10 +60,11 @@ pub fn empty(
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
PipelineData::ListStream(s, ..) => {
|
PipelineData::ListStream(s, ..) => {
|
||||||
|
let empty = s.into_iter().next().is_none();
|
||||||
if negate {
|
if negate {
|
||||||
Ok(Value::bool(s.count() != 0, head).into_pipeline_data())
|
Ok(Value::bool(!empty, head).into_pipeline_data())
|
||||||
} else {
|
} else {
|
||||||
Ok(Value::bool(s.count() == 0, head).into_pipeline_data())
|
Ok(Value::bool(empty, head).into_pipeline_data())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::Value(value, ..) => {
|
PipelineData::Value(value, ..) => {
|
||||||
|
@ -50,9 +50,9 @@ impl Command for Enumerate {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let span = call.head;
|
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.into_iter()
|
.into_iter()
|
||||||
@ -60,13 +60,13 @@ impl Command for Enumerate {
|
|||||||
.map(move |(idx, x)| {
|
.map(move |(idx, x)| {
|
||||||
Value::record(
|
Value::record(
|
||||||
record! {
|
record! {
|
||||||
"index" => Value::int(idx as i64, span),
|
"index" => Value::int(idx as i64, head),
|
||||||
"item" => x,
|
"item" => x,
|
||||||
},
|
},
|
||||||
span,
|
head,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc))
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +78,7 @@ impl Command for Every {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
Some(Value::error(err, span))
|
Some(Value::error(err, span))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
||||||
PipelineData::ExternalStream {
|
PipelineData::ExternalStream {
|
||||||
@ -92,7 +92,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
// This match allows non-iterables to be accepted,
|
// This match allows non-iterables to be accepted,
|
||||||
// which is currently considered undesirable (Nov 2022).
|
// which is currently considered undesirable (Nov 2022).
|
||||||
@ -108,7 +108,7 @@ a variable. On the other hand, the "row condition" syntax is not supported."#
|
|||||||
Some(Value::error(err, span))
|
Some(Value::error(err, span))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map(|data| data.set_metadata(metadata))
|
.map(|data| data.set_metadata(metadata))
|
||||||
|
@ -3,7 +3,7 @@ use fancy_regex::Regex;
|
|||||||
use nu_ansi_term::Style;
|
use nu_ansi_term::Style;
|
||||||
use nu_color_config::StyleComputer;
|
use nu_color_config::StyleComputer;
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::{Config, ListStream};
|
use nu_protocol::Config;
|
||||||
use nu_utils::IgnoreCaseExt;
|
use nu_utils::IgnoreCaseExt;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -416,9 +416,9 @@ fn find_with_rest_and_highlight(
|
|||||||
},
|
},
|
||||||
ctrlc,
|
ctrlc,
|
||||||
),
|
),
|
||||||
PipelineData::ListStream(stream, metadata) => Ok(ListStream::from_stream(
|
PipelineData::ListStream(stream, metadata) => {
|
||||||
stream
|
let stream = stream.modify(|iter| {
|
||||||
.map(move |mut x| {
|
iter.map(move |mut x| {
|
||||||
let span = x.span();
|
let span = x.span();
|
||||||
match &mut x {
|
match &mut x {
|
||||||
Value::Record { val, .. } => highlight_terms_in_record_with_search_columns(
|
Value::Record { val, .. } => highlight_terms_in_record_with_search_columns(
|
||||||
@ -442,10 +442,11 @@ fn find_with_rest_and_highlight(
|
|||||||
&cols_to_search_in_filter,
|
&cols_to_search_in_filter,
|
||||||
invert,
|
invert,
|
||||||
)
|
)
|
||||||
}),
|
})
|
||||||
ctrlc.clone(),
|
});
|
||||||
)
|
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
|
}
|
||||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
||||||
PipelineData::ExternalStream {
|
PipelineData::ExternalStream {
|
||||||
stdout: Some(stream),
|
stdout: Some(stream),
|
||||||
@ -496,7 +497,7 @@ fn find_with_rest_and_highlight(
|
|||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
Ok(output.into_pipeline_data(ctrlc))
|
Ok(output.into_pipeline_data(span, ctrlc))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ fn first_helper(
|
|||||||
} else {
|
} else {
|
||||||
Ok(iter
|
Ok(iter
|
||||||
.take(rows)
|
.take(rows)
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc))
|
.into_pipeline_data_with_metadata(span, ctrlc, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
@ -156,17 +156,18 @@ fn first_helper(
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(mut ls, metadata) => {
|
PipelineData::ListStream(stream, metadata) => {
|
||||||
if return_single_element {
|
if return_single_element {
|
||||||
if let Some(v) = ls.next() {
|
if let Some(v) = stream.into_iter().next() {
|
||||||
Ok(v.into_pipeline_data())
|
Ok(v.into_pipeline_data())
|
||||||
} else {
|
} else {
|
||||||
Err(ShellError::AccessEmptyContent { span: head })
|
Err(ShellError::AccessEmptyContent { span: head })
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Ok(ls
|
Ok(PipelineData::ListStream(
|
||||||
.take(rows)
|
stream.modify(|iter| iter.take(rows)),
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
metadata,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::ExternalStream { span, .. } => Err(ShellError::OnlySupportsThisInputType {
|
PipelineData::ExternalStream { span, .. } => Err(ShellError::OnlySupportsThisInputType {
|
||||||
|
@ -89,7 +89,7 @@ If multiple cell paths are given, this will produce a list of values."#
|
|||||||
output.push(val?);
|
output.push(val?);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output.into_iter().into_pipeline_data(ctrlc))
|
Ok(output.into_iter().into_pipeline_data(span, ctrlc))
|
||||||
}
|
}
|
||||||
.map(|x| x.set_metadata(metadata))
|
.map(|x| x.set_metadata(metadata))
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
|
use nu_protocol::ValueIterator;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Group;
|
pub struct Group;
|
||||||
@ -52,6 +53,7 @@ impl Command for Group {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let group_size: Spanned<usize> = call.req(engine_state, stack, 0)?;
|
let group_size: Spanned<usize> = call.req(engine_state, stack, 0)?;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
@ -61,16 +63,16 @@ impl Command for Group {
|
|||||||
let each_group_iterator = EachGroupIterator {
|
let each_group_iterator = EachGroupIterator {
|
||||||
group_size: group_size.item,
|
group_size: group_size.item,
|
||||||
input: Box::new(input.into_iter()),
|
input: Box::new(input.into_iter()),
|
||||||
span: call.head,
|
span: head,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(each_group_iterator.into_pipeline_data_with_metadata(metadata, ctrlc))
|
Ok(each_group_iterator.into_pipeline_data_with_metadata(head, ctrlc, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EachGroupIterator {
|
struct EachGroupIterator {
|
||||||
group_size: usize,
|
group_size: usize,
|
||||||
input: Box<dyn Iterator<Item = Value> + Send>,
|
input: ValueIterator,
|
||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -159,7 +159,7 @@ fn insert(
|
|||||||
}
|
}
|
||||||
Ok(value.into_pipeline_data_with_metadata(metadata))
|
Ok(value.into_pipeline_data_with_metadata(metadata))
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(mut stream, metadata) => {
|
PipelineData::ListStream(stream, metadata) => {
|
||||||
if let Some((
|
if let Some((
|
||||||
&PathMember::Int {
|
&PathMember::Int {
|
||||||
val,
|
val,
|
||||||
@ -169,6 +169,7 @@ fn insert(
|
|||||||
path,
|
path,
|
||||||
)) = cell_path.members.split_first()
|
)) = cell_path.members.split_first()
|
||||||
{
|
{
|
||||||
|
let mut stream = stream.into_iter();
|
||||||
let mut pre_elems = vec![];
|
let mut pre_elems = vec![];
|
||||||
|
|
||||||
for idx in 0..val {
|
for idx in 0..val {
|
||||||
@ -221,40 +222,39 @@ fn insert(
|
|||||||
Ok(pre_elems
|
Ok(pre_elems
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(stream)
|
.chain(stream)
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
} else if let Value::Closure { val, .. } = replacement {
|
} else if let Value::Closure { val, .. } = replacement {
|
||||||
let mut closure = ClosureEval::new(engine_state, stack, val);
|
let mut closure = ClosureEval::new(engine_state, stack, val);
|
||||||
Ok(stream
|
let stream = stream.map(move |mut value| {
|
||||||
.map(move |mut value| {
|
let err = insert_value_by_closure(
|
||||||
let err = insert_value_by_closure(
|
&mut value,
|
||||||
&mut value,
|
&mut closure,
|
||||||
&mut closure,
|
head,
|
||||||
head,
|
&cell_path.members,
|
||||||
&cell_path.members,
|
false,
|
||||||
false,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(e) = err {
|
if let Err(e) = err {
|
||||||
Value::error(e, head)
|
Value::error(e, head)
|
||||||
} else {
|
} else {
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
} else {
|
} else {
|
||||||
Ok(stream
|
let stream = stream.map(move |mut value| {
|
||||||
.map(move |mut value| {
|
if let Err(e) = value.insert_data_at_cell_path(
|
||||||
if let Err(e) = value.insert_data_at_cell_path(
|
&cell_path.members,
|
||||||
&cell_path.members,
|
replacement.clone(),
|
||||||
replacement.clone(),
|
head,
|
||||||
head,
|
) {
|
||||||
) {
|
Value::error(e, head)
|
||||||
Value::error(e, head)
|
} else {
|
||||||
} else {
|
value
|
||||||
value
|
}
|
||||||
}
|
});
|
||||||
})
|
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::Empty => Err(ShellError::IncompatiblePathAccess {
|
PipelineData::Empty => Err(ShellError::IncompatiblePathAccess {
|
||||||
|
@ -147,7 +147,7 @@ interleave
|
|||||||
// Now that threads are writing to the channel, we just return it as a stream
|
// Now that threads are writing to the channel, we just return it as a stream
|
||||||
Ok(rx
|
Ok(rx
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ impl Command for Items {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
Value::Error { error, .. } => Err(*error),
|
Value::Error { error, .. } => Err(*error),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => Err(ShellError::OnlySupportsThisInputType {
|
||||||
|
@ -52,9 +52,8 @@ impl Command for Lines {
|
|||||||
}
|
}
|
||||||
PipelineData::Empty => Ok(PipelineData::Empty),
|
PipelineData::Empty => Ok(PipelineData::Empty),
|
||||||
PipelineData::ListStream(stream, metadata) => {
|
PipelineData::ListStream(stream, metadata) => {
|
||||||
let iter = stream
|
let stream = stream.modify(|iter| {
|
||||||
.into_iter()
|
iter.filter_map(move |value| {
|
||||||
.filter_map(move |value| {
|
|
||||||
let span = value.span();
|
let span = value.span();
|
||||||
if let Value::String { val, .. } = value {
|
if let Value::String { val, .. } = value {
|
||||||
Some(
|
Some(
|
||||||
@ -72,11 +71,10 @@ impl Command for Lines {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.flatten();
|
.flatten()
|
||||||
|
});
|
||||||
|
|
||||||
Ok(iter
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone())
|
|
||||||
.set_metadata(metadata))
|
|
||||||
}
|
}
|
||||||
PipelineData::Value(val, ..) => {
|
PipelineData::Value(val, ..) => {
|
||||||
match val {
|
match val {
|
||||||
@ -97,7 +95,7 @@ impl Command for Lines {
|
|||||||
..
|
..
|
||||||
} => Ok(RawStreamLinesAdapter::new(stream, head, skip_empty)
|
} => Ok(RawStreamLinesAdapter::new(stream, head, skip_empty)
|
||||||
.map(move |x| x.unwrap_or_else(|err| Value::error(err, head)))
|
.map(move |x| x.unwrap_or_else(|err| Value::error(err, head)))
|
||||||
.into_pipeline_data(ctrlc)
|
.into_pipeline_data(head, ctrlc)
|
||||||
.set_metadata(metadata)),
|
.set_metadata(metadata)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,11 +85,10 @@ repeating this process with row 1, and so on."#
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let merge_value: Value = call.req(engine_state, stack, 0)?;
|
let merge_value: Value = call.req(engine_state, stack, 0)?;
|
||||||
|
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let call = call.clone();
|
|
||||||
|
|
||||||
match (&input, merge_value) {
|
match (&input, merge_value) {
|
||||||
// table (list of records)
|
// table (list of records)
|
||||||
@ -104,29 +103,25 @@ repeating this process with row 1, and so on."#
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |inp| match (inp.as_record(), table_iter.next()) {
|
.map(move |inp| match (inp.as_record(), table_iter.next()) {
|
||||||
(Ok(inp), Some(to_merge)) => match to_merge.as_record() {
|
(Ok(inp), Some(to_merge)) => match to_merge.as_record() {
|
||||||
Ok(to_merge) => Value::record(do_merge(inp, to_merge), call.head),
|
Ok(to_merge) => Value::record(do_merge(inp, to_merge), head),
|
||||||
Err(error) => Value::error(error, call.head),
|
Err(error) => Value::error(error, head),
|
||||||
},
|
},
|
||||||
(_, None) => inp,
|
(_, None) => inp,
|
||||||
(Err(error), _) => Value::error(error, call.head),
|
(Err(error), _) => Value::error(error, head),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
Ok(res.into_pipeline_data_with_metadata(head, ctrlc, metadata))
|
||||||
Ok(res.into_pipeline_data_with_metadata(md, ctrlc))
|
|
||||||
} else {
|
|
||||||
Ok(res.into_pipeline_data(ctrlc))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// record
|
// record
|
||||||
(
|
(
|
||||||
PipelineData::Value(Value::Record { val: inp, .. }, ..),
|
PipelineData::Value(Value::Record { val: inp, .. }, ..),
|
||||||
Value::Record { val: to_merge, .. },
|
Value::Record { val: to_merge, .. },
|
||||||
) => Ok(Value::record(do_merge(inp, &to_merge), call.head).into_pipeline_data()),
|
) => Ok(Value::record(do_merge(inp, &to_merge), head).into_pipeline_data()),
|
||||||
(PipelineData::Value(val, ..), ..) => {
|
(PipelineData::Value(val, ..), ..) => {
|
||||||
// Only point the "value originates here" arrow at the merge value
|
// Only point the "value originates here" arrow at the merge value
|
||||||
// if it was generated from a block. Otherwise, point at the pipeline value. -Leon 2022-10-27
|
// if it was generated from a block. Otherwise, point at the pipeline value. -Leon 2022-10-27
|
||||||
let span = if val.span() == Span::test_data() {
|
let span = if val.span() == Span::test_data() {
|
||||||
Span::new(call.head.start, call.head.start)
|
Span::new(head.start, head.start)
|
||||||
} else {
|
} else {
|
||||||
val.span()
|
val.span()
|
||||||
};
|
};
|
||||||
@ -134,14 +129,14 @@ repeating this process with row 1, and so on."#
|
|||||||
Err(ShellError::PipelineMismatch {
|
Err(ShellError::PipelineMismatch {
|
||||||
exp_input_type: "input, and argument, to be both record or both table"
|
exp_input_type: "input, and argument, to be both record or both table"
|
||||||
.to_string(),
|
.to_string(),
|
||||||
dst_span: call.head,
|
dst_span: head,
|
||||||
src_span: span,
|
src_span: span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::PipelineMismatch {
|
_ => Err(ShellError::PipelineMismatch {
|
||||||
exp_input_type: "input, and argument, to be both record or both table".to_string(),
|
exp_input_type: "input, and argument, to be both record or both table".to_string(),
|
||||||
dst_span: call.head,
|
dst_span: head,
|
||||||
src_span: Span::new(call.head.start, call.head.start),
|
src_span: Span::new(head.start, head.start),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,6 +109,7 @@ impl Command for Move {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let columns: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
let columns: Vec<Value> = call.rest(engine_state, stack, 0)?;
|
||||||
let after: Option<Value> = call.get_flag(engine_state, stack, "after")?;
|
let after: Option<Value> = call.get_flag(engine_state, stack, "after")?;
|
||||||
let before: Option<Value> = call.get_flag(engine_state, stack, "before")?;
|
let before: Option<Value> = call.get_flag(engine_state, stack, "before")?;
|
||||||
@ -126,7 +127,7 @@ impl Command for Move {
|
|||||||
return Err(ShellError::GenericError {
|
return Err(ShellError::GenericError {
|
||||||
error: "Cannot move columns".into(),
|
error: "Cannot move columns".into(),
|
||||||
msg: "Use either --after, or --before, not both".into(),
|
msg: "Use either --after, or --before, not both".into(),
|
||||||
span: Some(call.head),
|
span: Some(head),
|
||||||
help: None,
|
help: None,
|
||||||
inner: vec![],
|
inner: vec![],
|
||||||
})
|
})
|
||||||
@ -135,7 +136,7 @@ impl Command for Move {
|
|||||||
return Err(ShellError::GenericError {
|
return Err(ShellError::GenericError {
|
||||||
error: "Cannot move columns".into(),
|
error: "Cannot move columns".into(),
|
||||||
msg: "Missing --after or --before flag".into(),
|
msg: "Missing --after or --before flag".into(),
|
||||||
span: Some(call.head),
|
span: Some(head),
|
||||||
help: None,
|
help: None,
|
||||||
inner: vec![],
|
inner: vec![],
|
||||||
})
|
})
|
||||||
@ -144,36 +145,29 @@ impl Command for Move {
|
|||||||
|
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let call = call.clone();
|
|
||||||
|
|
||||||
match input {
|
match input {
|
||||||
PipelineData::Value(Value::List { .. }, ..) | PipelineData::ListStream { .. } => {
|
PipelineData::Value(Value::List { .. }, ..) | PipelineData::ListStream { .. } => {
|
||||||
let res = input.into_iter().map(move |x| match x.as_record() {
|
let res = input.into_iter().map(move |x| match x.as_record() {
|
||||||
Ok(record) => {
|
Ok(record) => {
|
||||||
match move_record_columns(record, &columns, &before_or_after, call.head) {
|
match move_record_columns(record, &columns, &before_or_after, head) {
|
||||||
Ok(val) => val,
|
Ok(val) => val,
|
||||||
Err(error) => Value::error(error, call.head),
|
Err(error) => Value::error(error, head),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(error) => Value::error(error, call.head),
|
Err(error) => Value::error(error, head),
|
||||||
});
|
});
|
||||||
|
|
||||||
if let Some(md) = metadata {
|
Ok(res.into_pipeline_data_with_metadata(head, ctrlc, metadata))
|
||||||
Ok(res.into_pipeline_data_with_metadata(md, ctrlc))
|
|
||||||
} else {
|
|
||||||
Ok(res.into_pipeline_data(ctrlc))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PipelineData::Value(Value::Record { val, .. }, ..) => {
|
PipelineData::Value(Value::Record { val, .. }, ..) => {
|
||||||
Ok(
|
Ok(move_record_columns(&val, &columns, &before_or_after, head)?
|
||||||
move_record_columns(&val, &columns, &before_or_after, call.head)?
|
.into_pipeline_data())
|
||||||
.into_pipeline_data(),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => Err(ShellError::PipelineMismatch {
|
_ => Err(ShellError::PipelineMismatch {
|
||||||
exp_input_type: "record or table".to_string(),
|
exp_input_type: "record or table".to_string(),
|
||||||
dst_span: call.head,
|
dst_span: head,
|
||||||
src_span: Span::new(call.head.start, call.head.start),
|
src_span: Span::new(head.start, head.start),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +159,7 @@ impl Command for ParEach {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
apply_order(vec).into_pipeline_data(engine_state.ctrlc.clone())
|
apply_order(vec).into_pipeline_data(span, engine_state.ctrlc.clone())
|
||||||
})),
|
})),
|
||||||
Value::Range { val, .. } => Ok(create_pool(max_threads)?.install(|| {
|
Value::Range { val, .. } => Ok(create_pool(max_threads)?.install(|| {
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
@ -186,7 +186,7 @@ impl Command for ParEach {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
apply_order(vec).into_pipeline_data(ctrlc)
|
apply_order(vec).into_pipeline_data(span, ctrlc)
|
||||||
})),
|
})),
|
||||||
// This match allows non-iterables to be accepted,
|
// This match allows non-iterables to be accepted,
|
||||||
// which is currently considered undesirable (Nov 2022).
|
// which is currently considered undesirable (Nov 2022).
|
||||||
@ -197,6 +197,7 @@ impl Command for ParEach {
|
|||||||
}
|
}
|
||||||
PipelineData::ListStream(stream, ..) => Ok(create_pool(max_threads)?.install(|| {
|
PipelineData::ListStream(stream, ..) => Ok(create_pool(max_threads)?.install(|| {
|
||||||
let vec = stream
|
let vec = stream
|
||||||
|
.into_iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.par_bridge()
|
.par_bridge()
|
||||||
.map(move |(index, value)| {
|
.map(move |(index, value)| {
|
||||||
@ -216,7 +217,7 @@ impl Command for ParEach {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
apply_order(vec).into_pipeline_data(engine_state.ctrlc.clone())
|
apply_order(vec).into_pipeline_data(head, engine_state.ctrlc.clone())
|
||||||
})),
|
})),
|
||||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::empty()),
|
||||||
PipelineData::ExternalStream {
|
PipelineData::ExternalStream {
|
||||||
@ -241,7 +242,7 @@ impl Command for ParEach {
|
|||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
apply_order(vec).into_pipeline_data(engine_state.ctrlc.clone())
|
apply_order(vec).into_pipeline_data(head, engine_state.ctrlc.clone())
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
.and_then(|x| x.filter(|v| !v.is_nothing(), engine_state.ctrlc.clone()))
|
.and_then(|x| x.filter(|v| !v.is_nothing(), engine_state.ctrlc.clone()))
|
||||||
|
@ -117,7 +117,7 @@ only unwrap the outer list, and leave the variable's contents untouched."#
|
|||||||
.into_pipeline_data()
|
.into_pipeline_data()
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(input)
|
.chain(input)
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ impl Command for Range {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let rows: Spanned<NumRange> = call.req(engine_state, stack, 0)?;
|
let rows: Spanned<NumRange> = call.req(engine_state, stack, 0)?;
|
||||||
|
|
||||||
@ -102,20 +103,20 @@ impl Command for Range {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if from > to {
|
if from > to {
|
||||||
Ok(PipelineData::Value(Value::nothing(call.head), None))
|
Ok(PipelineData::Value(Value::nothing(head), None))
|
||||||
} else {
|
} else {
|
||||||
let iter = v.into_iter().skip(from).take(to - from + 1);
|
let iter = v.into_iter().skip(from).take(to - from + 1);
|
||||||
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
Ok(iter.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let from = start as usize;
|
let from = start as usize;
|
||||||
let to = end as usize;
|
let to = end as usize;
|
||||||
|
|
||||||
if from > to {
|
if from > to {
|
||||||
Ok(PipelineData::Value(Value::nothing(call.head), None))
|
Ok(PipelineData::Value(Value::nothing(head), None))
|
||||||
} else {
|
} else {
|
||||||
let iter = input.into_iter().skip(from).take(to - from + 1);
|
let iter = input.into_iter().skip(from).take(to - from + 1);
|
||||||
Ok(iter.into_pipeline_data(engine_state.ctrlc.clone()))
|
Ok(iter.into_pipeline_data(head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.map(|x| x.set_metadata(metadata))
|
.map(|x| x.set_metadata(metadata))
|
||||||
|
@ -59,11 +59,11 @@ impl Command for Reverse {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
|
let values = input.into_iter_strict(head)?.collect::<Vec<_>>();
|
||||||
let v: Vec<_> = input.into_iter_strict(call.head)?.collect();
|
let iter = values.into_iter().rev();
|
||||||
let iter = v.into_iter().rev();
|
Ok(iter.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
Ok(iter.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,7 +215,7 @@ fn select(
|
|||||||
rows: unique_rows.into_iter().peekable(),
|
rows: unique_rows.into_iter().peekable(),
|
||||||
current: 0,
|
current: 0,
|
||||||
}
|
}
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())
|
.into_pipeline_data_with_metadata(call_span, engine_state.ctrlc.clone(), metadata)
|
||||||
} else {
|
} else {
|
||||||
input
|
input
|
||||||
};
|
};
|
||||||
@ -253,9 +253,11 @@ fn select(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output
|
Ok(output.into_iter().into_pipeline_data_with_metadata(
|
||||||
.into_iter()
|
call_span,
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
if !columns.is_empty() {
|
if !columns.is_empty() {
|
||||||
@ -300,7 +302,11 @@ fn select(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(values.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(values.into_pipeline_data_with_metadata(
|
||||||
|
call_span,
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
_ => Ok(PipelineData::empty()),
|
_ => Ok(PipelineData::empty()),
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,10 @@ impl Command for Shuffle {
|
|||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
let mut v: Vec<_> = input.into_iter_strict(call.head)?.collect();
|
let mut values = input.into_iter_strict(call.head)?.collect::<Vec<_>>();
|
||||||
v.shuffle(&mut thread_rng());
|
values.shuffle(&mut thread_rng());
|
||||||
let iter = v.into_iter();
|
let iter = values.into_iter();
|
||||||
Ok(iter.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(iter.into_pipeline_data_with_metadata(call.head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -101,7 +101,7 @@ impl Command for Skip {
|
|||||||
_ => Ok(input
|
_ => Ok(input
|
||||||
.into_iter_strict(call.head)?
|
.into_iter_strict(call.head)?
|
||||||
.skip(n)
|
.skip(n)
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(input_span, ctrlc, metadata)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,7 +88,7 @@ impl Command for SkipUntil {
|
|||||||
.map(|data| data.into_value(head).is_false())
|
.map(|data| data.into_value(head).is_false())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ impl Command for SkipWhile {
|
|||||||
.map(|data| data.into_value(head).is_true())
|
.map(|data| data.into_value(head).is_true())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,10 +134,11 @@ impl Command for Sort {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
||||||
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||||
let natural = call.has_flag(engine_state, stack, "natural")?;
|
let natural = call.has_flag(engine_state, stack, "natural")?;
|
||||||
let metadata = &input.metadata();
|
let metadata = input.metadata();
|
||||||
|
|
||||||
let span = input.span().unwrap_or(call.head);
|
let span = input.span().unwrap_or(call.head);
|
||||||
match input {
|
match input {
|
||||||
@ -163,18 +164,18 @@ impl Command for Sort {
|
|||||||
pipe_data => {
|
pipe_data => {
|
||||||
let mut vec: Vec<_> = pipe_data.into_iter().collect();
|
let mut vec: Vec<_> = pipe_data.into_iter().collect();
|
||||||
|
|
||||||
sort(&mut vec, call.head, insensitive, natural)?;
|
sort(&mut vec, head, insensitive, natural)?;
|
||||||
|
|
||||||
if reverse {
|
if reverse {
|
||||||
vec.reverse()
|
vec.reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
let iter = vec.into_iter();
|
let iter = vec.into_iter();
|
||||||
match metadata {
|
Ok(iter.into_pipeline_data_with_metadata(
|
||||||
Some(m) => Ok(iter
|
head,
|
||||||
.into_pipeline_data_with_metadata(m.clone(), engine_state.ctrlc.clone())),
|
engine_state.ctrlc.clone(),
|
||||||
None => Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())),
|
metadata,
|
||||||
}
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,33 +78,29 @@ impl Command for SortBy {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let columns: Vec<String> = call.rest(engine_state, stack, 0)?;
|
let columns: Vec<String> = call.rest(engine_state, stack, 0)?;
|
||||||
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
let reverse = call.has_flag(engine_state, stack, "reverse")?;
|
||||||
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
let insensitive = call.has_flag(engine_state, stack, "ignore-case")?;
|
||||||
let natural = call.has_flag(engine_state, stack, "natural")?;
|
let natural = call.has_flag(engine_state, stack, "natural")?;
|
||||||
let metadata = &input.metadata();
|
let metadata = input.metadata();
|
||||||
let mut vec: Vec<_> = input.into_iter_strict(call.head)?.collect();
|
let mut vec: Vec<_> = input.into_iter_strict(head)?.collect();
|
||||||
|
|
||||||
if columns.is_empty() {
|
if columns.is_empty() {
|
||||||
return Err(ShellError::MissingParameter {
|
return Err(ShellError::MissingParameter {
|
||||||
param_name: "columns".into(),
|
param_name: "columns".into(),
|
||||||
span: call.head,
|
span: head,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
crate::sort(&mut vec, columns, call.head, insensitive, natural)?;
|
crate::sort(&mut vec, columns, head, insensitive, natural)?;
|
||||||
|
|
||||||
if reverse {
|
if reverse {
|
||||||
vec.reverse()
|
vec.reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
let iter = vec.into_iter();
|
let iter = vec.into_iter();
|
||||||
match metadata {
|
Ok(iter.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
Some(m) => {
|
|
||||||
Ok(iter.into_pipeline_data_with_metadata(m.clone(), engine_state.ctrlc.clone()))
|
|
||||||
}
|
|
||||||
None => Ok(iter.into_pipeline_data(engine_state.ctrlc.clone())),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,6 +42,7 @@ impl Command for Take {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let rows_desired: usize = call.req(engine_state, stack, 0)?;
|
let rows_desired: usize = call.req(engine_state, stack, 0)?;
|
||||||
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
@ -54,7 +55,7 @@ impl Command for Take {
|
|||||||
Value::List { vals, .. } => Ok(vals
|
Value::List { vals, .. } => Ok(vals
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.take(rows_desired)
|
.take(rows_desired)
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata)),
|
||||||
Value::Binary { val, .. } => {
|
Value::Binary { val, .. } => {
|
||||||
let slice: Vec<u8> = val.into_iter().take(rows_desired).collect();
|
let slice: Vec<u8> = val.into_iter().take(rows_desired).collect();
|
||||||
Ok(PipelineData::Value(Value::binary(slice, span), metadata))
|
Ok(PipelineData::Value(Value::binary(slice, span), metadata))
|
||||||
@ -62,33 +63,34 @@ impl Command for Take {
|
|||||||
Value::Range { val, .. } => Ok(val
|
Value::Range { val, .. } => Ok(val
|
||||||
.into_range_iter(span, ctrlc.clone())
|
.into_range_iter(span, ctrlc.clone())
|
||||||
.take(rows_desired)
|
.take(rows_desired)
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata)),
|
||||||
// Propagate errors by explicitly matching them before the final case.
|
// Propagate errors by explicitly matching them before the final case.
|
||||||
Value::Error { error, .. } => Err(*error),
|
Value::Error { error, .. } => Err(*error),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list, binary or range".into(),
|
exp_input_type: "list, binary or range".into(),
|
||||||
wrong_type: other.get_type().to_string(),
|
wrong_type: other.get_type().to_string(),
|
||||||
dst_span: call.head,
|
dst_span: head,
|
||||||
src_span: other.span(),
|
src_span: other.span(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(ls, metadata) => Ok(ls
|
PipelineData::ListStream(stream, metadata) => Ok(PipelineData::ListStream(
|
||||||
.take(rows_desired)
|
stream.modify(|iter| iter.take(rows_desired)),
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
metadata,
|
||||||
|
)),
|
||||||
PipelineData::ExternalStream { span, .. } => {
|
PipelineData::ExternalStream { span, .. } => {
|
||||||
Err(ShellError::OnlySupportsThisInputType {
|
Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list, binary or range".into(),
|
exp_input_type: "list, binary or range".into(),
|
||||||
wrong_type: "raw data".into(),
|
wrong_type: "raw data".into(),
|
||||||
dst_span: call.head,
|
dst_span: head,
|
||||||
src_span: span,
|
src_span: span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
PipelineData::Empty => Err(ShellError::OnlySupportsThisInputType {
|
PipelineData::Empty => Err(ShellError::OnlySupportsThisInputType {
|
||||||
exp_input_type: "list, binary or range".into(),
|
exp_input_type: "list, binary or range".into(),
|
||||||
wrong_type: "null".into(),
|
wrong_type: "null".into(),
|
||||||
dst_span: call.head,
|
dst_span: head,
|
||||||
src_span: call.head,
|
src_span: head,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ impl Command for TakeUntil {
|
|||||||
.map(|data| data.into_value(head).is_false())
|
.map(|data| data.into_value(head).is_false())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ impl Command for TakeWhile {
|
|||||||
.map(|data| data.into_value(head).is_true())
|
.map(|data| data.into_value(head).is_true())
|
||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -64,6 +64,7 @@ use it in your pipeline."#
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let use_stderr = call.has_flag(engine_state, stack, "stderr")?;
|
let use_stderr = call.has_flag(engine_state, stack, "stderr")?;
|
||||||
|
|
||||||
let Spanned {
|
let Spanned {
|
||||||
@ -125,7 +126,7 @@ use it in your pipeline."#
|
|||||||
if use_stderr {
|
if use_stderr {
|
||||||
let stderr = stderr
|
let stderr = stderr
|
||||||
.map(|stderr| {
|
.map(|stderr| {
|
||||||
let iter = tee(stderr.stream, with_stream).err_span(call.head)?;
|
let iter = tee(stderr.stream, with_stream).err_span(head)?;
|
||||||
Ok::<_, ShellError>(RawStream::new(
|
Ok::<_, ShellError>(RawStream::new(
|
||||||
Box::new(iter.map(flatten_result)),
|
Box::new(iter.map(flatten_result)),
|
||||||
stderr.ctrlc,
|
stderr.ctrlc,
|
||||||
@ -145,7 +146,7 @@ use it in your pipeline."#
|
|||||||
} else {
|
} else {
|
||||||
let stdout = stdout
|
let stdout = stdout
|
||||||
.map(|stdout| {
|
.map(|stdout| {
|
||||||
let iter = tee(stdout.stream, with_stream).err_span(call.head)?;
|
let iter = tee(stdout.stream, with_stream).err_span(head)?;
|
||||||
Ok::<_, ShellError>(RawStream::new(
|
Ok::<_, ShellError>(RawStream::new(
|
||||||
Box::new(iter.map(flatten_result)),
|
Box::new(iter.map(flatten_result)),
|
||||||
stdout.ctrlc,
|
stdout.ctrlc,
|
||||||
@ -168,15 +169,16 @@ use it in your pipeline."#
|
|||||||
_ if use_stderr => Err(ShellError::UnsupportedInput {
|
_ if use_stderr => Err(ShellError::UnsupportedInput {
|
||||||
msg: "--stderr can only be used on external streams".into(),
|
msg: "--stderr can only be used on external streams".into(),
|
||||||
input: "the input to `tee` is not an external stream".into(),
|
input: "the input to `tee` is not an external stream".into(),
|
||||||
msg_span: call.head,
|
msg_span: head,
|
||||||
input_span: input.span().unwrap_or(call.head),
|
input_span: input.span().unwrap_or(head),
|
||||||
}),
|
}),
|
||||||
// Handle others with the plain iterator
|
// Handle others with the plain iterator
|
||||||
_ => {
|
_ => {
|
||||||
let teed = tee(input.into_iter(), move |rx| {
|
let teed = tee(input.into_iter(), move |rx| {
|
||||||
let input_from_channel = rx.into_pipeline_data_with_metadata(
|
let input_from_channel = rx.into_pipeline_data_with_metadata(
|
||||||
metadata_clone,
|
head,
|
||||||
closure_engine_state.ctrlc.clone(),
|
closure_engine_state.ctrlc.clone(),
|
||||||
|
metadata_clone,
|
||||||
);
|
);
|
||||||
let result = eval_block_with_early_return(
|
let result = eval_block_with_early_return(
|
||||||
&closure_engine_state,
|
&closure_engine_state,
|
||||||
@ -187,9 +189,13 @@ use it in your pipeline."#
|
|||||||
// Make sure to drain any iterator produced to avoid unexpected behavior
|
// Make sure to drain any iterator produced to avoid unexpected behavior
|
||||||
result.and_then(|data| data.drain())
|
result.and_then(|data| data.drain())
|
||||||
})
|
})
|
||||||
.err_span(call.head)?
|
.err_span(head)?
|
||||||
.map(move |result| result.unwrap_or_else(|err| Value::error(err, closure_span)))
|
.map(move |result| result.unwrap_or_else(|err| Value::error(err, closure_span)))
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone());
|
.into_pipeline_data_with_metadata(
|
||||||
|
head,
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
|
);
|
||||||
|
|
||||||
Ok(teed)
|
Ok(teed)
|
||||||
}
|
}
|
||||||
|
@ -284,7 +284,7 @@ pub fn transpose(
|
|||||||
metadata,
|
metadata,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(result_data.into_pipeline_data_with_metadata(metadata, ctrlc))
|
Ok(result_data.into_pipeline_data_with_metadata(name, ctrlc, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ fn update(
|
|||||||
}
|
}
|
||||||
Ok(value.into_pipeline_data_with_metadata(metadata))
|
Ok(value.into_pipeline_data_with_metadata(metadata))
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(mut stream, metadata) => {
|
PipelineData::ListStream(stream, metadata) => {
|
||||||
if let Some((
|
if let Some((
|
||||||
&PathMember::Int {
|
&PathMember::Int {
|
||||||
val,
|
val,
|
||||||
@ -153,6 +153,7 @@ fn update(
|
|||||||
path,
|
path,
|
||||||
)) = cell_path.members.split_first()
|
)) = cell_path.members.split_first()
|
||||||
{
|
{
|
||||||
|
let mut stream = stream.into_iter();
|
||||||
let mut pre_elems = vec![];
|
let mut pre_elems = vec![];
|
||||||
|
|
||||||
for idx in 0..=val {
|
for idx in 0..=val {
|
||||||
@ -186,38 +187,38 @@ fn update(
|
|||||||
Ok(pre_elems
|
Ok(pre_elems
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(stream)
|
.chain(stream)
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
} else if let Value::Closure { val, .. } = replacement {
|
} else if let Value::Closure { val, .. } = replacement {
|
||||||
let mut closure = ClosureEval::new(engine_state, stack, val);
|
let mut closure = ClosureEval::new(engine_state, stack, val);
|
||||||
Ok(stream
|
let stream = stream.map(move |mut value| {
|
||||||
.map(move |mut value| {
|
let err = update_value_by_closure(
|
||||||
let err = update_value_by_closure(
|
&mut value,
|
||||||
&mut value,
|
&mut closure,
|
||||||
&mut closure,
|
head,
|
||||||
head,
|
&cell_path.members,
|
||||||
&cell_path.members,
|
false,
|
||||||
false,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(e) = err {
|
if let Err(e) = err {
|
||||||
Value::error(e, head)
|
Value::error(e, head)
|
||||||
} else {
|
} else {
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
|
||||||
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
} else {
|
} else {
|
||||||
Ok(stream
|
let stream = stream.map(move |mut value| {
|
||||||
.map(move |mut value| {
|
if let Err(e) =
|
||||||
if let Err(e) =
|
value.update_data_at_cell_path(&cell_path.members, replacement.clone())
|
||||||
value.update_data_at_cell_path(&cell_path.members, replacement.clone())
|
{
|
||||||
{
|
Value::error(e, head)
|
||||||
Value::error(e, head)
|
} else {
|
||||||
} else {
|
value
|
||||||
value
|
}
|
||||||
}
|
});
|
||||||
})
|
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::Empty => Err(ShellError::IncompatiblePathAccess {
|
PipelineData::Empty => Err(ShellError::IncompatiblePathAccess {
|
||||||
|
@ -189,7 +189,7 @@ fn upsert(
|
|||||||
}
|
}
|
||||||
Ok(value.into_pipeline_data_with_metadata(metadata))
|
Ok(value.into_pipeline_data_with_metadata(metadata))
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(mut stream, metadata) => {
|
PipelineData::ListStream(stream, metadata) => {
|
||||||
if let Some((
|
if let Some((
|
||||||
&PathMember::Int {
|
&PathMember::Int {
|
||||||
val,
|
val,
|
||||||
@ -199,6 +199,7 @@ fn upsert(
|
|||||||
path,
|
path,
|
||||||
)) = cell_path.members.split_first()
|
)) = cell_path.members.split_first()
|
||||||
{
|
{
|
||||||
|
let mut stream = stream.into_iter();
|
||||||
let mut pre_elems = vec![];
|
let mut pre_elems = vec![];
|
||||||
|
|
||||||
for idx in 0..val {
|
for idx in 0..val {
|
||||||
@ -246,38 +247,38 @@ fn upsert(
|
|||||||
Ok(pre_elems
|
Ok(pre_elems
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.chain(stream)
|
.chain(stream)
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
} else if let Value::Closure { val, .. } = replacement {
|
} else if let Value::Closure { val, .. } = replacement {
|
||||||
let mut closure = ClosureEval::new(engine_state, stack, val);
|
let mut closure = ClosureEval::new(engine_state, stack, val);
|
||||||
Ok(stream
|
let stream = stream.map(move |mut value| {
|
||||||
.map(move |mut value| {
|
let err = upsert_value_by_closure(
|
||||||
let err = upsert_value_by_closure(
|
&mut value,
|
||||||
&mut value,
|
&mut closure,
|
||||||
&mut closure,
|
head,
|
||||||
head,
|
&cell_path.members,
|
||||||
&cell_path.members,
|
false,
|
||||||
false,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
if let Err(e) = err {
|
if let Err(e) = err {
|
||||||
Value::error(e, head)
|
Value::error(e, head)
|
||||||
} else {
|
} else {
|
||||||
value
|
value
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
|
||||||
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
} else {
|
} else {
|
||||||
Ok(stream
|
let stream = stream.map(move |mut value| {
|
||||||
.map(move |mut value| {
|
if let Err(e) =
|
||||||
if let Err(e) =
|
value.upsert_data_at_cell_path(&cell_path.members, replacement.clone())
|
||||||
value.upsert_data_at_cell_path(&cell_path.members, replacement.clone())
|
{
|
||||||
{
|
Value::error(e, head)
|
||||||
Value::error(e, head)
|
} else {
|
||||||
} else {
|
value
|
||||||
value
|
}
|
||||||
}
|
});
|
||||||
})
|
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
Ok(PipelineData::ListStream(stream, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PipelineData::Empty => Err(ShellError::IncompatiblePathAccess {
|
PipelineData::Empty => Err(ShellError::IncompatiblePathAccess {
|
||||||
|
@ -144,7 +144,7 @@ fn values(
|
|||||||
Value::List { vals, .. } => match get_values(&vals, head, span) {
|
Value::List { vals, .. } => match get_values(&vals, head, span) {
|
||||||
Ok(cols) => Ok(cols
|
Ok(cols) => Ok(cols
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata)),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
},
|
},
|
||||||
Value::Custom { val, .. } => {
|
Value::Custom { val, .. } => {
|
||||||
@ -152,7 +152,7 @@ fn values(
|
|||||||
match get_values(&[input_as_base_value], head, span) {
|
match get_values(&[input_as_base_value], head, span) {
|
||||||
Ok(cols) => Ok(cols
|
Ok(cols) => Ok(cols
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata)),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -160,7 +160,7 @@ fn values(
|
|||||||
.values()
|
.values()
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect::<Vec<_>>()
|
.collect::<Vec<_>>()
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata)),
|
||||||
// Propagate errors
|
// Propagate errors
|
||||||
Value::Error { error, .. } => Err(*error),
|
Value::Error { error, .. } => Err(*error),
|
||||||
other => Err(ShellError::OnlySupportsThisInputType {
|
other => Err(ShellError::OnlySupportsThisInputType {
|
||||||
@ -176,7 +176,7 @@ fn values(
|
|||||||
match get_values(&vals, head, head) {
|
match get_values(&vals, head, head) {
|
||||||
Ok(cols) => Ok(cols
|
Ok(cols) => Ok(cols
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.into_pipeline_data_with_metadata(metadata, ctrlc)),
|
.into_pipeline_data_with_metadata(head, ctrlc, metadata)),
|
||||||
Err(err) => Err(err),
|
Err(err) => Err(err),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ not supported."#
|
|||||||
Ok(data) => data.into_value(head).is_true().then_some(value),
|
Ok(data) => data.into_value(head).is_true().then_some(value),
|
||||||
Err(err) => Some(Value::error(err, head)),
|
Err(err) => Some(Value::error(err, head)),
|
||||||
})
|
})
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
|
use nu_protocol::ValueIterator;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Window;
|
pub struct Window;
|
||||||
@ -110,6 +111,7 @@ impl Command for Window {
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let group_size: Spanned<usize> = call.req(engine_state, stack, 0)?;
|
let group_size: Spanned<usize> = call.req(engine_state, stack, 0)?;
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
let metadata = input.metadata();
|
let metadata = input.metadata();
|
||||||
@ -123,19 +125,19 @@ impl Command for Window {
|
|||||||
let each_group_iterator = EachWindowIterator {
|
let each_group_iterator = EachWindowIterator {
|
||||||
group_size: group_size.item,
|
group_size: group_size.item,
|
||||||
input: Box::new(input.into_iter()),
|
input: Box::new(input.into_iter()),
|
||||||
span: call.head,
|
span: head,
|
||||||
previous: None,
|
previous: None,
|
||||||
stride,
|
stride,
|
||||||
remainder,
|
remainder,
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(each_group_iterator.into_pipeline_data_with_metadata(metadata, ctrlc))
|
Ok(each_group_iterator.into_pipeline_data_with_metadata(head, ctrlc, metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct EachWindowIterator {
|
struct EachWindowIterator {
|
||||||
group_size: usize,
|
group_size: usize,
|
||||||
input: Box<dyn Iterator<Item = Value> + Send>,
|
input: ValueIterator,
|
||||||
span: Span,
|
span: Span,
|
||||||
previous: Option<Vec<Value>>,
|
previous: Option<Vec<Value>>,
|
||||||
stride: usize,
|
stride: usize,
|
||||||
|
@ -42,9 +42,9 @@ impl Command for Wrap {
|
|||||||
| PipelineData::ListStream { .. } => Ok(input
|
| PipelineData::ListStream { .. } => Ok(input
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(move |x| Value::record(record! { name.clone() => x }, span))
|
.map(move |x| Value::record(record! { name.clone() => x }, span))
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone())),
|
.into_pipeline_data_with_metadata(span, engine_state.ctrlc.clone(), metadata)),
|
||||||
PipelineData::ExternalStream { .. } => Ok(Value::record(
|
PipelineData::ExternalStream { .. } => Ok(Value::record(
|
||||||
record! { name => input.into_value(call.head) },
|
record! { name => input.into_value(span) },
|
||||||
span,
|
span,
|
||||||
)
|
)
|
||||||
.into_pipeline_data_with_metadata(metadata)),
|
.into_pipeline_data_with_metadata(metadata)),
|
||||||
|
@ -112,7 +112,7 @@ impl Command for Zip {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.zip(other)
|
.zip(other)
|
||||||
.map(move |(x, y)| Value::list(vec![x, y], head))
|
.map(move |(x, y)| Value::list(vec![x, y], head))
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
.into_pipeline_data_with_metadata(head, engine_state.ctrlc.clone(), metadata))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,8 +84,11 @@ impl Command for FromJson {
|
|||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(converted_lines
|
Ok(converted_lines.into_pipeline_data_with_metadata(
|
||||||
.into_pipeline_data_with_metadata(metadata, engine_state.ctrlc.clone()))
|
span,
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
metadata,
|
||||||
|
))
|
||||||
} else if strict {
|
} else if strict {
|
||||||
Ok(convert_string_to_value_strict(&string_input, span)?
|
Ok(convert_string_to_value_strict(&string_input, span)?
|
||||||
.into_pipeline_data_with_metadata(metadata))
|
.into_pipeline_data_with_metadata(metadata))
|
||||||
|
@ -109,10 +109,9 @@ MessagePack: https://msgpack.org/
|
|||||||
call: &Call,
|
call: &Call,
|
||||||
input: PipelineData,
|
input: PipelineData,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let span = input.span().unwrap_or(call.head);
|
|
||||||
let objects = call.has_flag(engine_state, stack, "objects")?;
|
let objects = call.has_flag(engine_state, stack, "objects")?;
|
||||||
let opts = Opts {
|
let opts = Opts {
|
||||||
span,
|
span: call.head,
|
||||||
objects,
|
objects,
|
||||||
ctrlc: engine_state.ctrlc.clone(),
|
ctrlc: engine_state.ctrlc.clone(),
|
||||||
};
|
};
|
||||||
@ -126,10 +125,10 @@ MessagePack: https://msgpack.org/
|
|||||||
stdout: Some(raw_stream),
|
stdout: Some(raw_stream),
|
||||||
..
|
..
|
||||||
} => read_msgpack(ReadRawStream::new(raw_stream), opts),
|
} => read_msgpack(ReadRawStream::new(raw_stream), opts),
|
||||||
_ => Err(ShellError::PipelineMismatch {
|
input => Err(ShellError::PipelineMismatch {
|
||||||
exp_input_type: "binary".into(),
|
exp_input_type: "binary".into(),
|
||||||
dst_span: call.head,
|
dst_span: call.head,
|
||||||
src_span: span,
|
src_span: input.span().unwrap_or(call.head),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -257,7 +256,7 @@ pub(crate) fn read_msgpack(
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(ctrlc))
|
.into_pipeline_data(span, ctrlc))
|
||||||
} else {
|
} else {
|
||||||
// Read a single value and then make sure it's EOF
|
// Read a single value and then make sure it's EOF
|
||||||
let result = read_value(&mut input, span, 0)?;
|
let result = read_value(&mut input, span, 0)?;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use chrono_humanize::HumanTime;
|
use chrono_humanize::HumanTime;
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::{format_duration, format_filesize_from_conf, Config, ListStream, RawStream};
|
use nu_protocol::{format_duration, format_filesize_from_conf, Config, RawStream, ValueIterator};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ToText;
|
pub struct ToText;
|
||||||
@ -41,7 +41,7 @@ impl Command for ToText {
|
|||||||
Ok(PipelineData::ExternalStream {
|
Ok(PipelineData::ExternalStream {
|
||||||
stdout: Some(RawStream::new(
|
stdout: Some(RawStream::new(
|
||||||
Box::new(ListStreamIterator {
|
Box::new(ListStreamIterator {
|
||||||
stream,
|
stream: stream.into_inner(),
|
||||||
separator: line_ending.into(),
|
separator: line_ending.into(),
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
}),
|
}),
|
||||||
@ -86,7 +86,7 @@ impl Command for ToText {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct ListStreamIterator {
|
struct ListStreamIterator {
|
||||||
stream: ListStream,
|
stream: ValueIterator,
|
||||||
separator: String,
|
separator: String,
|
||||||
config: Config,
|
config: Config,
|
||||||
}
|
}
|
||||||
|
@ -183,7 +183,7 @@ used as the next argument to the closure, otherwise generation stops.
|
|||||||
|
|
||||||
Ok(iter
|
Ok(iter
|
||||||
.flatten()
|
.flatten()
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(call.head, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
|
use nu_protocol::ListStream;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Seq;
|
pub struct Seq;
|
||||||
@ -119,36 +120,32 @@ pub fn run_seq(
|
|||||||
let step = if free.len() > 2 { free[1] } else { 1.0 };
|
let step = if free.len() > 2 { free[1] } else { 1.0 };
|
||||||
let last = { free[free.len() - 1] };
|
let last = { free[free.len() - 1] };
|
||||||
|
|
||||||
if !contains_decimals {
|
let stream = if !contains_decimals {
|
||||||
// integers only
|
ListStream::new(
|
||||||
Ok(PipelineData::ListStream(
|
IntSeq {
|
||||||
nu_protocol::ListStream::from_stream(
|
count: first as i64,
|
||||||
IntSeq {
|
step: step as i64,
|
||||||
count: first as i64,
|
last: last as i64,
|
||||||
step: step as i64,
|
span,
|
||||||
last: last as i64,
|
},
|
||||||
span,
|
span,
|
||||||
},
|
engine_state.ctrlc.clone(),
|
||||||
engine_state.ctrlc.clone(),
|
)
|
||||||
),
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
} else {
|
} else {
|
||||||
// floats
|
ListStream::new(
|
||||||
Ok(PipelineData::ListStream(
|
FloatSeq {
|
||||||
nu_protocol::ListStream::from_stream(
|
first,
|
||||||
FloatSeq {
|
step,
|
||||||
first,
|
last,
|
||||||
step,
|
index: 0,
|
||||||
last,
|
span,
|
||||||
index: 0,
|
},
|
||||||
span,
|
span,
|
||||||
},
|
engine_state.ctrlc.clone(),
|
||||||
engine_state.ctrlc.clone(),
|
)
|
||||||
),
|
};
|
||||||
None,
|
|
||||||
))
|
Ok(stream.into())
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FloatSeq {
|
struct FloatSeq {
|
||||||
|
@ -92,17 +92,12 @@ pub fn help_aliases(
|
|||||||
&highlight_style,
|
&highlight_style,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
return Ok(found_cmds_vec
|
return Ok(Value::list(found_cmds_vec, head).into_pipeline_data());
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rest.is_empty() {
|
if rest.is_empty() {
|
||||||
let found_cmds_vec = build_help_aliases(engine_state, stack, head);
|
let found_cmds_vec = build_help_aliases(engine_state, stack, head);
|
||||||
|
Ok(Value::list(found_cmds_vec, head).into_pipeline_data())
|
||||||
Ok(found_cmds_vec
|
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
|
|
||||||
|
@ -72,17 +72,12 @@ pub fn help_commands(
|
|||||||
&highlight_style,
|
&highlight_style,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
return Ok(found_cmds_vec
|
return Ok(Value::list(found_cmds_vec, head).into_pipeline_data());
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rest.is_empty() {
|
if rest.is_empty() {
|
||||||
let found_cmds_vec = build_help_commands(engine_state, head);
|
let found_cmds_vec = build_help_commands(engine_state, head);
|
||||||
|
Ok(Value::list(found_cmds_vec, head).into_pipeline_data())
|
||||||
Ok(found_cmds_vec
|
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ impl Command for HelpEscapes {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
_engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
@ -40,9 +40,7 @@ impl Command for HelpEscapes {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(recs
|
Ok(Value::list(recs, call.head).into_pipeline_data())
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,17 +92,12 @@ pub fn help_externs(
|
|||||||
&highlight_style,
|
&highlight_style,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
return Ok(found_cmds_vec
|
return Ok(Value::list(found_cmds_vec, head).into_pipeline_data());
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rest.is_empty() {
|
if rest.is_empty() {
|
||||||
let found_cmds_vec = build_help_externs(engine_state, stack, head);
|
let found_cmds_vec = build_help_externs(engine_state, stack, head);
|
||||||
|
Ok(Value::list(found_cmds_vec, head).into_pipeline_data())
|
||||||
Ok(found_cmds_vec
|
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
|
|
||||||
|
@ -98,17 +98,12 @@ pub fn help_modules(
|
|||||||
&highlight_style,
|
&highlight_style,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
return Ok(found_cmds_vec
|
return Ok(Value::list(found_cmds_vec, head).into_pipeline_data());
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if rest.is_empty() {
|
if rest.is_empty() {
|
||||||
let found_cmds_vec = build_help_modules(engine_state, stack, head);
|
let found_cmds_vec = build_help_modules(engine_state, stack, head);
|
||||||
|
Ok(Value::list(found_cmds_vec, head).into_pipeline_data())
|
||||||
Ok(found_cmds_vec
|
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
|
||||||
} else {
|
} else {
|
||||||
let mut name = String::new();
|
let mut name = String::new();
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ impl Command for HelpOperators {
|
|||||||
|
|
||||||
fn run(
|
fn run(
|
||||||
&self,
|
&self,
|
||||||
engine_state: &EngineState,
|
_engine_state: &EngineState,
|
||||||
_stack: &mut Stack,
|
_stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
_input: PipelineData,
|
_input: PipelineData,
|
||||||
@ -43,9 +43,7 @@ impl Command for HelpOperators {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(recs
|
Ok(Value::list(recs, head).into_pipeline_data())
|
||||||
.into_iter()
|
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ pub fn calculate(
|
|||||||
let span = values.span().unwrap_or(name);
|
let span = values.span().unwrap_or(name);
|
||||||
match values {
|
match values {
|
||||||
PipelineData::ListStream(s, ..) => {
|
PipelineData::ListStream(s, ..) => {
|
||||||
helper_for_tables(&s.collect::<Vec<Value>>(), span, name, mf)
|
helper_for_tables(&s.into_iter().collect::<Vec<Value>>(), span, name, mf)
|
||||||
}
|
}
|
||||||
PipelineData::Value(Value::List { ref vals, .. }, ..) => match &vals[..] {
|
PipelineData::Value(Value::List { ref vals, .. }, ..) => match &vals[..] {
|
||||||
[Value::Record { .. }, _end @ ..] => helper_for_tables(
|
[Value::Record { .. }, _end @ ..] => helper_for_tables(
|
||||||
|
@ -660,7 +660,7 @@ Operating system commands:
|
|||||||
let ctrlc = engine_state.ctrlc.clone();
|
let ctrlc = engine_state.ctrlc.clone();
|
||||||
|
|
||||||
if list {
|
if list {
|
||||||
return generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring);
|
return Ok(generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code can now be one of the ansi abbreviations like green_bold
|
// The code can now be one of the ansi abbreviations like green_bold
|
||||||
@ -694,7 +694,7 @@ Operating system commands:
|
|||||||
let ctrlc = working_set.permanent().ctrlc.clone();
|
let ctrlc = working_set.permanent().ctrlc.clone();
|
||||||
|
|
||||||
if list {
|
if list {
|
||||||
return generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring);
|
return Ok(generate_ansi_code_list(ctrlc, call.head, use_ansi_coloring));
|
||||||
}
|
}
|
||||||
|
|
||||||
// The code can now be one of the ansi abbreviations like green_bold
|
// The code can now be one of the ansi abbreviations like green_bold
|
||||||
@ -833,8 +833,8 @@ fn generate_ansi_code_list(
|
|||||||
ctrlc: Option<Arc<AtomicBool>>,
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
call_span: Span,
|
call_span: Span,
|
||||||
use_ansi_coloring: bool,
|
use_ansi_coloring: bool,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> PipelineData {
|
||||||
return Ok(CODE_LIST
|
CODE_LIST
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.map(move |(i, ansi_code)| {
|
.map(move |(i, ansi_code)| {
|
||||||
@ -865,7 +865,7 @@ fn generate_ansi_code_list(
|
|||||||
|
|
||||||
Value::record(record, call_span)
|
Value::record(record, call_span)
|
||||||
})
|
})
|
||||||
.into_pipeline_data(ctrlc));
|
.into_pipeline_data(call_span, ctrlc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_ansi_hashmap(v: &[AnsiCode]) -> HashMap<&str, &str> {
|
fn build_ansi_hashmap(v: &[AnsiCode]) -> HashMap<&str, &str> {
|
||||||
|
@ -78,10 +78,7 @@ fn dice(
|
|||||||
Value::int(thread_rng.gen_range(1..sides + 1) as i64, span)
|
Value::int(thread_rng.gen_range(1..sides + 1) as i64, span)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(PipelineData::ListStream(
|
Ok(ListStream::new(iter, span, engine_state.ctrlc.clone()).into())
|
||||||
ListStream::from_stream(iter, engine_state.ctrlc.clone()),
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -230,7 +230,7 @@ impl Command for Char {
|
|||||||
|
|
||||||
// handle -l flag
|
// handle -l flag
|
||||||
if list {
|
if list {
|
||||||
return generate_character_list(ctrlc, call.head);
|
return Ok(generate_character_list(ctrlc, call.head));
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle -i flag
|
// handle -i flag
|
||||||
@ -265,7 +265,7 @@ impl Command for Char {
|
|||||||
|
|
||||||
// handle -l flag
|
// handle -l flag
|
||||||
if list {
|
if list {
|
||||||
return generate_character_list(ctrlc, call_span);
|
return Ok(generate_character_list(ctrlc, call_span));
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle -i flag
|
// handle -i flag
|
||||||
@ -286,11 +286,8 @@ impl Command for Char {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_character_list(
|
fn generate_character_list(ctrlc: Option<Arc<AtomicBool>>, call_span: Span) -> PipelineData {
|
||||||
ctrlc: Option<Arc<AtomicBool>>,
|
CHAR_MAP
|
||||||
call_span: Span,
|
|
||||||
) -> Result<PipelineData, ShellError> {
|
|
||||||
Ok(CHAR_MAP
|
|
||||||
.iter()
|
.iter()
|
||||||
.map(move |(name, s)| {
|
.map(move |(name, s)| {
|
||||||
let unicode = Value::string(
|
let unicode = Value::string(
|
||||||
@ -308,7 +305,7 @@ fn generate_character_list(
|
|||||||
|
|
||||||
Value::record(record, call_span)
|
Value::record(record, call_span)
|
||||||
})
|
})
|
||||||
.into_pipeline_data(ctrlc))
|
.into_pipeline_data(call_span, ctrlc)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_integer_flag(
|
fn handle_integer_flag(
|
||||||
|
@ -159,7 +159,7 @@ fn guess_width(
|
|||||||
Err(e) => Value::error(e, input_span),
|
Err(e) => Value::error(e, input_span),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(input_span, engine_state.ctrlc.clone()))
|
||||||
} else {
|
} else {
|
||||||
let length = result[0].len();
|
let length = result[0].len();
|
||||||
let columns: Vec<String> = (0..length).map(|n| format!("column{n}")).collect();
|
let columns: Vec<String> = (0..length).map(|n| format!("column{n}")).collect();
|
||||||
@ -184,7 +184,7 @@ fn guess_width(
|
|||||||
Err(e) => Value::error(e, input_span),
|
Err(e) => Value::error(e, input_span),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(input_span, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,7 +278,7 @@ fn detect_columns(
|
|||||||
None => Value::record(record, name_span),
|
None => Value::record(record, name_span),
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.into_pipeline_data(ctrlc))
|
.into_pipeline_data(call.head, ctrlc))
|
||||||
} else {
|
} else {
|
||||||
Ok(PipelineData::empty())
|
Ok(PipelineData::empty())
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
use fancy_regex::Regex;
|
use fancy_regex::Regex;
|
||||||
use nu_engine::command_prelude::*;
|
use nu_engine::command_prelude::*;
|
||||||
use nu_protocol::ListStream;
|
use nu_protocol::{ListStream, ValueIterator};
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
Arc,
|
Arc,
|
||||||
@ -187,44 +187,36 @@ fn operate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(PipelineData::ListStream(
|
Ok(ListStream::new(parsed.into_iter(), head, ctrlc).into())
|
||||||
ListStream::from_stream(parsed.into_iter(), ctrlc),
|
|
||||||
None,
|
|
||||||
))
|
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(stream, ..) => Ok(PipelineData::ListStream(
|
PipelineData::ListStream(stream, ..) => Ok(stream
|
||||||
ListStream::from_stream(
|
.modify(|stream| ParseStreamer {
|
||||||
ParseStreamer {
|
span: head,
|
||||||
span: head,
|
excess: Vec::new(),
|
||||||
excess: Vec::new(),
|
regex: regex_pattern,
|
||||||
regex: regex_pattern,
|
columns,
|
||||||
columns,
|
stream,
|
||||||
stream: stream.stream,
|
|
||||||
ctrlc: ctrlc.clone(),
|
|
||||||
},
|
|
||||||
ctrlc,
|
ctrlc,
|
||||||
),
|
})
|
||||||
None,
|
.into()),
|
||||||
)),
|
|
||||||
|
|
||||||
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty),
|
PipelineData::ExternalStream { stdout: None, .. } => Ok(PipelineData::Empty),
|
||||||
|
|
||||||
PipelineData::ExternalStream {
|
PipelineData::ExternalStream {
|
||||||
stdout: Some(stream),
|
stdout: Some(stream),
|
||||||
..
|
..
|
||||||
} => Ok(PipelineData::ListStream(
|
} => Ok(ListStream::new(
|
||||||
ListStream::from_stream(
|
ParseStreamerExternal {
|
||||||
ParseStreamerExternal {
|
span: head,
|
||||||
span: head,
|
excess: Vec::new(),
|
||||||
excess: Vec::new(),
|
regex: regex_pattern,
|
||||||
regex: regex_pattern,
|
columns,
|
||||||
columns,
|
stream: stream.stream,
|
||||||
stream: stream.stream,
|
},
|
||||||
},
|
head,
|
||||||
ctrlc,
|
ctrlc,
|
||||||
),
|
)
|
||||||
None,
|
.into()),
|
||||||
)),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -299,7 +291,7 @@ pub struct ParseStreamer {
|
|||||||
excess: Vec<Value>,
|
excess: Vec<Value>,
|
||||||
regex: Regex,
|
regex: Regex,
|
||||||
columns: Vec<String>,
|
columns: Vec<String>,
|
||||||
stream: Box<dyn Iterator<Item = Value> + Send + 'static>,
|
stream: ValueIterator,
|
||||||
ctrlc: Option<Arc<AtomicBool>>,
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -196,9 +196,12 @@ fn split_list(
|
|||||||
let mut temp_list = Vec::new();
|
let mut temp_list = Vec::new();
|
||||||
let mut returned_list = Vec::new();
|
let mut returned_list = Vec::new();
|
||||||
|
|
||||||
let iter = input.into_interruptible_iter(engine_state.ctrlc.clone());
|
|
||||||
let matcher = Matcher::new(call.has_flag(engine_state, stack, "regex")?, separator)?;
|
let matcher = Matcher::new(call.has_flag(engine_state, stack, "regex")?, separator)?;
|
||||||
for val in iter {
|
for val in input {
|
||||||
|
if nu_utils::ctrl_c::was_pressed(&engine_state.ctrlc) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if matcher.compare(&val)? {
|
if matcher.compare(&val)? {
|
||||||
if !temp_list.is_empty() {
|
if !temp_list.is_empty() {
|
||||||
returned_list.push(Value::list(temp_list.clone(), call.head));
|
returned_list.push(Value::list(temp_list.clone(), call.head));
|
||||||
|
@ -88,7 +88,7 @@ impl Command for Complete {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if let Some(exit_code) = exit_code {
|
if let Some(exit_code) = exit_code {
|
||||||
let mut v: Vec<_> = exit_code.collect();
|
let mut v: Vec<_> = exit_code.into_iter().collect();
|
||||||
|
|
||||||
if let Some(v) = v.pop() {
|
if let Some(v) = v.pop() {
|
||||||
record.push("exit_code", v);
|
record.push("exit_code", v);
|
||||||
|
@ -195,5 +195,5 @@ fn run_ps(
|
|||||||
|
|
||||||
Ok(output
|
Ok(output
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.into_pipeline_data(engine_state.ctrlc.clone()))
|
.into_pipeline_data(span, engine_state.ctrlc.clone()))
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ fn registry_query(
|
|||||||
*registry_key_span,
|
*registry_key_span,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
Ok(reg_values.into_pipeline_data(engine_state.ctrlc.clone()))
|
Ok(reg_values.into_pipeline_data(call_span, engine_state.ctrlc.clone()))
|
||||||
} else {
|
} else {
|
||||||
match registry_value {
|
match registry_value {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
|
@ -163,8 +163,6 @@ impl ExternalCommand {
|
|||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
let head = self.name.span;
|
let head = self.name.span;
|
||||||
|
|
||||||
let ctrlc = engine_state.ctrlc.clone();
|
|
||||||
|
|
||||||
#[allow(unused_mut)]
|
#[allow(unused_mut)]
|
||||||
let (cmd, mut reader) = self.create_process(&input, false, head)?;
|
let (cmd, mut reader) = self.create_process(&input, false, head)?;
|
||||||
|
|
||||||
@ -431,7 +429,7 @@ impl ExternalCommand {
|
|||||||
(
|
(
|
||||||
Some(RawStream::new(
|
Some(RawStream::new(
|
||||||
Box::new(ByteLines::new(combined)),
|
Box::new(ByteLines::new(combined)),
|
||||||
ctrlc.clone(),
|
engine_state.ctrlc.clone(),
|
||||||
head,
|
head,
|
||||||
None,
|
None,
|
||||||
)),
|
)),
|
||||||
@ -439,11 +437,21 @@ impl ExternalCommand {
|
|||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
let stdout = child.as_mut().stdout.take().map(|out| {
|
let stdout = child.as_mut().stdout.take().map(|out| {
|
||||||
RawStream::new(Box::new(ByteLines::new(out)), ctrlc.clone(), head, None)
|
RawStream::new(
|
||||||
|
Box::new(ByteLines::new(out)),
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
head,
|
||||||
|
None,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
let stderr = child.as_mut().stderr.take().map(|err| {
|
let stderr = child.as_mut().stderr.take().map(|err| {
|
||||||
RawStream::new(Box::new(ByteLines::new(err)), ctrlc.clone(), head, None)
|
RawStream::new(
|
||||||
|
Box::new(ByteLines::new(err)),
|
||||||
|
engine_state.ctrlc.clone(),
|
||||||
|
head,
|
||||||
|
None,
|
||||||
|
)
|
||||||
});
|
});
|
||||||
|
|
||||||
if matches!(self.err, OutDest::Pipe) {
|
if matches!(self.err, OutDest::Pipe) {
|
||||||
@ -505,15 +513,16 @@ impl ExternalCommand {
|
|||||||
})
|
})
|
||||||
.err_span(head)?;
|
.err_span(head)?;
|
||||||
|
|
||||||
let exit_code_receiver = ValueReceiver::new(exit_code_rx);
|
let exit_code = Some(ListStream::new(
|
||||||
|
ValueReceiver::new(exit_code_rx),
|
||||||
|
head,
|
||||||
|
None,
|
||||||
|
));
|
||||||
|
|
||||||
Ok(PipelineData::ExternalStream {
|
Ok(PipelineData::ExternalStream {
|
||||||
stdout,
|
stdout,
|
||||||
stderr,
|
stderr,
|
||||||
exit_code: Some(ListStream::from_stream(
|
exit_code,
|
||||||
Box::new(exit_code_receiver),
|
|
||||||
ctrlc.clone(),
|
|
||||||
)),
|
|
||||||
span: head,
|
span: head,
|
||||||
metadata: None,
|
metadata: None,
|
||||||
trim_end_newline: true,
|
trim_end_newline: true,
|
||||||
|
@ -214,6 +214,7 @@ fn which(
|
|||||||
stack: &mut Stack,
|
stack: &mut Stack,
|
||||||
call: &Call,
|
call: &Call,
|
||||||
) -> Result<PipelineData, ShellError> {
|
) -> Result<PipelineData, ShellError> {
|
||||||
|
let head = call.head;
|
||||||
let which_args = WhichArgs {
|
let which_args = WhichArgs {
|
||||||
applications: call.rest(engine_state, stack, 0)?,
|
applications: call.rest(engine_state, stack, 0)?,
|
||||||
all: call.has_flag(engine_state, stack, "all")?,
|
all: call.has_flag(engine_state, stack, "all")?,
|
||||||
@ -223,7 +224,7 @@ fn which(
|
|||||||
if which_args.applications.is_empty() {
|
if which_args.applications.is_empty() {
|
||||||
return Err(ShellError::MissingParameter {
|
return Err(ShellError::MissingParameter {
|
||||||
param_name: "application".into(),
|
param_name: "application".into(),
|
||||||
span: call.head,
|
span: head,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +232,7 @@ fn which(
|
|||||||
|
|
||||||
#[allow(deprecated)]
|
#[allow(deprecated)]
|
||||||
let cwd = env::current_dir_str(engine_state, stack)?;
|
let cwd = env::current_dir_str(engine_state, stack)?;
|
||||||
let paths = env::path_str(engine_state, stack, call.head)?;
|
let paths = env::path_str(engine_state, stack, head)?;
|
||||||
|
|
||||||
for app in which_args.applications {
|
for app in which_args.applications {
|
||||||
let values = which_single(
|
let values = which_single(
|
||||||
@ -244,7 +245,7 @@ fn which(
|
|||||||
output.extend(values);
|
output.extend(values);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(output.into_iter().into_pipeline_data(ctrlc))
|
Ok(output.into_iter().into_pipeline_data(head, ctrlc))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
@ -5,7 +5,9 @@
|
|||||||
use lscolors::{LsColors, Style};
|
use lscolors::{LsColors, Style};
|
||||||
use nu_color_config::{color_from_hex, StyleComputer, TextStyle};
|
use nu_color_config::{color_from_hex, StyleComputer, TextStyle};
|
||||||
use nu_engine::{command_prelude::*, env::get_config, env_to_string};
|
use nu_engine::{command_prelude::*, env::get_config, env_to_string};
|
||||||
use nu_protocol::{Config, DataSource, ListStream, PipelineMetadata, RawStream, TableMode};
|
use nu_protocol::{
|
||||||
|
Config, DataSource, ListStream, PipelineMetadata, RawStream, TableMode, ValueIterator,
|
||||||
|
};
|
||||||
use nu_table::{
|
use nu_table::{
|
||||||
common::create_nu_table_config, CollapsedTable, ExpandedTable, JustTable, NuTable, NuTableCell,
|
common::create_nu_table_config, CollapsedTable, ExpandedTable, JustTable, NuTable, NuTableCell,
|
||||||
StringResult, TableOpts, TableOutput,
|
StringResult, TableOpts, TableOutput,
|
||||||
@ -381,7 +383,7 @@ fn handle_table_command(
|
|||||||
// None of these two receive a StyleComputer because handle_row_stream() can produce it by itself using engine_state and stack.
|
// None of these two receive a StyleComputer because handle_row_stream() can produce it by itself using engine_state and stack.
|
||||||
PipelineData::Value(Value::List { vals, .. }, metadata) => {
|
PipelineData::Value(Value::List { vals, .. }, metadata) => {
|
||||||
let ctrlc = input.engine_state.ctrlc.clone();
|
let ctrlc = input.engine_state.ctrlc.clone();
|
||||||
let stream = ListStream::from_stream(vals.into_iter(), ctrlc);
|
let stream = ListStream::new(vals.into_iter(), span, ctrlc);
|
||||||
input.data = PipelineData::Empty;
|
input.data = PipelineData::Empty;
|
||||||
|
|
||||||
handle_row_stream(input, cfg, stream, metadata)
|
handle_row_stream(input, cfg, stream, metadata)
|
||||||
@ -405,7 +407,7 @@ fn handle_table_command(
|
|||||||
}
|
}
|
||||||
PipelineData::Value(Value::Range { val, .. }, metadata) => {
|
PipelineData::Value(Value::Range { val, .. }, metadata) => {
|
||||||
let ctrlc = input.engine_state.ctrlc.clone();
|
let ctrlc = input.engine_state.ctrlc.clone();
|
||||||
let stream = ListStream::from_stream(val.into_range_iter(span, ctrlc.clone()), ctrlc);
|
let stream = ListStream::new(val.into_range_iter(span, ctrlc), span, None);
|
||||||
input.data = PipelineData::Empty;
|
input.data = PipelineData::Empty;
|
||||||
handle_row_stream(input, cfg, stream, metadata)
|
handle_row_stream(input, cfg, stream, metadata)
|
||||||
}
|
}
|
||||||
@ -537,7 +539,6 @@ fn handle_row_stream(
|
|||||||
data_source: DataSource::Ls,
|
data_source: DataSource::Ls,
|
||||||
}) => {
|
}) => {
|
||||||
let config = get_config(input.engine_state, input.stack);
|
let config = get_config(input.engine_state, input.stack);
|
||||||
let ctrlc = ctrlc.clone();
|
|
||||||
let ls_colors_env_str = match input.stack.get_env_var(input.engine_state, "LS_COLORS") {
|
let ls_colors_env_str = match input.stack.get_env_var(input.engine_state, "LS_COLORS") {
|
||||||
Some(v) => Some(env_to_string(
|
Some(v) => Some(env_to_string(
|
||||||
"LS_COLORS",
|
"LS_COLORS",
|
||||||
@ -549,67 +550,55 @@ fn handle_row_stream(
|
|||||||
};
|
};
|
||||||
let ls_colors = get_ls_colors(ls_colors_env_str);
|
let ls_colors = get_ls_colors(ls_colors_env_str);
|
||||||
|
|
||||||
ListStream::from_stream(
|
stream.map(move |mut value| {
|
||||||
stream.map(move |mut x| match &mut x {
|
if let Value::Record { val: record, .. } = &mut value {
|
||||||
Value::Record { val: record, .. } => {
|
// Only the name column gets special colors, for now
|
||||||
// Only the name column gets special colors, for now
|
if let Some(value) = record.to_mut().get_mut("name") {
|
||||||
if let Some(value) = record.to_mut().get_mut("name") {
|
let span = value.span();
|
||||||
let span = value.span();
|
if let Value::String { val, .. } = value {
|
||||||
if let Value::String { val, .. } = value {
|
if let Some(val) = render_path_name(val, &config, &ls_colors, span) {
|
||||||
if let Some(val) = render_path_name(val, &config, &ls_colors, span)
|
*value = val;
|
||||||
{
|
|
||||||
*value = val;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
x
|
|
||||||
}
|
}
|
||||||
_ => x,
|
}
|
||||||
}),
|
value
|
||||||
ctrlc,
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
// Next, `to html -l` sources:
|
// Next, `to html -l` sources:
|
||||||
Some(PipelineMetadata {
|
Some(PipelineMetadata {
|
||||||
data_source: DataSource::HtmlThemes,
|
data_source: DataSource::HtmlThemes,
|
||||||
}) => {
|
}) => {
|
||||||
let ctrlc = ctrlc.clone();
|
stream.map(|mut value| {
|
||||||
|
if let Value::Record { val: record, .. } = &mut value {
|
||||||
ListStream::from_stream(
|
for (rec_col, rec_val) in record.to_mut().iter_mut() {
|
||||||
stream.map(move |mut x| match &mut x {
|
// Every column in the HTML theme table except 'name' is colored
|
||||||
Value::Record { val: record, .. } => {
|
if rec_col != "name" {
|
||||||
for (rec_col, rec_val) in record.to_mut().iter_mut() {
|
continue;
|
||||||
// Every column in the HTML theme table except 'name' is colored
|
}
|
||||||
if rec_col != "name" {
|
// Simple routine to grab the hex code, convert to a style,
|
||||||
continue;
|
// then place it in a new Value::String.
|
||||||
}
|
|
||||||
// Simple routine to grab the hex code, convert to a style,
|
let span = rec_val.span();
|
||||||
// then place it in a new Value::String.
|
if let Value::String { val, .. } = rec_val {
|
||||||
|
let s = match color_from_hex(val) {
|
||||||
let span = rec_val.span();
|
Ok(c) => match c {
|
||||||
if let Value::String { val, .. } = rec_val {
|
// .normal() just sets the text foreground color.
|
||||||
let s = match color_from_hex(val) {
|
Some(c) => c.normal(),
|
||||||
Ok(c) => match c {
|
None => nu_ansi_term::Style::default(),
|
||||||
// .normal() just sets the text foreground color.
|
},
|
||||||
Some(c) => c.normal(),
|
Err(_) => nu_ansi_term::Style::default(),
|
||||||
None => nu_ansi_term::Style::default(),
|
};
|
||||||
},
|
*rec_val = Value::string(
|
||||||
Err(_) => nu_ansi_term::Style::default(),
|
// Apply the style (ANSI codes) to the string
|
||||||
};
|
s.paint(&*val).to_string(),
|
||||||
*rec_val = Value::string(
|
span,
|
||||||
// Apply the style (ANSI codes) to the string
|
);
|
||||||
s.paint(&*val).to_string(),
|
|
||||||
span,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
x
|
|
||||||
}
|
}
|
||||||
_ => x,
|
}
|
||||||
}),
|
value
|
||||||
ctrlc,
|
})
|
||||||
)
|
|
||||||
}
|
}
|
||||||
_ => stream,
|
_ => stream,
|
||||||
};
|
};
|
||||||
@ -662,7 +651,7 @@ fn make_clickable_link(
|
|||||||
|
|
||||||
struct PagingTableCreator {
|
struct PagingTableCreator {
|
||||||
head: Span,
|
head: Span,
|
||||||
stream: ListStream,
|
stream: ValueIterator,
|
||||||
engine_state: EngineState,
|
engine_state: EngineState,
|
||||||
stack: Stack,
|
stack: Stack,
|
||||||
ctrlc: Option<Arc<AtomicBool>>,
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
@ -683,7 +672,7 @@ impl PagingTableCreator {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
PagingTableCreator {
|
PagingTableCreator {
|
||||||
head,
|
head,
|
||||||
stream,
|
stream: stream.into_inner(),
|
||||||
engine_state,
|
engine_state,
|
||||||
stack,
|
stack,
|
||||||
ctrlc,
|
ctrlc,
|
||||||
@ -822,7 +811,7 @@ impl Iterator for PagingTableCreator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn stream_collect(
|
fn stream_collect(
|
||||||
stream: &mut ListStream,
|
stream: impl Iterator<Item = Value>,
|
||||||
size: usize,
|
size: usize,
|
||||||
ctrlc: Option<Arc<AtomicBool>>,
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
) -> (Vec<Value>, bool) {
|
) -> (Vec<Value>, bool) {
|
||||||
@ -830,7 +819,7 @@ fn stream_collect(
|
|||||||
let mut end = true;
|
let mut end = true;
|
||||||
|
|
||||||
let mut batch = Vec::with_capacity(size);
|
let mut batch = Vec::with_capacity(size);
|
||||||
for (i, item) in stream.by_ref().enumerate() {
|
for (i, item) in stream.enumerate() {
|
||||||
batch.push(item);
|
batch.push(item);
|
||||||
|
|
||||||
// If we've been buffering over a second, go ahead and send out what we have so far
|
// If we've been buffering over a second, go ahead and send out what we have so far
|
||||||
@ -853,7 +842,7 @@ fn stream_collect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn stream_collect_abbriviated(
|
fn stream_collect_abbriviated(
|
||||||
stream: &mut ListStream,
|
stream: impl Iterator<Item = Value>,
|
||||||
size: usize,
|
size: usize,
|
||||||
ctrlc: Option<Arc<AtomicBool>>,
|
ctrlc: Option<Arc<AtomicBool>>,
|
||||||
) -> (Vec<Value>, usize, bool) {
|
) -> (Vec<Value>, usize, bool) {
|
||||||
@ -866,7 +855,7 @@ fn stream_collect_abbriviated(
|
|||||||
return (vec![], 0, false);
|
return (vec![], 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
for item in stream.by_ref() {
|
for item in stream {
|
||||||
read += 1;
|
read += 1;
|
||||||
|
|
||||||
if read <= size {
|
if read <= size {
|
||||||
|
@ -22,9 +22,9 @@ pub fn collect_pipeline(input: PipelineData) -> Result<(Vec<String>, Vec<Vec<Val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn collect_list_stream(mut stream: ListStream) -> (Vec<String>, Vec<Vec<Value>>) {
|
fn collect_list_stream(stream: ListStream) -> (Vec<String>, Vec<Vec<Value>>) {
|
||||||
let mut records = vec![];
|
let mut records = vec![];
|
||||||
for item in stream.by_ref() {
|
for item in stream {
|
||||||
records.push(item);
|
records.push(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ fn collect_external_stream(
|
|||||||
data.push(value);
|
data.push(value);
|
||||||
}
|
}
|
||||||
if let Some(exit_code) = exit_code {
|
if let Some(exit_code) = exit_code {
|
||||||
let list = exit_code.collect::<Vec<_>>();
|
let list = exit_code.into_iter().collect::<Vec<_>>();
|
||||||
let val = Value::list(list, span);
|
let val = Value::list(list, span);
|
||||||
|
|
||||||
columns.push(String::from("exit_code"));
|
columns.push(String::from("exit_code"));
|
||||||
|
@ -183,7 +183,7 @@ pub trait InterfaceManager {
|
|||||||
PipelineDataHeader::ListStream(info) => {
|
PipelineDataHeader::ListStream(info) => {
|
||||||
let handle = self.stream_manager().get_handle();
|
let handle = self.stream_manager().get_handle();
|
||||||
let reader = handle.read_stream(info.id, self.get_interface())?;
|
let reader = handle.read_stream(info.id, self.get_interface())?;
|
||||||
PipelineData::ListStream(ListStream::from_stream(reader, ctrlc.cloned()), None)
|
ListStream::new(reader, info.span, ctrlc.cloned()).into()
|
||||||
}
|
}
|
||||||
PipelineDataHeader::ExternalStream(info) => {
|
PipelineDataHeader::ExternalStream(info) => {
|
||||||
let handle = self.stream_manager().get_handle();
|
let handle = self.stream_manager().get_handle();
|
||||||
@ -203,7 +203,7 @@ pub trait InterfaceManager {
|
|||||||
.map(|list_info| {
|
.map(|list_info| {
|
||||||
handle
|
handle
|
||||||
.read_stream(list_info.id, self.get_interface())
|
.read_stream(list_info.id, self.get_interface())
|
||||||
.map(|reader| ListStream::from_stream(reader, ctrlc.cloned()))
|
.map(|reader| ListStream::new(reader, info.span, ctrlc.cloned()))
|
||||||
})
|
})
|
||||||
.transpose()?,
|
.transpose()?,
|
||||||
span: info.span,
|
span: info.span,
|
||||||
@ -278,7 +278,10 @@ pub trait Interface: Clone + Send {
|
|||||||
PipelineData::ListStream(stream, _) => {
|
PipelineData::ListStream(stream, _) => {
|
||||||
let (id, writer) = new_stream(LIST_STREAM_HIGH_PRESSURE)?;
|
let (id, writer) = new_stream(LIST_STREAM_HIGH_PRESSURE)?;
|
||||||
Ok((
|
Ok((
|
||||||
PipelineDataHeader::ListStream(ListStreamInfo { id }),
|
PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id,
|
||||||
|
span: stream.span(),
|
||||||
|
}),
|
||||||
PipelineDataWriter::ListStream(writer, stream),
|
PipelineDataWriter::ListStream(writer, stream),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -316,7 +319,7 @@ pub trait Interface: Clone + Send {
|
|||||||
.map(|(stream, (id, _))| RawStreamInfo::new(*id, stream)),
|
.map(|(stream, (id, _))| RawStreamInfo::new(*id, stream)),
|
||||||
exit_code: exit_code_stream
|
exit_code: exit_code_stream
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|&(id, _)| ListStreamInfo { id }),
|
.map(|&(id, _)| ListStreamInfo { id, span }),
|
||||||
trim_end_newline,
|
trim_end_newline,
|
||||||
});
|
});
|
||||||
// Collect the writers
|
// Collect the writers
|
||||||
|
@ -161,7 +161,10 @@ fn read_pipeline_data_list_stream() -> Result<(), ShellError> {
|
|||||||
}
|
}
|
||||||
test.add(StreamMessage::End(7));
|
test.add(StreamMessage::End(7));
|
||||||
|
|
||||||
let header = PipelineDataHeader::ListStream(ListStreamInfo { id: 7 });
|
let header = PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 7,
|
||||||
|
span: Span::test_data(),
|
||||||
|
});
|
||||||
|
|
||||||
let pipe = manager.read_pipeline_data(header, None)?;
|
let pipe = manager.read_pipeline_data(header, None)?;
|
||||||
assert!(
|
assert!(
|
||||||
@ -221,7 +224,10 @@ fn read_pipeline_data_external_stream() -> Result<(), ShellError> {
|
|||||||
is_binary: true,
|
is_binary: true,
|
||||||
known_size: None,
|
known_size: None,
|
||||||
}),
|
}),
|
||||||
exit_code: Some(ListStreamInfo { id: 14 }),
|
exit_code: Some(ListStreamInfo {
|
||||||
|
id: 14,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
trim_end_newline: true,
|
trim_end_newline: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -273,7 +279,10 @@ fn read_pipeline_data_external_stream() -> Result<(), ShellError> {
|
|||||||
}
|
}
|
||||||
assert_eq!(iterations, count, "stderr length");
|
assert_eq!(iterations, count, "stderr length");
|
||||||
|
|
||||||
assert_eq!(vec![Value::test_int(1)], exit_code.collect::<Vec<_>>());
|
assert_eq!(
|
||||||
|
vec![Value::test_int(1)],
|
||||||
|
exit_code.into_iter().collect::<Vec<_>>()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
_ => panic!("unexpected PipelineData: {pipe:?}"),
|
_ => panic!("unexpected PipelineData: {pipe:?}"),
|
||||||
}
|
}
|
||||||
@ -284,30 +293,13 @@ fn read_pipeline_data_external_stream() -> Result<(), ShellError> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn read_pipeline_data_ctrlc() -> Result<(), ShellError> {
|
|
||||||
let manager = TestInterfaceManager::new(&TestCase::new());
|
|
||||||
let header = PipelineDataHeader::ListStream(ListStreamInfo { id: 0 });
|
|
||||||
let ctrlc = Default::default();
|
|
||||||
match manager.read_pipeline_data(header, Some(&ctrlc))? {
|
|
||||||
PipelineData::ListStream(
|
|
||||||
ListStream {
|
|
||||||
ctrlc: stream_ctrlc,
|
|
||||||
..
|
|
||||||
},
|
|
||||||
_,
|
|
||||||
) => {
|
|
||||||
assert!(Arc::ptr_eq(&ctrlc, &stream_ctrlc.expect("ctrlc not set")));
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
_ => panic!("Unexpected PipelineData, should have been ListStream"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn read_pipeline_data_prepared_properly() -> Result<(), ShellError> {
|
fn read_pipeline_data_prepared_properly() -> Result<(), ShellError> {
|
||||||
let manager = TestInterfaceManager::new(&TestCase::new());
|
let manager = TestInterfaceManager::new(&TestCase::new());
|
||||||
let header = PipelineDataHeader::ListStream(ListStreamInfo { id: 0 });
|
let header = PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
});
|
||||||
match manager.read_pipeline_data(header, None)? {
|
match manager.read_pipeline_data(header, None)? {
|
||||||
PipelineData::ListStream(_, meta) => match meta {
|
PipelineData::ListStream(_, meta) => match meta {
|
||||||
Some(PipelineMetadata { data_source }) => match data_source {
|
Some(PipelineMetadata { data_source }) => match data_source {
|
||||||
@ -404,7 +396,7 @@ fn write_pipeline_data_list_stream() -> Result<(), ShellError> {
|
|||||||
|
|
||||||
// Set up pipeline data for a list stream
|
// Set up pipeline data for a list stream
|
||||||
let pipe = PipelineData::ListStream(
|
let pipe = PipelineData::ListStream(
|
||||||
ListStream::from_stream(values.clone().into_iter(), None),
|
ListStream::new(values.clone().into_iter(), Span::test_data(), None),
|
||||||
None,
|
None,
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -474,8 +466,9 @@ fn write_pipeline_data_external_stream() -> Result<(), ShellError> {
|
|||||||
span,
|
span,
|
||||||
None,
|
None,
|
||||||
)),
|
)),
|
||||||
exit_code: Some(ListStream::from_stream(
|
exit_code: Some(ListStream::new(
|
||||||
std::iter::once(exit_code.clone()),
|
std::iter::once(exit_code.clone()),
|
||||||
|
Span::test_data(),
|
||||||
None,
|
None,
|
||||||
)),
|
)),
|
||||||
span,
|
span,
|
||||||
|
@ -11,8 +11,8 @@ use nu_plugin_protocol::{
|
|||||||
PluginOutput, ProtocolInfo, StreamId, StreamMessage,
|
PluginOutput, ProtocolInfo, StreamId, StreamMessage,
|
||||||
};
|
};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
ast::Operator, CustomValue, IntoInterruptiblePipelineData, IntoSpanned, ListStream,
|
ast::Operator, CustomValue, IntoSpanned, PipelineData, PluginSignature, ShellError, Span,
|
||||||
PipelineData, PluginSignature, ShellError, Span, Spanned, Value,
|
Spanned, Value,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{btree_map, BTreeMap},
|
collections::{btree_map, BTreeMap},
|
||||||
@ -592,14 +592,15 @@ impl InterfaceManager for PluginInterfaceManager {
|
|||||||
})?;
|
})?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => {
|
PipelineData::ListStream(stream, meta) => {
|
||||||
let source = self.state.source.clone();
|
let source = self.state.source.clone();
|
||||||
Ok(stream
|
Ok(PipelineData::ListStream(
|
||||||
.map(move |mut value| {
|
stream.map(move |mut value| {
|
||||||
let _ = PluginCustomValueWithSource::add_source_in(&mut value, &source);
|
let _ = PluginCustomValueWithSource::add_source_in(&mut value, &source);
|
||||||
value
|
value
|
||||||
})
|
}),
|
||||||
.into_pipeline_data_with_metadata(meta, ctrlc))
|
meta,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
||||||
}
|
}
|
||||||
@ -1076,18 +1077,19 @@ impl Interface for PluginInterface {
|
|||||||
state.prepare_value(&mut value, &self.state.source)?;
|
state.prepare_value(&mut value, &self.state.source)?;
|
||||||
Ok(PipelineData::Value(value, meta))
|
Ok(PipelineData::Value(value, meta))
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => {
|
PipelineData::ListStream(stream, meta) => {
|
||||||
let source = self.state.source.clone();
|
let source = self.state.source.clone();
|
||||||
let state = state.clone();
|
let state = state.clone();
|
||||||
Ok(stream
|
Ok(PipelineData::ListStream(
|
||||||
.map(move |mut value| {
|
stream.map(move |mut value| {
|
||||||
match state.prepare_value(&mut value, &source) {
|
match state.prepare_value(&mut value, &source) {
|
||||||
Ok(()) => value,
|
Ok(()) => value,
|
||||||
// Put the error in the stream instead
|
// Put the error in the stream instead
|
||||||
Err(err) => Value::error(err, value.span()),
|
Err(err) => Value::error(err, value.span()),
|
||||||
}
|
}
|
||||||
})
|
}),
|
||||||
.into_pipeline_data_with_metadata(meta, ctrlc))
|
meta,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,10 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul
|
|||||||
|
|
||||||
// Create a stream...
|
// Create a stream...
|
||||||
let stream = manager.read_pipeline_data(
|
let stream = manager.read_pipeline_data(
|
||||||
PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }),
|
PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -105,7 +108,10 @@ fn manager_consume_all_propagates_io_error_to_readers() -> Result<(), ShellError
|
|||||||
test.set_read_error(test_io_error());
|
test.set_read_error(test_io_error());
|
||||||
|
|
||||||
let stream = manager.read_pipeline_data(
|
let stream = manager.read_pipeline_data(
|
||||||
PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }),
|
PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -331,7 +337,10 @@ fn manager_consume_call_response_forwards_to_subscriber_with_pipeline_data(
|
|||||||
|
|
||||||
manager.consume(PluginOutput::CallResponse(
|
manager.consume(PluginOutput::CallResponse(
|
||||||
0,
|
0,
|
||||||
PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { id: 0 })),
|
PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
})),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
@ -372,7 +381,10 @@ fn manager_consume_call_response_registers_streams() -> Result<(), ShellError> {
|
|||||||
// Check list streams, external streams
|
// Check list streams, external streams
|
||||||
manager.consume(PluginOutput::CallResponse(
|
manager.consume(PluginOutput::CallResponse(
|
||||||
0,
|
0,
|
||||||
PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { id: 0 })),
|
PluginCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
})),
|
||||||
))?;
|
))?;
|
||||||
manager.consume(PluginOutput::CallResponse(
|
manager.consume(PluginOutput::CallResponse(
|
||||||
1,
|
1,
|
||||||
@ -388,7 +400,10 @@ fn manager_consume_call_response_registers_streams() -> Result<(), ShellError> {
|
|||||||
is_binary: false,
|
is_binary: false,
|
||||||
known_size: None,
|
known_size: None,
|
||||||
}),
|
}),
|
||||||
exit_code: Some(ListStreamInfo { id: 3 }),
|
exit_code: Some(ListStreamInfo {
|
||||||
|
id: 3,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
trim_end_newline: false,
|
trim_end_newline: false,
|
||||||
})),
|
})),
|
||||||
))?;
|
))?;
|
||||||
@ -448,7 +463,10 @@ fn manager_consume_engine_call_forwards_to_subscriber_with_pipeline_data() -> Re
|
|||||||
span: Span::test_data(),
|
span: Span::test_data(),
|
||||||
},
|
},
|
||||||
positional: vec![],
|
positional: vec![],
|
||||||
input: PipelineDataHeader::ListStream(ListStreamInfo { id: 2 }),
|
input: PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 2,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
redirect_stdout: false,
|
redirect_stdout: false,
|
||||||
redirect_stderr: false,
|
redirect_stderr: false,
|
||||||
},
|
},
|
||||||
@ -681,7 +699,7 @@ fn manager_prepare_pipeline_data_adds_source_to_list_streams() -> Result<(), She
|
|||||||
[Value::test_custom_value(Box::new(
|
[Value::test_custom_value(Box::new(
|
||||||
test_plugin_custom_value(),
|
test_plugin_custom_value(),
|
||||||
))]
|
))]
|
||||||
.into_pipeline_data(None),
|
.into_pipeline_data(Span::test_data(), None),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let value = data
|
let value = data
|
||||||
@ -855,7 +873,7 @@ fn interface_write_plugin_call_writes_run_with_stream_input() -> Result<(), Shel
|
|||||||
positional: vec![],
|
positional: vec![],
|
||||||
named: vec![],
|
named: vec![],
|
||||||
},
|
},
|
||||||
input: values.clone().into_pipeline_data(None),
|
input: values.clone().into_pipeline_data(Span::test_data(), None),
|
||||||
}),
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
@ -1131,7 +1149,10 @@ fn interface_prepare_pipeline_data_accepts_normal_streams() -> Result<(), ShellE
|
|||||||
let interface = TestCase::new().plugin("test").get_interface();
|
let interface = TestCase::new().plugin("test").get_interface();
|
||||||
let values = normal_values(&interface);
|
let values = normal_values(&interface);
|
||||||
let state = CurrentCallState::default();
|
let state = CurrentCallState::default();
|
||||||
let data = interface.prepare_pipeline_data(values.clone().into_pipeline_data(None), &state)?;
|
let data = interface.prepare_pipeline_data(
|
||||||
|
values.clone().into_pipeline_data(Span::test_data(), None),
|
||||||
|
&state,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for (expected_value, actual_value) in values.iter().zip(data) {
|
for (expected_value, actual_value) in values.iter().zip(data) {
|
||||||
@ -1191,7 +1212,10 @@ fn interface_prepare_pipeline_data_rejects_bad_custom_value_in_a_stream() -> Res
|
|||||||
let interface = TestCase::new().plugin("test").get_interface();
|
let interface = TestCase::new().plugin("test").get_interface();
|
||||||
let values = bad_custom_values();
|
let values = bad_custom_values();
|
||||||
let state = CurrentCallState::default();
|
let state = CurrentCallState::default();
|
||||||
let data = interface.prepare_pipeline_data(values.clone().into_pipeline_data(None), &state)?;
|
let data = interface.prepare_pipeline_data(
|
||||||
|
values.clone().into_pipeline_data(Span::test_data(), None),
|
||||||
|
&state,
|
||||||
|
)?;
|
||||||
|
|
||||||
let mut count = 0;
|
let mut count = 0;
|
||||||
for value in data {
|
for value in data {
|
||||||
|
@ -116,6 +116,7 @@ impl PipelineDataHeader {
|
|||||||
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
|
||||||
pub struct ListStreamInfo {
|
pub struct ListStreamInfo {
|
||||||
pub id: StreamId,
|
pub id: StreamId,
|
||||||
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Additional information about external streams
|
/// Additional information about external streams
|
||||||
|
@ -79,7 +79,7 @@
|
|||||||
//!
|
//!
|
||||||
//! // #[test]
|
//! // #[test]
|
||||||
//! fn test_lowercase() -> Result<(), ShellError> {
|
//! fn test_lowercase() -> Result<(), ShellError> {
|
||||||
//! let input = vec![Value::test_string("FooBar")].into_pipeline_data(None);
|
//! let input = vec![Value::test_string("FooBar")].into_pipeline_data(Span::test_data(), None);
|
||||||
//! let output = PluginTest::new("lowercase", LowercasePlugin.into())?
|
//! let output = PluginTest::new("lowercase", LowercasePlugin.into())?
|
||||||
//! .eval_with("lowercase", input)?
|
//! .eval_with("lowercase", input)?
|
||||||
//! .into_value(Span::test_data());
|
//! .into_value(Span::test_data());
|
||||||
|
@ -91,7 +91,7 @@ impl PluginTest {
|
|||||||
/// let result = PluginTest::new("my_plugin", MyPlugin.into())?
|
/// let result = PluginTest::new("my_plugin", MyPlugin.into())?
|
||||||
/// .eval_with(
|
/// .eval_with(
|
||||||
/// "my-command",
|
/// "my-command",
|
||||||
/// vec![Value::test_int(42)].into_pipeline_data(None)
|
/// vec![Value::test_int(42)].into_pipeline_data(Span::test_data(), None)
|
||||||
/// )?
|
/// )?
|
||||||
/// .into_value(Span::test_data());
|
/// .into_value(Span::test_data());
|
||||||
/// assert_eq!(Value::test_string("42"), result);
|
/// assert_eq!(Value::test_string("42"), result);
|
||||||
|
@ -68,7 +68,7 @@ impl Plugin for LowercasePlugin {
|
|||||||
fn test_lowercase_using_eval_with() -> Result<(), ShellError> {
|
fn test_lowercase_using_eval_with() -> Result<(), ShellError> {
|
||||||
let result = PluginTest::new("lowercase", LowercasePlugin.into())?.eval_with(
|
let result = PluginTest::new("lowercase", LowercasePlugin.into())?.eval_with(
|
||||||
"lowercase",
|
"lowercase",
|
||||||
vec![Value::test_string("HeLlO wOrLd")].into_pipeline_data(None),
|
vec![Value::test_string("HeLlO wOrLd")].into_pipeline_data(Span::test_data(), None),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -11,8 +11,8 @@ use nu_plugin_protocol::{
|
|||||||
ProtocolInfo,
|
ProtocolInfo,
|
||||||
};
|
};
|
||||||
use nu_protocol::{
|
use nu_protocol::{
|
||||||
engine::Closure, Config, IntoInterruptiblePipelineData, LabeledError, ListStream, PipelineData,
|
engine::Closure, Config, LabeledError, PipelineData, PluginSignature, ShellError, Span,
|
||||||
PluginSignature, ShellError, Span, Spanned, Value,
|
Spanned, Value,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
collections::{btree_map, BTreeMap, HashMap},
|
collections::{btree_map, BTreeMap, HashMap},
|
||||||
@ -336,14 +336,15 @@ impl InterfaceManager for EngineInterfaceManager {
|
|||||||
PluginCustomValue::deserialize_custom_values_in(value)?;
|
PluginCustomValue::deserialize_custom_values_in(value)?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => Ok(stream
|
PipelineData::ListStream(stream, meta) => {
|
||||||
.map(|mut value| {
|
let stream = stream.map(|mut value| {
|
||||||
let span = value.span();
|
let span = value.span();
|
||||||
PluginCustomValue::deserialize_custom_values_in(&mut value)
|
PluginCustomValue::deserialize_custom_values_in(&mut value)
|
||||||
.map(|()| value)
|
.map(|()| value)
|
||||||
.unwrap_or_else(|err| Value::error(err, span))
|
.unwrap_or_else(|err| Value::error(err, span))
|
||||||
})
|
});
|
||||||
.into_pipeline_data_with_metadata(meta, ctrlc)),
|
Ok(PipelineData::ListStream(stream, meta))
|
||||||
|
}
|
||||||
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -910,14 +911,15 @@ impl Interface for EngineInterface {
|
|||||||
PluginCustomValue::serialize_custom_values_in(value)?;
|
PluginCustomValue::serialize_custom_values_in(value)?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
}
|
}
|
||||||
PipelineData::ListStream(ListStream { stream, ctrlc, .. }, meta) => Ok(stream
|
PipelineData::ListStream(stream, meta) => {
|
||||||
.map(|mut value| {
|
let stream = stream.map(|mut value| {
|
||||||
let span = value.span();
|
let span = value.span();
|
||||||
PluginCustomValue::serialize_custom_values_in(&mut value)
|
PluginCustomValue::serialize_custom_values_in(&mut value)
|
||||||
.map(|_| value)
|
.map(|_| value)
|
||||||
.unwrap_or_else(|err| Value::error(err, span))
|
.unwrap_or_else(|err| Value::error(err, span))
|
||||||
})
|
});
|
||||||
.into_pipeline_data_with_metadata(meta, ctrlc)),
|
Ok(PipelineData::ListStream(stream, meta))
|
||||||
|
}
|
||||||
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
PipelineData::Empty | PipelineData::ExternalStream { .. } => Ok(data),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,10 @@ fn manager_consume_all_exits_after_streams_and_interfaces_are_dropped() -> Resul
|
|||||||
|
|
||||||
// Create a stream...
|
// Create a stream...
|
||||||
let stream = manager.read_pipeline_data(
|
let stream = manager.read_pipeline_data(
|
||||||
PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }),
|
PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -109,7 +112,10 @@ fn manager_consume_all_propagates_io_error_to_readers() -> Result<(), ShellError
|
|||||||
test.set_read_error(test_io_error());
|
test.set_read_error(test_io_error());
|
||||||
|
|
||||||
let stream = manager.read_pipeline_data(
|
let stream = manager.read_pipeline_data(
|
||||||
PipelineDataHeader::ListStream(ListStreamInfo { id: 0 }),
|
PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -395,7 +401,10 @@ fn manager_consume_call_run_forwards_to_receiver_with_pipeline_data() -> Result<
|
|||||||
positional: vec![],
|
positional: vec![],
|
||||||
named: vec![],
|
named: vec![],
|
||||||
},
|
},
|
||||||
input: PipelineDataHeader::ListStream(ListStreamInfo { id: 6 }),
|
input: PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 6,
|
||||||
|
span: Span::test_data(),
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
@ -534,7 +543,10 @@ fn manager_consume_engine_call_response_forwards_to_subscriber_with_pipeline_dat
|
|||||||
|
|
||||||
manager.consume(PluginInput::EngineCallResponse(
|
manager.consume(PluginInput::EngineCallResponse(
|
||||||
0,
|
0,
|
||||||
EngineCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo { id: 0 })),
|
EngineCallResponse::PipelineData(PipelineDataHeader::ListStream(ListStreamInfo {
|
||||||
|
id: 0,
|
||||||
|
span: Span::test_data(),
|
||||||
|
})),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
for i in 0..2 {
|
for i in 0..2 {
|
||||||
@ -590,7 +602,7 @@ fn manager_prepare_pipeline_data_deserializes_custom_values_in_streams() -> Resu
|
|||||||
[Value::test_custom_value(Box::new(
|
[Value::test_custom_value(Box::new(
|
||||||
test_plugin_custom_value(),
|
test_plugin_custom_value(),
|
||||||
))]
|
))]
|
||||||
.into_pipeline_data(None),
|
.into_pipeline_data(Span::test_data(), None),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let value = data
|
let value = data
|
||||||
@ -621,7 +633,8 @@ fn manager_prepare_pipeline_data_embeds_deserialization_errors_in_streams() -> R
|
|||||||
|
|
||||||
let span = Span::new(20, 30);
|
let span = Span::new(20, 30);
|
||||||
let data = manager.prepare_pipeline_data(
|
let data = manager.prepare_pipeline_data(
|
||||||
[Value::custom(Box::new(invalid_custom_value), span)].into_pipeline_data(None),
|
[Value::custom(Box::new(invalid_custom_value), span)]
|
||||||
|
.into_pipeline_data(Span::test_data(), None),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let value = data
|
let value = data
|
||||||
@ -703,7 +716,8 @@ fn interface_write_response_with_stream() -> Result<(), ShellError> {
|
|||||||
|
|
||||||
interface
|
interface
|
||||||
.write_response(Ok::<_, ShellError>(
|
.write_response(Ok::<_, ShellError>(
|
||||||
[Value::test_int(3), Value::test_int(4), Value::test_int(5)].into_pipeline_data(None),
|
[Value::test_int(3), Value::test_int(4), Value::test_int(5)]
|
||||||
|
.into_pipeline_data(Span::test_data(), None),
|
||||||
))?
|
))?
|
||||||
.write()?;
|
.write()?;
|
||||||
|
|
||||||
@ -1105,7 +1119,7 @@ fn interface_prepare_pipeline_data_serializes_custom_values_in_streams() -> Resu
|
|||||||
[Value::test_custom_value(Box::new(
|
[Value::test_custom_value(Box::new(
|
||||||
expected_test_custom_value(),
|
expected_test_custom_value(),
|
||||||
))]
|
))]
|
||||||
.into_pipeline_data(None),
|
.into_pipeline_data(Span::test_data(), None),
|
||||||
&(),
|
&(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -1163,7 +1177,8 @@ fn interface_prepare_pipeline_data_embeds_serialization_errors_in_streams() -> R
|
|||||||
|
|
||||||
let span = Span::new(40, 60);
|
let span = Span::new(40, 60);
|
||||||
let data = interface.prepare_pipeline_data(
|
let data = interface.prepare_pipeline_data(
|
||||||
[Value::custom(Box::new(CantSerialize::BadVariant), span)].into_pipeline_data(None),
|
[Value::custom(Box::new(CantSerialize::BadVariant), span)]
|
||||||
|
.into_pipeline_data(Span::test_data(), None),
|
||||||
&(),
|
&(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user