addrs: All Referenceable implementations support String()

This gives us a convenient way to convert back to a string representation
that matches what the user would've written in configuration.
This commit is contained in:
Martin Atkins 2018-04-03 18:03:47 -07:00
parent f2809854a2
commit e5dfa17433
10 changed files with 83 additions and 0 deletions

View File

@ -6,3 +6,7 @@ type CountAttr struct {
referenceable referenceable
Name string Name string
} }
func (ca CountAttr) String() string {
return "count." + ca.Name
}

View File

@ -5,3 +5,7 @@ type InputVariable struct {
referenceable referenceable
Name string Name string
} }
func (v InputVariable) String() string {
return "var." + v.Name
}

View File

@ -17,6 +17,7 @@ import (
// InstanceKey. // InstanceKey.
type InstanceKey interface { type InstanceKey interface {
instanceKeySigil() instanceKeySigil()
String() string
} }
// ParseInstanceKey returns the instance key corresponding to the given value, // ParseInstanceKey returns the instance key corresponding to the given value,
@ -51,9 +52,19 @@ type IntKey int
func (k IntKey) instanceKeySigil() { func (k IntKey) instanceKeySigil() {
} }
func (k IntKey) String() string {
return fmt.Sprintf("[%d]", int(k))
}
// StringKey is the InstanceKey representation representing string indices, as // StringKey is the InstanceKey representation representing string indices, as
// used when the "for_each" argument is specified with a map or object type. // used when the "for_each" argument is specified with a map or object type.
type StringKey string type StringKey string
func (k StringKey) instanceKeySigil() { func (k StringKey) instanceKeySigil() {
} }
func (k StringKey) String() string {
// FIXME: This isn't _quite_ right because Go's quoted string syntax is
// slightly different than HCL's, but we'll accept it for now.
return fmt.Sprintf("[%q]", string(k))
}

View File

@ -5,3 +5,7 @@ type LocalValue struct {
referenceable referenceable
Name string Name string
} }
func (v LocalValue) String() string {
return "local." + v.Name
}

View File

@ -1,5 +1,9 @@
package addrs package addrs
import (
"fmt"
)
// ModuleCall is the address of a call from the current module to a child // ModuleCall is the address of a call from the current module to a child
// module. // module.
// //
@ -10,6 +14,10 @@ type ModuleCall struct {
Name string Name string
} }
func (c ModuleCall) String() string {
return "module." + c.Name
}
// Instance returns the address of an instance of the receiver identified by // Instance returns the address of an instance of the receiver identified by
// the given key. // the given key.
func (c ModuleCall) Instance(key InstanceKey) ModuleCallInstance { func (c ModuleCall) Instance(key InstanceKey) ModuleCallInstance {
@ -28,6 +36,13 @@ type ModuleCallInstance struct {
Key InstanceKey Key InstanceKey
} }
func (c ModuleCallInstance) String() string {
if c.Key == NoKey {
return c.Call.String()
}
return fmt.Sprintf("module.%s%s", c.Call.Name, c.Key)
}
// Output returns the address of an output of the receiver identified by its // Output returns the address of an output of the receiver identified by its
// name. // name.
func (c ModuleCallInstance) Output(name string) ModuleCallOutput { func (c ModuleCallInstance) Output(name string) ModuleCallOutput {
@ -44,3 +59,7 @@ type ModuleCallOutput struct {
Call ModuleCallInstance Call ModuleCallInstance
Name string Name string
} }
func (co ModuleCallOutput) String() string {
return fmt.Sprintf("%s.%s", co.Call.String(), co.Name)
}

View File

@ -6,3 +6,7 @@ type PathAttr struct {
referenceable referenceable
Name string Name string
} }
func (pa PathAttr) String() string {
return "path." + pa.Name
}

View File

@ -3,7 +3,14 @@ package addrs
// Referenceable is an interface implemented by all address types that can // Referenceable is an interface implemented by all address types that can
// appear as references in configuration language expressions. // appear as references in configuration language expressions.
type Referenceable interface { type Referenceable interface {
// All implementations of this interface must be covered by the type switch
// in lang.Scope.buildEvalContext.
referenceableSigil() referenceableSigil()
// String produces a string representation of the address that could be
// parsed as a HCL traversal and passed to ParseRef to produce an identical
// result.
String() string
} }
type referenceable struct { type referenceable struct {

View File

@ -1,5 +1,9 @@
package addrs package addrs
import (
"fmt"
)
// Resource is an address for a resource block within configuration, which // Resource is an address for a resource block within configuration, which
// contains potentially-multiple resource instances if that configuration // contains potentially-multiple resource instances if that configuration
// block uses "count" or "for_each". // block uses "count" or "for_each".
@ -10,6 +14,17 @@ type Resource struct {
Name string Name string
} }
func (r Resource) String() string {
switch r.Mode {
case ManagedResourceMode:
return fmt.Sprintf("%s.%s", r.Type, r.Name)
case DataResourceMode:
return fmt.Sprintf("data.%s.%s", r.Type, r.Name)
default:
panic(fmt.Errorf("resource address with invalid mode %s", r.Mode))
}
}
// Instance produces the address for a specific instance of the receiver // Instance produces the address for a specific instance of the receiver
// that is idenfied by the given key. // that is idenfied by the given key.
func (r Resource) Instance(key InstanceKey) ResourceInstance { func (r Resource) Instance(key InstanceKey) ResourceInstance {
@ -37,6 +52,13 @@ type ResourceInstance struct {
Key InstanceKey Key InstanceKey
} }
func (r ResourceInstance) String() string {
if r.Key == NoKey {
return r.Resource.String()
}
return r.Resource.String() + r.Key.String()
}
// Absolute returns an AbsResourceInstance from the receiver and the given module // Absolute returns an AbsResourceInstance from the receiver and the given module
// instance address. // instance address.
func (r ResourceInstance) Absolute(module ModuleInstance) AbsResourceInstance { func (r ResourceInstance) Absolute(module ModuleInstance) AbsResourceInstance {

View File

@ -8,3 +8,7 @@ type selfT int
func (s selfT) referenceableSigil() { func (s selfT) referenceableSigil() {
} }
func (s selfT) String() string {
return "self"
}

View File

@ -6,3 +6,7 @@ type TerraformAttr struct {
referenceable referenceable
Name string Name string
} }
func (ta TerraformAttr) String() string {
return "terraform." + ta.Name
}