@@ -6,48 +6,81 @@ import (
66)
77
88var (
9+ // ErrNotAttributePathStepper is returned when a type that doesn't full
10+ // the AttributePathStepper interface is passed to WalkAttributePath.
911 ErrNotAttributePathStepper = errors .New ("doesn't fill tftypes.AttributePathStepper interface" )
10- ErrInvalidStep = errors .New ("step cannot be applied to this value" )
12+
13+ // ErrInvalidStep is returned when an AttributePath has the wrong kind
14+ // of AttributePathStep for the type that WalkAttributePath is
15+ // operating on.
16+ ErrInvalidStep = errors .New ("step cannot be applied to this value" )
1117)
1218
19+ // AttributePath is a type that can point to a specific value within an
20+ // aggregate Terraform value. It consists of steps, each identifying one
21+ // element or attribute of the current value, and making that the current
22+ // value. This allows referring to arbitrarily precise values.
1323type AttributePath struct {
24+ // Steps are the steps that must be followed from the root of the value
25+ // to obtain the value being indicated.
1426 Steps []AttributePathStep
1527}
1628
29+ // NewErrorf returns an error associated with the value indicated by `a`. This
30+ // is equivalent to calling a.NewError(fmt.Errorf(f, args...)).
1731func (a AttributePath ) NewErrorf (f string , args ... interface {}) error {
1832 return attributePathError {
1933 error : fmt .Errorf (f , args ... ),
2034 path : a ,
2135 }
2236}
2337
38+ // NewError returns an error that associates `err` with the value indicated by
39+ // `a`.
2440func (a AttributePath ) NewError (err error ) error {
2541 return attributePathError {
2642 error : err ,
2743 path : a ,
2844 }
2945}
3046
47+ // WithAttributeName adds an AttributeName step to `a`, using `name` as the
48+ // attribute's name.
3149func (a * AttributePath ) WithAttributeName (name string ) {
3250 a .Steps = append (a .Steps , AttributeName (name ))
3351}
3452
53+ // WithElementKeyString adds an ElementKeyString step to `a`, using `key` as
54+ // the element's key.
3555func (a * AttributePath ) WithElementKeyString (key string ) {
3656 a .Steps = append (a .Steps , ElementKeyString (key ))
3757}
3858
59+ // WithElementKeyInt adds an ElementKeyInt step to `a`, using `key` as the
60+ // element's key.
3961func (a * AttributePath ) WithElementKeyInt (key int64 ) {
4062 a .Steps = append (a .Steps , ElementKeyInt (key ))
4163}
4264
65+ // WithElementKeyValue adds an ElementKeyValue to `a`, using `key` as the
66+ // element's key.
4367func (a * AttributePath ) WithElementKeyValue (key Value ) {
4468 a .Steps = append (a .Steps , ElementKeyValue (key ))
4569}
4670
71+ // WithoutLastStep removes the last step, whatever kind of step it was, from
72+ // `a`.
4773func (a * AttributePath ) WithoutLastStep () {
4874 a .Steps = a .Steps [:len (a .Steps )- 1 ]
4975}
5076
77+ // AttributePathStep is an intentionally unimplementable interface that
78+ // functions as an enum, allowing us to use different strongly-typed step types
79+ // as a generic "step" type.
80+ //
81+ // An AttributePathStep is meant to indicate a single step in an AttributePath,
82+ // indicating a specific attribute or element that is the next value in the
83+ // path.
5184type AttributePathStep interface {
5285 unfulfillable () // make this interface fillable only by this package
5386}
@@ -58,29 +91,53 @@ var (
5891 _ AttributePathStep = ElementKeyInt (0 )
5992)
6093
94+ // AttributeName is an AttributePathStep implementation that indicates the next
95+ // step in the AttributePath is to select an attribute. The value of the
96+ // AttributeName is the name of the attribute to be selected.
6197type AttributeName string
6298
6399func (a AttributeName ) unfulfillable () {}
64100
101+ // ElementKeyString is an AttributePathStep implementation that indicates the
102+ // next step in the AttributePath is to select an element using a string key.
103+ // The value of the ElementKeyString is the key of the element to select.
65104type ElementKeyString string
66105
67106func (e ElementKeyString ) unfulfillable () {}
68107
108+ // ElementKeyInt is an AttributePathStep implementation that indicates the next
109+ // step in the AttributePath is to select an element using an int64 key. The
110+ // value of the ElementKeyInt is the key of the element to select.
69111type ElementKeyInt int64
70112
71113func (e ElementKeyInt ) unfulfillable () {}
72114
115+ // ElementKeyValue is an AttributePathStep implementation that indicates the
116+ // next step in the AttributePath is to select an element using the element
117+ // itself as a key. The value of the ElementKeyValue is the key of the element
118+ // to select.
73119type ElementKeyValue Value
74120
75121func (e ElementKeyValue ) unfulfillable () {}
76122
123+ // AttributePathStepper is an interface that types can implement to make them
124+ // traversable by WalkAttributePath, allowing providers to retrieve the
125+ // specific value an AttributePath is pointing to.
77126type AttributePathStepper interface {
78127 // Return the attribute or element the AttributePathStep is referring
79128 // to, or an error if the AttributePathStep is referring to an
80129 // attribute or element that doesn't exist.
81130 ApplyTerraform5AttributePathStep (AttributePathStep ) (interface {}, error )
82131}
83132
133+ // WalkAttributePath will return the value that `path` is pointing to, using
134+ // `in` as the root. If an error is returned, the AttributePath returned will
135+ // indicate the steps that remained to be applied when the error was
136+ // encountered.
137+ //
138+ // map[string]interface{} and []interface{} types have built-in support. Other
139+ // types need to use the AttributePathStepper interface to tell
140+ // WalkAttributePath how to traverse themselves.
84141func WalkAttributePath (in interface {}, path AttributePath ) (interface {}, AttributePath , error ) {
85142 if len (path .Steps ) < 1 {
86143 return in , path , nil
0 commit comments