mirror of
https://github.com/nushell/nushell
synced 2024-12-29 06:23:11 +00:00
Use args structs to better extract multiple arguments
This commit is contained in:
parent
9951691023
commit
31790a9906
4 changed files with 55 additions and 57 deletions
|
@ -4,6 +4,11 @@ use crate::errors::ShellError;
|
||||||
use crate::object::base::select_fields;
|
use crate::object::base::select_fields;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct PickArgs {
|
||||||
|
rest: Vec<Tagged<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Pick;
|
pub struct Pick;
|
||||||
|
|
||||||
impl WholeStreamCommand for Pick {
|
impl WholeStreamCommand for Pick {
|
||||||
|
@ -12,7 +17,7 @@ impl WholeStreamCommand for Pick {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
pick(args, registry)
|
args.process(registry, pick)?.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -20,22 +25,15 @@ impl WholeStreamCommand for Pick {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("pick").required("fields", SyntaxType::Any)
|
Signature::build("pick").rest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pick(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
fn pick(
|
||||||
let args = args.evaluate_once(registry)?;
|
PickArgs { rest: fields }: PickArgs,
|
||||||
let (input, args) = args.parts();
|
RunnableContext { input, .. }: RunnableContext,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let fields: Result<Vec<String>, _> = args
|
let fields: Vec<_> = fields.iter().map(|f| f.item.clone()).collect();
|
||||||
.positional
|
|
||||||
.iter()
|
|
||||||
.flatten()
|
|
||||||
.map(|a| a.as_string())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let fields = fields?;
|
|
||||||
|
|
||||||
let objects = input
|
let objects = input
|
||||||
.values
|
.values
|
||||||
|
|
|
@ -3,6 +3,11 @@ use crate::errors::ShellError;
|
||||||
use crate::object::base::reject_fields;
|
use crate::object::base::reject_fields;
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
pub struct RejectArgs {
|
||||||
|
rest: Vec<Tagged<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct Reject;
|
pub struct Reject;
|
||||||
|
|
||||||
impl WholeStreamCommand for Reject {
|
impl WholeStreamCommand for Reject {
|
||||||
|
@ -11,7 +16,7 @@ impl WholeStreamCommand for Reject {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
reject(args, registry)
|
args.process(registry, reject)?.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -19,22 +24,15 @@ impl WholeStreamCommand for Reject {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
Signature::build("reject").required("fields", SyntaxType::Any)
|
Signature::build("reject").rest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reject(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
fn reject(
|
||||||
let args = args.evaluate_once(registry)?;
|
RejectArgs { rest: fields }: RejectArgs,
|
||||||
let (input, args) = args.parts();
|
RunnableContext { input, .. }: RunnableContext,
|
||||||
|
) -> Result<OutputStream, ShellError> {
|
||||||
let fields: Result<Vec<String>, _> = args
|
let fields: Vec<_> = fields.iter().map(|f| f.item.clone()).collect();
|
||||||
.positional
|
|
||||||
.iter()
|
|
||||||
.flatten()
|
|
||||||
.map(|a| a.as_string())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let fields = fields?;
|
|
||||||
|
|
||||||
let stream = input
|
let stream = input
|
||||||
.values
|
.values
|
||||||
|
|
|
@ -4,6 +4,11 @@ use crate::object::{Primitive, TaggedDictBuilder, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct SplitColumnArgs {
|
||||||
|
rest: Vec<Tagged<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SplitColumn;
|
pub struct SplitColumn;
|
||||||
|
|
||||||
impl WholeStreamCommand for SplitColumn {
|
impl WholeStreamCommand for SplitColumn {
|
||||||
|
@ -12,7 +17,7 @@ impl WholeStreamCommand for SplitColumn {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
split_column(args, registry)
|
args.process(registry, split_column)?.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -20,26 +25,25 @@ impl WholeStreamCommand for SplitColumn {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
// TODO: Signature?
|
|
||||||
// TODO: Improve error. Old error had extra info:
|
// TODO: Improve error. Old error had extra info:
|
||||||
//
|
//
|
||||||
// needs parameter (e.g. split-column ",")
|
// needs parameter (e.g. split-column ",")
|
||||||
Signature::build("split-column").required("delimeter", SyntaxType::Any)
|
Signature::build("split-column").rest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_column(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
fn split_column(
|
||||||
let args = args.evaluate_once(registry)?;
|
SplitColumnArgs { rest: positional }: SplitColumnArgs,
|
||||||
let span = args.name_span();
|
RunnableContext { input, name, .. }: RunnableContext,
|
||||||
let (input, args) = args.parts();
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
|
||||||
let positional: Vec<_> = args.positional.iter().flatten().cloned().collect();
|
|
||||||
|
|
||||||
Ok(input
|
Ok(input
|
||||||
.values
|
.values
|
||||||
.map(move |v| match v.item {
|
.map(move |v| match v.item {
|
||||||
Value::Primitive(Primitive::String(ref s)) => {
|
Value::Primitive(Primitive::String(ref s)) => {
|
||||||
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n");
|
let positional: Vec<_> = positional.iter().map(|f| f.item.clone()).collect();
|
||||||
|
|
||||||
|
// TODO: Require at least 1 positional argument.
|
||||||
|
let splitter = positional[0].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<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
|
||||||
|
|
||||||
|
@ -61,16 +65,13 @@ fn split_column(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputS
|
||||||
} else if split_result.len() == (positional.len() - 1) {
|
} else if split_result.len() == (positional.len() - 1) {
|
||||||
let mut dict = TaggedDictBuilder::new(v.tag());
|
let mut dict = TaggedDictBuilder::new(v.tag());
|
||||||
for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) {
|
for (&k, v) in split_result.iter().zip(positional.iter().skip(1)) {
|
||||||
dict.insert(
|
dict.insert(v, Value::Primitive(Primitive::String(k.into())));
|
||||||
v.as_string().unwrap(),
|
|
||||||
Value::Primitive(Primitive::String(k.into())),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
ReturnSuccess::value(dict.into_tagged_value())
|
ReturnSuccess::value(dict.into_tagged_value())
|
||||||
} else {
|
} else {
|
||||||
let mut dict = TaggedDictBuilder::new(v.tag());
|
let mut dict = TaggedDictBuilder::new(v.tag());
|
||||||
for k in positional.iter().skip(1) {
|
for k in positional.iter().skip(1) {
|
||||||
dict.insert(k.as_string().unwrap().trim(), Primitive::String("".into()));
|
dict.insert(k.trim(), Primitive::String("".into()));
|
||||||
}
|
}
|
||||||
ReturnSuccess::value(dict.into_tagged_value())
|
ReturnSuccess::value(dict.into_tagged_value())
|
||||||
}
|
}
|
||||||
|
@ -78,7 +79,7 @@ fn split_column(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputS
|
||||||
_ => Err(ShellError::labeled_error_with_secondary(
|
_ => Err(ShellError::labeled_error_with_secondary(
|
||||||
"Expected a string from pipeline",
|
"Expected a string from pipeline",
|
||||||
"requires string input",
|
"requires string input",
|
||||||
span,
|
name,
|
||||||
"value originates from here",
|
"value originates from here",
|
||||||
v.span(),
|
v.span(),
|
||||||
)),
|
)),
|
||||||
|
|
|
@ -4,6 +4,11 @@ use crate::object::{Primitive, Value};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
|
|
||||||
|
#[derive(Deserialize)]
|
||||||
|
struct SplitRowArgs {
|
||||||
|
rest: Vec<Tagged<String>>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct SplitRow;
|
pub struct SplitRow;
|
||||||
|
|
||||||
impl WholeStreamCommand for SplitRow {
|
impl WholeStreamCommand for SplitRow {
|
||||||
|
@ -12,7 +17,7 @@ impl WholeStreamCommand for SplitRow {
|
||||||
args: CommandArgs,
|
args: CommandArgs,
|
||||||
registry: &CommandRegistry,
|
registry: &CommandRegistry,
|
||||||
) -> Result<OutputStream, ShellError> {
|
) -> Result<OutputStream, ShellError> {
|
||||||
split_row(args, registry)
|
args.process(registry, split_row)?.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn name(&self) -> &str {
|
fn name(&self) -> &str {
|
||||||
|
@ -20,26 +25,22 @@ impl WholeStreamCommand for SplitRow {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn signature(&self) -> Signature {
|
fn signature(&self) -> Signature {
|
||||||
// TODO: Signature?
|
|
||||||
// TODO: Improve error. Old error had extra info:
|
// TODO: Improve error. Old error had extra info:
|
||||||
//
|
//
|
||||||
// needs parameter (e.g. split-row ",")
|
// needs parameter (e.g. split-row ",")
|
||||||
Signature::build("split-row").required("delimeter", SyntaxType::Any)
|
Signature::build("split-row").rest()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn split_row(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStream, ShellError> {
|
fn split_row(
|
||||||
let args = args.evaluate_once(registry)?;
|
SplitRowArgs { rest: positional }: SplitRowArgs,
|
||||||
let span = args.name_span();
|
RunnableContext { input, name, .. }: RunnableContext,
|
||||||
let (input, args) = args.parts();
|
) -> Result<OutputStream, ShellError> {
|
||||||
|
|
||||||
let positional: Vec<Tagged<Value>> = args.positional.iter().flatten().cloned().collect();
|
|
||||||
|
|
||||||
let stream = input
|
let stream = input
|
||||||
.values
|
.values
|
||||||
.map(move |v| match v.item {
|
.map(move |v| match v.item {
|
||||||
Value::Primitive(Primitive::String(ref s)) => {
|
Value::Primitive(Primitive::String(ref s)) => {
|
||||||
let splitter = positional[0].as_string().unwrap().replace("\\n", "\n");
|
let splitter = positional[0].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<_> = s.split(&splitter).filter(|s| s.trim() != "").collect();
|
||||||
|
|
||||||
|
@ -58,7 +59,7 @@ fn split_row(args: CommandArgs, registry: &CommandRegistry) -> Result<OutputStre
|
||||||
result.push_back(Err(ShellError::labeled_error_with_secondary(
|
result.push_back(Err(ShellError::labeled_error_with_secondary(
|
||||||
"Expected a string from pipeline",
|
"Expected a string from pipeline",
|
||||||
"requires string input",
|
"requires string input",
|
||||||
span,
|
name,
|
||||||
"value originates from here",
|
"value originates from here",
|
||||||
v.span(),
|
v.span(),
|
||||||
)));
|
)));
|
||||||
|
|
Loading…
Reference in a new issue