-
Notifications
You must be signed in to change notification settings - Fork 0
/
composed.go
139 lines (116 loc) · 2.72 KB
/
composed.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
133
134
135
136
137
138
139
package retention
type (
// UnaryPolicy is a Policy that applies some additional logic to a
// supplied Policy
UnaryPolicy interface {
Policy
Policy() Policy
}
// NotPolicy is a Policy that negates the retention logic of its
// supplied Policy
NotPolicy interface {
UnaryPolicy
}
// BinaryPolicy is a Policy where two Policies are combined in order
// to determine retention policy
BinaryPolicy interface {
Policy
Left() Policy
Right() Policy
}
// AndPolicy is a Policy from which both Policies must request that
// messages be retained in order to do so
AndPolicy interface {
BinaryPolicy
}
// OrPolicy is a Policy from which either Policy can request that
// messages be retained in order to do so
OrPolicy interface {
BinaryPolicy
}
unaryPolicy struct {
policy Policy
}
notPolicy struct {
unaryPolicy
}
binaryPolicy struct {
left Policy
right Policy
}
andPolicy struct {
binaryPolicy
}
orPolicy struct {
binaryPolicy
}
binaryPolicyState struct {
left State
right State
}
)
// Not returns a Policy that negates the logic of its supplied Policy
func Not(policy Policy) NotPolicy {
return ¬Policy{
unaryPolicy: unaryPolicy{
policy: policy,
},
}
}
func (p *notPolicy) Retain(state State, r *Statistics) (State, bool) {
state, ok := p.policy.Retain(state, r)
return state, !ok
}
func (p *unaryPolicy) InitialState() State {
return p.policy.InitialState()
}
func (p *unaryPolicy) Policy() Policy {
return p.policy
}
// And returns a Policy from which both Policies must request that messages be
// retained in order to do so
func And(left Policy, right Policy) AndPolicy {
return &andPolicy{
binaryPolicy: binaryPolicy{
left: left,
right: right,
},
}
}
func (p *andPolicy) Retain(s State, r *Statistics) (State, bool) {
state, lok, rok := p.retain(s, r)
return state, lok && rok
}
// Or returns a Policy from which either Policy can request that messages be
// retained in order to do so
func Or(left Policy, right Policy) OrPolicy {
return &orPolicy{
binaryPolicy: binaryPolicy{
left: left,
right: right,
},
}
}
func (p *orPolicy) Retain(s State, r *Statistics) (State, bool) {
state, lok, rok := p.retain(s, r)
return state, lok || rok
}
func (p *binaryPolicy) InitialState() State {
return &binaryPolicyState{
left: p.left.InitialState(),
right: p.right.InitialState(),
}
}
func (p *binaryPolicy) Left() Policy {
return p.left
}
func (p *binaryPolicy) Right() Policy {
return p.right
}
func (p *binaryPolicy) retain(s State, r *Statistics) (State, bool, bool) {
var lok, rok bool
state := s.(*binaryPolicyState)
state.left, lok = p.left.Retain(state.left, r)
state.right, rok = p.right.Retain(state.right, r)
return state, lok, rok
}