-
Notifications
You must be signed in to change notification settings - Fork 8
/
simple_tree_grower.go
124 lines (98 loc) · 2.82 KB
/
simple_tree_grower.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
120
121
122
123
124
//go:build !tinywasm
package gtree
func newGrowerSimple(
lastNodeFormat, intermedialNodeFormat branchFormat,
enabledValidation bool,
) growerSimple {
return &defaultGrowerSimple{
lastNodeFormat: lastNodeFormat,
intermedialNodeFormat: intermedialNodeFormat,
enabledValidation: enabledValidation,
}
}
type defaultGrowerSimple struct {
lastNodeFormat branchFormat
intermedialNodeFormat branchFormat
enabledValidation bool
}
type branchFormat struct {
directly, indirectly string
}
func (dg *defaultGrowerSimple) grow(roots []*Node) error {
for _, root := range roots {
if err := dg.assemble(root); err != nil {
return err
}
}
return nil
}
func (dg *defaultGrowerSimple) assemble(current *Node) error {
if err := dg.assembleBranch(current); err != nil {
return err
}
for _, child := range current.children {
if err := dg.assemble(child); err != nil {
return err
}
}
return nil
}
func (dg *defaultGrowerSimple) assembleBranch(current *Node) error {
current.clean() // 例えば、MkdirProgrammably funcでrootノードを使いまわすと、前回func実行時に形成されたノードの枝が残ったまま追記されてしまうため。
dg.assembleBranchDirectly(current)
// go back to the root to form a branch.
tmpParent := current.parent
if tmpParent != nil {
for ; !tmpParent.isRoot(); tmpParent = tmpParent.parent {
dg.assembleBranchIndirectly(current, tmpParent)
}
}
dg.assembleBranchFinally(current, tmpParent)
if dg.enabledValidation {
return current.validatePath()
}
return nil
}
func (dg *defaultGrowerSimple) assembleBranchDirectly(current *Node) {
if current == nil || current.isRoot() {
return
}
current.setPath(current.name)
if current.isLastOfHierarchy() {
current.setBranch(current.branch(), dg.lastNodeFormat.directly)
} else {
current.setBranch(current.branch(), dg.intermedialNodeFormat.directly)
}
}
func (dg *defaultGrowerSimple) assembleBranchIndirectly(current, parent *Node) {
if current == nil || parent == nil || current.isRoot() {
return
}
current.setPath(parent.name, current.path())
if parent.isLastOfHierarchy() {
current.setBranch(dg.lastNodeFormat.indirectly, current.branch())
} else {
current.setBranch(dg.intermedialNodeFormat.indirectly, current.branch())
}
}
func (*defaultGrowerSimple) assembleBranchFinally(current, root *Node) {
if current == nil {
return
}
if root != nil {
current.setPath(root.path(), current.path())
}
}
func (dg *defaultGrowerSimple) enableValidation() {
dg.enabledValidation = true
}
func newNopGrowerSimple() growerSimple {
return &nopGrowerSimple{}
}
type nopGrowerSimple struct{}
func (*nopGrowerSimple) grow(_ []*Node) error { return nil }
func (*nopGrowerSimple) enableValidation() {}
var (
_ growerSimple = (*defaultGrowerSimple)(nil)
_ growerSimple = (*nopGrowerSimple)(nil)
)