ipld-eth-server/vendor/github.com/aristanetworks/goarista/path/path.go
Matt K 293dd2e848 Add vendor dir (#16) (#4)
* Add vendor dir so builds dont require dep

* Pin specific version go-eth version
2018-01-29 13:44:18 -06:00

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
}