diff --git a/crates/nu-cmd-extra/src/extra/bits/and.rs b/crates/nu-cmd-extra/src/extra/bits/and.rs index e63b6f23e6f8..104cbe7de654 100644 --- a/crates/nu-cmd-extra/src/extra/bits/and.rs +++ b/crates/nu-cmd-extra/src/extra/bits/and.rs @@ -15,7 +15,13 @@ impl Command for BitsAnd { fn signature(&self) -> Signature { Signature::build("bits and") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required( "target", diff --git a/crates/nu-cmd-extra/src/extra/bits/not.rs b/crates/nu-cmd-extra/src/extra/bits/not.rs index 4948a1c4a10a..3e4e72529c1a 100644 --- a/crates/nu-cmd-extra/src/extra/bits/not.rs +++ b/crates/nu-cmd-extra/src/extra/bits/not.rs @@ -16,7 +16,13 @@ impl Command for BitsNot { fn signature(&self) -> Signature { Signature::build("bits not") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .switch( "signed", diff --git a/crates/nu-cmd-extra/src/extra/bits/or.rs b/crates/nu-cmd-extra/src/extra/bits/or.rs index 1c3c7243de38..41110e17cd06 100644 --- a/crates/nu-cmd-extra/src/extra/bits/or.rs +++ b/crates/nu-cmd-extra/src/extra/bits/or.rs @@ -15,7 +15,13 @@ impl Command for BitsOr { fn signature(&self) -> Signature { Signature::build("bits or") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required( "target", diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs index d299dd6dcc11..363c0104280f 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_left.rs @@ -18,7 +18,13 @@ impl Command for BitsRol { fn signature(&self) -> Signature { Signature::build("bits rol") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required("bits", SyntaxShape::Int, "number of bits to rotate left") .switch( diff --git a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs index 9e521a30e79b..c9f4f9ce9f19 100644 --- a/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/rotate_right.rs @@ -18,7 +18,13 @@ impl Command for BitsRor { fn signature(&self) -> Signature { Signature::build("bits ror") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required("bits", SyntaxShape::Int, "number of bits to rotate right") .switch( diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs index 802b29a04f05..05289b282fac 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_left.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_left.rs @@ -18,7 +18,13 @@ impl Command for BitsShl { fn signature(&self) -> Signature { Signature::build("bits shl") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required("bits", SyntaxShape::Int, "number of bits to shift left") .switch( diff --git a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs index f780ee667297..f94d81829dbc 100644 --- a/crates/nu-cmd-extra/src/extra/bits/shift_right.rs +++ b/crates/nu-cmd-extra/src/extra/bits/shift_right.rs @@ -18,7 +18,13 @@ impl Command for BitsShr { fn signature(&self) -> Signature { Signature::build("bits shr") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required("bits", SyntaxShape::Int, "number of bits to shift right") .switch( diff --git a/crates/nu-cmd-extra/src/extra/bits/xor.rs b/crates/nu-cmd-extra/src/extra/bits/xor.rs index 691ea6907937..c40d5ea587a4 100644 --- a/crates/nu-cmd-extra/src/extra/bits/xor.rs +++ b/crates/nu-cmd-extra/src/extra/bits/xor.rs @@ -15,7 +15,13 @@ impl Command for BitsXor { fn signature(&self) -> Signature { Signature::build("bits xor") - .input_output_types(vec![(Type::Int, Type::Int)]) + .input_output_types(vec![ + (Type::Int, Type::Int), + ( + Type::List(Box::new(Type::Int)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .required( "target", diff --git a/crates/nu-cmd-extra/src/extra/bytes/length.rs b/crates/nu-cmd-extra/src/extra/bytes/length.rs index bab8550a53f2..3f8caaf7215f 100644 --- a/crates/nu-cmd-extra/src/extra/bytes/length.rs +++ b/crates/nu-cmd-extra/src/extra/bytes/length.rs @@ -16,7 +16,13 @@ impl Command for BytesLen { fn signature(&self) -> Signature { Signature::build("bytes length") - .input_output_types(vec![(Type::Binary, Type::Int)]) + .input_output_types(vec![ + (Type::Binary, Type::Int), + ( + Type::List(Box::new(Type::Binary)), + Type::List(Box::new(Type::Int)), + ), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-cmd-extra/src/extra/bytes/remove.rs b/crates/nu-cmd-extra/src/extra/bytes/remove.rs index 8780d14ece25..8db1af62b5af 100644 --- a/crates/nu-cmd-extra/src/extra/bytes/remove.rs +++ b/crates/nu-cmd-extra/src/extra/bytes/remove.rs @@ -30,7 +30,10 @@ impl Command for BytesRemove { fn signature(&self) -> Signature { Signature::build("bytes remove") - .input_output_types(vec![(Type::Binary, Type::Binary)]) + .input_output_types(vec![ + (Type::Binary, Type::Binary), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .required("pattern", SyntaxShape::Binary, "the pattern to find") .rest( "rest", diff --git a/crates/nu-cmd-extra/src/extra/bytes/replace.rs b/crates/nu-cmd-extra/src/extra/bytes/replace.rs index dc12d7e344b8..2370d13eb1e1 100644 --- a/crates/nu-cmd-extra/src/extra/bytes/replace.rs +++ b/crates/nu-cmd-extra/src/extra/bytes/replace.rs @@ -30,7 +30,10 @@ impl Command for BytesReplace { fn signature(&self) -> Signature { Signature::build("bytes replace") - .input_output_types(vec![(Type::Binary, Type::Binary)]) + .input_output_types(vec![ + (Type::Binary, Type::Binary), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .required("find", SyntaxShape::Binary, "the pattern to find") .required("replace", SyntaxShape::Binary, "the replacement pattern") .rest( diff --git a/crates/nu-cmd-extra/src/extra/math/cos.rs b/crates/nu-cmd-extra/src/extra/math/cos.rs index d2b94b7fd9ef..96486431c8e0 100644 --- a/crates/nu-cmd-extra/src/extra/math/cos.rs +++ b/crates/nu-cmd-extra/src/extra/math/cos.rs @@ -13,7 +13,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math cos") .switch("degrees", "Use degrees instead of radians", Some('d')) - .input_output_types(vec![(Type::Number, Type::Float)]) + .input_output_types(vec![ + (Type::Number, Type::Float), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Float)), + ), + ]) .vectorizes_over_list(true) .category(Category::Math) } diff --git a/crates/nu-cmd-extra/src/extra/math/sin.rs b/crates/nu-cmd-extra/src/extra/math/sin.rs index 0db2dbc6da1f..276163eb0641 100644 --- a/crates/nu-cmd-extra/src/extra/math/sin.rs +++ b/crates/nu-cmd-extra/src/extra/math/sin.rs @@ -13,7 +13,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math sin") .switch("degrees", "Use degrees instead of radians", Some('d')) - .input_output_types(vec![(Type::Number, Type::Float)]) + .input_output_types(vec![ + (Type::Number, Type::Float), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Float)), + ), + ]) .vectorizes_over_list(true) .category(Category::Math) } diff --git a/crates/nu-cmd-extra/src/extra/math/tan.rs b/crates/nu-cmd-extra/src/extra/math/tan.rs index a6b3a8e64c86..65b8b61388b4 100644 --- a/crates/nu-cmd-extra/src/extra/math/tan.rs +++ b/crates/nu-cmd-extra/src/extra/math/tan.rs @@ -13,7 +13,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math tan") .switch("degrees", "Use degrees instead of radians", Some('d')) - .input_output_types(vec![(Type::Number, Type::Float)]) + .input_output_types(vec![ + (Type::Number, Type::Float), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Float)), + ), + ]) .vectorizes_over_list(true) .category(Category::Math) } diff --git a/crates/nu-cmd-extra/tests/commands/bytes/starts_with.rs b/crates/nu-cmd-extra/tests/commands/bytes/starts_with.rs index 797d5766e70a..1448c0decd78 100644 --- a/crates/nu-cmd-extra/tests/commands/bytes/starts_with.rs +++ b/crates/nu-cmd-extra/tests/commands/bytes/starts_with.rs @@ -21,7 +21,7 @@ fn basic_string_fails() { "# ); - assert!(actual.err.contains("Input type not supported")); + assert!(actual.err.contains("command doesn't support")); assert_eq!(actual.out, ""); } diff --git a/crates/nu-cmd-lang/src/core_commands/collect.rs b/crates/nu-cmd-lang/src/core_commands/collect.rs index ee827512e43e..f8415e841acf 100644 --- a/crates/nu-cmd-lang/src/core_commands/collect.rs +++ b/crates/nu-cmd-lang/src/core_commands/collect.rs @@ -16,7 +16,7 @@ impl Command for Collect { fn signature(&self) -> Signature { Signature::build("collect") - .input_output_types(vec![(Type::List(Box::new(Type::Any)), Type::Any)]) + .input_output_types(vec![(Type::Any, Type::Any)]) .required( "closure", SyntaxShape::Closure(Some(vec![SyntaxShape::Any])), diff --git a/crates/nu-command/src/conversions/into/decimal.rs b/crates/nu-command/src/conversions/into/decimal.rs index 11ceb0a902c8..66b03bd2f997 100644 --- a/crates/nu-command/src/conversions/into/decimal.rs +++ b/crates/nu-command/src/conversions/into/decimal.rs @@ -17,15 +17,21 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("into decimal") .input_output_types(vec![ + (Type::Int, Type::Number), (Type::String, Type::Number), (Type::Bool, Type::Number), (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Number)), + ), ]) .rest( "rest", SyntaxShape::CellPath, "for a data structure input, convert data at the given cell paths", ) + .allow_variants_without_examples(true) .category(Category::Conversions) } diff --git a/crates/nu-command/src/conversions/into/int.rs b/crates/nu-command/src/conversions/into/int.rs index 7e5c8e73886d..0d3e9dbdce1e 100644 --- a/crates/nu-command/src/conversions/into/int.rs +++ b/crates/nu-command/src/conversions/into/int.rs @@ -36,10 +36,17 @@ impl Command for SubCommand { (Type::Bool, Type::Int), // Unix timestamp in nanoseconds (Type::Date, Type::Int), + (Type::Duration, Type::Int), // TODO: Users should do this by dividing a Filesize by a Filesize explicitly (Type::Filesize, Type::Int), + (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Int)), + ), ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .named("radix", SyntaxShape::Number, "radix of integer", Some('r')) .switch("little-endian", "use little-endian byte decoding", None) .rest( diff --git a/crates/nu-command/src/conversions/into/string.rs b/crates/nu-command/src/conversions/into/string.rs index 8ede3f300fa1..699c74f8c851 100644 --- a/crates/nu-command/src/conversions/into/string.rs +++ b/crates/nu-command/src/conversions/into/string.rs @@ -40,6 +40,10 @@ impl Command for SubCommand { (Type::Bool, Type::String), (Type::Filesize, Type::String), (Type::Date, Type::String), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::String)), + ), ]) .allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032 .rest( diff --git a/crates/nu-command/src/env/load_env.rs b/crates/nu-command/src/env/load_env.rs index 0a84fa100d67..9f1102903acf 100644 --- a/crates/nu-command/src/env/load_env.rs +++ b/crates/nu-command/src/env/load_env.rs @@ -19,7 +19,10 @@ impl Command for LoadEnv { fn signature(&self) -> nu_protocol::Signature { Signature::build("load-env") - .input_output_types(vec![(Type::Record(vec![]), Type::Nothing)]) + .input_output_types(vec![ + (Type::Record(vec![]), Type::Nothing), + (Type::Nothing, Type::Nothing), + ]) .allow_variants_without_examples(true) .optional( "update", diff --git a/crates/nu-command/src/filters/append.rs b/crates/nu-command/src/filters/append.rs index d7b529e300e9..d5af53b7d128 100644 --- a/crates/nu-command/src/filters/append.rs +++ b/crates/nu-command/src/filters/append.rs @@ -16,11 +16,15 @@ impl Command for Append { fn signature(&self) -> nu_protocol::Signature { Signature::build("append") - .input_output_types(vec![( - Type::List(Box::new(Type::Any)), - Type::List(Box::new(Type::Any)), - )]) + .input_output_types(vec![ + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), + (Type::Record(vec![]), Type::Table(vec![])), + ]) .required("row", SyntaxShape::Any, "the row, list, or table to append") + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/each.rs b/crates/nu-command/src/filters/each.rs index d627b2b018f7..02043c05c454 100644 --- a/crates/nu-command/src/filters/each.rs +++ b/crates/nu-command/src/filters/each.rs @@ -41,6 +41,7 @@ with 'transpose' first."# Type::List(Box::new(Type::Any)), ), (Type::Table(vec![]), Type::List(Box::new(Type::Any))), + (Type::Any, Type::Any), ]) .required( "closure", @@ -48,6 +49,7 @@ with 'transpose' first."# "the closure to run", ) .switch("keep-empty", "keep empty result cells", Some('k')) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/find.rs b/crates/nu-command/src/filters/find.rs index 7a7422155498..5123827a26b3 100644 --- a/crates/nu-command/src/filters/find.rs +++ b/crates/nu-command/src/filters/find.rs @@ -29,7 +29,7 @@ impl Command for Find { Type::List(Box::new(Type::Any)), Type::List(Box::new(Type::Any)), ), - (Type::String, Type::String), + (Type::String, Type::Any), ( // For find -p Type::Table(vec![]), diff --git a/crates/nu-command/src/filters/first.rs b/crates/nu-command/src/filters/first.rs index 153391509d8f..8a9660dac7ce 100644 --- a/crates/nu-command/src/filters/first.rs +++ b/crates/nu-command/src/filters/first.rs @@ -33,12 +33,14 @@ impl Command for First { Type::Any, ), (Type::Binary, Type::Binary), + (Type::Range, Type::Any), ]) .optional( "rows", SyntaxShape::Int, "starting from the front, the number of rows to return", ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/get.rs b/crates/nu-command/src/filters/get.rs index 1a5be9fb962e..f9eb66e26e36 100644 --- a/crates/nu-command/src/filters/get.rs +++ b/crates/nu-command/src/filters/get.rs @@ -34,6 +34,7 @@ If multiple cell paths are given, this will produce a list of values."# Type::Any, ), (Type::Table(vec![]), Type::Any), + (Type::Record(vec![]), Type::Any), ]) .required( "cell_path", @@ -51,6 +52,7 @@ If multiple cell paths are given, this will produce a list of values."# "get path in a case sensitive manner", Some('s'), ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/insert.rs b/crates/nu-command/src/filters/insert.rs index 43840cdb6a68..14c4a65cada5 100644 --- a/crates/nu-command/src/filters/insert.rs +++ b/crates/nu-command/src/filters/insert.rs @@ -19,6 +19,10 @@ impl Command for Insert { .input_output_types(vec![ (Type::Record(vec![]), Type::Record(vec![])), (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), ]) .required( "field", @@ -30,6 +34,7 @@ impl Command for Insert { SyntaxShape::Any, "the new value to give the cell(s)", ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/select.rs b/crates/nu-command/src/filters/select.rs index d40d33709cda..0828c3d20995 100644 --- a/crates/nu-command/src/filters/select.rs +++ b/crates/nu-command/src/filters/select.rs @@ -21,6 +21,7 @@ impl Command for Select { .input_output_types(vec![ (Type::Record(vec![]), Type::Record(vec![])), (Type::Table(vec![]), Type::Table(vec![])), + (Type::List(Box::new(Type::Any)), Type::Any), ]) .switch( "ignore-errors", @@ -32,6 +33,7 @@ impl Command for Select { SyntaxShape::CellPath, "the columns to select from the table", ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/sort_by.rs b/crates/nu-command/src/filters/sort_by.rs index c606e0354093..7e1b0483009f 100644 --- a/crates/nu-command/src/filters/sort_by.rs +++ b/crates/nu-command/src/filters/sort_by.rs @@ -16,7 +16,13 @@ impl Command for SortBy { fn signature(&self) -> nu_protocol::Signature { Signature::build("sort-by") - .input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))]) + .input_output_types(vec![ + (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), + ]) .rest("columns", SyntaxShape::Any, "the column(s) to sort by") .switch("reverse", "Sort in reverse order", Some('r')) .switch( @@ -29,6 +35,7 @@ impl Command for SortBy { "Sort alphanumeric string-based columns naturally (1, 9, 10, 99, 100, ...)", Some('n'), ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/transpose.rs b/crates/nu-command/src/filters/transpose.rs index 1092161a087a..ede1b1c94201 100644 --- a/crates/nu-command/src/filters/transpose.rs +++ b/crates/nu-command/src/filters/transpose.rs @@ -29,6 +29,7 @@ impl Command for Transpose { .input_output_types(vec![ (Type::Table(vec![]), Type::Table(vec![])), (Type::Table(vec![]), Type::Record(vec![])), + (Type::Record(vec![]), Type::Table(vec![])), ]) .switch( "header-row", @@ -55,6 +56,7 @@ impl Command for Transpose { "on repetition of record fields due to `header-row`, keep all the values obtained", Some('a'), ) + .allow_variants_without_examples(true) .rest( "rest", SyntaxShape::String, diff --git a/crates/nu-command/src/filters/uniq_by.rs b/crates/nu-command/src/filters/uniq_by.rs index c1e65e6a6a38..16bbd3b497bf 100644 --- a/crates/nu-command/src/filters/uniq_by.rs +++ b/crates/nu-command/src/filters/uniq_by.rs @@ -17,7 +17,13 @@ impl Command for UniqBy { fn signature(&self) -> Signature { Signature::build("uniq-by") - .input_output_types(vec![(Type::Table(vec![]), Type::Table(vec![]))]) + .input_output_types(vec![ + (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), + ]) .rest("columns", SyntaxShape::Any, "the column(s) to filter by") .switch( "count", @@ -39,6 +45,7 @@ impl Command for UniqBy { "Return the input values that occur once only", Some('u'), ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/update.rs b/crates/nu-command/src/filters/update.rs index c4daced13bc0..7743252f598c 100644 --- a/crates/nu-command/src/filters/update.rs +++ b/crates/nu-command/src/filters/update.rs @@ -19,6 +19,10 @@ impl Command for Update { .input_output_types(vec![ (Type::Record(vec![]), Type::Record(vec![])), (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), ]) .required( "field", @@ -30,6 +34,7 @@ impl Command for Update { SyntaxShape::Any, "the new value to give the cell(s), or a closure to create the value", ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/upsert.rs b/crates/nu-command/src/filters/upsert.rs index 1c0fcaac5dc8..cbabfe2807f5 100644 --- a/crates/nu-command/src/filters/upsert.rs +++ b/crates/nu-command/src/filters/upsert.rs @@ -19,6 +19,10 @@ impl Command for Upsert { .input_output_types(vec![ (Type::Record(vec![]), Type::Record(vec![])), (Type::Table(vec![]), Type::Table(vec![])), + ( + Type::List(Box::new(Type::Any)), + Type::List(Box::new(Type::Any)), + ), ]) .required( "field", @@ -30,6 +34,7 @@ impl Command for Upsert { SyntaxShape::Any, "the new value to give the cell(s), or a closure to create the value", ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/where_.rs b/crates/nu-command/src/filters/where_.rs index a34651cc3407..e8d9b0de7bdc 100644 --- a/crates/nu-command/src/filters/where_.rs +++ b/crates/nu-command/src/filters/where_.rs @@ -32,12 +32,14 @@ not supported."# Type::List(Box::new(Type::Any)), ), (Type::Table(vec![]), Type::Table(vec![])), + (Type::Range, Type::Any), ]) .required( "row_condition", SyntaxShape::RowCondition, "Filter condition", ) + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/filters/wrap.rs b/crates/nu-command/src/filters/wrap.rs index 3cee9da09566..64f5be8df49e 100644 --- a/crates/nu-command/src/filters/wrap.rs +++ b/crates/nu-command/src/filters/wrap.rs @@ -23,8 +23,10 @@ impl Command for Wrap { .input_output_types(vec![ (Type::List(Box::new(Type::Any)), Type::Table(vec![])), (Type::Range, Type::Table(vec![])), + (Type::Any, Type::Record(vec![])), ]) .required("name", SyntaxShape::String, "the name of the column") + .allow_variants_without_examples(true) .category(Category::Filters) } diff --git a/crates/nu-command/src/math/abs.rs b/crates/nu-command/src/math/abs.rs index a4d1e8f623aa..2eeecb30b518 100644 --- a/crates/nu-command/src/math/abs.rs +++ b/crates/nu-command/src/math/abs.rs @@ -12,8 +12,15 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math abs") - .input_output_types(vec![(Type::Number, Type::Number)]) + .input_output_types(vec![ + (Type::Number, Type::Number), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Number)), + ), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/avg.rs b/crates/nu-command/src/math/avg.rs index 95cce92306a3..1deae7ee4ba2 100644 --- a/crates/nu-command/src/math/avg.rs +++ b/crates/nu-command/src/math/avg.rs @@ -14,7 +14,12 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math avg") - .input_output_types(vec![(Type::List(Box::new(Type::Number)), Type::Number)]) + .input_output_types(vec![ + (Type::List(Box::new(Type::Number)), Type::Number), + (Type::List(Box::new(Type::Duration)), Type::Duration), + (Type::List(Box::new(Type::Filesize)), Type::Filesize), + ]) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/ceil.rs b/crates/nu-command/src/math/ceil.rs index 7398b957a7c9..ae7f18173973 100644 --- a/crates/nu-command/src/math/ceil.rs +++ b/crates/nu-command/src/math/ceil.rs @@ -12,8 +12,15 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math ceil") - .input_output_types(vec![(Type::Number, Type::Int)]) + .input_output_types(vec![ + (Type::Number, Type::Int), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Number)), + ), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/floor.rs b/crates/nu-command/src/math/floor.rs index e605dfa8ae8d..5625417bf17e 100644 --- a/crates/nu-command/src/math/floor.rs +++ b/crates/nu-command/src/math/floor.rs @@ -12,8 +12,15 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math floor") - .input_output_types(vec![(Type::Number, Type::Int)]) + .input_output_types(vec![ + (Type::Number, Type::Int), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Number)), + ), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/log.rs b/crates/nu-command/src/math/log.rs index 257857ce3d86..1276b8d17dca 100644 --- a/crates/nu-command/src/math/log.rs +++ b/crates/nu-command/src/math/log.rs @@ -20,7 +20,15 @@ impl Command for SubCommand { SyntaxShape::Number, "Base for which the logarithm should be computed", ) - .input_output_types(vec![(Type::Number, Type::Float)]) + .input_output_types(vec![ + (Type::Number, Type::Float), + (Type::Number, Type::Int), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Number)), + ), + ]) + .allow_variants_without_examples(true) .vectorizes_over_list(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/max.rs b/crates/nu-command/src/math/max.rs index 1d6e18358385..fdfc99394645 100644 --- a/crates/nu-command/src/math/max.rs +++ b/crates/nu-command/src/math/max.rs @@ -18,6 +18,7 @@ impl Command for SubCommand { (Type::List(Box::new(Type::Number)), Type::Number), (Type::Table(vec![]), Type::Record(vec![])), ]) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/median.rs b/crates/nu-command/src/math/median.rs index 2fd925af53aa..02c5eb0d1d05 100644 --- a/crates/nu-command/src/math/median.rs +++ b/crates/nu-command/src/math/median.rs @@ -20,6 +20,7 @@ impl Command for SubCommand { (Type::List(Box::new(Type::Number)), Type::Number), (Type::Table(vec![]), Type::Record(vec![])), ]) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/min.rs b/crates/nu-command/src/math/min.rs index bfe10c6b31dc..2cb34581255f 100644 --- a/crates/nu-command/src/math/min.rs +++ b/crates/nu-command/src/math/min.rs @@ -18,6 +18,7 @@ impl Command for SubCommand { (Type::List(Box::new(Type::Number)), Type::Number), (Type::Table(vec![]), Type::Record(vec![])), ]) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/mode.rs b/crates/nu-command/src/math/mode.rs index ca0fd477f3a6..4f1de19d4375 100644 --- a/crates/nu-command/src/math/mode.rs +++ b/crates/nu-command/src/math/mode.rs @@ -45,6 +45,7 @@ impl Command for SubCommand { ), (Type::Table(vec![]), Type::Record(vec![])), ]) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/round.rs b/crates/nu-command/src/math/round.rs index ad4c378bec71..b595688e11e9 100644 --- a/crates/nu-command/src/math/round.rs +++ b/crates/nu-command/src/math/round.rs @@ -15,7 +15,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math round") - .input_output_types(vec![(Type::Number, Type::Number)]) + .input_output_types(vec![ + (Type::Number, Type::Number), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Number)), + ), + ]) .vectorizes_over_list(true) .named( "precision", diff --git a/crates/nu-command/src/math/sqrt.rs b/crates/nu-command/src/math/sqrt.rs index d34199915114..f67f42b06cd2 100644 --- a/crates/nu-command/src/math/sqrt.rs +++ b/crates/nu-command/src/math/sqrt.rs @@ -12,8 +12,15 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math sqrt") - .input_output_types(vec![(Type::Number, Type::Number)]) + .input_output_types(vec![ + (Type::Number, Type::Number), + ( + Type::List(Box::new(Type::Number)), + Type::List(Box::new(Type::Number)), + ), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/math/sum.rs b/crates/nu-command/src/math/sum.rs index 60d91a543fab..ed9d27012cd8 100644 --- a/crates/nu-command/src/math/sum.rs +++ b/crates/nu-command/src/math/sum.rs @@ -14,7 +14,12 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("math sum") - .input_output_types(vec![(Type::List(Box::new(Type::Number)), Type::Number)]) + .input_output_types(vec![ + (Type::List(Box::new(Type::Number)), Type::Number), + (Type::Range, Type::Number), + (Type::Table(vec![]), Type::Table(vec![])), + ]) + .allow_variants_without_examples(true) .category(Category::Math) } diff --git a/crates/nu-command/src/network/url/encode.rs b/crates/nu-command/src/network/url/encode.rs index ca13ff5015f1..0555fabe4405 100644 --- a/crates/nu-command/src/network/url/encode.rs +++ b/crates/nu-command/src/network/url/encode.rs @@ -17,7 +17,7 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("url encode") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![(Type::String, Type::String), (Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)))]) .vectorizes_over_list(true) .switch( "all", diff --git a/crates/nu-command/src/path/join.rs b/crates/nu-command/src/path/join.rs index 603a9a0c0474..d5a622c3135f 100644 --- a/crates/nu-command/src/path/join.rs +++ b/crates/nu-command/src/path/join.rs @@ -35,6 +35,7 @@ impl Command for SubCommand { .input_output_types(vec![ (Type::String, Type::String), (Type::List(Box::new(Type::String)), Type::String), + (Type::Record(vec![]), Type::String), (Type::Table(vec![]), Type::List(Box::new(Type::String))), ]) .named( @@ -43,6 +44,7 @@ impl Command for SubCommand { "For a record or table input, join strings at the given columns", Some('c'), ) + .allow_variants_without_examples(true) .rest("append", SyntaxShape::String, "Path to append to the input") } diff --git a/crates/nu-command/src/platform/ansi/strip.rs b/crates/nu-command/src/platform/ansi/strip.rs index 54f2bdfabc34..9c38e832a28a 100644 --- a/crates/nu-command/src/platform/ansi/strip.rs +++ b/crates/nu-command/src/platform/ansi/strip.rs @@ -15,12 +15,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("ansi strip") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![(Type::String, Type::String), (Type::List(Box::new(Type::String)), Type::List(Box::new(Type::String)))]) .rest( "cell path", SyntaxShape::CellPath, "for a data structure input, remove ANSI sequences from strings at the given cell paths", ) + .allow_variants_without_examples(true) .category(Category::Platform) } diff --git a/crates/nu-command/src/strings/parse.rs b/crates/nu-command/src/strings/parse.rs index ebeeee8a71d8..f74fd4237146 100644 --- a/crates/nu-command/src/strings/parse.rs +++ b/crates/nu-command/src/strings/parse.rs @@ -30,8 +30,12 @@ impl Command for Parse { SyntaxShape::String, "the pattern to match. Eg) \"{foo}: {bar}\"", ) - .input_output_types(vec![(Type::String, Type::Table(vec![]))]) + .input_output_types(vec![ + (Type::String, Type::Table(vec![])), + (Type::List(Box::new(Type::Any)), Type::Table(vec![])), + ]) .switch("regex", "use full regex syntax for patterns", Some('r')) + .allow_variants_without_examples(true) .category(Category::Strings) } diff --git a/crates/nu-command/src/strings/split/row.rs b/crates/nu-command/src/strings/split/row.rs index 74d5d322c7db..2ee5c83fb4db 100644 --- a/crates/nu-command/src/strings/split/row.rs +++ b/crates/nu-command/src/strings/split/row.rs @@ -16,8 +16,12 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("split row") - .input_output_types(vec![(Type::String, Type::List(Box::new(Type::String)))]) + .input_output_types(vec![ + (Type::String, Type::List(Box::new(Type::String))), + (Type::List(Box::new(Type::String)), Type::Table(vec![])), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .required( "separator", SyntaxShape::String, diff --git a/crates/nu-command/src/strings/str_/case/camel_case.rs b/crates/nu-command/src/strings/str_/case/camel_case.rs index 051599add59f..cee3e1993e2f 100644 --- a/crates/nu-command/src/strings/str_/case/camel_case.rs +++ b/crates/nu-command/src/strings/str_/case/camel_case.rs @@ -17,7 +17,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str camel-case") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/capitalize.rs b/crates/nu-command/src/strings/str_/case/capitalize.rs index 498b77f2bbdb..bad3ddb720ae 100644 --- a/crates/nu-command/src/strings/str_/case/capitalize.rs +++ b/crates/nu-command/src/strings/str_/case/capitalize.rs @@ -15,7 +15,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str capitalize") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/downcase.rs b/crates/nu-command/src/strings/str_/case/downcase.rs index 9c63e29b30de..df16626f4b9e 100644 --- a/crates/nu-command/src/strings/str_/case/downcase.rs +++ b/crates/nu-command/src/strings/str_/case/downcase.rs @@ -15,7 +15,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str downcase") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/kebab_case.rs b/crates/nu-command/src/strings/str_/case/kebab_case.rs index 44c55d124517..f807862e857d 100644 --- a/crates/nu-command/src/strings/str_/case/kebab_case.rs +++ b/crates/nu-command/src/strings/str_/case/kebab_case.rs @@ -17,7 +17,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str kebab-case") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/pascal_case.rs b/crates/nu-command/src/strings/str_/case/pascal_case.rs index 757aab1883f8..459dde3db18d 100644 --- a/crates/nu-command/src/strings/str_/case/pascal_case.rs +++ b/crates/nu-command/src/strings/str_/case/pascal_case.rs @@ -17,7 +17,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str pascal-case") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/screaming_snake_case.rs b/crates/nu-command/src/strings/str_/case/screaming_snake_case.rs index 4e4d6f677e76..840fce560c0d 100644 --- a/crates/nu-command/src/strings/str_/case/screaming_snake_case.rs +++ b/crates/nu-command/src/strings/str_/case/screaming_snake_case.rs @@ -16,7 +16,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str screaming-snake-case") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/snake_case.rs b/crates/nu-command/src/strings/str_/case/snake_case.rs index 137908421ea7..56e7bb2b0930 100644 --- a/crates/nu-command/src/strings/str_/case/snake_case.rs +++ b/crates/nu-command/src/strings/str_/case/snake_case.rs @@ -16,7 +16,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str snake-case") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/title_case.rs b/crates/nu-command/src/strings/str_/case/title_case.rs index 1690c2fa3c21..daab6fd47da7 100644 --- a/crates/nu-command/src/strings/str_/case/title_case.rs +++ b/crates/nu-command/src/strings/str_/case/title_case.rs @@ -17,7 +17,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str title-case") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/case/upcase.rs b/crates/nu-command/src/strings/str_/case/upcase.rs index fd4fdca79045..259026f56b60 100644 --- a/crates/nu-command/src/strings/str_/case/upcase.rs +++ b/crates/nu-command/src/strings/str_/case/upcase.rs @@ -14,8 +14,12 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str upcase") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .rest( "rest", SyntaxShape::CellPath, diff --git a/crates/nu-command/src/strings/str_/contains.rs b/crates/nu-command/src/strings/str_/contains.rs index ef47588fb19d..ce02b46b72f3 100644 --- a/crates/nu-command/src/strings/str_/contains.rs +++ b/crates/nu-command/src/strings/str_/contains.rs @@ -32,6 +32,7 @@ impl Command for SubCommand { .input_output_types(vec![ (Type::String, Type::Bool), (Type::Table(vec![]), Type::Table(vec![])), + (Type::List(Box::new(Type::String)), Type::List(Box::new(Type::Bool))) ]) .vectorizes_over_list(true) .required("string", SyntaxShape::String, "the substring to find") diff --git a/crates/nu-command/src/strings/str_/join.rs b/crates/nu-command/src/strings/str_/join.rs index e48adefacb1e..15e998c94d98 100644 --- a/crates/nu-command/src/strings/str_/join.rs +++ b/crates/nu-command/src/strings/str_/join.rs @@ -16,12 +16,16 @@ impl Command for StrJoin { fn signature(&self) -> Signature { Signature::build("str join") - .input_output_types(vec![(Type::List(Box::new(Type::String)), Type::String)]) + .input_output_types(vec![ + (Type::List(Box::new(Type::Any)), Type::String), + (Type::String, Type::String), + ]) .optional( "separator", SyntaxShape::String, "optional separator to use when creating string", ) + .allow_variants_without_examples(true) .category(Category::Strings) } diff --git a/crates/nu-command/src/strings/str_/length.rs b/crates/nu-command/src/strings/str_/length.rs index 78a90fc5280a..8f6c7c6db90e 100644 --- a/crates/nu-command/src/strings/str_/length.rs +++ b/crates/nu-command/src/strings/str_/length.rs @@ -29,7 +29,7 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str length") - .input_output_types(vec![(Type::String, Type::Int)]) + .input_output_types(vec![(Type::String, Type::Int), (Type::List(Box::new(Type::String)), Type::List(Box::new(Type::Int)))]) .vectorizes_over_list(true) .switch( "grapheme-clusters", diff --git a/crates/nu-command/src/strings/str_/replace.rs b/crates/nu-command/src/strings/str_/replace.rs index e6918fcd3bc6..7a4ece8e2174 100644 --- a/crates/nu-command/src/strings/str_/replace.rs +++ b/crates/nu-command/src/strings/str_/replace.rs @@ -34,7 +34,10 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str replace") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) .required("find", SyntaxShape::String, "the pattern to find") .required("replace", SyntaxShape::String, "the replacement string") diff --git a/crates/nu-command/src/strings/str_/reverse.rs b/crates/nu-command/src/strings/str_/reverse.rs index 22586be55ed1..89209d502890 100644 --- a/crates/nu-command/src/strings/str_/reverse.rs +++ b/crates/nu-command/src/strings/str_/reverse.rs @@ -16,7 +16,13 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str reverse") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), + ]) .vectorizes_over_list(true) .rest( "rest", diff --git a/crates/nu-command/src/strings/str_/substring.rs b/crates/nu-command/src/strings/str_/substring.rs index c94b0edd5f48..6079f64cc62f 100644 --- a/crates/nu-command/src/strings/str_/substring.rs +++ b/crates/nu-command/src/strings/str_/substring.rs @@ -42,8 +42,9 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str substring") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![(Type::String, Type::String), (Type::Table(vec![]), Type::Table(vec![]))]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .switch( "grapheme-clusters", "count indexes and split using grapheme clusters (all visible chars have length 1)", diff --git a/crates/nu-command/src/strings/str_/trim/trim_.rs b/crates/nu-command/src/strings/str_/trim/trim_.rs index 6b7c8888d211..e2b80ab88d3f 100644 --- a/crates/nu-command/src/strings/str_/trim/trim_.rs +++ b/crates/nu-command/src/strings/str_/trim/trim_.rs @@ -35,8 +35,16 @@ impl Command for SubCommand { fn signature(&self) -> Signature { Signature::build("str trim") - .input_output_types(vec![(Type::String, Type::String)]) + .input_output_types(vec![ + (Type::String, Type::String), + ( + Type::List(Box::new(Type::String)), + Type::List(Box::new(Type::String)), + ), + (Type::Table(vec![]), Type::Table(vec![])), + ]) .vectorizes_over_list(true) + .allow_variants_without_examples(true) .rest( "rest", SyntaxShape::CellPath, diff --git a/crates/nu-command/tests/commands/drop.rs b/crates/nu-command/tests/commands/drop.rs index 73d7e0c51942..ecba9177d24f 100644 --- a/crates/nu-command/tests/commands/drop.rs +++ b/crates/nu-command/tests/commands/drop.rs @@ -91,5 +91,5 @@ fn nth_missing_first_argument() { fn fail_on_non_iterator() { let actual = nu!("1 | drop 50"); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/last.rs b/crates/nu-command/tests/commands/last.rs index 2ff1254affbd..f84225b95019 100644 --- a/crates/nu-command/tests/commands/last.rs +++ b/crates/nu-command/tests/commands/last.rs @@ -78,7 +78,7 @@ fn last_errors_on_negative_index() { fn fail_on_non_iterator() { let actual = nu!("1 | last"); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } #[test] diff --git a/crates/nu-command/tests/commands/math/round.rs b/crates/nu-command/tests/commands/math/round.rs index 6b93ebd08375..5d2158a56f7d 100644 --- a/crates/nu-command/tests/commands/math/round.rs +++ b/crates/nu-command/tests/commands/math/round.rs @@ -32,5 +32,5 @@ fn can_round_float_with_negative_precision() { fn fails_with_wrong_input_type() { let actual = nu!("\"not_a_number\" | math round"); - assert!(actual.err.contains("Input type not supported")) + assert!(actual.err.contains("command doesn't support")) } diff --git a/crates/nu-command/tests/commands/mkdir.rs b/crates/nu-command/tests/commands/mkdir.rs index 250e7bdbce00..7943ce77665a 100644 --- a/crates/nu-command/tests/commands/mkdir.rs +++ b/crates/nu-command/tests/commands/mkdir.rs @@ -70,7 +70,6 @@ fn print_created_paths() { pipeline( r#" mkdir -v dir_1 dir_2 dir_3 - | length "# )); diff --git a/crates/nu-command/tests/commands/rename.rs b/crates/nu-command/tests/commands/rename.rs index 19d733f70c1b..50fc149458aa 100644 --- a/crates/nu-command/tests/commands/rename.rs +++ b/crates/nu-command/tests/commands/rename.rs @@ -83,7 +83,7 @@ fn errors_if_no_columns_present() { "# )); - assert!(actual.err.contains("only record input data is supported")); + assert!(actual.err.contains("command doesn't support")); }) } diff --git a/crates/nu-command/tests/commands/reverse.rs b/crates/nu-command/tests/commands/reverse.rs index e41459800f55..936cf9f9e428 100644 --- a/crates/nu-command/tests/commands/reverse.rs +++ b/crates/nu-command/tests/commands/reverse.rs @@ -14,5 +14,5 @@ fn can_get_reverse_first() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline("1 | reverse")); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/skip/skip_.rs b/crates/nu-command/tests/commands/skip/skip_.rs index ac461523b5c2..6b86843b2268 100644 --- a/crates/nu-command/tests/commands/skip/skip_.rs +++ b/crates/nu-command/tests/commands/skip/skip_.rs @@ -19,5 +19,5 @@ fn binary_skip() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline("1 | skip 2")); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/skip/until.rs b/crates/nu-command/tests/commands/skip/until.rs index e6acc9c5cde3..7925cf4bbd0c 100644 --- a/crates/nu-command/tests/commands/skip/until.rs +++ b/crates/nu-command/tests/commands/skip/until.rs @@ -54,5 +54,5 @@ fn condition_is_met() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline("1 | skip until {|row| $row == 2}")); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/skip/while_.rs b/crates/nu-command/tests/commands/skip/while_.rs index b008ba4dad54..15f9b6d3e12a 100644 --- a/crates/nu-command/tests/commands/skip/while_.rs +++ b/crates/nu-command/tests/commands/skip/while_.rs @@ -54,5 +54,5 @@ fn condition_is_met() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline("1 | skip while {|row| $row == 2}")); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/sort_by.rs b/crates/nu-command/tests/commands/sort_by.rs index 0d7165b2fdd1..d1c48dd7bf67 100644 --- a/crates/nu-command/tests/commands/sort_by.rs +++ b/crates/nu-command/tests/commands/sort_by.rs @@ -126,5 +126,5 @@ fn no_column_specified_fails() { fn fail_on_non_iterator() { let actual = nu!("1 | sort-by"); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/take/rows.rs b/crates/nu-command/tests/commands/take/rows.rs index 3f57a5911c22..a8099abf9138 100644 --- a/crates/nu-command/tests/commands/take/rows.rs +++ b/crates/nu-command/tests/commands/take/rows.rs @@ -51,7 +51,7 @@ fn fails_on_string() { "# )); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } #[test] diff --git a/crates/nu-command/tests/commands/take/until.rs b/crates/nu-command/tests/commands/take/until.rs index 5a6aaebc7099..0859abe5fa1a 100644 --- a/crates/nu-command/tests/commands/take/until.rs +++ b/crates/nu-command/tests/commands/take/until.rs @@ -55,5 +55,5 @@ fn condition_is_met() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline("1 | take until {|row| $row == 2}")); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/take/while_.rs b/crates/nu-command/tests/commands/take/while_.rs index 33e052ffdc45..07ad8a081913 100644 --- a/crates/nu-command/tests/commands/take/while_.rs +++ b/crates/nu-command/tests/commands/take/while_.rs @@ -54,5 +54,5 @@ fn condition_is_met() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline("1 | take while {|row| $row == 2}")); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } diff --git a/crates/nu-command/tests/commands/where_.rs b/crates/nu-command/tests/commands/where_.rs index 1f1ccc764bb2..d74d3f1dd37f 100644 --- a/crates/nu-command/tests/commands/where_.rs +++ b/crates/nu-command/tests/commands/where_.rs @@ -180,7 +180,7 @@ fn contains_operator() { fn fail_on_non_iterator() { let actual = nu!(cwd: ".", pipeline(r#"{"name": "foo", "size": 3} | where name == "foo""#)); - assert!(actual.err.contains("only_supports_this_input_type")); + assert!(actual.err.contains("command doesn't support")); } // Test that filtering on columns that might be missing/null works diff --git a/crates/nu-command/tests/format_conversions/csv.rs b/crates/nu-command/tests/format_conversions/csv.rs index cacb796f297e..b120d0a213c7 100644 --- a/crates/nu-command/tests/format_conversions/csv.rs +++ b/crates/nu-command/tests/format_conversions/csv.rs @@ -405,5 +405,5 @@ fn string_to_csv_error() { "# )); - assert!(actual.err.contains("can't convert")) + assert!(actual.err.contains("command doesn't support")) } diff --git a/crates/nu-command/tests/format_conversions/toml.rs b/crates/nu-command/tests/format_conversions/toml.rs index e0e220e31e3c..d69f77fbed07 100644 --- a/crates/nu-command/tests/format_conversions/toml.rs +++ b/crates/nu-command/tests/format_conversions/toml.rs @@ -70,7 +70,7 @@ fn table_to_toml_fails() { "# )); - assert_eq!(actual.out, "true"); + assert!(actual.err.contains("command doesn't support")); } #[test] @@ -83,7 +83,7 @@ fn string_to_toml_fails() { "# )); - assert_eq!(actual.out, "true"); + assert!(actual.err.contains("command doesn't support")); } #[test] diff --git a/crates/nu-parser/src/parser.rs b/crates/nu-parser/src/parser.rs index 3a4a318624e4..d0e1edfa3bcd 100644 --- a/crates/nu-parser/src/parser.rs +++ b/crates/nu-parser/src/parser.rs @@ -4,7 +4,7 @@ use crate::{ lite_parser::{lite_parse, LiteCommand, LiteElement, LitePipeline}, parse_mut, parse_patterns::{parse_match_pattern, parse_pattern}, - type_check::{math_result_type, type_compatible}, + type_check::{self, math_result_type, type_compatible}, Token, TokenContents, }; @@ -5582,6 +5582,8 @@ pub fn parse_block( block.span = Some(span); + type_check::check_block_input_output(working_set, &block); + block } diff --git a/crates/nu-parser/src/type_check.rs b/crates/nu-parser/src/type_check.rs index bb4f4e3a2dfa..f09d1e3b04af 100644 --- a/crates/nu-parser/src/type_check.rs +++ b/crates/nu-parser/src/type_check.rs @@ -1,5 +1,8 @@ use nu_protocol::{ - ast::{Bits, Boolean, Comparison, Expr, Expression, Math, Operator}, + ast::{ + Bits, Block, Boolean, Comparison, Expr, Expression, Math, Operator, Pipeline, + PipelineElement, + }, engine::StateWorkingSet, ParseError, Type, }; @@ -24,7 +27,30 @@ pub fn type_compatible(lhs: &Type, rhs: &Type) -> bool { match (lhs, rhs) { (Type::List(c), Type::List(d)) => type_compatible(c, d), - (Type::List(c), Type::Table(_)) => matches!(**c, Type::Any), + (Type::ListStream, Type::List(_)) => true, + (Type::List(_), Type::ListStream) => true, + (Type::List(c), Type::Table(table_fields)) => { + if matches!(**c, Type::Any) { + return true; + } + + if let Type::Record(fields) = &**c { + is_compatible(fields, table_fields) + } else { + false + } + } + (Type::Table(table_fields), Type::List(c)) => { + if matches!(**c, Type::Any) { + return true; + } + + if let Type::Record(fields) = &**c { + is_compatible(table_fields, fields) + } else { + false + } + } (Type::Number, Type::Int) => true, (Type::Int, Type::Number) => true, (Type::Number, Type::Float) => true, @@ -921,3 +947,108 @@ pub fn math_result_type( } } } + +pub fn check_pipeline_type( + working_set: &mut StateWorkingSet, + pipeline: &Pipeline, + input_type: Type, +) -> Type { + let mut current_type = input_type; + + 'elem: for elem in &pipeline.elements { + match elem { + PipelineElement::Expression( + _, + Expression { + expr: Expr::Call(call), + .. + }, + ) => { + let decl = working_set.get_decl(call.decl_id); + + if current_type == Type::Any { + let mut new_current_type = None; + for (_, call_output) in decl.signature().input_output_types { + if let Some(inner_current_type) = &new_current_type { + if inner_current_type == &Type::Any { + break; + } else if inner_current_type != &call_output { + // Union unequal types to Any for now + new_current_type = Some(Type::Any) + } + } else { + new_current_type = Some(call_output.clone()) + } + } + + if let Some(new_current_type) = new_current_type { + current_type = new_current_type + } else { + current_type = Type::Any; + } + continue 'elem; + } else { + for (call_input, call_output) in decl.signature().input_output_types { + if type_compatible(&call_input, ¤t_type) { + current_type = call_output.clone(); + continue 'elem; + } + } + } + + if !decl.signature().input_output_types.is_empty() { + working_set.error(ParseError::InputMismatch(current_type, call.head)) + } + current_type = Type::Any; + } + PipelineElement::Expression(_, Expression { ty, .. }) => { + current_type = ty.clone(); + } + _ => { + current_type = Type::Any; + } + } + } + + current_type +} + +pub fn check_block_input_output(working_set: &mut StateWorkingSet, block: &Block) { + // let inputs = block.input_types(); + + for (input_type, output_type) in &block.signature.input_output_types { + let mut current_type = input_type.clone(); + let mut current_output_type = Type::Nothing; + + for pipeline in &block.pipelines { + current_output_type = check_pipeline_type(working_set, pipeline, current_type); + current_type = Type::Nothing; + } + + if !type_compatible(output_type, ¤t_output_type) + && output_type != &Type::Any + && current_output_type != Type::Any + { + working_set.error(ParseError::OutputMismatch( + output_type.clone(), + block + .pipelines + .last() + .expect("internal error: we should have pipelines") + .elements + .last() + .expect("internal error: we should have elements") + .span(), + )) + } + } + + if block.signature.input_output_types.is_empty() { + let mut current_type = Type::Any; + + for pipeline in &block.pipelines { + let _ = check_pipeline_type(working_set, pipeline, current_type); + current_type = Type::Nothing; + } + } +} diff --git a/crates/nu-protocol/src/ast/block.rs b/crates/nu-protocol/src/ast/block.rs index e57171db0e95..0840cf642c3e 100644 --- a/crates/nu-protocol/src/ast/block.rs +++ b/crates/nu-protocol/src/ast/block.rs @@ -1,5 +1,5 @@ -use super::{Expr, Expression, Pipeline}; -use crate::{ast::PipelineElement, engine::StateWorkingSet, Signature, Span, Type, VarId}; +use super::Pipeline; +use crate::{ast::PipelineElement, Signature, Span, Type, VarId}; use serde::{Deserialize, Serialize}; use std::ops::{Index, IndexMut}; @@ -66,37 +66,6 @@ impl Block { } } - pub fn input_type(&self, working_set: &StateWorkingSet) -> Type { - if let Some(first) = self.pipelines.first() { - if let Some(first) = first.elements.first() { - match first { - PipelineElement::Expression( - _, - Expression { - expr: Expr::Call(call), - .. - }, - ) => { - let decl = working_set.get_decl(call.decl_id); - - decl.signature().get_input_type() - } - PipelineElement::Expression( - _, - Expression { - expr: Expr::ExternalCall(..), - .. - }, - ) => Type::Any, - _ => Type::Nothing, - } - } else { - Type::Nothing - } - } else { - Type::Nothing - } - } pub fn output_type(&self) -> Type { if let Some(last) = self.pipelines.last() { if let Some(last) = last.elements.last() { diff --git a/crates/nu-protocol/src/parse_error.rs b/crates/nu-protocol/src/parse_error.rs index e7f3f834ef26..610f513499a8 100644 --- a/crates/nu-protocol/src/parse_error.rs +++ b/crates/nu-protocol/src/parse_error.rs @@ -48,6 +48,14 @@ pub enum ParseError { #[diagnostic(code(nu::parser::parse_mismatch_with_full_string_msg))] ExpectedWithStringMsg(String, #[label("expected {0}")] Span), + #[error("Command does not support {0} input.")] + #[diagnostic(code(nu::parser::input_type_mismatch))] + InputMismatch(Type, #[label("command doesn't support {0} input")] Span), + + #[error("Command output doesn't match {0}.")] + #[diagnostic(code(nu::parser::output_type_mismatch))] + OutputMismatch(Type, #[label("command doesn't output {0}")] Span), + #[error("Type mismatch during operation.")] #[diagnostic(code(nu::parser::type_mismatch))] Mismatch(String, String, #[label("expected {0}, found {1}")] Span), // expected, found, span @@ -526,6 +534,8 @@ impl ParseError { ParseError::KeywordMissingArgument(_, _, s) => *s, ParseError::MissingType(s) => *s, ParseError::TypeMismatch(_, _, s) => *s, + ParseError::InputMismatch(_, s) => *s, + ParseError::OutputMismatch(_, s) => *s, ParseError::MissingRequiredFlag(_, s) => *s, ParseError::IncompleteMathExpression(s) => *s, ParseError::UnknownState(_, s) => *s, diff --git a/src/tests/test_bits.rs b/src/tests/test_bits.rs index 4399ea711aa7..ea4231786cc2 100644 --- a/src/tests/test_bits.rs +++ b/src/tests/test_bits.rs @@ -46,7 +46,7 @@ fn bits_xor_negative() -> TestResult { #[test] fn bits_xor_list() -> TestResult { run_test( - "[1 2 3 8 9 10] | bits xor 2 | str join '.'", + "[1 2 3 8 9 10] | bits xor 2 | into string | str join '.'", "3.0.1.10.11.8", ) } diff --git a/src/tests/test_engine.rs b/src/tests/test_engine.rs index 39ae57cf6802..4aa2b7453bd5 100644 --- a/src/tests/test_engine.rs +++ b/src/tests/test_engine.rs @@ -55,7 +55,7 @@ fn in_and_if_else() -> TestResult { #[test] fn help_works_with_missing_requirements() -> TestResult { // `each while` is part of the *extra* feature and adds 3 lines - let expected_length = if cfg!(feature = "extra") { "65" } else { "62" }; + let expected_length = if cfg!(feature = "extra") { "66" } else { "63" }; run_test(r#"each --help | lines | length"#, expected_length) }