package filterfs import "io/fs" import "fmt" // Filter returns true to include a file name and false to exclude it. type Filter func(name string) bool type FS struct { underlying fs.FS filter Filter } func Apply(sys fs.FS, filter Filter) FS { return FS{sys, filter} } type File struct { underlying fs.ReadDirFile filter Filter } func (f File) Stat() (fs.FileInfo, error) { return f.underlying.Stat() } func (f File) Read(buf []byte) (int, error) { return f.underlying.Read(buf) } func (f File) Close() error { return f.underlying.Close() } func filterEntries(filter Filter, entries []fs.DirEntry) []fs.DirEntry { result := []fs.DirEntry{} for _, entry := range entries { if filter(entry.Name()) { result = append(result, entry) } } return result } func (f File) ReadDir(n int) ([]fs.DirEntry, error) { entries, err := f.underlying.ReadDir(n) if err != nil { return entries, err } return filterEntries(f.filter, entries), nil } func (sys FS) Open(name string) (fs.File, error) { file, err := sys.underlying.Open(name) if err != nil { return nil, err } if dir, ok := file.(fs.ReadDirFile); ok { return File{dir, sys.filter}, nil } else { return file, nil } } func (sys FS) Glob(pattern string) ([]string, error) { entries, err := fs.Glob(sys.underlying, pattern) if err != nil { return entries, err } result := []string{} for _, entry := range entries { if sys.filter(entry) { result = append(result, entry) } } fmt.Printf("%v\n", entries) fmt.Printf("%v\n", result) return result, nil } /* func (sys FS) ReadDir(fname string) ([]fs.DirEntry, error) { entries, err := fs.ReadDir(sys.underlying, fname) if err != nil { return entries, err } return filterEntries(sys.filter, entries), nil } */ var _ fs.FS = &FS{} var _ fs.GlobFS = &FS{} var _ fs.ReadDirFS = &FS{}