-
Notifications
You must be signed in to change notification settings - Fork 0
/
directory.go
119 lines (93 loc) · 2.06 KB
/
directory.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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package main
import (
"io/fs"
"os"
"path"
"path/filepath"
"sort"
"strings"
"github.com/samber/mo"
)
type Directory struct {
path string
fsys fs.FS
}
type Order int
const (
ORDER_NAME Order = iota
ORDER_TIME
)
func NewDirectory(path string) Directory {
return Directory{path: path, fsys: os.DirFS(path)}
}
func (d Directory) String() string {
return d.path
}
func (d Directory) Name() string {
return filepath.Base(d.String())
}
func (d Directory) IsHidden() bool {
return strings.HasPrefix(d.Name(), ".")
}
func (d Directory) Parent() mo.Option[Directory] {
parent := path.Dir(d.String())
if parent == d.String() {
return mo.None[Directory]()
} else {
return mo.Some(NewDirectory(parent))
}
}
func (d Directory) Dirs(showAll bool, order Order) mo.Result[[]Directory] {
files, err := fs.ReadDir(d.fsys, ".")
if err != nil {
return mo.Err[[]Directory](err)
}
var entries []fs.DirEntry
for _, file := range files {
if file.IsDir() || getSymlink(filepath.Join(d.String(), file.Name())).IsPresent() {
if showAll || !strings.HasPrefix(file.Name(), ".") {
entries = append(entries, file)
}
}
}
switch order {
case ORDER_NAME:
case ORDER_TIME:
sort.Slice(entries, func(i, j int) bool {
af, _ := entries[i].Info()
bf, _ := entries[j].Info()
return bf.ModTime().After(af.ModTime())
})
}
var directories []Directory
for _, entry := range entries {
directories = append(directories, NewDirectory(filepath.Join(d.String(), entry.Name())))
}
return mo.Ok(directories)
}
func (d Directory) SymLink() mo.Option[string] {
return getSymlink(d.String())
}
func getSymlink(path string) mo.Option[string] {
info, err := os.Lstat(path)
if err != nil {
return mo.None[string]()
}
if info.Mode()&os.ModeSymlink == os.ModeSymlink {
realPath, err := os.Readlink(path)
if err != nil {
return mo.None[string]()
}
info, err := os.Lstat(realPath)
if err != nil {
return mo.None[string]()
}
if info.IsDir() {
return mo.Some(realPath)
} else {
return mo.None[string]()
}
} else {
return mo.None[string]()
}
}