Declare input and output types of commands (#6796)

* Add failing test that list of ints and floats is List<Number>

* Start defining subtype relation

* Make it possible to declare input and output types for commands

- Enforce them in tests

* Declare input and output types of commands

* Add formatted signatures to `help commands` table

* Revert SyntaxShape::Table -> Type::Table change

* Revert unnecessary derive(Hash) on SyntaxShape

Co-authored-by: JT <547158+jntrnr@users.noreply.github.com>
This commit is contained in:
Dan Davison
2022-11-09 16:55:05 -05:00
committed by GitHub
parent f878276de7
commit df94052180
238 changed files with 2315 additions and 756 deletions

View File

@@ -3,7 +3,7 @@ use nu_engine::CallExt;
use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Category, Example, PipelineData, ShellError, Signature, Span, Value,
Category, Example, PipelineData, ShellError, Signature, Span, Type, Value,
};
#[derive(Clone)]
@@ -19,7 +19,9 @@ impl Command for Fmt {
}
fn signature(&self) -> nu_protocol::Signature {
Signature::build("fmt").category(Category::Conversions)
Signature::build("fmt")
.input_output_types(vec![(Type::Number, Type::Record(vec![]))])
.category(Category::Conversions)
}
fn search_terms(&self) -> Vec<&str> {

View File

@@ -4,7 +4,7 @@ use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, SyntaxShape,
Value,
Type, Value,
};
#[derive(Clone)]
@@ -17,6 +17,16 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into binary")
.input_output_types(vec![
(Type::Binary, Type::Binary),
(Type::Int, Type::Binary),
(Type::Number, Type::Binary),
(Type::String, Type::Binary),
(Type::Bool, Type::Binary),
(Type::Filesize, Type::Binary),
(Type::Date, Type::Binary),
])
.allow_variants_without_examples(true) // TODO: supply exhaustive examples
.rest(
"rest",
SyntaxShape::CellPath,

View File

@@ -3,7 +3,7 @@ use nu_engine::CallExt;
use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
};
#[derive(Clone)]
@@ -16,6 +16,13 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into bool")
.input_output_types(vec![
(Type::Int, Type::Bool),
(Type::Number, Type::Bool),
(Type::String, Type::Bool),
(Type::Bool, Type::Bool),
(Type::List(Box::new(Type::Any)), Type::Table(vec![])),
])
.rest(
"rest",
SyntaxShape::CellPath,
@@ -89,6 +96,11 @@ impl Command for SubCommand {
example: "1 | into bool",
result: Some(Value::boolean(true, span)),
},
Example {
description: "convert decimal to boolean",
example: "0.3 | into bool",
result: Some(Value::boolean(true, span)),
},
Example {
description: "convert decimal string to boolean",
example: "'0.0' | into bool",

View File

@@ -7,7 +7,7 @@ use nu_protocol::ast::CellPath;
use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{
Category, Example, IntoPipelineData, PipelineData, ShellError, Signature, Span, Spanned,
SyntaxShape, Value,
SyntaxShape, Type, Value,
};
struct Arguments {
@@ -64,7 +64,11 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into datetime")
.named(
.input_output_types(vec![
(Type::Int, Type::Date),
(Type::String, Type::Date),
])
.named(
"timezone",
SyntaxShape::String,
"Specify timezone if the input is a Unix timestamp. Valid options: 'UTC' ('u') or 'LOCAL' ('l')",

View File

@@ -3,7 +3,7 @@ use nu_engine::CallExt;
use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
};
#[derive(Clone)]
@@ -15,11 +15,16 @@ impl Command for SubCommand {
}
fn signature(&self) -> Signature {
Signature::build("into decimal").rest(
"rest",
SyntaxShape::CellPath,
"optionally convert text into decimal by column paths",
)
Signature::build("into decimal")
.input_output_types(vec![
(Type::String, Type::Number),
(Type::Bool, Type::Number),
])
.rest(
"rest",
SyntaxShape::CellPath,
"optionally convert text into decimal by column paths",
)
}
fn usage(&self) -> &str {

View File

@@ -3,7 +3,7 @@ use nu_parser::parse_duration_bytes;
use nu_protocol::{
ast::{Call, CellPath, Expr},
engine::{Command, EngineState, Stack},
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Unit,
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Unit,
Value,
};
@@ -17,6 +17,13 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into duration")
.input_output_types(vec![
(Type::String, Type::Duration),
(Type::Duration, Type::Duration),
// TODO: --convert option should be implemented as `format duration`
(Type::String, Type::String),
(Type::Duration, Type::String),
])
.named(
"convert",
SyntaxShape::String,
@@ -121,11 +128,19 @@ impl Command for SubCommand {
span,
}),
},
Example {
description: "Convert duration to duration",
example: "420sec | into duration",
result: Some(Value::Duration {
val: 7 * 60 * 1000 * 1000 * 1000,
span,
}),
},
Example {
description: "Convert duration to the requested duration as a string",
example: "420sec | into duration --convert min",
example: "420sec | into duration --convert ms",
result: Some(Value::String {
val: "7 min".to_string(),
val: "420000 ms".to_string(),
span,
}),
},

View File

@@ -3,7 +3,7 @@ use nu_engine::CallExt;
use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
};
#[derive(Clone)]
@@ -16,6 +16,12 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into filesize")
.input_output_types(vec![
(Type::Int, Type::Filesize),
(Type::Number, Type::Filesize),
(Type::String, Type::Filesize),
(Type::Filesize, Type::Filesize),
])
.rest(
"rest",
SyntaxShape::CellPath,

View File

@@ -3,7 +3,7 @@ use nu_engine::CallExt;
use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Value,
Category, Example, PipelineData, ShellError, Signature, Span, SyntaxShape, Type, Value,
};
struct Arguments {
@@ -28,6 +28,16 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into int")
.input_output_types(vec![
(Type::String, Type::Int),
(Type::Number, Type::Int),
(Type::Bool, Type::Int),
// Unix timestamp in seconds
(Type::Date, Type::Int),
// TODO: Users should do this by dividing a Filesize by a Filesize explicitly
(Type::Filesize, Type::Int),
])
.vectorizes_over_list(true)
.named("radix", SyntaxShape::Number, "radix of integer", Some('r'))
.switch("little-endian", "use little-endian byte decoding", None)
.rest(

View File

@@ -4,7 +4,7 @@ use nu_protocol::{
ast::{Call, CellPath},
engine::{Command, EngineState, Stack},
into_code, Category, Config, Example, IntoPipelineData, PipelineData, ShellError, Signature,
Span, SyntaxShape, Value,
Span, SyntaxShape, Type, Value,
};
use nu_utils::get_system_locale;
use num_format::ToFormattedString;
@@ -32,6 +32,16 @@ impl Command for SubCommand {
fn signature(&self) -> Signature {
Signature::build("into string")
.input_output_types(vec![
(Type::Binary, Type::String),
(Type::Int, Type::String),
(Type::Number, Type::String),
(Type::String, Type::String),
(Type::Bool, Type::String),
(Type::Filesize, Type::String),
(Type::Date, Type::String),
])
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
// FIXME - need to support column paths
.rest(
"rest",
@@ -135,11 +145,12 @@ impl Command for SubCommand {
span: Span::test_data(),
}),
},
Example {
description: "convert date to string",
example: "date now | into string",
result: None,
},
// TODO: This should work but does not; see https://github.com/nushell/nushell/issues/7032
// Example {
// description: "convert date to string",
// example: "'2020-10-10 10:00:00 +02:00' | into datetime | into string",
// result: Some(Value::test_string("Sat Oct 10 10:00:00 2020")),
// },
Example {
description: "convert filepath to string",
example: "ls Cargo.toml | get name | into string",
@@ -147,8 +158,8 @@ impl Command for SubCommand {
},
Example {
description: "convert filesize to string",
example: "ls Cargo.toml | get size | into string",
result: None,
example: "1KiB | into string",
result: Some(Value::test_string("1,024 B")),
},
]
}