1
0
Fork 0

Adding upstream version 3.10.8.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-05-18 09:37:23 +02:00
parent 37e9b6d587
commit 03bfe4079e
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
356 changed files with 28857 additions and 0 deletions

51
path/interface.go Normal file
View 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
View 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
View 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
View 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
View 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
}