]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blame_incremental - vendor/github.com/hashicorp/terraform/addrs/instance_key.go
Merge branch 'fix_read_test' of github.com:alexandreFre/terraform-provider-statuscake
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / addrs / instance_key.go
... / ...
CommitLineData
1package addrs
2
3import (
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.
18type InstanceKey interface {
19 instanceKeySigil()
20 String() string
21}
22
23// ParseInstanceKey returns the instance key corresponding to the given value,
24// which must be known and non-null.
25//
26// If an unknown or null value is provided then this function will panic. This
27// function is intended to deal with the values that would naturally be found
28// in a hcl.TraverseIndex, which (when parsed from source, at least) can never
29// contain unknown or null values.
30func ParseInstanceKey(key cty.Value) (InstanceKey, error) {
31 switch key.Type() {
32 case cty.String:
33 return StringKey(key.AsString()), nil
34 case cty.Number:
35 var idx int
36 err := gocty.FromCtyValue(key, &idx)
37 return IntKey(idx), err
38 default:
39 return NoKey, fmt.Errorf("either a string or an integer is required")
40 }
41}
42
43// NoKey represents the absense of an InstanceKey, for the single instance
44// of a configuration object that does not use "count" or "for_each" at all.
45var NoKey InstanceKey
46
47// IntKey is the InstanceKey representation representing integer indices, as
48// used when the "count" argument is specified or if for_each is used with
49// a sequence type.
50type IntKey int
51
52func (k IntKey) instanceKeySigil() {
53}
54
55func (k IntKey) String() string {
56 return fmt.Sprintf("[%d]", int(k))
57}
58
59// StringKey is the InstanceKey representation representing string indices, as
60// used when the "for_each" argument is specified with a map or object type.
61type StringKey string
62
63func (k StringKey) instanceKeySigil() {
64}
65
66func (k StringKey) String() string {
67 // FIXME: This isn't _quite_ right because Go's quoted string syntax is
68 // slightly different than HCL's, but we'll accept it for now.
69 return fmt.Sprintf("[%q]", string(k))
70}
71
72// InstanceKeyLess returns true if the first given instance key i should sort
73// before the second key j, and false otherwise.
74func InstanceKeyLess(i, j InstanceKey) bool {
75 iTy := instanceKeyType(i)
76 jTy := instanceKeyType(j)
77
78 switch {
79 case i == j:
80 return false
81 case i == NoKey:
82 return true
83 case j == NoKey:
84 return false
85 case iTy != jTy:
86 // The ordering here is arbitrary except that we want NoKeyType
87 // to sort before the others, so we'll just use the enum values
88 // of InstanceKeyType here (where NoKey is zero, sorting before
89 // any other).
90 return uint32(iTy) < uint32(jTy)
91 case iTy == IntKeyType:
92 return int(i.(IntKey)) < int(j.(IntKey))
93 case iTy == StringKeyType:
94 return string(i.(StringKey)) < string(j.(StringKey))
95 default:
96 // Shouldn't be possible to get down here in practice, since the
97 // above is exhaustive.
98 return false
99 }
100}
101
102func instanceKeyType(k InstanceKey) InstanceKeyType {
103 if _, ok := k.(StringKey); ok {
104 return StringKeyType
105 }
106 if _, ok := k.(IntKey); ok {
107 return IntKeyType
108 }
109 return NoKeyType
110}
111
112// InstanceKeyType represents the different types of instance key that are
113// supported. Usually it is sufficient to simply type-assert an InstanceKey
114// value to either IntKey or StringKey, but this type and its values can be
115// used to represent the types themselves, rather than specific values
116// of those types.
117type InstanceKeyType rune
118
119const (
120 NoKeyType InstanceKeyType = 0
121 IntKeyType InstanceKeyType = 'I'
122 StringKeyType InstanceKeyType = 'S'
123)