293dd2e848
* Add vendor dir so builds dont require dep * Pin specific version go-eth version
113 lines
2.6 KiB
Go
113 lines
2.6 KiB
Go
// Copyright (c) 2017 Arista Networks, Inc.
|
|
// Use of this source code is governed by the Apache License 2.0
|
|
// that can be found in the COPYING file.
|
|
|
|
// Package path provides functionality for dealing with absolute paths elementally.
|
|
package path
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/aristanetworks/goarista/key"
|
|
)
|
|
|
|
// Path is an absolute path broken down into elements where each element is a key.Key.
|
|
type Path []key.Key
|
|
|
|
func copyElements(path Path, elements ...interface{}) {
|
|
for i, element := range elements {
|
|
switch val := element.(type) {
|
|
case string:
|
|
path[i] = key.New(val)
|
|
case key.Key:
|
|
path[i] = val
|
|
default:
|
|
panic(fmt.Errorf("unsupported type: %T", element))
|
|
}
|
|
}
|
|
}
|
|
|
|
// New constructs a Path from a variable number of elements.
|
|
// Each element may either be a string or a key.Key.
|
|
func New(elements ...interface{}) Path {
|
|
path := make(Path, len(elements))
|
|
copyElements(path, elements...)
|
|
return path
|
|
}
|
|
|
|
// FromString constructs a Path from the elements resulting
|
|
// from a split of the input string by "/". The string MUST
|
|
// begin with a '/' character unless it is the empty string
|
|
// in which case an empty Path is returned.
|
|
func FromString(str string) Path {
|
|
if str == "" {
|
|
return Path{}
|
|
} else if str[0] != '/' {
|
|
panic(fmt.Errorf("not an absolute path: %q", str))
|
|
}
|
|
elements := strings.Split(str, "/")[1:]
|
|
path := make(Path, len(elements))
|
|
for i, element := range elements {
|
|
path[i] = key.New(element)
|
|
}
|
|
return path
|
|
}
|
|
|
|
// Append appends a variable number of elements to a Path.
|
|
// Each element may either be a string or a key.Key.
|
|
func Append(path Path, elements ...interface{}) Path {
|
|
if len(elements) == 0 {
|
|
return path
|
|
}
|
|
n := len(path)
|
|
p := make(Path, n+len(elements))
|
|
copy(p, path)
|
|
copyElements(p[n:], elements...)
|
|
return p
|
|
}
|
|
|
|
// String returns the Path as a string.
|
|
func (p Path) String() string {
|
|
if len(p) == 0 {
|
|
return ""
|
|
}
|
|
var buf bytes.Buffer
|
|
for _, element := range p {
|
|
buf.WriteByte('/')
|
|
buf.WriteString(element.String())
|
|
}
|
|
return buf.String()
|
|
}
|
|
|
|
// Equal returns whether the Path contains the same elements as the other Path.
|
|
// This method implements key.Comparable.
|
|
func (p Path) Equal(other interface{}) bool {
|
|
o, ok := other.(Path)
|
|
if !ok {
|
|
return false
|
|
}
|
|
if len(o) != len(p) {
|
|
return false
|
|
}
|
|
return o.hasPrefix(p)
|
|
}
|
|
|
|
// HasPrefix returns whether the Path is prefixed by the other Path.
|
|
func (p Path) HasPrefix(prefix Path) bool {
|
|
if len(prefix) > len(p) {
|
|
return false
|
|
}
|
|
return p.hasPrefix(prefix)
|
|
}
|
|
|
|
func (p Path) hasPrefix(prefix Path) bool {
|
|
for i := range prefix {
|
|
if !prefix[i].Equal(p[i]) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|