mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 19:37:45 +02:00
Allow invocations and fix span error reporting.
This commit is contained in:
@ -7,7 +7,7 @@ use nu_protocol::{
|
||||
did_you_mean, ColumnPath, PathMember, Primitive, ReturnSuccess, Signature, SyntaxShape,
|
||||
UnspannedPathMember, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::span_for_spanned_list;
|
||||
use nu_source::HasFallibleSpan;
|
||||
use nu_value_ext::get_data_by_column_path;
|
||||
|
||||
pub struct Get;
|
||||
@ -65,7 +65,7 @@ pub fn get_column_path(path: &ColumnPath, obj: &Value) -> Result<Value, ShellErr
|
||||
obj,
|
||||
path,
|
||||
Box::new(move |(obj_source, column_path_tried, error)| {
|
||||
let path_members_span = span_for_spanned_list(fields.members().iter().map(|p| p.span));
|
||||
let path_members_span = fields.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
match &obj_source.value {
|
||||
UntaggedValue::Table(rows) => match column_path_tried {
|
||||
|
@ -2,11 +2,13 @@ use crate::commands::classified::block::run_block;
|
||||
use crate::commands::WholeStreamCommand;
|
||||
use crate::context::CommandRegistry;
|
||||
use crate::prelude::*;
|
||||
use futures::stream::once;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_value_ext::ValueExt;
|
||||
|
||||
use futures::stream::once;
|
||||
pub struct Insert;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@ -49,14 +51,14 @@ async fn process_row(
|
||||
mut context: Arc<Context>,
|
||||
input: Value,
|
||||
mut value: Arc<Value>,
|
||||
column: Arc<ColumnPath>,
|
||||
field: Arc<ColumnPath>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let value = Arc::make_mut(&mut value);
|
||||
|
||||
Ok(match value {
|
||||
Value {
|
||||
value: UntaggedValue::Block(block),
|
||||
..
|
||||
tag: block_tag,
|
||||
} => {
|
||||
let for_block = input.clone();
|
||||
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
||||
@ -98,35 +100,32 @@ async fn process_row(
|
||||
Value {
|
||||
value: UntaggedValue::Row(_),
|
||||
..
|
||||
} => match obj.insert_data_at_column_path(&column, result) {
|
||||
} => match obj.insert_data_at_column_path(&field, result) {
|
||||
Ok(v) => OutputStream::one(ReturnSuccess::value(v)),
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
},
|
||||
Value { tag, .. } => OutputStream::one(Err(ShellError::labeled_error(
|
||||
_ => OutputStream::one(Err(ShellError::labeled_error(
|
||||
"Unrecognized type in stream",
|
||||
"original value",
|
||||
tag,
|
||||
block_tag.clone(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
}
|
||||
}
|
||||
_ => match input {
|
||||
obj
|
||||
@
|
||||
value => match input {
|
||||
Value {
|
||||
value: UntaggedValue::Row(_),
|
||||
value: UntaggedValue::Primitive(Primitive::Nothing),
|
||||
..
|
||||
} => match obj.insert_data_at_column_path(&column, value.clone()) {
|
||||
} => match scope.it.insert_data_at_column_path(&field, value.clone()) {
|
||||
Ok(v) => OutputStream::one(ReturnSuccess::value(v)),
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
},
|
||||
_ => match input.insert_data_at_column_path(&field, value.clone()) {
|
||||
Ok(v) => OutputStream::one(ReturnSuccess::value(v)),
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
},
|
||||
Value { tag, .. } => OutputStream::one(Err(ShellError::labeled_error(
|
||||
"Unrecognized type in stream",
|
||||
"original value",
|
||||
tag,
|
||||
))),
|
||||
},
|
||||
})
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ use crate::prelude::*;
|
||||
use nu_data::base::select_fields;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Signature, SyntaxShape, Value};
|
||||
use nu_source::span_for_spanned_list;
|
||||
use nu_source::HasFallibleSpan;
|
||||
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -106,7 +106,7 @@ async fn operate(
|
||||
.flatten()
|
||||
.collect::<Vec<&ColumnPath>>();
|
||||
|
||||
let after_span = span_for_spanned_list(after.members().iter().map(|p| p.span));
|
||||
let after_span = after.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
if after.members().len() == 1 {
|
||||
let keys = column_paths
|
||||
@ -154,7 +154,7 @@ async fn operate(
|
||||
.flatten()
|
||||
.collect::<Vec<&ColumnPath>>();
|
||||
|
||||
let before_span = span_for_spanned_list(before.members().iter().map(|p| p.span));
|
||||
let before_span = before.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
if before.members().len() == 1 {
|
||||
let keys = column_paths
|
||||
@ -207,7 +207,7 @@ fn move_after(
|
||||
tag: impl Into<Tag>,
|
||||
) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
let from_fields = span_for_spanned_list(from.members().iter().map(|p| p.span));
|
||||
let from_fields = from.maybe_span().unwrap_or_else(Span::unknown);
|
||||
let from = if let Some((last, _)) = from.split_last() {
|
||||
last.as_string()
|
||||
} else {
|
||||
@ -270,7 +270,7 @@ fn move_before(
|
||||
tag: impl Into<Tag>,
|
||||
) -> Result<Value, ShellError> {
|
||||
let tag = tag.into();
|
||||
let from_fields = span_for_spanned_list(from.members().iter().map(|p| p.span));
|
||||
let from_fields = from.maybe_span().unwrap_or_else(Span::unknown);
|
||||
let from = if let Some((last, _)) = from.split_last() {
|
||||
last.as_string()
|
||||
} else {
|
||||
|
@ -3,7 +3,10 @@ use crate::commands::WholeStreamCommand;
|
||||
use crate::context::CommandRegistry;
|
||||
use crate::prelude::*;
|
||||
use nu_errors::ShellError;
|
||||
use nu_protocol::{ColumnPath, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue, Value};
|
||||
use nu_protocol::{
|
||||
ColumnPath, Primitive, ReturnSuccess, Scope, Signature, SyntaxShape, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::HasFallibleSpan;
|
||||
use nu_value_ext::ValueExt;
|
||||
|
||||
use futures::stream::once;
|
||||
@ -54,13 +57,15 @@ async fn process_row(
|
||||
input: Value,
|
||||
mut replacement: Arc<Value>,
|
||||
field: Arc<ColumnPath>,
|
||||
tag: Arc<Tag>,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let tag = &*tag;
|
||||
let replacement = Arc::make_mut(&mut replacement);
|
||||
|
||||
Ok(match replacement {
|
||||
Value {
|
||||
value: UntaggedValue::Block(block),
|
||||
..
|
||||
tag: block_tag,
|
||||
} => {
|
||||
let for_block = input.clone();
|
||||
let input_stream = once(async { Ok(for_block) }).to_input_stream();
|
||||
@ -110,35 +115,41 @@ async fn process_row(
|
||||
obj.tag,
|
||||
))),
|
||||
},
|
||||
Value { tag, .. } => OutputStream::one(Err(ShellError::labeled_error(
|
||||
_ => OutputStream::one(Err(ShellError::labeled_error(
|
||||
"Unrecognized type in stream",
|
||||
"original value",
|
||||
tag,
|
||||
block_tag.clone(),
|
||||
))),
|
||||
}
|
||||
}
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
}
|
||||
}
|
||||
_ => match input {
|
||||
obj
|
||||
@
|
||||
replacement => match input {
|
||||
Value {
|
||||
value: UntaggedValue::Row(_),
|
||||
value: UntaggedValue::Primitive(Primitive::Nothing),
|
||||
..
|
||||
} => match obj.replace_data_at_column_path(&field, replacement.clone()) {
|
||||
} => match scope
|
||||
.it
|
||||
.replace_data_at_column_path(&field, replacement.clone())
|
||||
{
|
||||
Some(v) => OutputStream::one(ReturnSuccess::value(v)),
|
||||
None => OutputStream::one(Err(ShellError::labeled_error(
|
||||
"update could not find place to insert column",
|
||||
"column name",
|
||||
obj.tag,
|
||||
field.maybe_span().unwrap_or_else(|| tag.span),
|
||||
))),
|
||||
},
|
||||
Value { tag, .. } => OutputStream::one(Err(ShellError::labeled_error(
|
||||
"Unrecognized type in stream",
|
||||
"original value",
|
||||
tag,
|
||||
))),
|
||||
Value { value: _, ref tag } => {
|
||||
match input.replace_data_at_column_path(&field, replacement.clone()) {
|
||||
Some(v) => OutputStream::one(ReturnSuccess::value(v)),
|
||||
None => OutputStream::one(Err(ShellError::labeled_error(
|
||||
"update could not find place to insert column",
|
||||
"column name",
|
||||
field.maybe_span().unwrap_or_else(|| tag.span),
|
||||
))),
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
}
|
||||
@ -148,6 +159,7 @@ async fn update(
|
||||
registry: &CommandRegistry,
|
||||
) -> Result<OutputStream, ShellError> {
|
||||
let registry = registry.clone();
|
||||
let name_tag = Arc::new(raw_args.call_info.name_tag.clone());
|
||||
let scope = Arc::new(raw_args.call_info.scope.clone());
|
||||
let context = Arc::new(Context::from_raw(&raw_args, ®istry));
|
||||
let (UpdateArgs { field, replacement }, input) = raw_args.process(®istry).await?;
|
||||
@ -156,13 +168,14 @@ async fn update(
|
||||
|
||||
Ok(input
|
||||
.then(move |input| {
|
||||
let tag = name_tag.clone();
|
||||
let scope = scope.clone();
|
||||
let context = context.clone();
|
||||
let replacement = replacement.clone();
|
||||
let field = field.clone();
|
||||
|
||||
async {
|
||||
match process_row(scope, context, input, replacement, field).await {
|
||||
match process_row(scope, context, input, replacement, field, tag).await {
|
||||
Ok(s) => s,
|
||||
Err(e) => OutputStream::one(Err(e)),
|
||||
}
|
||||
|
@ -30,3 +30,19 @@ fn sets_the_column_from_a_block_full_stream_output() {
|
||||
|
||||
assert_eq!(actual.out, "true");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sets_the_column_from_an_invocation() {
|
||||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
wrap content
|
||||
| insert content $(open --raw cargo_sample.toml | lines | first 5)
|
||||
| get content.1
|
||||
| str contains "nu"
|
||||
| echo $it
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "true");
|
||||
}
|
||||
|
@ -46,3 +46,19 @@ fn sets_the_column_from_a_block_full_stream_output() {
|
||||
|
||||
assert_eq!(actual.out, "true");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sets_the_column_from_an_invocation() {
|
||||
let actual = nu!(
|
||||
cwd: "tests/fixtures/formats", pipeline(
|
||||
r#"
|
||||
wrap content
|
||||
| update content $(open --raw cargo_sample.toml | lines | first 5)
|
||||
| get content.1
|
||||
| str contains "nu"
|
||||
| echo $it
|
||||
"#
|
||||
));
|
||||
|
||||
assert_eq!(actual.out, "true");
|
||||
}
|
||||
|
@ -5,7 +5,9 @@ use nu_protocol::{
|
||||
ColumnPath, MaybeOwned, PathMember, Primitive, ShellTypeName, SpannedTypeName,
|
||||
UnspannedPathMember, UntaggedValue, Value,
|
||||
};
|
||||
use nu_source::{HasSpan, PrettyDebug, Spanned, SpannedItem, Tag, Tagged, TaggedItem};
|
||||
use nu_source::{
|
||||
HasFallibleSpan, HasSpan, PrettyDebug, Span, Spanned, SpannedItem, Tag, Tagged, TaggedItem,
|
||||
};
|
||||
use num_traits::cast::ToPrimitive;
|
||||
|
||||
pub trait ValueExt {
|
||||
@ -220,8 +222,7 @@ pub fn swap_data_by_column_path(
|
||||
&value,
|
||||
path,
|
||||
Box::new(move |(obj_source, column_path_tried, error)| {
|
||||
let path_members_span =
|
||||
nu_source::span_for_spanned_list(fields.members().iter().map(|p| p.span));
|
||||
let path_members_span = fields.maybe_span().unwrap_or_else(Span::unknown);
|
||||
|
||||
match &obj_source.value {
|
||||
UntaggedValue::Table(rows) => match column_path_tried {
|
||||
|
Reference in New Issue
Block a user