Skip to content

Commit a2b51a9

Browse files
author
Paddy Carver
committed
Second revision.
Split paths and the wildcard version out into two different abstractions. Move them into the `attr` package.
1 parent 53e96c3 commit a2b51a9

File tree

3 files changed

+414
-160
lines changed

3 files changed

+414
-160
lines changed

attr/path.go

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
package attr
2+
3+
// Path is used to identify part of a tfsdk.Schema, attr.Type, or attr.Value.
4+
// It is a series of steps, describing a traversal of a Terraform type. Each
5+
// Terraform type has its own limits on what steps can be used to traverse it.
6+
type Path struct {
7+
steps []step
8+
}
9+
10+
// New returns an Path that is ready to be used.
11+
func NewPath() Path {
12+
return Path{}
13+
}
14+
15+
func copySteps(in []step) []step {
16+
out := make([]step, len(in))
17+
copy(out, in)
18+
return out
19+
}
20+
21+
// IsEmpty returns true if a Path has no steps and effectively points to the
22+
// root of the value.
23+
func (a Path) IsEmpty() bool {
24+
return len(a.steps) < 1
25+
}
26+
27+
// Parent returns a Path pointing to the parent of the attribute or element
28+
// that `a` points to. If `a` has no parent, an empty Path is returned.
29+
func (a Path) Parent() Path {
30+
if len(a.steps) < 1 {
31+
return Path{steps: []step{}}
32+
}
33+
return Path{
34+
steps: copySteps(a.steps)[:len(a.steps)-1],
35+
}
36+
}
37+
38+
// Attribute returns a copy of `a`, with another step added to select the named
39+
// attribute of the object that `a` points to.
40+
func (a Path) Attribute(name string) Path {
41+
return Path{
42+
steps: append(copySteps(a.steps), attributeName(name)),
43+
}
44+
}
45+
46+
// ElementKey returns a copy of `a` with another step added to select the named
47+
// key of the map that `a` points to.
48+
func (a Path) ElementKey(name string) Path {
49+
return Path{
50+
steps: append(copySteps(a.steps), elementKeyString(name)),
51+
}
52+
}
53+
54+
// ElementPos returns a copy of `a` with another step added to select the
55+
// element that is in the specified position of the list or tuple that `a`
56+
// points to.
57+
func (a Path) ElementPos(pos int) Path {
58+
return Path{
59+
steps: append(copySteps(a.steps), elementKeyInt(pos)),
60+
}
61+
}
62+
63+
// Element returns a copy of `a` with another step added to select the
64+
// specified element of the set that `a` points to.
65+
func (a Path) Element(val Value) Path {
66+
return Path{
67+
steps: append(copySteps(a.steps), elementKeyValue{Value: val}),
68+
}
69+
}
70+
71+
type step interface {
72+
unimplementablePathStep()
73+
}
74+
75+
// attributeName is a step that selects a single attribute, by its name. It is
76+
// used on attr.TypeWithAttributeTypes, tfsdk.NestedAttributes, and
77+
// tfsdk.Schema types.
78+
type attributeName string
79+
80+
func (a attributeName) unimplementablePathStep() {}
81+
82+
// elementKeyString is a step that selects a single element using a string
83+
// index. It is used on attr.TypeWithElementType types that return a
84+
// tftypes.Map from their TerraformType method. It is also used on
85+
// tfsdk.MapNestedAttribute nested attributes.
86+
type elementKeyString string
87+
88+
func (e elementKeyString) unimplementablePathStep() {}
89+
90+
// elementKeyInt is a step that selects a single element using an integer
91+
// index. It is used on attr.TypeWithElementTypes types and
92+
// attr.TypeWithElementType types that return a tftypes.List from their
93+
// TerraformType method. It is also used on tfsdk.ListNestedAttribute nested
94+
// attributes.
95+
type elementKeyInt int
96+
97+
func (e elementKeyInt) unimplementablePathStep() {}
98+
99+
// elementKeyValue is a step that selects a single element using an attr.Value
100+
// index. It is used on attr.TypeWithElementType types that return a
101+
// tftypes.Set from their TerraformType method. It is also used on
102+
// tfsdk.SetNestedAttribute nested attributes.
103+
type elementKeyValue struct {
104+
Value Value
105+
}
106+
107+
func (e elementKeyValue) unimplementablePathStep() {}

0 commit comments

Comments
 (0)