diff --git a/template.go b/template.go index 67fd7ebd2..7bd28bda3 100644 --- a/template.go +++ b/template.go @@ -107,10 +107,23 @@ func RunTemplate(environment map[string]any, template Template) (string, error) if err != nil { return "", err } - out, _, err := prg.Eval(environment) + + // Convert environment to json otherwise structs will not be casted to cel-go's ref.Val + envJSONRaw, err := json.Marshal(environment) + if err != nil { + return "", fmt.Errorf("failed to marshal environment: %v", err) + } + + var envJSON map[string]any + if err := json.Unmarshal(envJSONRaw, &envJSON); err != nil { + return "", fmt.Errorf("failed to unmarshal environment: %v", err) + } + + out, _, err := prg.Eval(envJSON) if err != nil { return "", err } + return fmt.Sprintf("%v", out.Value()), nil } diff --git a/template_test.go b/template_test.go index 50c5685b5..23b94dc57 100644 --- a/template_test.go +++ b/template_test.go @@ -67,6 +67,15 @@ func TestGomplate(t *testing.T) { } func TestCel(t *testing.T) { + type Address struct { + City string `json:"city"` + } + + type Person struct { + Name string `json:"name"` + Address Address `json:"address"` + } + tests := []struct { env map[string]interface{} expression string @@ -101,6 +110,20 @@ func TestCel(t *testing.T) { {nil, `"hello, world".replace("world", "team")`, "hello, team"}, // strings lib {nil, `sets.contains([1, 2, 3, 4], [2, 3])`, "true"}, // sets lib {nil, `[1,2,3,4].slice(1, 3)`, "[2 3]"}, // lists lib + + // Support structs as environment var (by default they are not) + { + map[string]any{ + "results": Person{ + Name: "Aditya", + Address: Address{ + City: "Kathmandu", + }, + }, + }, + `results.address.city == "Kathmandu" && results.name == "Aditya"`, + "true", + }, } for _, tc := range tests {