Files
gof3/tree/generic/path.go
Earl Warren fb2e7aad84 tree/f3: define f3.Path with additional accessors
So they can be used like so to go from the root down:

p.Root().Forge().Users()
2024-03-08 18:37:26 +07:00

151 lines
3.0 KiB
Go

// Copyright Earl Warren <contact@earl-warren.org>
// Copyright Loïc Dachary <loic@dachary.org>
// SPDX-License-Identifier: MIT
package generic
import (
"path/filepath"
"strings"
)
type Path interface {
Clone() Path
Length() int
PathString() PathString
PathMappedString() PathString
String() string
Append(child NodeInterface) Path
RemoveFirst() Path
PopFirst() (NodeInterface, Path)
Pop() (NodeInterface, Path)
Empty() bool
First() NodeInterface
Last() NodeInterface
All() []NodeInterface
}
type PathImplementation []NodeInterface
func PathAbsoluteString(current, destination string) string {
if !strings.HasPrefix(destination, "/") {
return current + "/" + destination
}
return destination
}
func PathAbsolute(current, destination string) Path {
return NewPathFromString(PathAbsoluteString(current, destination))
}
func PathStringRelative(current, destination string) string {
r, err := filepath.Rel(current, destination)
if err != nil {
panic(err)
}
return r
}
func NewPathFromString(pathString string) Path {
pathString = filepath.Clean(pathString)
if pathString == "." {
node := NewNode()
node.SetID(NodeID("."))
return NewPath(node)
}
path := make([]NodeInterface, 0, 10)
if strings.HasPrefix(pathString, "/") {
root := NewNode()
root.SetKind(KindRoot)
path = append(path, root)
pathString = pathString[1:]
}
if pathString == "" {
return NewPath(path...)
}
for _, id := range strings.Split(pathString, "/") {
node := NewNode()
node.SetID(NodeID(id))
path = append(path, node)
}
return NewPath(path...)
}
func NewPath(nodes ...NodeInterface) Path {
return PathImplementation(nodes)
}
func (o PathImplementation) PathString() PathString {
elements := make([]string, 0, 10)
for _, node := range o {
elements = append(elements, string(node.GetID()))
}
return elements
}
func (o PathImplementation) PathMappedString() PathString {
elements := make([]string, 0, 10)
for _, node := range o {
elements = append(elements, string(node.GetMappedID()))
}
return elements
}
func (o PathImplementation) String() string {
return o.PathString().Join()
}
func (o PathImplementation) Length() int {
return len(o)
}
func (o PathImplementation) Clone() Path {
return o[:]
}
func (o PathImplementation) Append(child NodeInterface) Path {
return append(o, child)
}
func (o PathImplementation) PopFirst() (NodeInterface, Path) {
return o.First(), o.RemoveFirst()
}
func (o PathImplementation) RemoveFirst() Path {
return o[1:]
}
func (o PathImplementation) Pop() (NodeInterface, Path) {
return o.Last(), o.RemoveLast()
}
func (o PathImplementation) RemoveLast() Path {
return o[:len(o)-1]
}
func (o PathImplementation) Empty() bool {
return len(o) == 0
}
func (o PathImplementation) Last() NodeInterface {
return o[len(o)-1]
}
func (o PathImplementation) First() NodeInterface {
return o[0]
}
func (o PathImplementation) All() []NodeInterface {
return o
}
type PathString []string
func (o PathString) Empty() bool {
return len(o) == 0
}
func (o PathString) Join() string {
return strings.Join(o, "/")
}