aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/zclconf/go-cty/cty/path.go
diff options
context:
space:
mode:
authorappilon <apilon@hashicorp.com>2019-02-27 16:43:31 -0500
committerGitHub <noreply@github.com>2019-02-27 16:43:31 -0500
commit844b5a68d8af4791755b8f0ad293cc99f5959183 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/zclconf/go-cty/cty/path.go
parent303b299eeb6b06e939e35905e4b34cb410dd9dc3 (diff)
parent15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (diff)
downloadterraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.gz
terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.tar.zst
terraform-provider-statuscake-844b5a68d8af4791755b8f0ad293cc99f5959183.zip
Merge pull request #27 from terraform-providers/go-modules-2019-02-22
[MODULES] Switch to Go Modules
Diffstat (limited to 'vendor/github.com/zclconf/go-cty/cty/path.go')
-rw-r--r--vendor/github.com/zclconf/go-cty/cty/path.go186
1 files changed, 186 insertions, 0 deletions
diff --git a/vendor/github.com/zclconf/go-cty/cty/path.go b/vendor/github.com/zclconf/go-cty/cty/path.go
new file mode 100644
index 0000000..84a9de0
--- /dev/null
+++ b/vendor/github.com/zclconf/go-cty/cty/path.go
@@ -0,0 +1,186 @@
1package cty
2
3import (
4 "errors"
5 "fmt"
6)
7
8// A Path is a sequence of operations to locate a nested value within a
9// data structure.
10//
11// The empty Path represents the given item. Any PathSteps within represent
12// taking a single step down into a data structure.
13//
14// Path has some convenience methods for gradually constructing a path,
15// but callers can also feel free to just produce a slice of PathStep manually
16// and convert to this type, which may be more appropriate in environments
17// where memory pressure is a concern.
18type Path []PathStep
19
20// PathStep represents a single step down into a data structure, as part
21// of a Path. PathStep is a closed interface, meaning that the only
22// permitted implementations are those within this package.
23type PathStep interface {
24 pathStepSigil() pathStepImpl
25 Apply(Value) (Value, error)
26}
27
28// embed pathImpl into a struct to declare it a PathStep implementation
29type pathStepImpl struct{}
30
31func (p pathStepImpl) pathStepSigil() pathStepImpl {
32 return p
33}
34
35// Index returns a new Path that is the reciever with an IndexStep appended
36// to the end.
37//
38// This is provided as a convenient way to construct paths, but each call
39// will create garbage so it should not be used where memory pressure is a
40// concern.
41func (p Path) Index(v Value) Path {
42 ret := make(Path, len(p)+1)
43 copy(ret, p)
44 ret[len(p)] = IndexStep{
45 Key: v,
46 }
47 return ret
48}
49
50// GetAttr returns a new Path that is the reciever with a GetAttrStep appended
51// to the end.
52//
53// This is provided as a convenient way to construct paths, but each call
54// will create garbage so it should not be used where memory pressure is a
55// concern.
56func (p Path) GetAttr(name string) Path {
57 ret := make(Path, len(p)+1)
58 copy(ret, p)
59 ret[len(p)] = GetAttrStep{
60 Name: name,
61 }
62 return ret
63}
64
65// Apply applies each of the steps in turn to successive values starting with
66// the given value, and returns the result. If any step returns an error,
67// the whole operation returns an error.
68func (p Path) Apply(val Value) (Value, error) {
69 var err error
70 for i, step := range p {
71 val, err = step.Apply(val)
72 if err != nil {
73 return NilVal, fmt.Errorf("at step %d: %s", i, err)
74 }
75 }
76 return val, nil
77}
78
79// LastStep applies the given path up to the last step and then returns
80// the resulting value and the final step.
81//
82// This is useful when dealing with assignment operations, since in that
83// case the *value* of the last step is not important (and may not, in fact,
84// present at all) and we care only about its location.
85//
86// Since LastStep applies all steps except the last, it will return errors
87// for those steps in the same way as Apply does.
88//
89// If the path has *no* steps then the returned PathStep will be nil,
90// representing that any operation should be applied directly to the
91// given value.
92func (p Path) LastStep(val Value) (Value, PathStep, error) {
93 var err error
94
95 if len(p) == 0 {
96 return val, nil, nil
97 }
98
99 journey := p[:len(p)-1]
100 val, err = journey.Apply(val)
101 if err != nil {
102 return NilVal, nil, err
103 }
104 return val, p[len(p)-1], nil
105}
106
107// Copy makes a shallow copy of the receiver. Often when paths are passed to
108// caller code they come with the constraint that they are valid only until
109// the caller returns, due to how they are constructed internally. Callers
110// can use Copy to conveniently produce a copy of the value that _they_ control
111// the validity of.
112func (p Path) Copy() Path {
113 ret := make(Path, len(p))
114 copy(ret, p)
115 return ret
116}
117
118// IndexStep is a Step implementation representing applying the index operation
119// to a value, which must be of either a list, map, or set type.
120//
121// When describing a path through a *type* rather than a concrete value,
122// the Key may be an unknown value, indicating that the step applies to
123// *any* key of the given type.
124//
125// When indexing into a set, the Key is actually the element being accessed
126// itself, since in sets elements are their own identity.
127type IndexStep struct {
128 pathStepImpl
129 Key Value
130}
131
132// Apply returns the value resulting from indexing the given value with
133// our key value.
134func (s IndexStep) Apply(val Value) (Value, error) {
135 switch s.Key.Type() {
136 case Number:
137 if !val.Type().IsListType() {
138 return NilVal, errors.New("not a list type")
139 }
140 case String:
141 if !val.Type().IsMapType() {
142 return NilVal, errors.New("not a map type")
143 }
144 default:
145 return NilVal, errors.New("key value not number or string")
146 }
147
148 has := val.HasIndex(s.Key)
149 if !has.IsKnown() {
150 return UnknownVal(val.Type().ElementType()), nil
151 }
152 if !has.True() {
153 return NilVal, errors.New("value does not have given index key")
154 }
155
156 return val.Index(s.Key), nil
157}
158
159func (s IndexStep) GoString() string {
160 return fmt.Sprintf("cty.IndexStep{Key:%#v}", s.Key)
161}
162
163// GetAttrStep is a Step implementation representing retrieving an attribute
164// from a value, which must be of an object type.
165type GetAttrStep struct {
166 pathStepImpl
167 Name string
168}
169
170// Apply returns the value of our named attribute from the given value, which
171// must be of an object type that has a value of that name.
172func (s GetAttrStep) Apply(val Value) (Value, error) {
173 if !val.Type().IsObjectType() {
174 return NilVal, errors.New("not an object type")
175 }
176
177 if !val.Type().HasAttribute(s.Name) {
178 return NilVal, fmt.Errorf("object has no attribute %q", s.Name)
179 }
180
181 return val.GetAttr(s.Name), nil
182}
183
184func (s GetAttrStep) GoString() string {
185 return fmt.Sprintf("cty.GetAttrStep{Name:%q}", s.Name)
186}