1package fs
2
3import "fmt"
4
5// DirEntries is a slice of Object or *Dir
6type DirEntries []DirEntry
7
8// Len is part of sort.Interface.
9func (ds DirEntries) Len() int {
10	return len(ds)
11}
12
13// Swap is part of sort.Interface.
14func (ds DirEntries) Swap(i, j int) {
15	ds[i], ds[j] = ds[j], ds[i]
16}
17
18// Less is part of sort.Interface.
19func (ds DirEntries) Less(i, j int) bool {
20	return CompareDirEntries(ds[i], ds[j]) < 0
21}
22
23// ForObject runs the function supplied on every object in the entries
24func (ds DirEntries) ForObject(fn func(o Object)) {
25	for _, entry := range ds {
26		o, ok := entry.(Object)
27		if ok {
28			fn(o)
29		}
30	}
31}
32
33// ForObjectError runs the function supplied on every object in the entries
34func (ds DirEntries) ForObjectError(fn func(o Object) error) error {
35	for _, entry := range ds {
36		o, ok := entry.(Object)
37		if ok {
38			err := fn(o)
39			if err != nil {
40				return err
41			}
42		}
43	}
44	return nil
45}
46
47// ForDir runs the function supplied on every Directory in the entries
48func (ds DirEntries) ForDir(fn func(dir Directory)) {
49	for _, entry := range ds {
50		dir, ok := entry.(Directory)
51		if ok {
52			fn(dir)
53		}
54	}
55}
56
57// ForDirError runs the function supplied on every Directory in the entries
58func (ds DirEntries) ForDirError(fn func(dir Directory) error) error {
59	for _, entry := range ds {
60		dir, ok := entry.(Directory)
61		if ok {
62			err := fn(dir)
63			if err != nil {
64				return err
65			}
66		}
67	}
68	return nil
69}
70
71// DirEntryType returns a string description of the DirEntry, either
72// "object", "directory" or "unknown type XXX"
73func DirEntryType(d DirEntry) string {
74	switch d.(type) {
75	case Object:
76		return "object"
77	case Directory:
78		return "directory"
79	}
80	return fmt.Sprintf("unknown type %T", d)
81}
82
83// CompareDirEntries returns 1 if a > b, 0 if a == b and -1 if a < b
84// If two dir entries have the same name, compare their types (directories are before objects)
85func CompareDirEntries(a, b DirEntry) int {
86	aName := a.Remote()
87	bName := b.Remote()
88
89	if aName > bName {
90		return 1
91	} else if aName < bName {
92		return -1
93	}
94
95	typeA := DirEntryType(a)
96	typeB := DirEntryType(b)
97
98	// same name, compare types
99	if typeA > typeB {
100		return 1
101	} else if typeA < typeB {
102		return -1
103	}
104
105	return 0
106}
107