From f0cb2dafbbcc04897a0d2273ebf8aa3b9ae60270 Mon Sep 17 00:00:00 2001 From: Douglas <32344964+NotTheDr01ds@users.noreply.github.com> Date: Thu, 14 Nov 2024 04:07:37 -0500 Subject: [PATCH] Allow duration to be added to date (#14295) # Description Fixes #14294 - Turned out to be a whole lot easier than I expected, but please double-check me on this, since it's an area I haven't been in before. # User-Facing Changes Allow date to be added to a duration type. # Tests + Formatting Tests added: * Duration + Date is allowed * Duration - Date is not allowed --- crates/nu-parser/src/type_check.rs | 1 + crates/nu-protocol/src/value/mod.rs | 11 +++++++++++ tests/repl/test_type_check.rs | 12 ++++++++++++ 3 files changed, 24 insertions(+) diff --git a/crates/nu-parser/src/type_check.rs b/crates/nu-parser/src/type_check.rs index 1b66258ded..a7de3800e2 100644 --- a/crates/nu-parser/src/type_check.rs +++ b/crates/nu-parser/src/type_check.rs @@ -88,6 +88,7 @@ pub fn math_result_type( (Type::Float, Type::Number) => (Type::Number, None), (Type::String, Type::String) => (Type::String, None), (Type::Date, Type::Duration) => (Type::Date, None), + (Type::Duration, Type::Date) => (Type::Date, None), (Type::Duration, Type::Duration) => (Type::Duration, None), (Type::Filesize, Type::Filesize) => (Type::Filesize, None), diff --git a/crates/nu-protocol/src/value/mod.rs b/crates/nu-protocol/src/value/mod.rs index 26d8384cee..1a1e8fada2 100644 --- a/crates/nu-protocol/src/value/mod.rs +++ b/crates/nu-protocol/src/value/mod.rs @@ -2444,6 +2444,17 @@ impl Value { Ok(Value::string(lhs.to_string() + rhs, span)) } + (Value::Duration { val: lhs, .. }, Value::Date { val: rhs, .. }) => { + if let Some(val) = rhs.checked_add_signed(chrono::Duration::nanoseconds(*lhs)) { + Ok(Value::date(val, span)) + } else { + Err(ShellError::OperatorOverflow { + msg: "addition operation overflowed".into(), + span, + help: None, + }) + } + } (Value::Date { val: lhs, .. }, Value::Duration { val: rhs, .. }) => { if let Some(val) = lhs.checked_add_signed(chrono::Duration::nanoseconds(*rhs)) { Ok(Value::date(val, span)) diff --git a/tests/repl/test_type_check.rs b/tests/repl/test_type_check.rs index 8a00f2f486..95ef7f4323 100644 --- a/tests/repl/test_type_check.rs +++ b/tests/repl/test_type_check.rs @@ -37,6 +37,11 @@ fn date_minus_duration() -> TestResult { run_test(input, expected) } +#[test] +fn duration_minus_date_not_supported() -> TestResult { + fail_test("2day - 2023-04-22", "doesn't support these values") +} + #[test] fn date_plus_duration() -> TestResult { let input = "2023-04-18 + 2day | format date %Y-%m-%d"; @@ -44,6 +49,13 @@ fn date_plus_duration() -> TestResult { run_test(input, expected) } +#[test] +fn duration_plus_date() -> TestResult { + let input = "2024-11-10T00:00:00-00:00 + 4hr | format date"; + let expected = "Sun, 10 Nov 2024 04:00:00 +0000"; + run_test(input, expected) +} + #[test] fn block_not_first_class_def() -> TestResult { fail_test(