@ -258,10 +258,8 @@ func interpolationFuncCoalesce() ast.Function {
}
}
// interpolationFuncConcat implements the "concat" function that
// concatenates multiple strings. This isn't actually necessary anymore
// since our language supports string concat natively, but for backwards
// compat we do this.
// interpolationFuncConcat implements the "concat" function that concatenates
// multiple lists.
func interpolationFuncConcat ( ) ast . Function {
return ast . Function {
ArgTypes : [ ] ast . Type { ast . TypeAny } ,
@ -269,33 +267,42 @@ func interpolationFuncConcat() ast.Function {
Variadic : true ,
VariadicType : ast . TypeAny ,
Callback : func ( args [ ] interface { } ) ( interface { } , error ) {
var finalListElements [ ] string
var outputList [ ] ast . Variable
for _ , arg := range args {
// Append strings for backward compatibility
if argument , ok := arg . ( string ) ; ok {
finalListElements = append ( finalListElements , argument )
continue
}
// Otherwise variables
if argument , ok := arg . ( [ ] ast . Variable ) ; ok {
for _ , element := range argument {
t := element . Type
switch t {
switch arg := arg . ( type ) {
case string :
outputList = append ( outputList , ast . Variable { Type : ast . TypeString , Value : arg } )
case [ ] ast . Variable :
for _ , v := range arg {
switch v . Type {
case ast . TypeString :
finalListElements = append ( finalListElements , element . Value . ( string ) )
outputList = append ( outputList , v )
case ast . TypeList :
outputList = append ( outputList , v )
case ast . TypeMap :
outputList = append ( outputList , v )
default :
return nil , fmt . Errorf ( "concat() does not support lists of %s" , t . Printable ( ) )
return nil , fmt . Errorf ( "concat() does not support lists of %s" , v. Type . Printable ( ) )
}
}
continue
default :
return nil , fmt . Errorf ( "concat() does not support %T" , arg )
}
}
return nil , fmt . Errorf ( "arguments to concat() must be a string or list of strings" )
// we don't support heterogeneous types, so make sure all types match the first
if len ( outputList ) > 0 {
firstType := outputList [ 0 ] . Type
for _ , v := range outputList [ 1 : ] {
if v . Type != firstType {
return nil , fmt . Errorf ( "unexpected %s in list of %s" , v . Type . Printable ( ) , firstType . Printable ( ) )
}
}
}
return stringSliceToVariableValue ( finalListElements ) , nil
return outputList , nil
} ,
}
}