From a414bac7d3e96ab00876c4571eabb8198f7722c5 Mon Sep 17 00:00:00 2001 From: Atomys Date: Thu, 9 May 2024 20:22:44 +0200 Subject: [PATCH] feat: introduce toduration conversion function (#27) ## Description This pull request introduce the `toDuration` as proposed in #8 and https://github.com/Masterminds/sprig/issues/388 using the `cast` package. ## Changes - Add the function `toDuration` ## Fixes #8 ## Checklist - [x] I have read the **CONTRIBUTING.md** document. - [x] My code follows the code style of this project. - [x] I have added tests to cover my changes. - [x] All new and existing tests passed. - [ ] I have updated the documentation accordingly. - [x] This change requires a change to the documentation on the website. --- conversion_functions.go | 17 +++++++++++++++++ conversion_functions_test.go | 13 +++++++++++++ sprout.go | 1 + 3 files changed, 31 insertions(+) diff --git a/conversion_functions.go b/conversion_functions.go index 7f3195a..4e0dc2e 100644 --- a/conversion_functions.go +++ b/conversion_functions.go @@ -128,6 +128,23 @@ func (fh *FunctionHandler) ToDate(fmt, str string) time.Time { return result } +// ToDuration converts a value to a time.Duration. +// +// Parameters: +// +// v any - the value to convert to time.Duration. This value can be a string, int, or another compatible type. +// +// Returns: +// +// time.Duration - the duration representation of the value. +// +// Example: +// +// {{ (toDuration "1h30m").Seconds }} // Output: 5400 +func (fh *FunctionHandler) ToDuration(v any) time.Duration { + return cast.ToDuration(v) +} + // MustToDate tries to parse a string into a time.Time object based on a format, // returning an error if parsing fails. // diff --git a/conversion_functions_test.go b/conversion_functions_test.go index 2a103b0..6f7dbe2 100644 --- a/conversion_functions_test.go +++ b/conversion_functions_test.go @@ -82,6 +82,19 @@ func TestToDate(t *testing.T) { runTestCases(t, tests) } +func TestToDuration(t *testing.T) { + var tests = testCases{ + {"TestInt", `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, "time.Duration-1ns", map[string]any{"V": 1}}, + {"TestInt32", `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, "time.Duration-1µs", map[string]any{"V": int32(1000)}}, + {"TestFloat64", `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, "time.Duration-1.00042ms", map[string]any{"V": float64(1000 * 1000.42)}}, + {"TestString", `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, "time.Duration-1m0s", map[string]any{"V": "1m"}}, + {"TestInvalid", `{{$v := toDuration .V }}{{typeOf $v}}-{{$v}}`, "time.Duration-0s", map[string]any{"V": "aaaa"}}, + {"TestCallingOnIt", `{{ (toDuration "1h30m").Seconds }}`, "5400", nil}, + } + + runTestCases(t, tests) +} + func TestMustToDate(t *testing.T) { var tests = mustTestCases{ {testCase{"TestDate", `{{$v := mustToDate "2006-01-02" .V }}{{typeOf $v}}-{{$v}}`, "time.Time-2024-05-09 00:00:00 +0000 UTC", map[string]any{"V": "2024-05-09"}}, ""}, diff --git a/sprout.go b/sprout.go index 8cad5a2..ecd7a2d 100644 --- a/sprout.go +++ b/sprout.go @@ -154,6 +154,7 @@ func FuncMap(opts ...FunctionHandlerOption) template.FuncMap { fnHandler.funcMap["toFloat64"] = fnHandler.ToFloat64 fnHandler.funcMap["seq"] = fnHandler.Seq fnHandler.funcMap["toOctal"] = fnHandler.ToOctal + fnHandler.funcMap["toDuration"] = fnHandler.ToDuration fnHandler.funcMap["split"] = fnHandler.Split fnHandler.funcMap["splitList"] = fnHandler.SplitList fnHandler.funcMap["splitn"] = fnHandler.Splitn