package strings import ( "fmt" "github.com/zclconf/go-cty/cty" "github.com/zclconf/go-cty/cty/function" ) func Format() function.Function { return function.New(&function.Spec{ Description: "Format a string", Params: []function.Parameter{ { Name: "format", Description: "format for the resulting string", Type: cty.String, }, }, VarParam: &function.Parameter{ Name: "args", Description: "variadic args for format", Type: cty.DynamicPseudoType, }, Type: function.StaticReturnType(cty.String), Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { format := args[0].AsString() formatArgs := make([]any, 0, len(args)) if len(args) > 1 { for i := 1; i < len(args); i++ { if unboxed := unbox(args[i]); unboxed != nil { formatArgs = append(formatArgs, unboxed) } } } return cty.StringVal(fmt.Sprintf(format, formatArgs...)), nil }, }) } func unbox(in cty.Value) any { switch in.Type() { case cty.String: return in.AsString() case cty.Number: bigFloat := in.AsBigFloat() if bigFloat.IsInt() { i, _ := bigFloat.Int64() return i } else { f, _ := bigFloat.Float64() return f } case cty.Bool: return in.True() default: return nil } }