]> git.maquefel.me Git - brevno-suite/hugo/commitdiff
Expand the numeric conversions to template funcs/methods
authorBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 22 Oct 2025 17:12:11 +0000 (19:12 +0200)
committerBjørn Erik Pedersen <bjorn.erik.pedersen@gmail.com>
Wed, 22 Oct 2025 19:04:39 +0000 (21:04 +0200)
So the example mentioned in #14079 also works for TOML and JSON front matter.

See #14079

common/hreflect/helpers.go
common/hreflect/helpers_test.go
tpl/templates/templates_integration_test.go

index 6aa12de573a5f58b465725e3143c6e58cbf39471..51be0d1cf8451ba2cc3b032674800b8b5bf311f3 100644 (file)
@@ -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
 }
index 0b008a44ec56192a0c488a1b329c6aceef615ae2..28d3519cf139fc8883e5a3b4a91547b3b3a766a3 100644 (file)
@@ -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))
index d923d7c0bf72d1bd457972c5f99e52d6edc17ba8..a1bd9a1937c73624601f27e825407dc8f9d9c9f4 100644 (file)
@@ -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")
 }