8 "github.com/zclconf/go-cty/cty"
11 // FormatCtyPath is a helper function to produce a user-friendly string
12 // representation of a cty.Path. The result uses a syntax similar to the
13 // HCL expression language in the hope of it being familiar to users.
14 func FormatCtyPath(path cty.Path) string {
16 for _, step := range path {
17 switch ts := step.(type) {
19 fmt.Fprintf(&buf, ".%s", ts.Name)
26 buf.WriteString("null")
28 buf.WriteString("(not yet known)")
29 case keyTy == cty.Number:
30 bf := key.AsBigFloat()
31 buf.WriteString(bf.Text('g', -1))
32 case keyTy == cty.String:
33 buf.WriteString(strconv.Quote(key.AsString()))
35 buf.WriteString("...")
43 // FormatError is a helper function to produce a user-friendly string
44 // representation of certain special error types that we might want to
45 // include in diagnostic messages.
47 // This currently has special behavior only for cty.PathError, where a
48 // non-empty path is rendered in a HCL-like syntax as context.
49 func FormatError(err error) string {
50 perr, ok := err.(cty.PathError)
51 if !ok || len(perr.Path) == 0 {
55 return fmt.Sprintf("%s: %s", FormatCtyPath(perr.Path), perr.Error())
58 // FormatErrorPrefixed is like FormatError except that it presents any path
59 // information after the given prefix string, which is assumed to contain
60 // an HCL syntax representation of the value that errors are relative to.
61 func FormatErrorPrefixed(err error, prefix string) string {
62 perr, ok := err.(cty.PathError)
63 if !ok || len(perr.Path) == 0 {
64 return fmt.Sprintf("%s: %s", prefix, err.Error())
67 return fmt.Sprintf("%s%s: %s", prefix, FormatCtyPath(perr.Path), perr.Error())