-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathslices.go
183 lines (164 loc) · 4.4 KB
/
slices.go
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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
package fs
import (
"cmp"
"context"
"slices"
"sort"
"time"
)
// NameIndex returns the slice index of the first file
// where the passed filename equals the result from the Name method
// or -1 in case of no match.
func NameIndex[F interface{ Name() string }](files []F, filename string) int {
for i, f := range files {
if f.Name() == filename {
return i
}
}
return -1
}
// ContainsName returns true if the passed filename
// matches the result from the Name method of any of the files.
func ContainsName[F interface{ Name() string }](files []F, filename string) bool {
for _, f := range files {
if f.Name() == filename {
return true
}
}
return false
}
// LocalPathIndex returns the slice index of the first file
// where the passed localPath equals the result from the LocalPath method
// or -1 in case of no match.
func LocalPathIndex[F interface{ LocalPath() string }](files []F, localPath string) int {
for i, f := range files {
if f.LocalPath() == localPath {
return i
}
}
return -1
}
// ContainsLocalPath returns true if the passed localPath
// matches the result from the LocalPath method of any of the files.
func ContainsLocalPath[F interface{ LocalPath() string }](files []F, localPath string) bool {
for _, f := range files {
if f.LocalPath() == localPath {
return true
}
}
return false
}
// ContentHashIndex returns the slice index of the first file
// where the passed hash equals the result from the ContentHashContext method
// or -1 in case of no match.
func ContentHashIndex[F interface {
ContentHashContext(ctx context.Context) (string, error)
}](ctx context.Context, files []F, hash string) (int, error) {
for i, f := range files {
fHash, err := f.ContentHashContext(ctx)
if err != nil {
return -1, err
}
if fHash == hash {
return i, nil
}
}
return -1, nil
}
// NotExistsIndex returns the slice index of the first FileReader
// where the Exists method returned false
// or -1 in case of no match.
func NotExistsIndex[F interface{ Exists() bool }](files []F) int {
for i, f := range files {
if !f.Exists() {
return i
}
}
return -1
}
// AllExist returns true if the Exists method of all files returned true
func AllExist[F interface{ Exists() bool }](files []F) bool {
for _, f := range files {
if !f.Exists() {
return false
}
}
return true
}
// FileURLs returns the URLs of the passed files
func FileURLs[F interface{ URL() string }](files []F) []string {
fileURLs := make([]string, len(files))
for i, file := range files {
fileURLs[i] = file.URL()
}
return fileURLs
}
// FilePaths returns the FileSystem specific paths the passed files
func FilePaths[F interface{ Path() string }](files []F) []string {
paths := make([]string, len(files))
for i, file := range files {
paths[i] = file.Path()
}
return paths
}
// FileNames returns the names of the passed files
func FileNames[T interface{ Name() string }](files []T) []string {
names := make([]string, len(files))
for i, file := range files {
names[i] = file.Name()
}
return names
}
func SortByName[F interface{ Name() string }](files []F) {
slices.SortFunc(files, func(a, b F) int {
return cmp.Compare(a.Name(), b.Name())
})
}
func SortByNameDirsFirst[F FileReader](files []F) {
sort.Slice(files, func(i, j int) bool {
fi := files[i]
fj := files[j]
if isLess, ok := compareDirsFirst(fi, fj); ok {
return isLess
}
return fi.Name() < fj.Name()
})
}
func SortByPath[F interface{ Path() string }](files []F) {
slices.SortFunc(files, func(a, b F) int {
return cmp.Compare(a.Path(), b.Path())
})
}
func SortByLocalPath[F interface{ LocalPath() string }](files []F) {
slices.SortFunc(files, func(a, b F) int {
return cmp.Compare(a.LocalPath(), b.LocalPath())
})
}
func SortBySize[F interface{ Size() int64 }](files []F) {
slices.SortFunc(files, func(a, b F) int {
return cmp.Compare(a.Size(), b.Size())
})
}
func SortByModified[F interface{ Modified() time.Time }](files []File) {
sort.Slice(files, func(i, j int) bool {
return files[i].Modified().Before(files[j].Modified())
})
}
func SortByModifiedDirsFirst(files []File) {
sort.Slice(files, func(i, j int) bool {
fi := files[i]
fj := files[j]
if isLess, ok := compareDirsFirst(fi, fj); ok {
return isLess
}
return fi.Modified().Before(fj.Modified())
})
}
func compareDirsFirst(fi, fj FileReader) (isLess, ok bool) {
idir := fi.IsDir()
jdir := fj.IsDir()
if idir == jdir {
return false, false
}
return idir, true
}