From 2ea42f296c458c4e268f2199137b7068687ebd19 Mon Sep 17 00:00:00 2001 From: gorogoroumaru Date: Sat, 22 Aug 2020 12:46:48 +0900 Subject: [PATCH] Date subcommands (#2383) * refactored date command * format files --- crates/nu-cli/src/cli.rs | 4 +- crates/nu-cli/src/commands.rs | 2 +- crates/nu-cli/src/commands/date.rs | 175 ---------------------- crates/nu-cli/src/commands/date/format.rs | 63 ++++++++ crates/nu-cli/src/commands/date/mod.rs | 9 ++ crates/nu-cli/src/commands/date/now.rs | 50 +++++++ crates/nu-cli/src/commands/date/utc.rs | 50 +++++++ crates/nu-cli/src/commands/date/utils.rs | 64 ++++++++ 8 files changed, 240 insertions(+), 177 deletions(-) delete mode 100644 crates/nu-cli/src/commands/date.rs create mode 100644 crates/nu-cli/src/commands/date/format.rs create mode 100644 crates/nu-cli/src/commands/date/mod.rs create mode 100644 crates/nu-cli/src/commands/date/now.rs create mode 100644 crates/nu-cli/src/commands/date/utc.rs create mode 100644 crates/nu-cli/src/commands/date/utils.rs diff --git a/crates/nu-cli/src/cli.rs b/crates/nu-cli/src/cli.rs index 357cfcaf85..263e464ef8 100644 --- a/crates/nu-cli/src/cli.rs +++ b/crates/nu-cli/src/cli.rs @@ -261,7 +261,9 @@ pub fn create_default_context( whole_stream_command(Save), whole_stream_command(Touch), whole_stream_command(Cpy), - whole_stream_command(Date), + whole_stream_command(DateNow), + whole_stream_command(DateUTC), + whole_stream_command(DateFormat), whole_stream_command(Cal), whole_stream_command(Mkdir), whole_stream_command(Mv), diff --git a/crates/nu-cli/src/commands.rs b/crates/nu-cli/src/commands.rs index c360a401e4..046fa6e625 100644 --- a/crates/nu-cli/src/commands.rs +++ b/crates/nu-cli/src/commands.rs @@ -147,7 +147,7 @@ pub(crate) use config::{ }; pub(crate) use count::Count; pub(crate) use cp::Cpy; -pub(crate) use date::Date; +pub(crate) use date::{DateFormat, DateNow, DateUTC}; pub(crate) use debug::Debug; pub(crate) use default::Default; pub(crate) use do_::Do; diff --git a/crates/nu-cli/src/commands/date.rs b/crates/nu-cli/src/commands/date.rs deleted file mode 100644 index 74a445995c..0000000000 --- a/crates/nu-cli/src/commands/date.rs +++ /dev/null @@ -1,175 +0,0 @@ -use crate::prelude::*; -use chrono::{DateTime, Local, Utc}; -use nu_errors::ShellError; -use nu_protocol::{Dictionary, Value}; - -use crate::commands::WholeStreamCommand; -use chrono::{Datelike, TimeZone, Timelike}; -use core::fmt::Display; -use indexmap::IndexMap; -use nu_protocol::{Signature, SyntaxShape, UntaggedValue}; - -pub struct Date; - -#[async_trait] -impl WholeStreamCommand for Date { - fn name(&self) -> &str { - "date" - } - - fn signature(&self) -> Signature { - Signature::build("date") - .switch("utc", "use universal time (UTC)", Some('u')) - .switch("local", "use the local time", Some('l')) - .named( - "format", - SyntaxShape::String, - "report datetime in supplied strftime format", - Some('f'), - ) - .switch("raw", "print date without tables", Some('r')) - } - - fn usage(&self) -> &str { - "Get the current datetime." - } - - async fn run( - &self, - args: CommandArgs, - registry: &CommandRegistry, - ) -> Result { - date(args, registry).await - } - - fn examples(&self) -> Vec { - vec![ - Example { - description: "Get the current local time and date", - example: "date", - result: None, - }, - Example { - description: "Get the current UTC time and date", - example: "date --utc", - result: None, - }, - Example { - description: "Get the current time and date and report it based on format", - example: "date --format '%Y-%m-%d %H:%M:%S.%f %z'", - result: None, - }, - Example { - description: "Get the current time and date and report it without a table", - example: "date --format '%Y-%m-%d %H:%M:%S.%f %z' --raw", - result: None, - }, - ] - } -} - -pub fn date_to_value_raw(dt: DateTime, dt_format: String) -> String -where - T::Offset: Display, -{ - let result = dt.format(&dt_format); - format!("{}", result) -} - -pub fn date_to_value(dt: DateTime, tag: Tag, dt_format: String) -> Value -where - T::Offset: Display, -{ - let mut indexmap = IndexMap::new(); - - if dt_format.is_empty() { - indexmap.insert( - "year".to_string(), - UntaggedValue::int(dt.year()).into_value(&tag), - ); - indexmap.insert( - "month".to_string(), - UntaggedValue::int(dt.month()).into_value(&tag), - ); - indexmap.insert( - "day".to_string(), - UntaggedValue::int(dt.day()).into_value(&tag), - ); - indexmap.insert( - "hour".to_string(), - UntaggedValue::int(dt.hour()).into_value(&tag), - ); - indexmap.insert( - "minute".to_string(), - UntaggedValue::int(dt.minute()).into_value(&tag), - ); - indexmap.insert( - "second".to_string(), - UntaggedValue::int(dt.second()).into_value(&tag), - ); - - let tz = dt.offset(); - indexmap.insert( - "timezone".to_string(), - UntaggedValue::string(format!("{}", tz)).into_value(&tag), - ); - } else { - let result = dt.format(&dt_format); - indexmap.insert( - "formatted".to_string(), - UntaggedValue::string(format!("{}", result)).into_value(&tag), - ); - } - - UntaggedValue::Row(Dictionary::from(indexmap)).into_value(&tag) -} - -pub async fn date( - args: CommandArgs, - registry: &CommandRegistry, -) -> Result { - let registry = registry.clone(); - let args = args.evaluate_once(®istry).await?; - let tag = args.call_info.name_tag.clone(); - let raw = args.has("raw"); - - let dt_fmt = if args.has("format") { - if let Some(dt_fmt) = args.get("format") { - dt_fmt.convert_to_string() - } else { - "".to_string() - } - } else { - "".to_string() - }; - - let value = if args.has("utc") { - let utc: DateTime = Utc::now(); - if raw { - UntaggedValue::string(date_to_value_raw(utc, dt_fmt)).into_untagged_value() - } else { - date_to_value(utc, tag, dt_fmt) - } - } else { - let local: DateTime = Local::now(); - if raw { - UntaggedValue::string(date_to_value_raw(local, dt_fmt)).into_untagged_value() - } else { - date_to_value(local, tag, dt_fmt) - } - }; - - Ok(OutputStream::one(value)) -} - -#[cfg(test)] -mod tests { - use super::Date; - - #[test] - fn examples_work_as_expected() { - use crate::examples::test as test_examples; - - test_examples(Date {}) - } -} diff --git a/crates/nu-cli/src/commands/date/format.rs b/crates/nu-cli/src/commands/date/format.rs new file mode 100644 index 0000000000..5dc6038b4e --- /dev/null +++ b/crates/nu-cli/src/commands/date/format.rs @@ -0,0 +1,63 @@ +use crate::prelude::*; +use chrono::{DateTime, Local}; +use nu_errors::ShellError; + +use crate::commands::date::utils::{date_to_value, date_to_value_raw}; +use crate::commands::WholeStreamCommand; +use nu_protocol::{Signature, SyntaxShape, UntaggedValue}; +use nu_source::Tagged; + +pub struct Date; + +#[derive(Deserialize)] +pub struct FormatArgs { + format: Tagged, + raw: Option, +} + +#[async_trait] +impl WholeStreamCommand for Date { + fn name(&self) -> &str { + "date format" + } + + fn signature(&self) -> Signature { + Signature::build("date format") + .required("format", SyntaxShape::String, "strftime format") + .switch("raw", "print date without tables", Some('r')) + } + + fn usage(&self) -> &str { + "format the current date using the given format string." + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + format(args, registry).await + } +} + +pub async fn format( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let registry = registry.clone(); + let tag = args.call_info.name_tag.clone(); + let (FormatArgs { format, raw }, _) = args.process(®istry).await?; + + let dt_fmt = format.to_string(); + + let value = { + let local: DateTime = Local::now(); + if let Some(true) = raw { + UntaggedValue::string(date_to_value_raw(local, dt_fmt)).into_untagged_value() + } else { + date_to_value(local, tag, dt_fmt) + } + }; + + Ok(OutputStream::one(value)) +} diff --git a/crates/nu-cli/src/commands/date/mod.rs b/crates/nu-cli/src/commands/date/mod.rs new file mode 100644 index 0000000000..6fcffd68ec --- /dev/null +++ b/crates/nu-cli/src/commands/date/mod.rs @@ -0,0 +1,9 @@ +pub mod format; +pub mod now; +pub mod utc; + +mod utils; + +pub use format::Date as DateFormat; +pub use now::Date as DateNow; +pub use utc::Date as DateUTC; diff --git a/crates/nu-cli/src/commands/date/now.rs b/crates/nu-cli/src/commands/date/now.rs new file mode 100644 index 0000000000..ebe608a0db --- /dev/null +++ b/crates/nu-cli/src/commands/date/now.rs @@ -0,0 +1,50 @@ +use crate::prelude::*; +use chrono::{DateTime, Local}; +use nu_errors::ShellError; + +use crate::commands::date::utils::date_to_value; +use crate::commands::WholeStreamCommand; +use nu_protocol::Signature; + +pub struct Date; + +#[async_trait] +impl WholeStreamCommand for Date { + fn name(&self) -> &str { + "date now" + } + + fn signature(&self) -> Signature { + Signature::build("date now") + } + + fn usage(&self) -> &str { + "return the current date." + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + now(args, registry).await + } +} + +pub async fn now( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let registry = registry.clone(); + let args = args.evaluate_once(®istry).await?; + let tag = args.call_info.name_tag.clone(); + + let no_fmt = "".to_string(); + + let value = { + let local: DateTime = Local::now(); + date_to_value(local, tag, no_fmt) + }; + + Ok(OutputStream::one(value)) +} diff --git a/crates/nu-cli/src/commands/date/utc.rs b/crates/nu-cli/src/commands/date/utc.rs new file mode 100644 index 0000000000..4dbaca688c --- /dev/null +++ b/crates/nu-cli/src/commands/date/utc.rs @@ -0,0 +1,50 @@ +use crate::prelude::*; +use chrono::{DateTime, Utc}; +use nu_errors::ShellError; + +use crate::commands::date::utils::date_to_value; +use crate::commands::WholeStreamCommand; +use nu_protocol::Signature; + +pub struct Date; + +#[async_trait] +impl WholeStreamCommand for Date { + fn name(&self) -> &str { + "date utc" + } + + fn signature(&self) -> Signature { + Signature::build("date utc") + } + + fn usage(&self) -> &str { + "return the current date in utc." + } + + async fn run( + &self, + args: CommandArgs, + registry: &CommandRegistry, + ) -> Result { + utc(args, registry).await + } +} + +pub async fn utc( + args: CommandArgs, + registry: &CommandRegistry, +) -> Result { + let registry = registry.clone(); + let args = args.evaluate_once(®istry).await?; + let tag = args.call_info.name_tag.clone(); + + let no_fmt = "".to_string(); + + let value = { + let local: DateTime = Utc::now(); + date_to_value(local, tag, no_fmt) + }; + + Ok(OutputStream::one(value)) +} diff --git a/crates/nu-cli/src/commands/date/utils.rs b/crates/nu-cli/src/commands/date/utils.rs new file mode 100644 index 0000000000..026a26dcb9 --- /dev/null +++ b/crates/nu-cli/src/commands/date/utils.rs @@ -0,0 +1,64 @@ +use crate::prelude::*; +use chrono::DateTime; +use nu_protocol::{Dictionary, Value}; + +use chrono::{Datelike, TimeZone, Timelike}; +use core::fmt::Display; +use indexmap::IndexMap; +use nu_protocol::UntaggedValue; + +pub fn date_to_value_raw(dt: DateTime, dt_format: String) -> String +where + T::Offset: Display, +{ + let result = dt.format(&dt_format); + format!("{}", result) +} + +pub fn date_to_value(dt: DateTime, tag: Tag, dt_format: String) -> Value +where + T::Offset: Display, +{ + let mut indexmap = IndexMap::new(); + + if dt_format.is_empty() { + indexmap.insert( + "year".to_string(), + UntaggedValue::int(dt.year()).into_value(&tag), + ); + indexmap.insert( + "month".to_string(), + UntaggedValue::int(dt.month()).into_value(&tag), + ); + indexmap.insert( + "day".to_string(), + UntaggedValue::int(dt.day()).into_value(&tag), + ); + indexmap.insert( + "hour".to_string(), + UntaggedValue::int(dt.hour()).into_value(&tag), + ); + indexmap.insert( + "minute".to_string(), + UntaggedValue::int(dt.minute()).into_value(&tag), + ); + indexmap.insert( + "second".to_string(), + UntaggedValue::int(dt.second()).into_value(&tag), + ); + + let tz = dt.offset(); + indexmap.insert( + "timezone".to_string(), + UntaggedValue::string(format!("{}", tz)).into_value(&tag), + ); + } else { + let result = dt.format(&dt_format); + indexmap.insert( + "formatted".to_string(), + UntaggedValue::string(format!("{}", result)).into_value(&tag), + ); + } + + UntaggedValue::Row(Dictionary::from(indexmap)).into_value(&tag) +}