Skip to content

Commit

Permalink
feat: support templating map struct fields whose map values are also map
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe committed Apr 16, 2024
1 parent 632727b commit 018b085
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 3 deletions.
28 changes: 25 additions & 3 deletions structtemplater.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package gomplate

import (
"encoding/json"
"reflect"
"strings"

Expand Down Expand Up @@ -60,13 +61,34 @@ func (w StructTemplater) StructField(f reflect.StructField, v reflect.Value) err
return err
}

if val.Kind() == reflect.String {
newVal, err := w.Template(val.String())
concreteVal := reflect.ValueOf(val.Interface())
switch concreteVal.Kind() {
case reflect.String:
newVal, err := w.Template(concreteVal.String())
if err != nil {
return err
}
newMap.SetMapIndex(newKey, reflect.ValueOf(newVal))
} else {

case reflect.Map:
marshalled, err := json.Marshal(val.Interface())
if err != nil {
newMap.SetMapIndex(newKey, val)
} else {
templated, err := w.Template(string(marshalled))
if err != nil {
return err
}

var unmarshalled map[string]any
if err := json.Unmarshal([]byte(templated), &unmarshalled); err != nil {
newMap.SetMapIndex(newKey, val)
} else {
newMap.SetMapIndex(newKey, reflect.ValueOf(unmarshalled))
}
}

default:
newMap.SetMapIndex(newKey, val)
}
}
Expand Down
43 changes: 43 additions & 0 deletions structtemplater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type Test struct {
Template string `template:"true"`
NoTemplate string
Inner Inner
JSONMap map[string]any `template:"true"`
Labels map[string]string `template:"true"`
LabelsRaw map[string]string
}
Expand Down Expand Up @@ -108,6 +109,48 @@ var tests = []test{
},
},
},
{
name: "deeply nested map",
StructTemplater: StructTemplater{
RequiredTag: "template",
ValueFunctions: true,
Values: map[string]interface{}{
"msg": "world",
},
},
Input: &Test{
Template: "{{msg}}",
JSONMap: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": "{{msg}}",
},
"j": []map[string]any{
{
"l": "{{msg}}",
},
},
},
"e": "hello {{msg}}",
},
},
Output: &Test{
Template: "world",
JSONMap: map[string]any{
"a": map[string]any{
"b": map[string]any{
"c": "world",
},
"j": []any{
map[string]any{
"l": "world",
},
},
},
"e": "hello world",
},
},
},
}

func TestMain(t *testing.T) {
Expand Down

0 comments on commit 018b085

Please sign in to comment.