generated from dogmatiq/template-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprojection.go
137 lines (110 loc) · 3.65 KB
/
projection.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
package configkit
import (
"context"
"reflect"
"github.com/dogmatiq/configkit/internal/typename/goreflect"
"github.com/dogmatiq/configkit/internal/validation"
"github.com/dogmatiq/dogma"
"github.com/dogmatiq/enginekit/message"
)
// Projection is an interface that represents the configuration of a Dogma
// projection message handler.
type Projection interface {
Handler
}
// RichProjection is a specialization of Projection that exposes information
// about the Go types used to implement the underlying Dogma handler.
type RichProjection interface {
RichHandler
// Handler returns the underlying message handler.
Handler() dogma.ProjectionMessageHandler
// DeliveryPolicy returns the projection's delivery policy.
DeliveryPolicy() dogma.ProjectionDeliveryPolicy
}
// FromProjection returns the configuration for a projection message handler.
//
// It panics if the handler is configured incorrectly. Use Recover() to convert
// configuration related panic values to errors.
func FromProjection(h dogma.ProjectionMessageHandler) RichProjection {
cfg := fromProjectionUnvalidated(h)
cfg.mustValidate()
return cfg
}
func fromProjectionUnvalidated(h dogma.ProjectionMessageHandler) *richProjection {
cfg := &richProjection{handler: h}
h.Configure(&projectionConfigurer{cfg})
return cfg
}
// richProjection is an implementation of RichProjection.
type richProjection struct {
ident Identity
types EntityMessages[message.Type]
deliveryPolicy dogma.ProjectionDeliveryPolicy
isDisabled bool
handler dogma.ProjectionMessageHandler
}
func (h *richProjection) Identity() Identity {
return h.ident
}
func (h *richProjection) MessageNames() EntityMessages[message.Name] {
return asMessageNames(h.types)
}
func (h *richProjection) MessageTypes() EntityMessages[message.Type] {
return h.types
}
func (h *richProjection) TypeName() string {
return goreflect.NameOf(h.ReflectType())
}
func (h *richProjection) ReflectType() reflect.Type {
return reflect.TypeOf(h.handler)
}
func (h *richProjection) IsDisabled() bool {
return h.isDisabled
}
func (h *richProjection) AcceptVisitor(ctx context.Context, v Visitor) error {
return v.VisitProjection(ctx, h)
}
func (h *richProjection) AcceptRichVisitor(ctx context.Context, v RichVisitor) error {
return v.VisitRichProjection(ctx, h)
}
func (h *richProjection) HandlerType() HandlerType {
return ProjectionHandlerType
}
func (h *richProjection) Handler() dogma.ProjectionMessageHandler {
return h.handler
}
func (h *richProjection) DeliveryPolicy() dogma.ProjectionDeliveryPolicy {
if h.deliveryPolicy == nil {
return dogma.UnicastProjectionDeliveryPolicy{}
}
return h.deliveryPolicy
}
func (h *richProjection) isConfigured() bool {
return !h.ident.IsZero() ||
len(h.types) != 0 ||
h.deliveryPolicy != nil
}
func (h *richProjection) mustValidate() {
mustHaveValidIdentity(h.Identity(), h.ReflectType())
mustHaveConsumerRoute(&h.types, message.EventKind, h.Identity(), h.ReflectType())
}
// projectionConfigurer is the default implementation of
// [dogma.ProjectionConfigurer].
type projectionConfigurer struct {
config *richProjection
}
func (c *projectionConfigurer) Identity(name, key string) {
configureIdentity(&c.config.ident, name, key, c.config.ReflectType())
}
func (c *projectionConfigurer) Routes(routes ...dogma.ProjectionRoute) {
configureRoutes(&c.config.types, routes, c.config.ident, c.config.ReflectType())
}
func (c *projectionConfigurer) Disable(...dogma.DisableOption) {
c.config.isDisabled = true
}
func (c *projectionConfigurer) DeliveryPolicy(p dogma.ProjectionDeliveryPolicy) {
if p == nil {
validation.Panicf("delivery policy must not be nil")
}
c.config.deliveryPolicy = p
}