mirror of
https://github.com/nushell/nushell.git
synced 2025-08-09 18:57:44 +02:00
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:
@ -4,7 +4,8 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::{
|
||||
ast::Call,
|
||||
engine::{Command, EngineState, Stack},
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type,
|
||||
Value,
|
||||
};
|
||||
use nu_utils::locale::get_system_locale_string;
|
||||
use std::fmt::{Display, Write};
|
||||
@ -21,6 +22,11 @@ impl Command for SubCommand {
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date format")
|
||||
.input_output_types(vec![
|
||||
(Type::Date, Type::String),
|
||||
(Type::String, Type::String),
|
||||
])
|
||||
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
|
||||
.switch("list", "lists strftime cheatsheet", Some('l'))
|
||||
.optional(
|
||||
"format string",
|
||||
@ -66,8 +72,18 @@ impl Command for SubCommand {
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
// TODO: This should work but does not; see https://github.com/nushell/nushell/issues/7032
|
||||
// Example {
|
||||
// description: "Format a given date-time using the default format (RFC 2822).",
|
||||
// example: r#"'2021-10-22 20:00:12 +01:00' | into datetime | date format"#,
|
||||
// result: Some(Value::String {
|
||||
// val: "Fri, 22 Oct 2021 20:00:12 +0100".to_string(),
|
||||
// span: Span::test_data(),
|
||||
// }),
|
||||
// },
|
||||
Example {
|
||||
description: "Format a given date using the default format (RFC 2822).",
|
||||
description:
|
||||
"Format a given date-time as a string using the default format (RFC 2822).",
|
||||
example: r#""2021-10-22 20:00:12 +01:00" | date format"#,
|
||||
result: Some(Value::String {
|
||||
val: "Fri, 22 Oct 2021 20:00:12 +0100".to_string(),
|
||||
@ -75,13 +91,13 @@ impl Command for SubCommand {
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Format a given date using a given format string.",
|
||||
example: "date format '%Y-%m-%d'",
|
||||
description: "Format the current date-time using a given format string.",
|
||||
example: r#"date now | date format "%Y-%m-%d %H:%M:%S""#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Format a given date using a given format string.",
|
||||
example: r#"date format "%Y-%m-%d %H:%M:%S""#,
|
||||
description: "Format the current date using a given format string.",
|
||||
example: r#"date now | date format "%Y-%m-%d %H:%M:%S""#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
|
@ -3,7 +3,7 @@ use chrono::{DateTime, FixedOffset, Local};
|
||||
use chrono_humanize::HumanTime;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Value};
|
||||
use nu_protocol::{Category, Example, PipelineData, ShellError, Signature, Span, Type, Value};
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -13,7 +13,13 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date humanize").category(Category::Date)
|
||||
Signature::build("date humanize")
|
||||
.input_output_types(vec![
|
||||
(Type::Date, Type::String),
|
||||
(Type::String, Type::String),
|
||||
])
|
||||
.allow_variants_without_examples(true)
|
||||
.category(Category::Date)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -45,21 +51,11 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
vec![
|
||||
Example {
|
||||
description: "Print a 'humanized' format for the date, relative to now.",
|
||||
example: "date humanize",
|
||||
result: Some(Value::String {
|
||||
val: "now".to_string(),
|
||||
span: Span::test_data(),
|
||||
}),
|
||||
},
|
||||
Example {
|
||||
description: "Print a 'humanized' format for the date, relative to now.",
|
||||
example: r#""2021-10-22 20:00:12 +01:00" | date humanize"#,
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
vec![Example {
|
||||
description: "Print a 'humanized' format for the date, relative to now.",
|
||||
example: r#""2021-10-22 20:00:12 +01:00" | date humanize"#,
|
||||
result: None,
|
||||
}]
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@ use chrono_tz::TZ_VARIANTS;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Category, Example, IntoInterruptiblePipelineData, PipelineData, Signature, Span, Value,
|
||||
Category, Example, IntoInterruptiblePipelineData, PipelineData, Signature, Span, Type, Value,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
@ -14,7 +14,9 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date list-timezone").category(Category::Date)
|
||||
Signature::build("date list-timezone")
|
||||
.input_output_types(vec![(Type::Nothing, Type::Table(vec![]))])
|
||||
.category(Category::Date)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
|
@ -1,7 +1,7 @@
|
||||
use chrono::Local;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{Category, Example, IntoPipelineData, PipelineData, Signature, Value};
|
||||
use nu_protocol::{Category, Example, IntoPipelineData, PipelineData, Signature, Type, Value};
|
||||
#[derive(Clone)]
|
||||
pub struct SubCommand;
|
||||
|
||||
@ -11,7 +11,9 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date now").category(Category::Date)
|
||||
Signature::build("date now")
|
||||
.input_output_types(vec![(Type::Nothing, Type::Date)])
|
||||
.category(Category::Date)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
|
@ -2,6 +2,7 @@ use crate::date::utils::parse_date_from_string;
|
||||
use chrono::{DateTime, Datelike, FixedOffset, Local, Timelike};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::Type;
|
||||
use nu_protocol::{
|
||||
Category, Example, PipelineData, ShellError::DatetimeParseError, Signature, Span, Value,
|
||||
};
|
||||
@ -15,11 +16,17 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date to-record").category(Category::Date)
|
||||
Signature::build("date to-record")
|
||||
.input_output_types(vec![
|
||||
(Type::Date, Type::Record(vec![])),
|
||||
(Type::String, Type::Record(vec![])),
|
||||
])
|
||||
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
|
||||
.category(Category::Date)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
"Convert the date into a structured table."
|
||||
"Convert the date into a record."
|
||||
}
|
||||
|
||||
fn search_terms(&self) -> Vec<&str> {
|
||||
@ -38,46 +45,54 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
let example_result_1 = || {
|
||||
let span = Span::test_data();
|
||||
let cols = vec![
|
||||
"year".into(),
|
||||
"month".into(),
|
||||
"day".into(),
|
||||
"hour".into(),
|
||||
"minute".into(),
|
||||
"second".into(),
|
||||
"timezone".into(),
|
||||
];
|
||||
let vals = vec![
|
||||
Value::Int { val: 2020, span },
|
||||
Value::Int { val: 4, span },
|
||||
Value::Int { val: 12, span },
|
||||
Value::Int { val: 22, span },
|
||||
Value::Int { val: 10, span },
|
||||
Value::Int { val: 57, span },
|
||||
Value::String {
|
||||
val: "+02:00".to_string(),
|
||||
span,
|
||||
},
|
||||
];
|
||||
Some(Value::Record { cols, vals, span })
|
||||
};
|
||||
|
||||
vec![
|
||||
Example {
|
||||
description: "Convert the current date into a structured table.",
|
||||
example: "date to-table",
|
||||
description: "Convert the current date into a record.",
|
||||
example: "date to-record",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Convert the current date into a structured table.",
|
||||
description: "Convert the current date into a record.",
|
||||
example: "date now | date to-record",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Convert a given date into a structured table.",
|
||||
example: " '2020-04-12 22:10:57 +0200' | date to-record",
|
||||
result: {
|
||||
let span = Span::test_data();
|
||||
let cols = vec![
|
||||
"year".into(),
|
||||
"month".into(),
|
||||
"day".into(),
|
||||
"hour".into(),
|
||||
"minute".into(),
|
||||
"second".into(),
|
||||
"timezone".into(),
|
||||
];
|
||||
let vals = vec![
|
||||
Value::Int { val: 2020, span },
|
||||
Value::Int { val: 4, span },
|
||||
Value::Int { val: 12, span },
|
||||
Value::Int { val: 22, span },
|
||||
Value::Int { val: 10, span },
|
||||
Value::Int { val: 57, span },
|
||||
Value::String {
|
||||
val: "+02:00".to_string(),
|
||||
span,
|
||||
},
|
||||
];
|
||||
Some(Value::Record { cols, vals, span })
|
||||
},
|
||||
description: "Convert a date string into a record.",
|
||||
example: "'2020-04-12 22:10:57 +0200' | date to-record",
|
||||
result: example_result_1(),
|
||||
},
|
||||
// TODO: This should work but does not; see https://github.com/nushell/nushell/issues/7032
|
||||
// Example {
|
||||
// description: "Convert a date into a record.",
|
||||
// example: "'2020-04-12 22:10:57 +0200' | into datetime | date to-record",
|
||||
// result: example_result_1(),
|
||||
// },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ use crate::date::utils::parse_date_from_string;
|
||||
use chrono::{DateTime, Datelike, FixedOffset, Local, Timelike};
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::Type;
|
||||
use nu_protocol::{
|
||||
Category, Example, PipelineData, ShellError::DatetimeParseError, Signature, Span, Value,
|
||||
};
|
||||
@ -15,7 +16,13 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date to-table").category(Category::Date)
|
||||
Signature::build("date to-table")
|
||||
.input_output_types(vec![
|
||||
(Type::Date, Type::Table(vec![])),
|
||||
(Type::String, Type::Table(vec![])),
|
||||
])
|
||||
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
|
||||
.category(Category::Date)
|
||||
}
|
||||
|
||||
fn usage(&self) -> &str {
|
||||
@ -38,49 +45,57 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
let example_result_1 = || {
|
||||
let span = Span::test_data();
|
||||
let cols = vec![
|
||||
"year".into(),
|
||||
"month".into(),
|
||||
"day".into(),
|
||||
"hour".into(),
|
||||
"minute".into(),
|
||||
"second".into(),
|
||||
"timezone".into(),
|
||||
];
|
||||
let vals = vec![
|
||||
Value::Int { val: 2020, span },
|
||||
Value::Int { val: 4, span },
|
||||
Value::Int { val: 12, span },
|
||||
Value::Int { val: 22, span },
|
||||
Value::Int { val: 10, span },
|
||||
Value::Int { val: 57, span },
|
||||
Value::String {
|
||||
val: "+02:00".to_string(),
|
||||
span,
|
||||
},
|
||||
];
|
||||
Some(Value::List {
|
||||
vals: vec![Value::Record { cols, vals, span }],
|
||||
span,
|
||||
})
|
||||
};
|
||||
|
||||
vec![
|
||||
Example {
|
||||
description: "Convert the date into a structured table.",
|
||||
description: "Convert the current date into a table.",
|
||||
example: "date to-table",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Convert the date into a structured table.",
|
||||
description: "Convert the date into a table.",
|
||||
example: "date now | date to-table",
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Convert a given date into a structured table.",
|
||||
example: " '2020-04-12 22:10:57 +0200' | date to-table",
|
||||
result: {
|
||||
let span = Span::test_data();
|
||||
let cols = vec![
|
||||
"year".into(),
|
||||
"month".into(),
|
||||
"day".into(),
|
||||
"hour".into(),
|
||||
"minute".into(),
|
||||
"second".into(),
|
||||
"timezone".into(),
|
||||
];
|
||||
let vals = vec![
|
||||
Value::Int { val: 2020, span },
|
||||
Value::Int { val: 4, span },
|
||||
Value::Int { val: 12, span },
|
||||
Value::Int { val: 22, span },
|
||||
Value::Int { val: 10, span },
|
||||
Value::Int { val: 57, span },
|
||||
Value::String {
|
||||
val: "+02:00".to_string(),
|
||||
span,
|
||||
},
|
||||
];
|
||||
Some(Value::List {
|
||||
vals: vec![Value::Record { cols, vals, span }],
|
||||
span,
|
||||
})
|
||||
},
|
||||
description: "Convert a given date into a table.",
|
||||
example: "'2020-04-12 22:10:57 +0200' | date to-table",
|
||||
result: example_result_1(),
|
||||
},
|
||||
// TODO: This should work but does not; see https://github.com/nushell/nushell/issues/7032
|
||||
// Example {
|
||||
// description: "Convert a given date into a table.",
|
||||
// example: "'2020-04-12 22:10:57 +0200' | into datetime | date to-table",
|
||||
// result: example_result_1(),
|
||||
// },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ use nu_engine::CallExt;
|
||||
use nu_protocol::ast::Call;
|
||||
use nu_protocol::engine::{Command, EngineState, Stack};
|
||||
use nu_protocol::{
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Value,
|
||||
Category, Example, PipelineData, ShellError, Signature, Span, Spanned, SyntaxShape, Type, Value,
|
||||
};
|
||||
|
||||
use chrono::{FixedOffset, TimeZone};
|
||||
@ -20,6 +20,8 @@ impl Command for SubCommand {
|
||||
|
||||
fn signature(&self) -> Signature {
|
||||
Signature::build("date to-timezone")
|
||||
.input_output_types(vec![(Type::Date, Type::Date), (Type::String, Type::Date)])
|
||||
.allow_variants_without_examples(true) // https://github.com/nushell/nushell/issues/7032
|
||||
.required("time zone", SyntaxShape::String, "time zone description")
|
||||
.category(Category::Date)
|
||||
}
|
||||
@ -62,6 +64,16 @@ impl Command for SubCommand {
|
||||
}
|
||||
|
||||
fn examples(&self) -> Vec<Example> {
|
||||
let example_result_1 = || {
|
||||
let dt = FixedOffset::east(5 * 3600)
|
||||
.ymd(2020, 10, 10)
|
||||
.and_hms(13, 00, 00);
|
||||
Some(Value::Date {
|
||||
val: dt,
|
||||
span: Span::test_data(),
|
||||
})
|
||||
};
|
||||
|
||||
vec![
|
||||
Example {
|
||||
description: "Get the current date in UTC+05:00",
|
||||
@ -81,19 +93,14 @@ impl Command for SubCommand {
|
||||
Example {
|
||||
description: "Get the current date in Hawaii",
|
||||
example: r#""2020-10-10 10:00:00 +02:00" | date to-timezone "+0500""#,
|
||||
// result: None
|
||||
// The following should be the result of the test, but it fails. Cannot figure it out why.
|
||||
result: {
|
||||
let dt = FixedOffset::east(5 * 3600)
|
||||
.ymd(2020, 10, 10)
|
||||
.and_hms(13, 00, 00);
|
||||
|
||||
Some(Value::Date {
|
||||
val: dt,
|
||||
span: Span::test_data(),
|
||||
})
|
||||
},
|
||||
result: example_result_1(),
|
||||
},
|
||||
// TODO: This should work but does not; see https://github.com/nushell/nushell/issues/7032
|
||||
// Example {
|
||||
// description: "Get the current date in Hawaii, from a datetime object",
|
||||
// example: r#""2020-10-10 10:00:00 +02:00" | into datetime | date to-timezone "+0500""#,
|
||||
// result: example_result_1(),
|
||||
// },
|
||||
]
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user