mirror of
https://github.com/nushell/nushell
synced 2024-11-10 23:24:14 +00:00
Another batch of removing async_stream (#1971)
This commit is contained in:
parent
935a5f6b9e
commit
d82ce26b44
12 changed files with 286 additions and 304 deletions
|
@ -26,14 +26,10 @@ impl WholeStreamCommand for Command {
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let stream = async_stream! {
|
Ok(OutputStream::one(Ok(ReturnSuccess::Value(
|
||||||
yield Ok(ReturnSuccess::Value(
|
UntaggedValue::string(crate::commands::help::get_help(&Command, ®istry))
|
||||||
UntaggedValue::string(crate::commands::help::get_help(&Command, ®istry))
|
.into_value(Tag::unknown()),
|
||||||
.into_value(Tag::unknown()),
|
))))
|
||||||
));
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,41 +35,52 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
split_row(args, registry)
|
split_row(args, registry).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_row(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn split_row(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
let stream = async_stream! {
|
let name = args.call_info.name_tag.clone();
|
||||||
let name = args.call_info.name_tag.clone();
|
let (SplitRowArgs { separator }, input) = args.process(®istry).await?;
|
||||||
let (SplitRowArgs { separator }, mut input) = args.process(®istry).await?;
|
Ok(input
|
||||||
while let Some(v) = input.next().await {
|
.flat_map(move |v| {
|
||||||
if let Ok(s) = v.as_string() {
|
if let Ok(s) = v.as_string() {
|
||||||
let splitter = separator.item.replace("\\n", "\n");
|
let splitter = separator.item.replace("\\n", "\n");
|
||||||
trace!("splitting with {:?}", splitter);
|
trace!("splitting with {:?}", splitter);
|
||||||
let split_result: Vec<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
|
let split_result: Vec<String> = s
|
||||||
|
.split(&splitter)
|
||||||
|
.filter_map(|s| {
|
||||||
|
if s.trim() != "" {
|
||||||
|
Some(s.to_string())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
trace!("split result = {:?}", split_result);
|
trace!("split result = {:?}", split_result);
|
||||||
|
|
||||||
for s in split_result {
|
futures::stream::iter(split_result.into_iter().map(move |s| {
|
||||||
yield ReturnSuccess::value(
|
ReturnSuccess::value(
|
||||||
UntaggedValue::Primitive(Primitive::String(s.into())).into_value(&v.tag),
|
UntaggedValue::Primitive(Primitive::String(s)).into_value(&v.tag),
|
||||||
);
|
)
|
||||||
}
|
}))
|
||||||
|
.to_output_stream()
|
||||||
} else {
|
} else {
|
||||||
yield Err(ShellError::labeled_error_with_secondary(
|
OutputStream::one(Err(ShellError::labeled_error_with_secondary(
|
||||||
"Expected a string from pipeline",
|
"Expected a string from pipeline",
|
||||||
"requires string input",
|
"requires string input",
|
||||||
name.span,
|
name.span,
|
||||||
"value originates from here",
|
"value originates from here",
|
||||||
v.tag.span,
|
v.tag.span,
|
||||||
));
|
)))
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -49,47 +49,44 @@ impl WholeStreamCommand for SubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { rest }, mut input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, v.tag()) {
|
match action(&v, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => return Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -49,47 +49,46 @@ impl WholeStreamCommand for SubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { rest }, mut input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, v.tag()) {
|
match action(&v, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
yield Err(err);
|
return Err(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -59,50 +59,49 @@ impl WholeStreamCommand for SubCommand {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Replace(String);
|
struct Replace(String);
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { replace, rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { replace, rest }, mut input) = args.process(®istry).await?;
|
let options = Replace(replace.item);
|
||||||
let options = Replace(replace.item);
|
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, &options, v.tag()) {
|
match action(&v, &options, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let options = options.clone();
|
let options = options.clone();
|
||||||
|
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, &options, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, &options, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
yield Err(err);
|
return Err(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(_input: &Value, options: &Replace, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(_input: &Value, options: &Replace, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -46,7 +46,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -73,91 +73,83 @@ impl WholeStreamCommand for SubCommand {
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
struct Substring(usize, usize);
|
struct Substring(usize, usize);
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let name = args.call_info.name_tag.clone();
|
let name = args.call_info.name_tag.clone();
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { range, rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { range, rest }, mut input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let v: Vec<&str> = range.item.split(',').collect();
|
let v: Vec<&str> = range.item.split(',').collect();
|
||||||
|
|
||||||
let start = match v[0] {
|
let start = match v[0] {
|
||||||
"" => 0,
|
"" => 0,
|
||||||
_ => v[0]
|
_ => v[0].trim().parse().map_err(|_| {
|
||||||
.trim()
|
ShellError::labeled_error(
|
||||||
.parse()
|
"could not perform substring",
|
||||||
.map_err(|_| {
|
"could not perform substring",
|
||||||
ShellError::labeled_error(
|
|
||||||
"could not perform substring",
|
|
||||||
"could not perform substring",
|
|
||||||
name.span,
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
let end = match v[1] {
|
|
||||||
"" => usize::max_value(),
|
|
||||||
_ => v[1]
|
|
||||||
.trim()
|
|
||||||
.parse()
|
|
||||||
.map_err(|_| {
|
|
||||||
ShellError::labeled_error(
|
|
||||||
"could not perform substring",
|
|
||||||
"could not perform substring",
|
|
||||||
name.span,
|
|
||||||
)
|
|
||||||
})?
|
|
||||||
};
|
|
||||||
|
|
||||||
if start > end {
|
|
||||||
yield Err(ShellError::labeled_error(
|
|
||||||
"End must be greater than or equal to Start",
|
|
||||||
"End must be greater than or equal to Start",
|
|
||||||
name.span,
|
name.span,
|
||||||
));
|
)
|
||||||
return;
|
})?,
|
||||||
}
|
};
|
||||||
|
|
||||||
let options = Substring(start, end);
|
let end = match v[1] {
|
||||||
|
"" => usize::max_value(),
|
||||||
|
_ => v[1].trim().parse().map_err(|_| {
|
||||||
|
ShellError::labeled_error(
|
||||||
|
"could not perform substring",
|
||||||
|
"could not perform substring",
|
||||||
|
name.span,
|
||||||
|
)
|
||||||
|
})?,
|
||||||
|
};
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
if start > end {
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"End must be greater than or equal to Start",
|
||||||
|
"End must be greater than or equal to Start",
|
||||||
|
name.span,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
let options = Substring(start, end);
|
||||||
|
|
||||||
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, &options, v.tag()) {
|
match action(&v, &options, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let options = options.clone();
|
let options = options.clone();
|
||||||
|
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, &options, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, &options, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
yield Err(err);
|
return Err(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: &Value, options: &Substring, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(input: &Value, options: &Substring, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -52,47 +52,46 @@ impl WholeStreamCommand for SubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { rest }, mut input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, v.tag()) {
|
match action(&v, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
yield Err(err);
|
return Err(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -40,7 +40,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -52,47 +52,46 @@ impl WholeStreamCommand for SubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { rest }, mut input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, v.tag()) {
|
match action(&v, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
yield Err(err);
|
return Err(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -37,7 +37,7 @@ impl WholeStreamCommand for SubCommand {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
operate(args, registry)
|
operate(args, registry).await
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -49,47 +49,46 @@ impl WholeStreamCommand for SubCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn operate(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn operate(
|
||||||
|
args: CommandArgs,
|
||||||
|
registry: &CommandRegistry,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (Arguments { rest }, input) = args.process(®istry).await?;
|
||||||
let (Arguments { rest }, mut input) = args.process(®istry).await?;
|
|
||||||
|
|
||||||
let column_paths: Vec<_> = rest.iter().map(|x| x.clone()).collect();
|
let column_paths: Vec<_> = rest;
|
||||||
|
|
||||||
while let Some(v) = input.next().await {
|
Ok(input
|
||||||
|
.map(move |v| {
|
||||||
if column_paths.is_empty() {
|
if column_paths.is_empty() {
|
||||||
match action(&v, v.tag()) {
|
match action(&v, v.tag()) {
|
||||||
Ok(out) => yield ReturnSuccess::value(out),
|
Ok(out) => ReturnSuccess::value(out),
|
||||||
Err(err) => {
|
Err(err) => Err(err),
|
||||||
yield Err(err);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
let mut ret = v;
|
||||||
let mut ret = v.clone();
|
|
||||||
|
|
||||||
for path in &column_paths {
|
for path in &column_paths {
|
||||||
let swapping = ret.swap_data_by_column_path(path, Box::new(move |old| action(old, old.tag())));
|
let swapping = ret.swap_data_by_column_path(
|
||||||
|
path,
|
||||||
|
Box::new(move |old| action(old, old.tag())),
|
||||||
|
);
|
||||||
|
|
||||||
match swapping {
|
match swapping {
|
||||||
Ok(new_value) => {
|
Ok(new_value) => {
|
||||||
ret = new_value;
|
ret = new_value;
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
yield Err(err);
|
return Err(err);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield ReturnSuccess::value(ret);
|
ReturnSuccess::value(ret)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
};
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
fn action(input: &Value, tag: impl Into<Tag>) -> Result<Value, ShellError> {
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::commands::WholeStreamCommand;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use nu_errors::ShellError;
|
use nu_errors::ShellError;
|
||||||
use nu_protocol::{ReturnSuccess, ReturnValue, Signature, UntaggedValue};
|
use nu_protocol::{ReturnSuccess, Signature, UntaggedValue};
|
||||||
|
|
||||||
pub struct What;
|
pub struct What;
|
||||||
|
|
||||||
|
@ -28,23 +28,23 @@ impl WholeStreamCommand for What {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
// args.process(registry, what)?.run()
|
what(args, registry).await
|
||||||
what(args, registry)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn what(args: CommandArgs, _registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
pub async fn what(
|
||||||
let stream = async_stream! {
|
args: CommandArgs,
|
||||||
let mut input = args.input;
|
_registry: &CommandRegistry,
|
||||||
while let Some(row) = input.next().await {
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
Ok(args
|
||||||
|
.input
|
||||||
|
.map(|row| {
|
||||||
let name = value::format_type(&row, 100);
|
let name = value::format_type(&row, 100);
|
||||||
yield ReturnSuccess::value(UntaggedValue::string(name).into_value(Tag::unknown_anchor(row.tag.span)));
|
ReturnSuccess::value(
|
||||||
}
|
UntaggedValue::string(name).into_value(Tag::unknown_anchor(row.tag.span)),
|
||||||
};
|
)
|
||||||
|
})
|
||||||
let stream: BoxStream<'static, ReturnValue> = stream.boxed();
|
.to_output_stream())
|
||||||
|
|
||||||
Ok(OutputStream::from(stream))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -38,8 +38,7 @@ impl WholeStreamCommand for Wrap {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
// args.process(registry, wrap)?.run()
|
wrap(args, registry).await
|
||||||
wrap(args, registry)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn examples(&self) -> Vec<Example> {
|
fn examples(&self) -> Vec<Example> {
|
||||||
|
@ -84,64 +83,57 @@ impl WholeStreamCommand for Wrap {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn wrap(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
async fn wrap(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
||||||
let registry = registry.clone();
|
let registry = registry.clone();
|
||||||
|
|
||||||
let stream = async_stream! {
|
let (WrapArgs { column }, mut input) = args.process(®istry).await?;
|
||||||
let (WrapArgs { column }, mut input) = args.process(®istry).await?;
|
let mut result_table = vec![];
|
||||||
let mut result_table = vec![];
|
let mut are_all_rows = true;
|
||||||
let mut are_all_rows = true;
|
|
||||||
|
|
||||||
while let Some(value) = input.next().await {
|
while let Some(value) = input.next().await {
|
||||||
match value {
|
match value {
|
||||||
Value {
|
Value {
|
||||||
value: UntaggedValue::Row(_),
|
value: UntaggedValue::Row(_),
|
||||||
..
|
..
|
||||||
} => {
|
} => {
|
||||||
result_table.push(value);
|
result_table.push(value);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
are_all_rows = false;
|
are_all_rows = false;
|
||||||
|
|
||||||
let mut index_map = IndexMap::new();
|
let mut index_map = IndexMap::new();
|
||||||
index_map.insert(
|
index_map.insert(
|
||||||
match &column {
|
match &column {
|
||||||
Some(key) => key.item.clone(),
|
Some(key) => key.item.clone(),
|
||||||
None => DEFAULT_COLUMN_NAME.to_string(),
|
None => DEFAULT_COLUMN_NAME.to_string(),
|
||||||
},
|
},
|
||||||
value,
|
value,
|
||||||
);
|
);
|
||||||
|
|
||||||
result_table.push(UntaggedValue::row(index_map).into_value(Tag::unknown()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
result_table.push(UntaggedValue::row(index_map).into_value(Tag::unknown()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if are_all_rows {
|
if are_all_rows {
|
||||||
let mut index_map = IndexMap::new();
|
let mut index_map = IndexMap::new();
|
||||||
index_map.insert(
|
index_map.insert(
|
||||||
match &column {
|
match &column {
|
||||||
Some(key) => key.item.clone(),
|
Some(key) => key.item.clone(),
|
||||||
None => DEFAULT_COLUMN_NAME.to_string(),
|
None => DEFAULT_COLUMN_NAME.to_string(),
|
||||||
},
|
},
|
||||||
UntaggedValue::table(&result_table).into_value(Tag::unknown()),
|
UntaggedValue::table(&result_table).into_value(Tag::unknown()),
|
||||||
);
|
);
|
||||||
|
|
||||||
let row = UntaggedValue::row(index_map).into_untagged_value();
|
let row = UntaggedValue::row(index_map).into_untagged_value();
|
||||||
|
|
||||||
yield ReturnSuccess::value(row);
|
Ok(OutputStream::one(ReturnSuccess::value(row)))
|
||||||
} else {
|
} else {
|
||||||
for item in result_table
|
Ok(
|
||||||
.iter()
|
futures::stream::iter(result_table.into_iter().map(ReturnSuccess::value))
|
||||||
.map(|row| ReturnSuccess::value(row.clone())) {
|
.to_output_stream(),
|
||||||
|
)
|
||||||
yield item;
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
@ -562,54 +562,54 @@ impl Shell for FilesystemShell {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let stream = async_stream! {
|
Ok(
|
||||||
for (f, tag) in all_targets.iter() {
|
futures::stream::iter(all_targets.into_iter().map(move |(f, tag)| {
|
||||||
let is_empty = || match f.read_dir() {
|
let is_empty = || match f.read_dir() {
|
||||||
Ok(mut p) => p.next().is_none(),
|
Ok(mut p) => p.next().is_none(),
|
||||||
Err(_) => false
|
Err(_) => false,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Ok(metadata) = f.symlink_metadata() {
|
if let Ok(metadata) = f.symlink_metadata() {
|
||||||
if metadata.is_file() || metadata.file_type().is_symlink() || recursive.item || is_empty() {
|
if metadata.is_file()
|
||||||
|
|| metadata.file_type().is_symlink()
|
||||||
|
|| recursive.item
|
||||||
|
|| is_empty()
|
||||||
|
{
|
||||||
let result;
|
let result;
|
||||||
#[cfg(feature = "trash-support")]
|
#[cfg(feature = "trash-support")]
|
||||||
{
|
{
|
||||||
let rm_always_trash = config::config(Tag::unknown())?.get("rm_always_trash").map(|val| val.is_true()).unwrap_or(false);
|
let rm_always_trash = config::config(Tag::unknown())?
|
||||||
|
.get("rm_always_trash")
|
||||||
|
.map(|val| val.is_true())
|
||||||
|
.unwrap_or(false);
|
||||||
result = if _trash.item || (rm_always_trash && !_permanent.item) {
|
result = if _trash.item || (rm_always_trash && !_permanent.item) {
|
||||||
trash::remove(f)
|
trash::remove(&f).map_err(|_| f.to_string_lossy())
|
||||||
.map_err(|e| f.to_string_lossy())
|
|
||||||
} else if metadata.is_file() {
|
} else if metadata.is_file() {
|
||||||
std::fs::remove_file(f)
|
std::fs::remove_file(&f).map_err(|_| f.to_string_lossy())
|
||||||
.map_err(|e| f.to_string_lossy())
|
|
||||||
} else {
|
} else {
|
||||||
std::fs::remove_dir_all(f)
|
std::fs::remove_dir_all(&f).map_err(|_| f.to_string_lossy())
|
||||||
.map_err(|e| f.to_string_lossy())
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "trash-support"))]
|
#[cfg(not(feature = "trash-support"))]
|
||||||
{
|
{
|
||||||
result = if metadata.is_file() {
|
result = if metadata.is_file() {
|
||||||
std::fs::remove_file(f)
|
std::fs::remove_file(&f).map_err(|_| f.to_string_lossy())
|
||||||
.map_err(|e| f.to_string_lossy())
|
|
||||||
} else {
|
} else {
|
||||||
std::fs::remove_dir_all(f)
|
std::fs::remove_dir_all(&f).map_err(|_| f.to_string_lossy())
|
||||||
.map_err(|e| f.to_string_lossy())
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(e) = result {
|
if let Err(e) = result {
|
||||||
let msg = format!("Could not delete {:}", e);
|
let msg = format!("Could not delete {:}", e);
|
||||||
yield Err(ShellError::labeled_error(msg, e, tag))
|
Err(ShellError::labeled_error(msg, e, tag))
|
||||||
} else {
|
} else {
|
||||||
let val = format!("deleted {:}", f.to_string_lossy()).into();
|
let val = format!("deleted {:}", f.to_string_lossy()).into();
|
||||||
yield Ok(ReturnSuccess::Value(val))
|
Ok(ReturnSuccess::Value(val))
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = format!(
|
let msg =
|
||||||
"Cannot remove {:}. try --recursive",
|
format!("Cannot remove {:}. try --recursive", f.to_string_lossy());
|
||||||
f.to_string_lossy()
|
Err(ShellError::labeled_error(
|
||||||
);
|
|
||||||
yield Err(ShellError::labeled_error(
|
|
||||||
msg,
|
msg,
|
||||||
"cannot remove non-empty directory",
|
"cannot remove non-empty directory",
|
||||||
tag,
|
tag,
|
||||||
|
@ -617,16 +617,15 @@ impl Shell for FilesystemShell {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let msg = format!("no such file or directory: {:}", f.to_string_lossy());
|
let msg = format!("no such file or directory: {:}", f.to_string_lossy());
|
||||||
yield Err(ShellError::labeled_error(
|
Err(ShellError::labeled_error(
|
||||||
msg,
|
msg,
|
||||||
"no such file or directory",
|
"no such file or directory",
|
||||||
tag,
|
tag,
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}))
|
||||||
};
|
.to_output_stream(),
|
||||||
|
)
|
||||||
Ok(stream.to_output_stream())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn path(&self) -> String {
|
fn path(&self) -> String {
|
||||||
|
|
Loading…
Reference in a new issue