You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
80 lines
1.9 KiB
Go
80 lines
1.9 KiB
Go
package userfunc
|
|
|
|
import (
|
|
"github.com/hashicorp/hcl/v2"
|
|
"github.com/zclconf/go-cty/cty/function"
|
|
)
|
|
|
|
var funcBodySchema = &hcl.BodySchema{
|
|
Attributes: []hcl.AttributeSchema{
|
|
{
|
|
Name: "params",
|
|
Required: true,
|
|
},
|
|
{
|
|
Name: "variadic_param",
|
|
Required: false,
|
|
},
|
|
{
|
|
Name: "result",
|
|
Required: true,
|
|
},
|
|
},
|
|
}
|
|
|
|
func decodeUserFunctions(body hcl.Body, blockType string, contextFunc ContextFunc) (funcs map[string]function.Function, remain hcl.Body, diags hcl.Diagnostics) {
|
|
schema := &hcl.BodySchema{
|
|
Blocks: []hcl.BlockHeaderSchema{
|
|
{
|
|
Type: blockType,
|
|
LabelNames: []string{"name"},
|
|
},
|
|
},
|
|
}
|
|
|
|
content, remain, diags := body.PartialContent(schema)
|
|
if diags.HasErrors() {
|
|
return nil, remain, diags
|
|
}
|
|
|
|
// first call to getBaseCtx will populate context, and then the same
|
|
// context will be used for all subsequent calls. It's assumed that
|
|
// all functions in a given body should see an identical context.
|
|
var baseCtx *hcl.EvalContext
|
|
getBaseCtx := func() *hcl.EvalContext {
|
|
if baseCtx == nil {
|
|
if contextFunc != nil {
|
|
baseCtx = contextFunc()
|
|
}
|
|
}
|
|
// baseCtx might still be nil here, and that's okay
|
|
return baseCtx
|
|
}
|
|
|
|
funcs = make(map[string]function.Function)
|
|
|
|
for _, block := range content.Blocks {
|
|
name := block.Labels[0]
|
|
funcContent, funcDiags := block.Body.Content(funcBodySchema)
|
|
diags = append(diags, funcDiags...)
|
|
if funcDiags.HasErrors() {
|
|
continue
|
|
}
|
|
|
|
paramsExpr := funcContent.Attributes["params"].Expr
|
|
resultExpr := funcContent.Attributes["result"].Expr
|
|
var varParamExpr hcl.Expression
|
|
if funcContent.Attributes["variadic_param"] != nil {
|
|
varParamExpr = funcContent.Attributes["variadic_param"].Expr
|
|
}
|
|
f, funcDiags := NewFunction(paramsExpr, varParamExpr, resultExpr, getBaseCtx)
|
|
if funcDiags.HasErrors() {
|
|
diags = append(diags, funcDiags...)
|
|
continue
|
|
}
|
|
funcs[name] = f
|
|
}
|
|
|
|
return funcs, remain, diags
|
|
}
|