-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathnodeWrapper.go
132 lines (107 loc) · 2.9 KB
/
nodeWrapper.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
125
126
127
128
129
130
131
132
package tensile
import (
"errors"
)
type Node interface {
Shape() Shape
Identifier() string
}
var _ Node = (*NodeWrapper)(nil)
// NodeWrapper wraps around nodes to provide some common functionality.
type NodeWrapper struct {
Node Node
Before, After []string
}
func NodeWrap(node Node) NodeWrapper {
// Ensure a node wrapper is not wrapped
if nw, ok := node.(*NodeWrapper); ok {
return *nw
}
return NodeWrapper{
Node: node,
}
}
func (nw NodeWrapper) Shape() Shape {
return nw.Node.Shape()
}
func (nw NodeWrapper) Identifier() string {
return nw.Node.Identifier()
}
func (nw NodeWrapper) Identity() (Shape, string) {
return nw.Node.Shape(), nw.Node.Identifier()
}
func (nw NodeWrapper) String() string {
return FormatIdentity(nw.Node.Shape(), nw.Node.Identifier())
}
// Validator validates an element when adding it to a queue.
// The error will be returned by the queue if validation fails.
//
// This can be used to e.g. validate that all required options are set
// or to set internal values.
type Validator interface {
Validate() error
}
var ErrNodeIsNil = errors.New("tensile: node in wrapper is nil")
func (nw NodeWrapper) Validate() error {
if nw.Node == nil {
return ErrNodeIsNil
}
if validator, ok := nw.Node.(Validator); ok {
return validator.Validate()
}
return nil
}
// IsCollisioner is used to detect wether two nodes with the same
// identity cause a collision.
type IsCollisioner interface {
// IsCollision receives another node and should return an error if they
// are colliding.
// See the Package node for an example.
IsCollision(other Node) error
}
func (nw NodeWrapper) IsCollision(other NodeWrapper) error {
if isCollisioner, ok := nw.Node.(IsCollisioner); ok {
return isCollisioner.IsCollision(other.Node)
}
return ErrIsCollisionerNotImplemented
}
type AfterNoder interface {
// AfterNodes lists nodes after which this node must be executed if they exist.
AfterNodes() []string
}
func (nw NodeWrapper) AfterNodes() []string {
after := nw.After
if afterNoder, ok := nw.Node.(AfterNoder); ok {
after = append(after, afterNoder.AfterNodes()...)
}
return after
}
type BeforeNoder interface {
// BeforeNodes lists nodes before which this node must be executed if they exist.
BeforeNodes() []string
}
func (nw NodeWrapper) BeforeNodes() []string {
before := nw.Before
if beforeNoder, ok := nw.Node.(BeforeNoder); ok {
before = append(before, beforeNoder.BeforeNodes()...)
}
return before
}
type NeedsExecutioner interface {
NeedsExecution(Context) (bool, error)
}
func (nw NodeWrapper) NeedsExecution(ctx Context) (bool, error) {
if needsExecutioner, ok := nw.Node.(NeedsExecutioner); ok {
return needsExecutioner.NeedsExecution(ctx)
}
return true, nil
}
type Executor interface {
Execute(Context) (any, error)
}
func (nw NodeWrapper) Execute(ctx Context) (any, error) {
if executor, ok := nw.Node.(Executor); ok {
return executor.Execute(ctx)
}
return nil, nil
}