File: filesystem.go

package info (click to toggle)
golang-github-marstr-collection 0.3.3%2Bgit20171004.e631537-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 152 kB
  • sloc: makefile: 2
file content (77 lines) | stat: -rw-r--r-- 1,761 bytes parent folder | download | duplicates (2)
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
package collection

import (
	"errors"
	"os"
	"path/filepath"
)

// DirectoryOptions is a means of configuring a `Directory` instance to including various children in its enumeration without
// supplying a `Where` clause later.
type DirectoryOptions uint

// These constants define all of the supported options for configuring a `Directory`
const (
	DirectoryOptionsExcludeFiles = 1 << iota
	DirectoryOptionsExcludeDirectories
	DirectoryOptionsRecursive
)

// Directory treats a filesystem path as a collection of filesystem entries, specifically a collection of directories and files.
type Directory struct {
	Location string
	Options  DirectoryOptions
}

func defaultEnumeratePredicate(loc string, info os.FileInfo) bool {
	return true
}

func (d Directory) applyOptions(loc string, info os.FileInfo) bool {
	if info.IsDir() && 0 != (d.Options&DirectoryOptionsExcludeDirectories) {
		return false
	}

	if !info.IsDir() && 0 != d.Options&DirectoryOptionsExcludeFiles {
		return false
	}

	return true
}

// Enumerate lists the items in a `Directory`
func (d Directory) Enumerate(cancel <-chan struct{}) Enumerator {
	results := make(chan interface{})

	go func() {
		defer close(results)

		filepath.Walk(d.Location, func(currentLocation string, info os.FileInfo, openErr error) (err error) {
			if openErr != nil {
				err = openErr
				return
			}

			if d.Location == currentLocation {
				return
			}

			if info.IsDir() && 0 == d.Options&DirectoryOptionsRecursive {
				err = filepath.SkipDir
			}

			if d.applyOptions(currentLocation, info) {
				select {
				case results <- currentLocation:
					// Intentionally Left Blank
				case <-cancel:
					err = errors.New("directory enumeration cancelled")
				}
			}

			return
		})
	}()

	return results
}