github.com/beauknowssoftware/makehcl@v0.0.0-20200322000747-1b9bb1e1c008/internal/parse/evaluateExpressions.go (about) 1 package parse 2 3 import ( 4 "fmt" 5 6 "github.com/hashicorp/hcl/v2" 7 "github.com/zclconf/go-cty/cty" 8 ) 9 10 func evaluateStringMap(expr hcl.Expression, ctx *hcl.EvalContext) (map[string]string, error) { 11 val, diag := expr.Value(ctx) 12 if diag.HasErrors() { 13 return nil, diag 14 } 15 16 t := val.Type() 17 18 if !t.IsObjectType() { 19 if et := t.MapElementType(); et == nil { 20 return nil, fmt.Errorf("expected map of string, got %v", t.FriendlyName()) 21 } else if *et != cty.String { 22 return nil, fmt.Errorf("expected list of string, but got map of %v", et.FriendlyName()) 23 } 24 } 25 26 m := val.AsValueMap() 27 result := make(map[string]string, len(m)) 28 29 for k, v := range m { 30 result[k] = v.AsString() 31 } 32 33 return result, nil 34 } 35 36 func evaluateStringArray(expr hcl.Expression, ctx *hcl.EvalContext) ([]string, error) { 37 val, diag := expr.Value(ctx) 38 if diag.HasErrors() { 39 return nil, diag 40 } 41 42 t := val.Type() 43 if t == cty.String { 44 s, err := evaluateString(expr, ctx) 45 if err != nil { 46 return nil, err 47 } 48 49 return []string{s}, nil 50 } 51 52 if t.IsTupleType() { 53 ets := t.TupleElementTypes() 54 if ets == nil { 55 return nil, fmt.Errorf("expected tuple of string, got %v", t.FriendlyName()) 56 } 57 58 for i, et := range ets { 59 if et != cty.String { 60 return nil, fmt.Errorf("expected list of string, but element %v was %v", i, et.FriendlyName()) 61 } 62 } 63 64 sl := val.AsValueSlice() 65 result := make([]string, 0, len(sl)) 66 67 for _, e := range sl { 68 result = append(result, e.AsString()) 69 } 70 71 return result, nil 72 } 73 74 if et := t.ListElementType(); et == nil { 75 return nil, fmt.Errorf("expected list of string, got %v", t.FriendlyName()) 76 } else if *et != cty.String { 77 return nil, fmt.Errorf("expected list of string, got list of %v", et.FriendlyName()) 78 } 79 80 sl := val.AsValueSlice() 81 result := make([]string, 0, len(sl)) 82 83 for _, e := range sl { 84 result = append(result, e.AsString()) 85 } 86 87 return result, nil 88 } 89 90 func evaluateIterable(expr hcl.Expression, ctx *hcl.EvalContext) ([]cty.Value, error) { 91 val, diag := expr.Value(ctx) 92 if diag.HasErrors() { 93 return nil, diag 94 } 95 96 if !val.CanIterateElements() { 97 return nil, fmt.Errorf("expected an iterable type, got %v", val.Type().FriendlyName()) 98 } 99 100 return val.AsValueSlice(), nil 101 } 102 103 func evaluateValueArray(expr hcl.Expression, ctx *hcl.EvalContext) ([]cty.Value, error) { 104 val, diag := expr.Value(ctx) 105 if diag.HasErrors() { 106 return nil, diag 107 } 108 109 t := val.Type() 110 if t.IsTupleType() { 111 return val.AsValueSlice(), nil 112 } 113 114 if !t.IsListType() { 115 return nil, fmt.Errorf("expected list, got %v", t.FriendlyName()) 116 } 117 118 return val.AsValueSlice(), nil 119 } 120 121 func evaluateString(expr hcl.Expression, ctx *hcl.EvalContext) (string, error) { 122 val, diag := expr.Value(ctx) 123 if diag.HasErrors() { 124 return "", diag 125 } 126 127 t := val.Type() 128 if t != cty.String { 129 return "", fmt.Errorf("expected a string, got a %v", t.FriendlyName()) 130 } 131 132 return val.AsString(), nil 133 } 134 135 func evaluateBool(expr hcl.Expression, ctx *hcl.EvalContext) (bool, error) { 136 val, diag := expr.Value(ctx) 137 if diag.HasErrors() { 138 return false, diag 139 } 140 141 t := val.Type() 142 if t != cty.Bool { 143 return false, fmt.Errorf("expected a bool, got a %v", t.FriendlyName()) 144 } 145 146 return val.True(), nil 147 }