Skip to content

Commit

Permalink
Add from.DirWalk
Browse files Browse the repository at this point in the history
  • Loading branch information
empijei committed Dec 12, 2024
1 parent e6e4c73 commit 0cfb897
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
23 changes: 23 additions & 0 deletions from/from.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package from
import (
"bufio"
"context"
"errors"
"io/fs"
"iter"
)

Expand Down Expand Up @@ -39,3 +41,24 @@ func Chan[T any](ctx context.Context, src <-chan T) iter.Seq[T] {
}
}
}

// DirStep represents a step in a directory Walk.
type DirStep struct {
FullPath string
Entry fs.DirEntry
}

// DirWalk emits all entries for root and its subdirectories.
// Errors are forwarded, and the consumer may decide wether to stop iteration or continue consuming further values.
//
// Use os.DirFS(path) to create fsys from disk.
func DirWalk(ctx context.Context, fsys fs.FS, root string) iter.Seq2[DirStep, error] {
return func(yield func(DirStep, error) bool) {
fs.WalkDir(fsys, root, func(path string, d fs.DirEntry, err error) error {
if !yield(DirStep{FullPath: path, Entry: d}, err) {
return errors.New("consumer stopped")
}
return nil
})
}
}
27 changes: 27 additions & 0 deletions from/from_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ package from_test
import (
"bufio"
"context"
"io/fs"
"slices"
"strings"
"testing"
"testing/fstest"

"github.com/empijei/itertools/from"
"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -63,3 +65,28 @@ func TestChan(t *testing.T) {
}
})
}

func TestDirWalk(t *testing.T) {
fsys := fstest.MapFS(map[string]*fstest.MapFile{
"root/foo/bar.txt": {Data: []byte("hello bar")},
"root/empty": {Mode: fs.ModeDir},
"root/cat.txt": {Data: []byte("hello cat")},
})

var errs []error
var dirs []string
from.DirWalk(context.Background(), fsys, "root")(func(ds from.DirStep, err error) bool {
if err != nil {
errs = append(errs, err)
}
dirs = append(dirs, ds.FullPath)
return true
})
want := []string{"root", "root/cat.txt", "root/empty", "root/foo", "root/foo/bar.txt"}
if diff := cmp.Diff(want, dirs); diff != "" {
t.Errorf("DirWalk: got %v want %v diff:\n%s", dirs, want, diff)
}
if len(errs) != 0 {
t.Errorf("DirWalk errors: got %v want none", errs)
}
}

0 comments on commit 0cfb897

Please sign in to comment.