blob: e9c905c96bcf449e1af4cd3eccfcd698a8618db4 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
|
package noder
import (
"bytes"
"strings"
"golang.org/x/text/unicode/norm"
)
// Path values represent a noder and its ancestors. The root goes first
// and the actual final noder the path is referring to will be the last.
//
// A path implements the Noder interface, redirecting all the interface
// calls to its final noder.
//
// Paths build from an empty Noder slice are not valid paths and should
// not be used.
type Path []Noder
// String returns the full path of the final noder as a string, using
// "/" as the separator.
func (p Path) String() string {
var buf bytes.Buffer
sep := ""
for _, e := range p {
_, _ = buf.WriteString(sep)
sep = "/"
_, _ = buf.WriteString(e.Name())
}
return buf.String()
}
// Last returns the final noder in the path.
func (p Path) Last() Noder {
return p[len(p)-1]
}
// Hash returns the hash of the final noder of the path.
func (p Path) Hash() []byte {
return p.Last().Hash()
}
// Name returns the name of the final noder of the path.
func (p Path) Name() string {
return p.Last().Name()
}
// IsDir returns if the final noder of the path is a directory-like
// noder.
func (p Path) IsDir() bool {
return p.Last().IsDir()
}
// Children returns the children of the final noder in the path.
func (p Path) Children() ([]Noder, error) {
return p.Last().Children()
}
// NumChildren returns the number of children the final noder of the
// path has.
func (p Path) NumChildren() (int, error) {
return p.Last().NumChildren()
}
// Compare returns -1, 0 or 1 if the path p is smaller, equal or bigger
// than other, in "directory order"; for example:
//
// "a" < "b"
// "a/b/c/d/z" < "b"
// "a/b/a" > "a/b"
func (p Path) Compare(other Path) int {
i := 0
for {
switch {
case len(other) == len(p) && i == len(p):
return 0
case i == len(other):
return 1
case i == len(p):
return -1
default:
form := norm.Form(norm.NFC)
this := form.String(p[i].Name())
that := form.String(other[i].Name())
cmp := strings.Compare(this, that)
if cmp != 0 {
return cmp
}
}
i++
}
}
|