Adding upstream version 3.10.8.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
37e9b6d587
commit
03bfe4079e
356 changed files with 28857 additions and 0 deletions
51
path/interface.go
Normal file
51
path/interface.go
Normal file
|
@ -0,0 +1,51 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package path
|
||||
|
||||
import (
|
||||
"code.forgejo.org/f3/gof3/v3/f3"
|
||||
"code.forgejo.org/f3/gof3/v3/id"
|
||||
"code.forgejo.org/f3/gof3/v3/kind"
|
||||
)
|
||||
|
||||
type PathElementAllocator func() PathElement
|
||||
|
||||
type PathElement interface {
|
||||
SetID(id.NodeID)
|
||||
GetID() id.NodeID
|
||||
|
||||
SetMappedID(id.NodeID)
|
||||
GetMappedID() id.NodeID
|
||||
|
||||
SetKind(kind kind.Kind)
|
||||
GetKind() kind.Kind
|
||||
|
||||
ToFormat() f3.Interface
|
||||
}
|
||||
|
||||
type Path interface {
|
||||
Length() int
|
||||
PathString() PathString
|
||||
PathMappedString() PathString
|
||||
String() string
|
||||
ReadablePathString() PathString
|
||||
ReadableString() string
|
||||
Append(child PathElement) Path
|
||||
RemoveFirst() Path
|
||||
PopFirst() (PathElement, Path)
|
||||
Pop() (PathElement, Path)
|
||||
RemoveLast() Path
|
||||
Empty() bool
|
||||
First() PathElement
|
||||
Last() PathElement
|
||||
All() []PathElement
|
||||
}
|
||||
|
||||
type PathString interface {
|
||||
Empty() bool
|
||||
Join() string
|
||||
Append(element string)
|
||||
Elements() []string
|
||||
}
|
61
path/operations.go
Normal file
61
path/operations.go
Normal file
|
@ -0,0 +1,61 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package path
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.forgejo.org/f3/gof3/v3/id"
|
||||
"code.forgejo.org/f3/gof3/v3/kind"
|
||||
)
|
||||
|
||||
func PathAbsoluteString(current, destination string) string {
|
||||
if !strings.HasPrefix(destination, "/") {
|
||||
return filepath.Clean(current + "/" + destination)
|
||||
}
|
||||
return filepath.Clean(destination)
|
||||
}
|
||||
|
||||
func PathAbsolute(allocator PathElementAllocator, current, destination string) Path {
|
||||
return NewPathFromString(allocator, PathAbsoluteString(current, destination))
|
||||
}
|
||||
|
||||
func PathRelativeString(current, destination string) string {
|
||||
r, err := filepath.Rel(current, destination)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
func NewPathFromString(allocator PathElementAllocator, pathString string) Path {
|
||||
pathString = filepath.Clean(pathString)
|
||||
if pathString == "." {
|
||||
e := allocator()
|
||||
e.SetID(id.NewNodeID("."))
|
||||
return NewPath(e)
|
||||
}
|
||||
path := make([]PathElement, 0, 10)
|
||||
if strings.HasPrefix(pathString, "/") {
|
||||
root := allocator()
|
||||
root.SetKind(kind.KindRoot)
|
||||
path = append(path, root)
|
||||
pathString = pathString[1:]
|
||||
}
|
||||
if pathString == "" {
|
||||
return NewPath(path...)
|
||||
}
|
||||
for _, i := range strings.Split(pathString, "/") {
|
||||
e := allocator()
|
||||
e.SetID(id.NewNodeID(i))
|
||||
path = append(path, e)
|
||||
}
|
||||
return NewPath(path...)
|
||||
}
|
||||
|
||||
func NewPath(nodes ...PathElement) Path {
|
||||
return Implementation(nodes)
|
||||
}
|
106
path/path.go
Normal file
106
path/path.go
Normal file
|
@ -0,0 +1,106 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package path
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"code.forgejo.org/f3/gof3/v3/id"
|
||||
)
|
||||
|
||||
type Implementation []PathElement
|
||||
|
||||
func (o Implementation) PathString() PathString {
|
||||
elements := NewPathString()
|
||||
for i, e := range o {
|
||||
eid := e.GetID()
|
||||
// i == 0 is root and intentionally empty
|
||||
if i > 0 && eid == id.NilID {
|
||||
eid = id.NewNodeID("nothing")
|
||||
}
|
||||
elements.Append(eid.String())
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
func (o Implementation) PathMappedString() PathString {
|
||||
elements := NewPathString()
|
||||
for _, e := range o {
|
||||
elements.Append(e.GetMappedID().String())
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
func (o Implementation) String() string {
|
||||
return o.PathString().Join()
|
||||
}
|
||||
|
||||
var replacer = strings.NewReplacer(
|
||||
"{", "%7B",
|
||||
"}", "%7D",
|
||||
)
|
||||
|
||||
func (o Implementation) ReadablePathString() PathString {
|
||||
elements := NewPathString()
|
||||
if o.Length() > 0 {
|
||||
elements.Append("")
|
||||
for _, e := range o[1:] {
|
||||
element := e.GetID().String()
|
||||
if f := e.ToFormat(); f != nil {
|
||||
name := f.GetName()
|
||||
if element != name {
|
||||
element = fmt.Sprintf("{%s/%s}", replacer.Replace(name), element)
|
||||
}
|
||||
}
|
||||
elements.Append(element)
|
||||
}
|
||||
}
|
||||
return elements
|
||||
}
|
||||
|
||||
func (o Implementation) ReadableString() string {
|
||||
return o.ReadablePathString().Join()
|
||||
}
|
||||
|
||||
func (o Implementation) Length() int {
|
||||
return len(o)
|
||||
}
|
||||
|
||||
func (o Implementation) Append(child PathElement) Path {
|
||||
return append(o, child)
|
||||
}
|
||||
|
||||
func (o Implementation) PopFirst() (PathElement, Path) {
|
||||
return o.First(), o.RemoveFirst()
|
||||
}
|
||||
|
||||
func (o Implementation) RemoveFirst() Path {
|
||||
return o[1:]
|
||||
}
|
||||
|
||||
func (o Implementation) Pop() (PathElement, Path) {
|
||||
return o.Last(), o.RemoveLast()
|
||||
}
|
||||
|
||||
func (o Implementation) RemoveLast() Path {
|
||||
return o[:len(o)-1]
|
||||
}
|
||||
|
||||
func (o Implementation) Empty() bool {
|
||||
return len(o) == 0
|
||||
}
|
||||
|
||||
func (o Implementation) Last() PathElement {
|
||||
return o[len(o)-1]
|
||||
}
|
||||
|
||||
func (o Implementation) First() PathElement {
|
||||
return o[0]
|
||||
}
|
||||
|
||||
func (o Implementation) All() []PathElement {
|
||||
return o
|
||||
}
|
182
path/path_test.go
Normal file
182
path/path_test.go
Normal file
|
@ -0,0 +1,182 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package path
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
"code.forgejo.org/f3/gof3/v3/f3"
|
||||
"code.forgejo.org/f3/gof3/v3/id"
|
||||
"code.forgejo.org/f3/gof3/v3/kind"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
type PathElementTest struct {
|
||||
id id.NodeID
|
||||
mapped id.NodeID
|
||||
kind kind.Kind
|
||||
name string
|
||||
}
|
||||
|
||||
func NewPathElementTest() PathElement {
|
||||
return &PathElementTest{
|
||||
id: id.NilID,
|
||||
mapped: id.NilID,
|
||||
}
|
||||
}
|
||||
|
||||
func (o PathElementTest) GetID() id.NodeID { return o.id }
|
||||
func (o *PathElementTest) SetID(i id.NodeID) { o.id = i }
|
||||
|
||||
func (o PathElementTest) GetMappedID() id.NodeID { return o.mapped }
|
||||
func (o *PathElementTest) SetMappedID(mapped id.NodeID) { o.mapped = mapped }
|
||||
|
||||
func (o PathElementTest) GetKind() kind.Kind { return o.kind }
|
||||
func (o *PathElementTest) SetKind(kind kind.Kind) { o.kind = kind }
|
||||
|
||||
type PathF3Test struct {
|
||||
f3.Common
|
||||
name string
|
||||
}
|
||||
|
||||
func (o *PathF3Test) GetName() string {
|
||||
if o.name != "" {
|
||||
return o.name
|
||||
}
|
||||
return o.Common.GetName()
|
||||
}
|
||||
|
||||
func (o PathElementTest) ToFormat() f3.Interface {
|
||||
return &PathF3Test{
|
||||
Common: f3.NewCommon(o.GetID().String()),
|
||||
name: o.name,
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPathFromString(t *testing.T) {
|
||||
for _, pathString := range []string{"", ".", "A/.."} {
|
||||
path := NewPathFromString(NewPathElementTest, pathString)
|
||||
assert.False(t, path.Empty(), path.String())
|
||||
assert.Len(t, path, 1, path.String())
|
||||
assert.EqualValues(t, ".", path.First().GetID())
|
||||
}
|
||||
for _, pathString := range []string{"/", "/.", "/..", "/A/.."} {
|
||||
path := NewPathFromString(NewPathElementTest, pathString)
|
||||
assert.False(t, path.Empty(), path.String())
|
||||
assert.Len(t, path, 1, path.String())
|
||||
assert.EqualValues(t, kind.KindRoot, path.First().GetKind(), path.String())
|
||||
assert.EqualValues(t, "", path.First().GetID())
|
||||
}
|
||||
for _, pathString := range []string{"A", "A/.", "B/../A"} {
|
||||
path := NewPathFromString(NewPathElementTest, pathString)
|
||||
assert.False(t, path.Empty(), path.String())
|
||||
assert.Len(t, path, 1, path.String())
|
||||
assert.NotEqualValues(t, kind.KindRoot, path.First().GetKind(), path.String())
|
||||
assert.EqualValues(t, "A", path.First().GetID())
|
||||
}
|
||||
{
|
||||
pathString := "/A"
|
||||
path := NewPathFromString(NewPathElementTest, pathString)
|
||||
assert.False(t, path.Empty(), path.String())
|
||||
assert.Len(t, path, 2, path.String())
|
||||
assert.EqualValues(t, kind.KindRoot, path.First().GetKind(), path.String())
|
||||
notRoot := path.RemoveFirst()
|
||||
assert.NotEqualValues(t, kind.KindRoot, notRoot.First().GetKind(), path.String())
|
||||
assert.EqualValues(t, pathString, path.String(), path.String())
|
||||
}
|
||||
{
|
||||
pathString := "A/B"
|
||||
path := NewPathFromString(NewPathElementTest, pathString)
|
||||
assert.False(t, path.Empty(), path.String())
|
||||
assert.Len(t, path, 2, path.String())
|
||||
assert.NotEqualValues(t, kind.KindRoot, path.First().GetKind(), path.String())
|
||||
notRoot := path.RemoveFirst()
|
||||
assert.NotEqualValues(t, kind.KindRoot, notRoot.First().GetKind(), path.String())
|
||||
assert.EqualValues(t, pathString, path.String(), path.String())
|
||||
}
|
||||
{
|
||||
pathString := "../B"
|
||||
path := NewPathFromString(NewPathElementTest, pathString)
|
||||
assert.False(t, path.Empty(), path.String())
|
||||
assert.Len(t, path, 2, path.String())
|
||||
assert.NotEqualValues(t, kind.KindRoot, path.First().GetKind(), path.String())
|
||||
notRoot := path.RemoveFirst()
|
||||
assert.NotEqualValues(t, kind.KindRoot, notRoot.First().GetKind(), path.String())
|
||||
assert.EqualValues(t, pathString, path.String(), path.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestPathAbsoluteString(t *testing.T) {
|
||||
assert.Equal(t, "/c", PathAbsoluteString("/a/b", "/c/d/.."))
|
||||
assert.Equal(t, "/a/b/c", PathAbsoluteString("/a/b", "c"))
|
||||
assert.Equal(t, "/a/b/c", PathAbsoluteString("/a/./b", "c/d/.."))
|
||||
}
|
||||
|
||||
func TestPathAbsolute(t *testing.T) {
|
||||
assert.Equal(t, "/a/b/c", PathAbsolute(NewPathElementTest, "/a/b", "c").String())
|
||||
}
|
||||
|
||||
func TestPathRelativeString(t *testing.T) {
|
||||
assert.Equal(t, "../c", PathRelativeString("/a/b/d", "/a/b/c"))
|
||||
assert.Panics(t, func() { PathRelativeString("/a/b/d", "") })
|
||||
}
|
||||
|
||||
func TestPathString(t *testing.T) {
|
||||
path := NewPathFromString(NewPathElementTest, "/a/b/c")
|
||||
assert.Equal(t, "/a/b/c", path.PathString().Join())
|
||||
last, path := path.Pop()
|
||||
path = path.Append(NewPathElementTest())
|
||||
path = path.Append(last)
|
||||
assert.Equal(t, "/a/b/nothing/c", path.PathString().Join())
|
||||
}
|
||||
|
||||
func TestPathReadable(t *testing.T) {
|
||||
path := NewPathFromString(NewPathElementTest, "/a/b/c")
|
||||
name := "N{AM}E"
|
||||
path.Last().(*PathElementTest).name = name
|
||||
assert.Equal(t, name, path.Last().ToFormat().GetName())
|
||||
expected := fmt.Sprintf("/a/b/{%s/c}", replacer.Replace(name))
|
||||
assert.Equal(t, expected, path.ReadablePathString().Join())
|
||||
assert.Equal(t, expected, path.ReadableString())
|
||||
|
||||
path = NewPathFromString(NewPathElementTest, "")
|
||||
assert.Equal(t, "", path.ReadableString())
|
||||
}
|
||||
|
||||
func TestPathMappedString(t *testing.T) {
|
||||
path := NewPathFromString(NewPathElementTest, "/a/b")
|
||||
for _, node := range path.All() {
|
||||
node.SetMappedID(id.NewNodeID(node.GetID().String() + "M"))
|
||||
}
|
||||
assert.Equal(t, "M/aM/bM", path.PathMappedString().Join())
|
||||
}
|
||||
|
||||
func TestPathMethods(t *testing.T) {
|
||||
path := NewPathFromString(NewPathElementTest, "/a/b/c")
|
||||
assert.Equal(t, "/a/b/c", path.String())
|
||||
assert.Equal(t, 4, path.Length())
|
||||
assert.Len(t, path.All(), 4)
|
||||
assert.False(t, path.Empty())
|
||||
|
||||
first, path := path.PopFirst()
|
||||
assert.Equal(t, "", first.GetID().String())
|
||||
assert.Equal(t, "a/b/c", path.String())
|
||||
|
||||
assert.Equal(t, "a", path.First().GetID().String())
|
||||
|
||||
assert.Equal(t, "c", path.Last().GetID().String())
|
||||
|
||||
firstRemoved := path.RemoveFirst()
|
||||
assert.Equal(t, "b/c", firstRemoved.String())
|
||||
|
||||
last, lastRemoved := path.Pop()
|
||||
assert.Equal(t, "c", last.GetID().String())
|
||||
assert.Equal(t, "a/b", lastRemoved.String())
|
||||
|
||||
lastRemoved = path.RemoveLast()
|
||||
assert.Equal(t, "a/b", lastRemoved.String())
|
||||
}
|
33
path/pathstring.go
Normal file
33
path/pathstring.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
// Copyright Earl Warren <contact@earl-warren.org>
|
||||
// Copyright Loïc Dachary <loic@dachary.org>
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package path
|
||||
|
||||
import "strings"
|
||||
|
||||
func NewPathString() PathString {
|
||||
return &pathString{
|
||||
elements: make([]string, 0, 10),
|
||||
}
|
||||
}
|
||||
|
||||
type pathString struct {
|
||||
elements []string
|
||||
}
|
||||
|
||||
func (o pathString) Empty() bool {
|
||||
return len(o.elements) == 0
|
||||
}
|
||||
|
||||
func (o pathString) Join() string {
|
||||
return strings.Join(o.elements, "/")
|
||||
}
|
||||
|
||||
func (o *pathString) Append(element string) {
|
||||
o.elements = append(o.elements, element)
|
||||
}
|
||||
|
||||
func (o pathString) Elements() []string {
|
||||
return o.elements
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue