addrs: "Less" comparison method for resource and module instances
This can be used to sort lists of resource instance and module instance addresses, such as in a rendered plan.
This commit is contained in:
parent
c23a971ed1
commit
00199cd2ed
|
@ -68,3 +68,56 @@ func (k StringKey) String() string {
|
|||
// slightly different than HCL's, but we'll accept it for now.
|
||||
return fmt.Sprintf("[%q]", string(k))
|
||||
}
|
||||
|
||||
// InstanceKeyLess returns true if the first given instance key i should sort
|
||||
// before the second key j, and false otherwise.
|
||||
func InstanceKeyLess(i, j InstanceKey) bool {
|
||||
iTy := instanceKeyType(i)
|
||||
jTy := instanceKeyType(j)
|
||||
|
||||
switch {
|
||||
case i == j:
|
||||
return false
|
||||
case i == NoKey:
|
||||
return true
|
||||
case j == NoKey:
|
||||
return false
|
||||
case iTy != jTy:
|
||||
// The ordering here is arbitrary except that we want NoKeyType
|
||||
// to sort before the others, so we'll just use the enum values
|
||||
// of InstanceKeyType here (where NoKey is zero, sorting before
|
||||
// any other).
|
||||
return uint32(iTy) < uint32(jTy)
|
||||
case iTy == IntKeyType:
|
||||
return int(i.(IntKey)) < int(j.(IntKey))
|
||||
case iTy == StringKeyType:
|
||||
return string(i.(StringKey)) < string(j.(StringKey))
|
||||
default:
|
||||
// Shouldn't be possible to get down here in practice, since the
|
||||
// above is exhaustive.
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func instanceKeyType(k InstanceKey) InstanceKeyType {
|
||||
if _, ok := k.(StringKey); ok {
|
||||
return StringKeyType
|
||||
}
|
||||
if _, ok := k.(IntKey); ok {
|
||||
return IntKeyType
|
||||
}
|
||||
return NoKeyType
|
||||
}
|
||||
|
||||
// InstanceKeyType represents the different types of instance key that are
|
||||
// supported. Usually it is sufficient to simply type-assert an InstanceKey
|
||||
// value to either IntKey or StringKey, but this type and its values can be
|
||||
// used to represent the types themselves, rather than specific values
|
||||
// of those types.
|
||||
type InstanceKeyType rune
|
||||
|
||||
const (
|
||||
NoKeyType InstanceKeyType = 0
|
||||
IntKeyType InstanceKeyType = 'I'
|
||||
StringKeyType InstanceKeyType = 'S'
|
||||
)
|
||||
|
|
|
@ -235,6 +235,27 @@ func (m ModuleInstance) String() string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// Less returns true if the receiver should sort before the given other value
|
||||
// in a sorted list of addresses.
|
||||
func (m ModuleInstance) Less(o ModuleInstance) bool {
|
||||
if len(m) != len(o) {
|
||||
// Shorter path sorts first.
|
||||
return len(m) < len(o)
|
||||
}
|
||||
|
||||
for i := range m {
|
||||
mS, oS := m[i], o[i]
|
||||
switch {
|
||||
case mS.Name != oS.Name:
|
||||
return mS.Name < oS.Name
|
||||
case mS.InstanceKey != oS.InstanceKey:
|
||||
return InstanceKeyLess(mS.InstanceKey, oS.InstanceKey)
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Ancestors returns a slice containing the receiver and all of its ancestor
|
||||
// module instances, all the way up to (and including) the root module.
|
||||
// The result is ordered by depth, with the root module always first.
|
||||
|
|
|
@ -204,6 +204,35 @@ func (r AbsResourceInstance) String() string {
|
|||
return fmt.Sprintf("%s.%s", r.Module.String(), r.Resource.String())
|
||||
}
|
||||
|
||||
// Less returns true if the receiver should sort before the given other value
|
||||
// in a sorted list of addresses.
|
||||
func (r AbsResourceInstance) Less(o AbsResourceInstance) bool {
|
||||
switch {
|
||||
|
||||
case len(r.Module) != len(o.Module):
|
||||
return len(r.Module) < len(o.Module)
|
||||
|
||||
case r.Module.String() != o.Module.String():
|
||||
return r.Module.Less(o.Module)
|
||||
|
||||
case r.Resource.Resource.Mode != o.Resource.Resource.Mode:
|
||||
return r.Resource.Resource.Mode == DataResourceMode
|
||||
|
||||
case r.Resource.Resource.Type != o.Resource.Resource.Type:
|
||||
return r.Resource.Resource.Type < o.Resource.Resource.Type
|
||||
|
||||
case r.Resource.Resource.Name != o.Resource.Resource.Name:
|
||||
return r.Resource.Resource.Name < o.Resource.Resource.Name
|
||||
|
||||
case r.Resource.Key != o.Resource.Key:
|
||||
return InstanceKeyLess(r.Resource.Key, o.Resource.Key)
|
||||
|
||||
default:
|
||||
return false
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// ResourceMode defines which lifecycle applies to a given resource. Each
|
||||
// resource lifecycle has a slightly different address format.
|
||||
type ResourceMode rune
|
||||
|
|
Loading…
Reference in New Issue