-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtraverse.go
65 lines (52 loc) · 1.17 KB
/
traverse.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
package gestalt
type Traverser interface {
Path() string
}
type Visitor interface {
Push(Traverser, Component)
Pop(Traverser, Component)
}
type traverser struct {
path *pathVisitor
visitors []Visitor
}
func TraversePaths(node Component, fn func(string)) {
Traverse(node, newSimpleVisitor(fn))
}
func Traverse(node Component, visitors ...Visitor) {
newTraverser(visitors...).Traverse(node)
}
func newTraverser(visitors ...Visitor) *traverser {
path := newPathVisitor()
return &traverser{
path: path,
visitors: append([]Visitor{path}, visitors...),
}
}
func (t *traverser) Traverse(node Component) {
for _, v := range t.visitors {
v.Push(t, node)
}
if c, ok := node.(CompositeComponent); ok {
for _, c := range c.Children() {
t.Traverse(c)
}
}
for i := len(t.visitors) - 1; i >= 0; i-- {
t.visitors[i].Pop(t, node)
}
}
func (t *traverser) Path() string {
return t.path.Current()
}
type simpleVisitor struct {
fn func(string)
}
func newSimpleVisitor(fn func(string)) *simpleVisitor {
return &simpleVisitor{fn}
}
func (v *simpleVisitor) Push(t Traverser, _ Component) {
v.fn(t.Path())
}
func (v *simpleVisitor) Pop(_ Traverser, _ Component) {
}