github.com/terraform-linters/tflint-plugin-sdk@v0.22.0/terraform/addrs/instance_key.go (about) 1 package addrs 2 3 import ( 4 "fmt" 5 6 "github.com/zclconf/go-cty/cty" 7 "github.com/zclconf/go-cty/cty/gocty" 8 ) 9 10 // InstanceKey represents the key of an instance within an object that 11 // contains multiple instances due to using "count" or "for_each" arguments 12 // in configuration. 13 // 14 // IntKey and StringKey are the two implementations of this type. No other 15 // implementations are allowed. The single instance of an object that _isn't_ 16 // using "count" or "for_each" is represented by NoKey, which is a nil 17 // InstanceKey. 18 type InstanceKey interface { 19 instanceKeySigil() 20 String() string 21 22 // Value returns the cty.Value of the appropriate type for the InstanceKey 23 // value. 24 Value() cty.Value 25 } 26 27 // ParseInstanceKey returns the instance key corresponding to the given value, 28 // which must be known and non-null. 29 // 30 // If an unknown or null value is provided then this function will panic. This 31 // function is intended to deal with the values that would naturally be found 32 // in a hcl.TraverseIndex, which (when parsed from source, at least) can never 33 // contain unknown or null values. 34 func ParseInstanceKey(key cty.Value) (InstanceKey, error) { 35 switch key.Type() { 36 case cty.String: 37 return StringKey(key.AsString()), nil 38 case cty.Number: 39 var idx int 40 err := gocty.FromCtyValue(key, &idx) 41 return IntKey(idx), err 42 default: 43 return NoKey, fmt.Errorf("either a string or an integer is required") 44 } 45 } 46 47 // NoKey represents the absense of an InstanceKey, for the single instance 48 // of a configuration object that does not use "count" or "for_each" at all. 49 var NoKey InstanceKey 50 51 // IntKey is the InstanceKey representation representing integer indices, as 52 // used when the "count" argument is specified or if for_each is used with 53 // a sequence type. 54 type IntKey int 55 56 func (k IntKey) instanceKeySigil() { 57 } 58 59 func (k IntKey) String() string { 60 return fmt.Sprintf("[%d]", int(k)) 61 } 62 63 // Value returns a cty.Value of type Number 64 func (k IntKey) Value() cty.Value { 65 return cty.NumberIntVal(int64(k)) 66 } 67 68 // StringKey is the InstanceKey representation representing string indices, as 69 // used when the "for_each" argument is specified with a map or object type. 70 type StringKey string 71 72 func (k StringKey) instanceKeySigil() { 73 } 74 75 func (k StringKey) String() string { 76 // FIXME: This isn't _quite_ right because Go's quoted string syntax is 77 // slightly different than HCL's, but we'll accept it for now. 78 return fmt.Sprintf("[%q]", string(k)) 79 } 80 81 // Value returns a cty.Value of type String 82 func (k StringKey) Value() cty.Value { 83 return cty.StringVal(string(k)) 84 } 85 86 // InstanceKeyType represents the different types of instance key that are 87 // supported. Usually it is sufficient to simply type-assert an InstanceKey 88 // value to either IntKey or StringKey, but this type and its values can be 89 // used to represent the types themselves, rather than specific values 90 // of those types. 91 type InstanceKeyType rune 92 93 const ( 94 // NoKeyType is a type of NoKey instance key 95 NoKeyType InstanceKeyType = 0 96 // IntKeyType is a type of IntKey instance key 97 IntKeyType InstanceKeyType = 'I' 98 // StringKeyType is a type of StringKey instance key 99 StringKeyType InstanceKeyType = 'S' 100 )