-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathiter.go
63 lines (53 loc) · 1.23 KB
/
iter.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
package aferox
import (
"io/fs"
"github.com/spf13/afero"
"github.com/unmango/go/iter"
"github.com/unmango/go/option"
)
type ErrFilter func(error) error
type iterOptions struct {
continueOnErr bool
errFilter ErrFilter
skipDirs bool
}
type IterOption func(*iterOptions)
func ContinueOnError(options *iterOptions) {
options.continueOnErr = true
}
func SkipDirs(options *iterOptions) {
options.skipDirs = true
}
func FilterErrors(filter ErrFilter) IterOption {
return func(options *iterOptions) {
options.errFilter = filter
}
}
func Iter(fsys afero.Fs, root string, options ...IterOption) iter.Seq3[string, fs.FileInfo, error] {
opts := iterOptions{}
option.ApplyAll(&opts, options)
return func(yield func(string, fs.FileInfo, error) bool) {
done := false
err := afero.Walk(fsys, root,
func(path string, info fs.FileInfo, err error) error {
if err != nil && !opts.continueOnErr {
return err
}
if err != nil && opts.errFilter != nil {
return opts.errFilter(err)
}
if info.IsDir() && opts.skipDirs {
return nil
}
if done = !yield(path, info, err); done {
return fs.SkipAll
} else {
return nil
}
},
)
if err != nil && !done {
yield("", nil, err)
}
}
}