databricks-cli/libs/dyn/path.go

113 lines
2.0 KiB
Go

package dyn
import (
"bytes"
"fmt"
)
type pathComponent struct {
key string
index int
}
func (c pathComponent) Key() string {
return c.key
}
func (c pathComponent) Index() int {
return c.index
}
func (c pathComponent) isKey() bool {
return c.key != ""
}
func (c pathComponent) isIndex() bool {
return c.key == ""
}
// Path represents a path to a value in a [Value] configuration tree.
type Path []pathComponent
// EmptyPath is the empty path.
// It is defined for convenience and clarity.
var EmptyPath = Path{}
// Key returns a path component for a key.
func Key(k string) pathComponent {
return pathComponent{key: k}
}
// Index returns a path component for an index.
func Index(i int) pathComponent {
return pathComponent{index: i}
}
// NewPath returns a new path from the given components.
// The individual components may be created with [Key] or [Index].
func NewPath(cs ...pathComponent) Path {
return cs
}
// Join joins the given paths.
func (p Path) Join(qs ...Path) Path {
for _, q := range qs {
p = p.Append(q...)
}
return p
}
// Append appends the given components to the path.
func (p Path) Append(cs ...pathComponent) Path {
return append(p, cs...)
}
// Equal returns true if the paths are equal.
func (p Path) Equal(q Path) bool {
pl := len(p)
ql := len(q)
if pl != ql {
return false
}
for i := 0; i < pl; i++ {
if p[i] != q[i] {
return false
}
}
return true
}
// HasPrefix returns true if the path has the specified prefix.
// The empty path is a prefix of all paths.
func (p Path) HasPrefix(q Path) bool {
pl := len(p)
ql := len(q)
if pl < ql {
return false
}
for i := 0; i < ql; i++ {
if p[i] != q[i] {
return false
}
}
return true
}
// String returns a string representation of the path.
func (p Path) String() string {
var buf bytes.Buffer
for i, c := range p {
if i > 0 && c.key != "" {
buf.WriteRune('.')
}
if c.key != "" {
buf.WriteString(c.key)
} else {
buf.WriteString(fmt.Sprintf("[%d]", c.index))
}
}
return buf.String()
}