packer-cn/hcl2template/types.decodable.go

57 lines
1.4 KiB
Go

package hcl2template
import (
"fmt"
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/hcldec"
"github.com/zclconf/go-cty/cty"
"github.com/zclconf/go-cty/cty/gocty"
)
type Decodable interface {
FlatMapstructure() interface{}
}
type SelfSpecified interface {
HCL2Spec() map[string]hcldec.Spec
}
func decodeDecodable(block *hcl.Block, ctx *hcl.EvalContext, dec Decodable) (interface{}, hcl.Diagnostics) {
var diags hcl.Diagnostics
flatCfg := dec.FlatMapstructure()
var spec hcldec.ObjectSpec
if ss, selfSpecified := flatCfg.(SelfSpecified); selfSpecified {
spec = hcldec.ObjectSpec(ss.HCL2Spec())
} else {
diags = append(diags, &hcl.Diagnostic{
Summary: "Unknown type",
Subject: &block.DefRange,
Detail: fmt.Sprintf("Cannot get spec from a %T", flatCfg),
})
return nil, diags
}
val, moreDiags := hcldec.Decode(block.Body, spec, ctx)
diags = append(diags, moreDiags...)
err := gocty.FromCtyValue(val, flatCfg)
if err != nil {
switch err := err.(type) {
case cty.PathError:
diags = append(diags, &hcl.Diagnostic{
Summary: "gocty.FromCtyValue: " + err.Error(),
Subject: &block.DefRange,
Detail: fmt.Sprintf("%v", err.Path),
})
default:
diags = append(diags, &hcl.Diagnostic{
Summary: "gocty.FromCtyValue: " + err.Error(),
Subject: &block.DefRange,
Detail: fmt.Sprintf("%v", err),
})
}
}
return flatCfg, diags
}