@@ -409,16 +409,54 @@ func interpolationFuncJoin() ast.Function {
409409}
410410
411411// interpolationFuncJSONEncode implements the "jsonencode" function that encodes
412- // a string as its JSON representation.
412+ // a string, list, or map as its JSON representation. For now, values in the
413+ // list or map may only be strings.
413414func interpolationFuncJSONEncode () ast.Function {
414415 return ast.Function {
415- ArgTypes : []ast.Type {ast .TypeString },
416+ ArgTypes : []ast.Type {ast .TypeAny },
416417 ReturnType : ast .TypeString ,
417418 Callback : func (args []interface {}) (interface {}, error ) {
418- s := args [0 ].(string )
419- jEnc , err := json .Marshal (s )
419+ var toEncode interface {}
420+
421+ switch typedArg := args [0 ].(type ) {
422+ case string :
423+ toEncode = typedArg
424+
425+ case []ast.Variable :
426+ // We preallocate the list here. Note that it's important that in
427+ // the length 0 case, we have an empty list rather than nil, as
428+ // they encode differently.
429+ // XXX It would be nice to support arbitrarily nested data here. Is
430+ // there an inverse of hil.InterfaceToVariable?
431+ strings := make ([]string , len (typedArg ))
432+
433+ for i , v := range typedArg {
434+ if v .Type != ast .TypeString {
435+ return "" , fmt .Errorf ("list elements must be strings" )
436+ }
437+ strings [i ] = v .Value .(string )
438+ }
439+ toEncode = strings
440+
441+ case map [string ]ast.Variable :
442+ // XXX It would be nice to support arbitrarily nested data here. Is
443+ // there an inverse of hil.InterfaceToVariable?
444+ stringMap := make (map [string ]string )
445+ for k , v := range typedArg {
446+ if v .Type != ast .TypeString {
447+ return "" , fmt .Errorf ("map values must be strings" )
448+ }
449+ stringMap [k ] = v .Value .(string )
450+ }
451+ toEncode = stringMap
452+
453+ default :
454+ return "" , fmt .Errorf ("unknown type for JSON encoding: %T" , args [0 ])
455+ }
456+
457+ jEnc , err := json .Marshal (toEncode )
420458 if err != nil {
421- return "" , fmt .Errorf ("failed to encode JSON data '%s'" , s )
459+ return "" , fmt .Errorf ("failed to encode JSON data '%s'" , toEncode )
422460 }
423461 return string (jEnc ), nil
424462 },
0 commit comments