From: Bjørn Erik Pedersen Date: Wed, 22 Oct 2025 17:12:11 +0000 (+0200) Subject: Expand the numeric conversions to template funcs/methods X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=e08278d165399bd2d7d7331d966129a2faa268b2;p=brevno-suite%2Fhugo Expand the numeric conversions to template funcs/methods So the example mentioned in #14079 also works for TOML and JSON front matter. See #14079 --- diff --git a/common/hreflect/helpers.go b/common/hreflect/helpers.go index 6aa12de57..51be0d1cf 100644 --- a/common/hreflect/helpers.go +++ b/common/hreflect/helpers.go @@ -315,6 +315,7 @@ func IsContextType(tp reflect.Type) bool { // This is currently only implemented for int kinds, // added to handle the move to a new YAML library which produces uint64 for unsigned integers. // We can expand on this later if needed. +// This conversion is lossless. // See Issue 14079. func ConvertIfPossible(val reflect.Value, typ reflect.Type) (reflect.Value, bool) { if IsInt(typ.Kind()) { @@ -333,6 +334,21 @@ func ConvertIfPossible(val reflect.Value, typ reflect.Type) (reflect.Value, bool } return val.Convert(typ), true } + if IsFloat(val.Kind()) { + f := val.Float() + if f < float64(math.MinInt64) || f > float64(math.MaxInt64) { + return reflect.Value{}, false + } + i := int64(f) + if typ.OverflowInt(i) { + return reflect.Value{}, false + } + // Check for lossless conversion. + if float64(i) != f { + return reflect.Value{}, false + } + return val.Convert(typ), true + } } return reflect.Value{}, false } diff --git a/common/hreflect/helpers_test.go b/common/hreflect/helpers_test.go index 0b008a44e..28d3519cf 100644 --- a/common/hreflect/helpers_test.go +++ b/common/hreflect/helpers_test.go @@ -231,6 +231,33 @@ func TestCastIfPossible(t *testing.T) { ok: true, expected: int(math.MaxInt16), }, + // From float to int. + { + name: "float64(1.5) to int", + value: float64(1.5), + typ: int(0), + ok: false, // loss of precision + }, + { + name: "float64(1.0) to int", + value: float64(1.0), + typ: int(0), + ok: true, + expected: int(1), + }, + { + name: "float64(math.MaxFloat64) to int16", + value: float64(math.MaxFloat64), + typ: int16(0), + ok: false, // overflow + }, + { + name: "float64(32767) to int16", + value: float64(32767), + typ: int16(0), + ok: true, + expected: int16(32767), + }, } { v, ok := ConvertIfPossible(reflect.ValueOf(test.value), reflect.TypeOf(test.typ)) diff --git a/tpl/templates/templates_integration_test.go b/tpl/templates/templates_integration_test.go index d923d7c0b..a1bd9a193 100644 --- a/tpl/templates/templates_integration_test.go +++ b/tpl/templates/templates_integration_test.go @@ -327,11 +327,53 @@ myinteger: 2 -- layouts/all.html -- {{ $date := "2023-10-15T13:18:50-07:00" | time }} {{ $mydata := resources.Get "mydata.yaml" | transform.Unmarshal }} -date: {{ $date | time.Format "2006-01-06" }}| -date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-06" }}| +date: {{ $date | time.Format "2006-01-02" }}| +date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-02" }}| ` b := hugolib.Test(t, files) - b.AssertFileContent("public/index.html", "date: 2023-10-23|", "date+2y: 2025-10-25|") + b.AssertFileContent("public/index.html", "date: 2023-10-15", "date+2y: 2025-10-15") +} + +func TestTOMLAddDateIssue14079(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ["page", "section", "taxonomy", "term", "sitemap", "RSS"] +-- assets/mydata.toml -- +myinteger = 2 +-- layouts/all.html -- +{{ $date := "2023-10-15T13:18:50-07:00" | time }} +{{ $mydata := resources.Get "mydata.toml" | transform.Unmarshal }} +date: {{ $date | time.Format "2006-01-02" }}| +date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-02" }}| +` + + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", "date: 2023-10-15", "date+2y: 2025-10-15") +} + +func TestJSONAddDateIssue14079(t *testing.T) { + t.Parallel() + + files := ` +-- hugo.toml -- +disableKinds = ["page", "section", "taxonomy", "term", "sitemap", "RSS"] +-- assets/mydata.json -- +{ + "myinteger": 2 +} +-- layouts/all.html -- +{{ $date := "2023-10-15T13:18:50-07:00" | time }} +{{ $mydata := resources.Get "mydata.json" | transform.Unmarshal }} +date: {{ $date | time.Format "2006-01-02" }}| +date+2y: {{ $date.AddDate $mydata.myinteger 0 0 | time.Format "2006-01-02" }}| +` + + b := hugolib.Test(t, files) + + b.AssertFileContent("public/index.html", "date: 2023-10-15", "date+2y: 2025-10-15") }