Allow different names for ...rest (#3954)

* Allow different names for ...rest

* Resolves #3945

* This change requires an explicit name for the rest argument in `WholeStreamCommand`,
  which is why there are so many changed files.

* Remove redundant clone

* Add tests
This commit is contained in:
Hristo Filaretov 2021-08-26 19:58:53 +02:00 committed by GitHub
parent 88817a8f10
commit b8e2bdd6b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
97 changed files with 270 additions and 87 deletions

View file

@ -22,6 +22,7 @@ impl WholeStreamCommand for Histogram {
None,
)
.rest(
"rest",
SyntaxShape::ColumnPath,
"column name to give the histogram's frequency column",
)

View file

@ -13,6 +13,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into binary").rest(
"rest",
SyntaxShape::ColumnPath,
"column paths to convert to binary (for table input)",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into path").rest(
"rest",
SyntaxShape::ColumnPath,
"column paths to convert to filepath (for table input)",
)

View file

@ -13,6 +13,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into int").rest(
"rest",
SyntaxShape::ColumnPath,
"column paths to convert to int (for table input)",
)

View file

@ -20,6 +20,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into string")
.rest(
"rest",
SyntaxShape::ColumnPath,
"column paths to convert to string (for table input)",
)

View file

@ -15,7 +15,7 @@ impl WholeStreamCommand for Alias {
Signature::build("alias")
.required("name", SyntaxShape::String, "the name of the alias")
.required("equals", SyntaxShape::String, "the equals sign")
.rest(SyntaxShape::Any, "the expansion for the alias")
.rest("rest", SyntaxShape::Any, "the expansion for the alias")
}
fn usage(&self) -> &str {

View file

@ -27,7 +27,7 @@ impl WholeStreamCommand for Do {
"ignore errors as the block runs",
Some('i'),
)
.rest(SyntaxShape::Any, "the parameter(s) for the block")
.rest("rest", SyntaxShape::Any, "the parameter(s) for the block")
}
fn usage(&self) -> &str {

View file

@ -12,7 +12,7 @@ impl WholeStreamCommand for Echo {
}
fn signature(&self) -> Signature {
Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")
Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")
}
fn usage(&self) -> &str {

View file

@ -18,7 +18,11 @@ impl WholeStreamCommand for Help {
fn signature(&self) -> Signature {
Signature::build("help")
.rest(SyntaxShape::String, "the name of command to get help on")
.rest(
"rest",
SyntaxShape::String,
"the name of command to get help on",
)
.named(
"find",
SyntaxShape::String,

View file

@ -41,7 +41,7 @@ impl WholeStreamCommand for Command {
"custom configuration source file",
None,
)
.rest(SyntaxShape::String, "source file(s) to run")
.rest("rest", SyntaxShape::String, "source file(s) to run")
}
fn usage(&self) -> &str {

View file

@ -20,7 +20,11 @@ impl WholeStreamCommand for DataFrame {
}
fn signature(&self) -> Signature {
Signature::build("dataframe drop").rest(SyntaxShape::Any, "column names to be dropped")
Signature::build("dataframe drop").rest(
"rest",
SyntaxShape::Any,
"column names to be dropped",
)
}
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -19,7 +19,11 @@ impl WholeStreamCommand for DataFrame {
}
fn signature(&self) -> Signature {
Signature::build("dataframe get").rest(SyntaxShape::Any, "column names to sort dataframe")
Signature::build("dataframe get").rest(
"rest",
SyntaxShape::Any,
"column names to sort dataframe",
)
}
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -20,7 +20,7 @@ impl WholeStreamCommand for DataFrame {
}
fn signature(&self) -> Signature {
Signature::build("dataframe group-by").rest(SyntaxShape::Any, "groupby columns")
Signature::build("dataframe group-by").rest("rest", SyntaxShape::Any, "groupby columns")
}
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -20,7 +20,7 @@ impl WholeStreamCommand for DataFrame {
}
fn signature(&self) -> Signature {
Signature::build("dataframe select").rest(SyntaxShape::Any, "selected column names")
Signature::build("dataframe select").rest("rest", SyntaxShape::Any, "selected column names")
}
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -21,7 +21,7 @@ impl WholeStreamCommand for DataFrame {
fn signature(&self) -> Signature {
Signature::build("dataframe sort")
.switch("reverse", "invert sort", Some('r'))
.rest(SyntaxShape::Any, "column names to sort dataframe")
.rest("rest", SyntaxShape::Any, "column names to sort dataframe")
}
fn run(&self, args: CommandArgs) -> Result<OutputStream, ShellError> {

View file

@ -12,6 +12,7 @@ impl WholeStreamCommand for Mkdir {
fn signature(&self) -> Signature {
Signature::build("mkdir")
.rest(
"rest",
SyntaxShape::FilePath,
"the name(s) of the path(s) to create",
)

View file

@ -26,7 +26,11 @@ impl WholeStreamCommand for Remove {
)
.switch("recursive", "delete subdirectories recursively", Some('r'))
.switch("force", "suppress error when no file", Some('f'))
.rest(SyntaxShape::GlobPattern, "the file path(s) to remove")
.rest(
"rest",
SyntaxShape::GlobPattern,
"the file path(s) to remove",
)
}
fn usage(&self) -> &str {

View file

@ -19,7 +19,7 @@ impl WholeStreamCommand for Touch {
SyntaxShape::FilePath,
"the path of the file you want to create",
)
.rest(SyntaxShape::FilePath, "additional files to create")
.rest("rest", SyntaxShape::FilePath, "additional files to create")
}
fn usage(&self) -> &str {
"Creates one or more files."

View file

@ -17,7 +17,11 @@ impl WholeStreamCommand for Compact {
}
fn signature(&self) -> Signature {
Signature::build("compact").rest(SyntaxShape::Any, "the columns to compact from the table")
Signature::build("compact").rest(
"rest",
SyntaxShape::Any,
"the columns to compact from the table",
)
}
fn usage(&self) -> &str {

View file

@ -18,7 +18,7 @@ impl WholeStreamCommand for SubCommand {
SyntaxShape::Int,
"the number of the row to drop",
)
.rest(SyntaxShape::Any, "Optionally drop more rows")
.rest("rest", SyntaxShape::Any, "Optionally drop more rows")
}
fn usage(&self) -> &str {

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("empty?")
.rest(
"rest",
SyntaxShape::ColumnPath,
"the names of the columns to check emptiness",
)

View file

@ -14,7 +14,11 @@ impl WholeStreamCommand for Command {
}
fn signature(&self) -> Signature {
Signature::build("flatten").rest(SyntaxShape::String, "optionally flatten data by column")
Signature::build("flatten").rest(
"rest",
SyntaxShape::String,
"optionally flatten data by column",
)
}
fn usage(&self) -> &str {

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("get").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally return additional data by path",
)

View file

@ -14,7 +14,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("move")
.rest(SyntaxShape::ColumnPath, "the columns to move")
.rest("rest", SyntaxShape::ColumnPath, "the columns to move")
.named(
"after",
SyntaxShape::ColumnPath,

View file

@ -18,7 +18,7 @@ impl WholeStreamCommand for Nth {
SyntaxShape::Int,
"the number of the row to return",
)
.rest(SyntaxShape::Any, "Optionally return more rows")
.rest("rest", SyntaxShape::Any, "Optionally return more rows")
.switch("skip", "Skip the rows instead of selecting them", Some('s'))
}

View file

@ -36,6 +36,7 @@ impl WholeStreamCommand for Pivot {
Some('i'),
)
.rest(
"rest",
SyntaxShape::String,
"the names to give columns once pivoted",
)

View file

@ -13,7 +13,11 @@ impl WholeStreamCommand for Reject {
}
fn signature(&self) -> Signature {
Signature::build("reject").rest(SyntaxShape::String, "the names of columns to remove")
Signature::build("reject").rest(
"rest",
SyntaxShape::String,
"the names of columns to remove",
)
}
fn usage(&self) -> &str {

View file

@ -19,7 +19,11 @@ impl WholeStreamCommand for Rename {
SyntaxShape::String,
"the new name for the first column",
)
.rest(SyntaxShape::String, "the new name for additional columns")
.rest(
"rest",
SyntaxShape::String,
"the new name for additional columns",
)
}
fn usage(&self) -> &str {

View file

@ -17,6 +17,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("rotate").rest(
"rest",
SyntaxShape::String,
"the names to give columns once rotated",
)

View file

@ -17,6 +17,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("rotate counter-clockwise").rest(
"rest",
SyntaxShape::String,
"the names to give columns once rotated",
)

View file

@ -16,6 +16,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("select").rest(
"rest",
SyntaxShape::ColumnPath,
"the columns to select from the table",
)

View file

@ -21,7 +21,7 @@ impl WholeStreamCommand for SortBy {
Some('i'),
)
.switch("reverse", "Sort in reverse order", Some('r'))
.rest(SyntaxShape::String, "the column(s) to sort by")
.rest("rest", SyntaxShape::String, "the column(s) to sort by")
}
fn usage(&self) -> &str {

View file

@ -45,6 +45,7 @@ impl WholeStreamCommand for SubCommand {
"decode the input from base64",
Some('d'))
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally base64 encode / decode data by column paths",
)

View file

@ -12,6 +12,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("hash").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert by column paths",
)

View file

@ -38,6 +38,7 @@ where
fn signature(&self) -> Signature {
Signature::build(self.name()).rest(
"rest",
SyntaxShape::ColumnPath,
format!("optionally {} encode data by column paths", D::name()),
)

View file

@ -15,7 +15,7 @@ impl WholeStreamCommand for Seq {
fn signature(&self) -> Signature {
Signature::build("seq")
.rest(SyntaxShape::Number, "sequence values")
.rest("rest", SyntaxShape::Number, "sequence values")
.named(
"separator",
SyntaxShape::String,

View file

@ -14,8 +14,11 @@ impl WholeStreamCommand for UrlHost {
}
fn signature(&self) -> Signature {
Signature::build("url host")
.rest(SyntaxShape::ColumnPath, "optionally operate by column path")
Signature::build("url host").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -14,8 +14,11 @@ impl WholeStreamCommand for UrlPath {
}
fn signature(&self) -> Signature {
Signature::build("url path")
.rest(SyntaxShape::ColumnPath, "optionally operate by column path")
Signature::build("url path").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -14,8 +14,11 @@ impl WholeStreamCommand for UrlQuery {
}
fn signature(&self) -> Signature {
Signature::build("url query")
.rest(SyntaxShape::ColumnPath, "optionally operate by column path")
Signature::build("url query").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -14,7 +14,11 @@ impl WholeStreamCommand for UrlScheme {
}
fn signature(&self) -> Signature {
Signature::build("url scheme").rest(SyntaxShape::ColumnPath, "optionally operate by path")
Signature::build("url scheme").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally operate by path",
)
}
fn usage(&self) -> &str {

View file

@ -26,7 +26,11 @@ impl WholeStreamCommand for PathBasename {
fn signature(&self) -> Signature {
Signature::build("path basename")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
.rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named(
"replace",
SyntaxShape::String,

View file

@ -27,7 +27,11 @@ impl WholeStreamCommand for PathDirname {
fn signature(&self) -> Signature {
Signature::build("path dirname")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
.rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named(
"replace",
SyntaxShape::String,

View file

@ -23,8 +23,11 @@ impl WholeStreamCommand for PathExists {
}
fn signature(&self) -> Signature {
Signature::build("path exists")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
Signature::build("path exists").rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -32,7 +32,11 @@ impl WholeStreamCommand for PathExpand {
"Throw an error if the path could not be expanded",
Some('s'),
)
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
.rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -26,7 +26,11 @@ impl WholeStreamCommand for PathJoin {
fn signature(&self) -> Signature {
Signature::build("path join")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
.rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named(
"append",
SyntaxShape::FilePath,

View file

@ -28,7 +28,11 @@ impl WholeStreamCommand for PathParse {
fn signature(&self) -> Signature {
Signature::build("path parse")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
.rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
.named(
"extension",
SyntaxShape::String,

View file

@ -31,7 +31,11 @@ impl WholeStreamCommand for PathRelativeTo {
SyntaxShape::FilePath,
"Parent shared with the input path",
)
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
.rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -23,8 +23,11 @@ impl WholeStreamCommand for PathSplit {
}
fn signature(&self) -> Signature {
Signature::build("path split")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
Signature::build("path split").rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -24,8 +24,11 @@ impl WholeStreamCommand for PathType {
}
fn signature(&self) -> Signature {
Signature::build("path type")
.rest(SyntaxShape::ColumnPath, "Optionally operate by column path")
Signature::build("path type").rest(
"rest",
SyntaxShape::ColumnPath,
"Optionally operate by column path",
)
}
fn usage(&self) -> &str {

View file

@ -40,6 +40,7 @@ impl WholeStreamCommand for SubCommand {
Some('d'),
)
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally, draw gradients using text from column paths",
)

View file

@ -15,6 +15,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("ansi strip").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally, remove ansi sequences by column paths",
)

View file

@ -25,6 +25,7 @@ impl WholeStreamCommand for Exec {
Signature::build("exec")
.required("command", SyntaxShape::FilePath, "the command to execute")
.rest(
"rest",
SyntaxShape::GlobPattern,
"any additional arguments for the command",
)

View file

@ -19,7 +19,7 @@ impl WholeStreamCommand for Kill {
SyntaxShape::Int,
"process id of process that is to be killed",
)
.rest(SyntaxShape::Int, "rest of processes to kill")
.rest("rest", SyntaxShape::Int, "rest of processes to kill")
.switch("force", "forcefully kill the process", Some('f'))
.switch("quiet", "won't print anything to the console", Some('q'));

View file

@ -43,7 +43,7 @@ impl WholeStreamCommand for RunExternalCommand {
}
fn signature(&self) -> Signature {
Signature::build(self.name()).rest(SyntaxShape::Any, "external command arguments")
Signature::build(self.name()).rest("rest", SyntaxShape::Any, "external command arguments")
}
fn usage(&self) -> &str {

View file

@ -21,7 +21,7 @@ impl WholeStreamCommand for Sleep {
fn signature(&self) -> Signature {
Signature::build("sleep")
.required("duration", SyntaxShape::Duration, "time to sleep")
.rest(SyntaxShape::Duration, "additional time")
.rest("rest", SyntaxShape::Duration, "additional time")
}
fn usage(&self) -> &str {

View file

@ -16,7 +16,7 @@ impl WholeStreamCommand for Which {
fn signature(&self) -> Signature {
Signature::build("which")
.required("application", SyntaxShape::String, "application")
.rest(SyntaxShape::String, "additional applications")
.rest("rest", SyntaxShape::String, "additional applications")
.switch("all", "list all executables", Some('a'))
}

View file

@ -13,8 +13,11 @@ impl WholeStreamCommand for BuildString {
}
fn signature(&self) -> Signature {
Signature::build("build-string")
.rest(SyntaxShape::Any, "all values to form into the string")
Signature::build("build-string").rest(
"rest",
SyntaxShape::Any,
"all values to form into the string",
)
}
fn usage(&self) -> &str {

View file

@ -135,7 +135,7 @@ impl WholeStreamCommand for Char {
SyntaxShape::Any,
"the name of the character to output",
)
.rest(SyntaxShape::String, "multiple Unicode bytes")
.rest("rest", SyntaxShape::String, "multiple Unicode bytes")
.switch("list", "List all supported character names", Some('l'))
.switch("unicode", "Unicode string i.e. 1f378", Some('u'))
}

View file

@ -22,7 +22,11 @@ impl WholeStreamCommand for SubCommand {
"the character that denotes what separates columns",
)
.switch("collapse-empty", "remove empty columns", Some('c'))
.rest(SyntaxShape::String, "column names to give the new columns")
.rest(
"rest",
SyntaxShape::String,
"column names to give the new columns",
)
}
fn usage(&self) -> &str {

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str capitalize").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally capitalize text by column paths",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str camel-case").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text to camelCase by column paths",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str kebab-case").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text to kebab-case by column paths",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str pascal-case").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text to PascalCase by column paths",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str screaming-snake-case").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text to SCREAMING_SNAKE_CASE by column paths",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str snake-case").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text to snake_case by column paths",
)

View file

@ -12,6 +12,7 @@ impl WholeStreamCommand for Command {
fn signature(&self) -> Signature {
Signature::build("str").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert by column paths",
)

View file

@ -25,6 +25,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str contains")
.required("pattern", SyntaxShape::String, "the pattern to find")
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally check if string contains pattern by column paths",
)

View file

@ -21,6 +21,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str downcase").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally downcase text by column paths",
)

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str ends-with")
.required("pattern", SyntaxShape::String, "the pattern to match")
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally matches suffix of text by column paths",
)

View file

@ -28,6 +28,7 @@ impl WholeStreamCommand for SubCommand {
.required("find", SyntaxShape::String, "the pattern to find")
.required("replace", SyntaxShape::String, "the replacement pattern")
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally find and replace text by column paths",
)

View file

@ -33,6 +33,7 @@ impl WholeStreamCommand for SubCommand {
"the pattern to find index of",
)
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally returns index of pattern in string by column paths",
)

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str length").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally find length of text by column paths",
)

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for SubCommand {
Some('c'),
)
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally check if string contains pattern by column paths",
)

View file

@ -19,6 +19,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str reverse").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally reverse text by column paths",
)

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for SubCommand {
Some('c'),
)
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally check if string contains pattern by column paths",
)

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str starts-with")
.required("pattern", SyntaxShape::String, "the pattern to match")
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally matches prefix of text by column paths",
)

View file

@ -31,6 +31,7 @@ impl WholeStreamCommand for SubCommand {
"the indexes to substring [start end]",
)
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally substring text by column paths",
)

View file

@ -77,6 +77,7 @@ impl WholeStreamCommand for SubCommand {
Some('f'),
)
.rest(
"rest",
SyntaxShape::Any,
"optionally convert text into datetime by column paths",
)

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str to-decimal").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text into decimal by column paths",
)

View file

@ -24,6 +24,7 @@ impl WholeStreamCommand for SubCommand {
Signature::build("str to-int")
.named("radix", SyntaxShape::Number, "radix of integer", Some('r'))
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally convert text into integer by column paths",
)

View file

@ -14,6 +14,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str trim")
.rest(
"rest",
SyntaxShape::ColumnPath,
"optionally trim text by column paths",
)

View file

@ -21,6 +21,7 @@ impl WholeStreamCommand for SubCommand {
fn signature(&self) -> Signature {
Signature::build("str upcase").rest(
"rest",
SyntaxShape::ColumnPath,
"optionally upcase text by column paths",
)

View file

@ -20,7 +20,7 @@ impl WholeStreamCommand for Command {
}
fn signature(&self) -> Signature {
Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")
Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")
}
fn usage(&self) -> &str {

View file

@ -356,7 +356,8 @@ mod tests {
#[test]
fn completes_internal_command_names() {
let registry: VecRegistry =
vec![Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")].into();
vec![Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")]
.into();
let line = "echo 1 | echo 2";
assert_eq!(
@ -402,7 +403,7 @@ mod tests {
fn completes_flags() {
let registry: VecRegistry = vec![Signature::build("du")
.switch("recursive", "the values to echo", None)
.rest(SyntaxShape::Any, "blah")]
.rest("rest", SyntaxShape::Any, "blah")]
.into();
let line = "du --recurs";
@ -442,7 +443,7 @@ mod tests {
fn completes_flags_with_just_a_single_hyphen() {
let registry: VecRegistry = vec![Signature::build("du")
.switch("recursive", "the values to echo", None)
.rest(SyntaxShape::Any, "blah")]
.rest("rest", SyntaxShape::Any, "blah")]
.into();
let line = "du -";
@ -459,7 +460,8 @@ mod tests {
#[test]
fn completes_arguments() {
let registry: VecRegistry =
vec![Signature::build("echo").rest(SyntaxShape::Any, "the values to echo")].into();
vec![Signature::build("echo").rest("rest", SyntaxShape::Any, "the values to echo")]
.into();
let line = "echo 1 | echo 2";
assert_eq!(

View file

@ -205,7 +205,7 @@ pub fn get_documentation(
}
if let Some(rest_positional) = &signature.rest_positional {
long_desc.push_str(&format!(" ...args: {}\n", rest_positional.1));
long_desc.push_str(&format!(" ...args: {}\n", rest_positional.2));
}
}
if !signature.named.is_empty() {

View file

@ -125,7 +125,7 @@ fn get_signature(sig: &mut Signature, tag: Tag) -> Vec<Value> {
}
match r {
Some((shape, desc)) => {
Some((rest_name, shape, desc)) => {
let mut indexmap = IndexMap::new();
// let output = format!("Rest|{}|{}|{}\n", name, shape.syntax_shape_name(), desc);
// eprintln!("{}", output);
@ -136,7 +136,7 @@ fn get_signature(sig: &mut Signature, tag: Tag) -> Vec<Value> {
);
indexmap.insert(
"parameter_name".to_string(),
UntaggedValue::string("".to_string()).into_value(&tag),
UntaggedValue::string(rest_name.to_string()).into_value(&tag),
);
indexmap.insert(
"parameter_type".to_string(),

View file

@ -468,7 +468,10 @@ impl VarSyntaxShapeDeductor {
if let Expression::Variable(var_name, _) = &positional.expr {
let deduced_shape = {
if pos_idx >= signature.positional.len() {
signature.rest_positional.as_ref().map(|(shape, _)| shape)
signature
.rest_positional
.as_ref()
.map(|(_, shape, _)| shape)
} else {
match &signature.positional[pos_idx].0 {
PositionalType::Mandatory(_, shape)

View file

@ -139,7 +139,7 @@ impl WholeStreamCommand for Arc<Block> {
_ => break,
}
}
if block.params.rest_positional.is_some() {
if let Some(rest_pos) = &block.params.rest_positional {
let elements: Vec<_> = args_iter.collect();
let start = if let Some(first) = elements.first() {
first.tag.span.start()
@ -153,15 +153,15 @@ impl WholeStreamCommand for Arc<Block> {
};
ctx.scope.add_var(
"$rest",
format!("${}", rest_pos.0),
UntaggedValue::Table(elements).into_value(Span::new(start, end)),
);
}
} else if block.params.rest_positional.is_some() {
} else if let Some(rest_pos) = &block.params.rest_positional {
//If there is a rest arg, but no args were provided,
//we have to set $rest to an empty table
ctx.scope.add_var(
"$rest",
format!("${}", rest_pos.0),
UntaggedValue::Table(Vec::new()).into_value(Span::new(0, 0)),
);
}

View file

@ -88,7 +88,7 @@ mod tests {
Signature::build("bundle add")
.switch("skip-install", "Adds the gem to the Gemfile but does not install it.", None)
.named("group", SyntaxShape::String, "Specify the group(s) for the added gem. Multiple groups should be separated by commas.", Some('g'))
.rest(SyntaxShape::Any, "options")
.rest("rest", SyntaxShape::Any, "options")
}
#[test]

View file

@ -1601,7 +1601,7 @@ fn parse_internal_command(
positional.push(arg);
current_positional += 1;
} else if let Some((rest_type, _)) = &signature.rest_positional {
} else if let Some((_, rest_type, _)) = &signature.rest_positional {
let (arg, err) = parse_arg(*rest_type, scope, &lite_cmd.parts[idx]);
if error.is_none() {
error = err;

View file

@ -185,20 +185,20 @@ pub fn parse_type_token(type_: &Token) -> (SyntaxShape, Option<ParseError>) {
}
}
pub(crate) fn parse_rest_name(name_token: &Token) -> Option<ParseError> {
pub(crate) fn parse_rest_name(name_token: &Token) -> (Spanned<String>, Option<ParseError>) {
return if let TokenContents::Baseline(name) = &name_token.contents {
if !name.starts_with("...") {
Some(parse_rest_name_err(name_token))
} else if !name.starts_with("...rest") {
Some(ParseError::mismatch(
"rest argument name to be 'rest'",
token_to_spanned_string(name_token),
))
} else {
None
match name.strip_prefix("...") {
Some(var_name) => (var_name.to_string().spanned(name_token.span), None),
None => (
"InternalError".to_string().spanned(name_token.span),
Some(parse_rest_name_err(name_token)),
),
}
} else {
Some(parse_rest_name_err(name_token))
(
"InternalError".to_string().spanned(name_token.span),
Some(parse_rest_name_err(name_token)),
)
};
fn parse_rest_name_err(token: &Token) -> ParseError {

View file

@ -231,7 +231,7 @@ fn parse_rest(
tokens: &[Token],
tokens_as_str: &Spanned<String>,
) -> (
Option<(SyntaxShape, Description)>,
Option<(String, SyntaxShape, Description)>,
usize,
Option<ParseError>,
) {
@ -251,7 +251,7 @@ fn parse_rest(
let mut type_ = SyntaxShape::Any;
let mut comment = "".to_string();
let error = parse_rest_name(&tokens[i]);
let (name, error) = parse_rest_name(&tokens[i]);
err = err.or(error);
i += 1;
@ -268,7 +268,7 @@ fn parse_rest(
comment = parsed_comment.unwrap_or_else(|| "".to_string());
}
(Some((type_, comment)), i, err)
(Some((name.item, type_, comment)), i, err)
}
fn parse_optional_type(tokens: &[Token]) -> (Option<SyntaxShape>, usize, Option<ParseError>) {
@ -352,7 +352,7 @@ fn to_signature(
name: &str,
params: Vec<Parameter>,
flags: Vec<Flag>,
rest: Option<(SyntaxShape, Description)>,
rest: Option<(String, SyntaxShape, Description)>,
) -> Signature {
let mut sign = Signature::new(name);

View file

@ -332,7 +332,23 @@ fn simple_def_with_rest_arg() {
assert!(err.is_none());
assert_eq!(
sign.rest_positional,
Some((SyntaxShape::Any, "".to_string()))
Some(("rest".to_string(), SyntaxShape::Any, "".to_string()))
);
}
#[test]
fn simple_def_with_rest_arg_other_name() {
let name = "my_func";
let sign = "[ ...paths:path # A pathological test]";
let (sign, err) = parse_signature(name, &sign.to_string().spanned_unknown());
assert!(err.is_none());
assert_eq!(
sign.rest_positional,
Some((
"paths".to_string(),
SyntaxShape::FilePath,
"A pathological test".to_string()
))
);
}
@ -344,7 +360,11 @@ fn simple_def_with_rest_arg_with_type_and_comment() {
assert!(err.is_none());
assert_eq!(
sign.rest_positional,
Some((SyntaxShape::FilePath, "My super cool rest arg".to_string()))
Some((
"rest".to_string(),
SyntaxShape::FilePath,
"My super cool rest arg".to_string()
))
);
}
@ -380,6 +400,10 @@ fn simple_def_with_param_flag_and_rest() {
);
assert_eq!(
sign.rest_positional,
Some((SyntaxShape::Table, "Another rest".to_string()))
Some((
"rest".to_string(),
SyntaxShape::Table,
"Another rest".to_string()
))
);
}

View file

@ -147,7 +147,7 @@ pub struct Signature {
/// The list of positional arguments, both required and optional, and their corresponding types and help text
pub positional: Vec<(PositionalType, Description)>,
/// After the positional arguments, a catch-all for the rest of the arguments that might follow, their type, and help text
pub rest_positional: Option<(SyntaxShape, Description)>,
pub rest_positional: Option<(String, SyntaxShape, Description)>,
/// The named flags with corresponding type and help text
pub named: IndexMap<String, (NamedType, Description)>,
/// The type of values being sent out from the command into the pipeline, if any
@ -194,7 +194,7 @@ impl Signature {
allowed.insert(shape.display());
}
if let Some((shape, _)) = &self.rest_positional {
if let Some((_, shape, _)) = &self.rest_positional {
allowed.insert(shape.display());
}
@ -348,8 +348,13 @@ impl Signature {
/// Set the type for the "rest" of the positional arguments
/// Note: Not naming the field in your struct holding the rest values "rest", can
/// cause errors when deserializing
pub fn rest(mut self, ty: SyntaxShape, desc: impl Into<String>) -> Signature {
self.rest_positional = Some((ty, desc.into()));
pub fn rest(
mut self,
name: impl Into<String>,
ty: SyntaxShape,
desc: impl Into<String>,
) -> Signature {
self.rest_positional = Some((name.into(), ty, desc.into()));
self
}

View file

@ -31,7 +31,7 @@ impl Plugin for Inc {
"increment the patch version (eg 1.2.1 -> 1.2.2)",
Some('p'),
)
.rest(SyntaxShape::ColumnPath, "the column(s) to update")
.rest("rest", SyntaxShape::ColumnPath, "the column(s) to update")
.filter())
}

View file

@ -8,7 +8,11 @@ impl Plugin for Start {
fn config(&mut self) -> Result<Signature, ShellError> {
Ok(Signature::build("start")
.desc("Opens each file/directory/URL using the default application")
.rest(SyntaxShape::String, "files/urls/directories to open")
.rest(
"rest",
SyntaxShape::String,
"files/urls/directories to open",
)
.named(
"application",
SyntaxShape::String,

View file

@ -373,6 +373,25 @@ fn run_custom_command_with_empty_rest() {
assert_eq!(actual.err, r#""#);
}
#[test]
fn run_custom_command_with_rest_other_name() {
let actual = nu!(
cwd: ".",
r#"
def say-hello [
greeting:string,
...names:string # All of the names
] {
echo $"($greeting), ($names | sort-by | str collect ' ')"
}
say-hello Salutations E D C A B
"#
);
assert_eq!(actual.out, r#"Salutations, A B C D E"#);
assert_eq!(actual.err, r#""#);
}
#[test]
fn alias_a_load_env() {
let actual = nu!(