generated from dogmatiq/template-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhandlertype.go
241 lines (203 loc) · 6.33 KB
/
handlertype.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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
package configkit
import (
"bytes"
"fmt"
"slices"
"github.com/dogmatiq/configkit/internal/validation"
"github.com/dogmatiq/enginekit/message"
)
// HandlerType is an enumeration of the types of handlers.
type HandlerType string
const (
// AggregateHandlerType is the handler type for dogma.AggregateMessageHandler.
AggregateHandlerType HandlerType = "aggregate"
// ProcessHandlerType is the handler type for dogma.ProcessMessageHandler.
ProcessHandlerType HandlerType = "process"
// IntegrationHandlerType is the handler type for dogma.IntegrationMessageHandler.
IntegrationHandlerType HandlerType = "integration"
// ProjectionHandlerType is the handler type for dogma.ProjectionMessageHandler.
ProjectionHandlerType HandlerType = "projection"
)
// HandlerTypes is a slice of the valid handler types.
var HandlerTypes = []HandlerType{
AggregateHandlerType,
ProcessHandlerType,
IntegrationHandlerType,
ProjectionHandlerType,
}
const (
aggregateHandlerTypeShortString = "AGG"
processHandlerTypeShortString = "PRC"
integrationHandlerTypeShortString = "INT"
projectionHandlerTypeShortString = "PRJ"
)
var (
aggregateHandlerTypeBinary = []byte{'A'}
processHandlerTypeBinary = []byte{'P'}
integrationHandlerTypeBinary = []byte{'I'}
projectionHandlerTypeBinary = []byte{'R'}
)
// Validate returns an error if t is not a valid handler type.
func (t HandlerType) Validate() error {
switch t {
case AggregateHandlerType,
ProcessHandlerType,
IntegrationHandlerType,
ProjectionHandlerType:
return nil
default:
return validation.Errorf("invalid handler type: %s", string(t))
}
}
// MustValidate panics if t is not a valid handler type.
func (t HandlerType) MustValidate() {
if err := t.Validate(); err != nil {
panic(err)
}
}
// Is returns true if t is one of the given types.
func (t HandlerType) Is(types ...HandlerType) bool {
t.MustValidate()
for _, x := range types {
x.MustValidate()
if t == x {
return true
}
}
return false
}
// MustBe panics if t is not one of the given types.
func (t HandlerType) MustBe(types ...HandlerType) {
if !t.Is(types...) {
panic("unexpected handler type: " + t.String())
}
}
// MustNotBe panics if t is one of the given types.
func (t HandlerType) MustNotBe(types ...HandlerType) {
if t.Is(types...) {
panic("unexpected handler type: " + t.String())
}
}
// IsConsumerOf returns true if handlers of type t can consume messages of the
// given kind.
func (t HandlerType) IsConsumerOf(k message.Kind) bool {
return slices.Contains(t.Consumes(), k)
}
// IsProducerOf returns true if handlers of type t can produce messages of the
// given kind.
func (t HandlerType) IsProducerOf(k message.Kind) bool {
return slices.Contains(t.Produces(), k)
}
// Consumes returns the kind of messages that can be consumed by handlers of
// type t.
func (t HandlerType) Consumes() []message.Kind {
t.MustValidate()
switch t {
case AggregateHandlerType:
return []message.Kind{message.CommandKind}
case ProcessHandlerType:
return []message.Kind{message.EventKind, message.TimeoutKind}
case IntegrationHandlerType:
return []message.Kind{message.CommandKind}
default: // ProjectionHandlerType
return []message.Kind{message.EventKind}
}
}
// Produces returns the kinds of messages that can be produced by handlers of
// type t.
func (t HandlerType) Produces() []message.Kind {
t.MustValidate()
switch t {
case AggregateHandlerType:
return []message.Kind{message.EventKind}
case ProcessHandlerType:
return []message.Kind{message.CommandKind, message.TimeoutKind}
case IntegrationHandlerType:
return []message.Kind{message.EventKind}
default: // ProjectionHandlerType
return nil
}
}
// ShortString returns a short (3-character) representation of the handler type.
func (t HandlerType) ShortString() string {
t.MustValidate()
switch t {
case AggregateHandlerType:
return aggregateHandlerTypeShortString
case ProcessHandlerType:
return processHandlerTypeShortString
case IntegrationHandlerType:
return integrationHandlerTypeShortString
default: // ProjectionHandlerType
return projectionHandlerTypeShortString
}
}
// String returns a string representation of the handler type.
func (t HandlerType) String() string {
if err := t.Validate(); err != nil {
return "<" + err.Error() + ">"
}
return string(t)
}
// MarshalText returns a UTF-8 representation of the handler type.
func (t HandlerType) MarshalText() ([]byte, error) {
return []byte(t), t.Validate()
}
// UnmarshalText unmarshals a type from its UTF-8 representation.
func (t *HandlerType) UnmarshalText(text []byte) error {
x := HandlerType(text)
if x.Validate() != nil {
return fmt.Errorf("invalid text representation of handler type: %s", text)
}
*t = x
return nil
}
// MarshalBinary returns a binary representation of the handler type.
func (t HandlerType) MarshalBinary() ([]byte, error) {
if err := t.Validate(); err != nil {
return nil, err
}
switch t {
case AggregateHandlerType:
return aggregateHandlerTypeBinary, nil
case ProcessHandlerType:
return processHandlerTypeBinary, nil
case IntegrationHandlerType:
return integrationHandlerTypeBinary, nil
default: // ProjectionHandlerType
return projectionHandlerTypeBinary, nil
}
}
// UnmarshalBinary unmarshals a type from its binary representation.
func (t *HandlerType) UnmarshalBinary(data []byte) error {
if bytes.Equal(data, aggregateHandlerTypeBinary) {
*t = AggregateHandlerType
} else if bytes.Equal(data, processHandlerTypeBinary) {
*t = ProcessHandlerType
} else if bytes.Equal(data, integrationHandlerTypeBinary) {
*t = IntegrationHandlerType
} else if bytes.Equal(data, projectionHandlerTypeBinary) {
*t = ProjectionHandlerType
} else {
return fmt.Errorf("invalid binary representation of handler type: %s", data)
}
return nil
}
// ConsumersOf returns the handler types that can consume messages of kind k.
func ConsumersOf(k message.Kind) []HandlerType {
return message.MapByKind(
k,
[]HandlerType{AggregateHandlerType, IntegrationHandlerType},
[]HandlerType{ProcessHandlerType, ProjectionHandlerType},
[]HandlerType{ProcessHandlerType},
)
}
// ProducersOf returns the handler types that can produces messages of kind k.
func ProducersOf(k message.Kind) []HandlerType {
return message.MapByKind(
k,
[]HandlerType{ProcessHandlerType},
[]HandlerType{AggregateHandlerType, IntegrationHandlerType},
[]HandlerType{ProcessHandlerType},
)
}