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  }