config: jsonencode function to support nested lists and maps
This commit is contained in:
parent
0da6b95ef8
commit
28b5708fef
|
@ -824,8 +824,7 @@ func interpolationFuncJoin() ast.Function {
|
|||
}
|
||||
|
||||
// interpolationFuncJSONEncode implements the "jsonencode" function that encodes
|
||||
// a string, list, or map as its JSON representation. For now, values in the
|
||||
// list or map may only be strings.
|
||||
// a string, list, or map as its JSON representation.
|
||||
func interpolationFuncJSONEncode() ast.Function {
|
||||
return ast.Function{
|
||||
ArgTypes: []ast.Type{ast.TypeAny},
|
||||
|
@ -838,28 +837,36 @@ func interpolationFuncJSONEncode() ast.Function {
|
|||
toEncode = typedArg
|
||||
|
||||
case []ast.Variable:
|
||||
// We preallocate the list here. Note that it's important that in
|
||||
// the length 0 case, we have an empty list rather than nil, as
|
||||
// they encode differently.
|
||||
// XXX It would be nice to support arbitrarily nested data here. Is
|
||||
// there an inverse of hil.InterfaceToVariable?
|
||||
strings := make([]string, len(typedArg))
|
||||
|
||||
for i, v := range typedArg {
|
||||
if v.Type != ast.TypeString {
|
||||
return "", fmt.Errorf("list elements must be strings")
|
||||
variable, _ := hil.InterfaceToVariable(typedArg)
|
||||
toEncode, _ = hil.VariableToInterface(variable)
|
||||
|
||||
jEnc, err := json.Marshal(toEncode)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to encode JSON data '%s'", toEncode)
|
||||
}
|
||||
return string(jEnc), nil
|
||||
|
||||
}
|
||||
strings[i] = v.Value.(string)
|
||||
}
|
||||
toEncode = strings
|
||||
|
||||
case map[string]ast.Variable:
|
||||
// XXX It would be nice to support arbitrarily nested data here. Is
|
||||
// there an inverse of hil.InterfaceToVariable?
|
||||
stringMap := make(map[string]string)
|
||||
for k, v := range typedArg {
|
||||
if v.Type != ast.TypeString {
|
||||
return "", fmt.Errorf("map values must be strings")
|
||||
variable, _ := hil.InterfaceToVariable(typedArg)
|
||||
toEncode, _ = hil.VariableToInterface(variable)
|
||||
|
||||
jEnc, err := json.Marshal(toEncode)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to encode JSON data '%s'", toEncode)
|
||||
}
|
||||
return string(jEnc), nil
|
||||
}
|
||||
stringMap[k] = v.Value.(string)
|
||||
}
|
||||
|
|
|
@ -1406,8 +1406,6 @@ func TestInterpolateFuncJSONEncode(t *testing.T) {
|
|||
Type: ast.TypeString,
|
||||
},
|
||||
"list": interfaceToVariableSwallowError([]string{"foo", "bar\tbaz"}),
|
||||
// XXX can't use InterfaceToVariable as it converts empty slice into empty
|
||||
// map.
|
||||
"emptylist": ast.Variable{
|
||||
Value: []ast.Variable{},
|
||||
Type: ast.TypeList,
|
||||
|
@ -1416,9 +1414,7 @@ func TestInterpolateFuncJSONEncode(t *testing.T) {
|
|||
"foo": "bar",
|
||||
"ba \n z": "q\\x",
|
||||
}),
|
||||
"emptymap": interfaceToVariableSwallowError(map[string]string{}),
|
||||
|
||||
// Not yet supported (but it would be nice)
|
||||
"emptymap": interfaceToVariableSwallowError(map[string]string{}),
|
||||
"nestedlist": interfaceToVariableSwallowError([][]string{{"foo"}}),
|
||||
"nestedmap": interfaceToVariableSwallowError(map[string][]string{"foo": {"bar"}}),
|
||||
},
|
||||
|
@ -1470,13 +1466,13 @@ func TestInterpolateFuncJSONEncode(t *testing.T) {
|
|||
},
|
||||
{
|
||||
`${jsonencode(nestedlist)}`,
|
||||
nil,
|
||||
true,
|
||||
`[["foo"]]`,
|
||||
false,
|
||||
},
|
||||
{
|
||||
`${jsonencode(nestedmap)}`,
|
||||
nil,
|
||||
true,
|
||||
`{"foo":["bar"]}`,
|
||||
false,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
|
|
@ -262,10 +262,9 @@ The supported built-in functions are:
|
|||
* `join(",", aws_instance.foo.*.id)`
|
||||
* `join(",", var.ami_list)`
|
||||
|
||||
* `jsonencode(item)` - Returns a JSON-encoded representation of the given
|
||||
item, which may be a string, list of strings, or map from string to string.
|
||||
Note that if the item is a string, the return value includes the double
|
||||
quotes.
|
||||
* `jsonencode(value)` - Returns a JSON-encoded representation of the given
|
||||
value, which can contain arbitrarily-nested lists and maps. Note that if
|
||||
the value is a string then its value will be placed in quotes.
|
||||
|
||||
* `keys(map)` - Returns a lexically sorted list of the map keys.
|
||||
|
||||
|
|
Loading…
Reference in New Issue