1package middleware
2
3import (
4 "context"
5)
6
7// DeserializeInput provides the input parameters for the DeserializeInput to
8// consume. DeserializeMiddleware should not modify the Request, and instead
9// forward it along to the next DeserializeHandler.
10type DeserializeInput struct {
11 Request interface{}
12}
13
14// DeserializeOutput provides the result returned by the next
15// DeserializeHandler. The DeserializeMiddleware should deserialize the
16// RawResponse into a Result that can be consumed by middleware higher up in
17// the stack.
18type DeserializeOutput struct {
19 RawResponse interface{}
20 Result interface{}
21}
22
23// DeserializeHandler provides the interface for the next handler the
24// DeserializeMiddleware will call in the middleware chain.
25type DeserializeHandler interface {
26 HandleDeserialize(ctx context.Context, in DeserializeInput) (
27 out DeserializeOutput, metadata Metadata, err error,
28 )
29}
30
31// DeserializeMiddleware provides the interface for middleware specific to the
32// serialize step. Delegates to the next DeserializeHandler for further
33// processing.
34type DeserializeMiddleware interface {
35 // ID returns a unique ID for the middleware in the DeserializeStep. The step does not
36 // allow duplicate IDs.
37 ID() string
38
39 // HandleDeserialize invokes the middleware behavior which must delegate to the next handler
40 // for the middleware chain to continue. The method must return a result or
41 // error to its caller.
42 HandleDeserialize(ctx context.Context, in DeserializeInput, next DeserializeHandler) (
43 out DeserializeOutput, metadata Metadata, err error,
44 )
45}
46
47// DeserializeMiddlewareFunc returns a DeserializeMiddleware with the unique ID
48// provided, and the func to be invoked.
49func DeserializeMiddlewareFunc(id string, fn func(context.Context, DeserializeInput, DeserializeHandler) (DeserializeOutput, Metadata, error)) DeserializeMiddleware {
50 return deserializeMiddlewareFunc{
51 id: id,
52 fn: fn,
53 }
54}
55
56type deserializeMiddlewareFunc struct {
57 // Unique ID for the middleware.
58 id string
59
60 // Middleware function to be called.
61 fn func(context.Context, DeserializeInput, DeserializeHandler) (
62 DeserializeOutput, Metadata, error,
63 )
64}
65
66// ID returns the unique ID for the middleware.
67func (s deserializeMiddlewareFunc) ID() string { return s.id }
68
69// HandleDeserialize invokes the middleware Fn.
70func (s deserializeMiddlewareFunc) HandleDeserialize(ctx context.Context, in DeserializeInput, next DeserializeHandler) (
71 out DeserializeOutput, metadata Metadata, err error,
72) {
73 return s.fn(ctx, in, next)
74}
75
76var _ DeserializeMiddleware = (deserializeMiddlewareFunc{})
77
78// DeserializeStep provides the ordered grouping of DeserializeMiddleware to be
79// invoked on a handler.
80type DeserializeStep struct {
81 ids *orderedIDs
82}
83
84// NewDeserializeStep returns a DeserializeStep ready to have middleware for
85// initialization added to it.
86func NewDeserializeStep() *DeserializeStep {
87 return &DeserializeStep{
88 ids: newOrderedIDs(),
89 }
90}
91
92var _ Middleware = (*DeserializeStep)(nil)
93
94// ID returns the unique ID of the step as a middleware.
95func (s *DeserializeStep) ID() string {
96 return "Deserialize stack step"
97}
98
99// HandleMiddleware invokes the middleware by decorating the next handler
100// provided. Returns the result of the middleware and handler being invoked.
101//
102// Implements Middleware interface.
103func (s *DeserializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
104 out interface{}, metadata Metadata, err error,
105) {
106 order := s.ids.GetOrder()
107
108 var h DeserializeHandler = deserializeWrapHandler{Next: next}
109 for i := len(order) - 1; i >= 0; i-- {
110 h = decoratedDeserializeHandler{
111 Next: h,
112 With: order[i].(DeserializeMiddleware),
113 }
114 }
115
116 sIn := DeserializeInput{
117 Request: in,
118 }
119
120 res, metadata, err := h.HandleDeserialize(ctx, sIn)
121 return res.Result, metadata, err
122}
123
124// Get retrieves the middleware identified by id. If the middleware is not present, returns false.
125func (s *DeserializeStep) Get(id string) (DeserializeMiddleware, bool) {
126 get, ok := s.ids.Get(id)
127 if !ok {
128 return nil, false
129 }
130 return get.(DeserializeMiddleware), ok
131}
132
133// Add injects the middleware to the relative position of the middleware group.
134// Returns an error if the middleware already exists.
135func (s *DeserializeStep) Add(m DeserializeMiddleware, pos RelativePosition) error {
136 return s.ids.Add(m, pos)
137}
138
139// Insert injects the middleware relative to an existing middleware ID.
140// Returns error if the original middleware does not exist, or the middleware
141// being added already exists.
142func (s *DeserializeStep) Insert(m DeserializeMiddleware, relativeTo string, pos RelativePosition) error {
143 return s.ids.Insert(m, relativeTo, pos)
144}
145
146// Swap removes the middleware by id, replacing it with the new middleware.
147// Returns the middleware removed, or error if the middleware to be removed
148// doesn't exist.
149func (s *DeserializeStep) Swap(id string, m DeserializeMiddleware) (DeserializeMiddleware, error) {
150 removed, err := s.ids.Swap(id, m)
151 if err != nil {
152 return nil, err
153 }
154
155 return removed.(DeserializeMiddleware), nil
156}
157
158// Remove removes the middleware by id. Returns error if the middleware
159// doesn't exist.
160func (s *DeserializeStep) Remove(id string) (DeserializeMiddleware, error) {
161 removed, err := s.ids.Remove(id)
162 if err != nil {
163 return nil, err
164 }
165
166 return removed.(DeserializeMiddleware), nil
167}
168
169// List returns a list of the middleware in the step.
170func (s *DeserializeStep) List() []string {
171 return s.ids.List()
172}
173
174// Clear removes all middleware in the step.
175func (s *DeserializeStep) Clear() {
176 s.ids.Clear()
177}
178
179type deserializeWrapHandler struct {
180 Next Handler
181}
182
183var _ DeserializeHandler = (*deserializeWrapHandler)(nil)
184
185// HandleDeserialize implements DeserializeHandler, converts types and delegates to underlying
186// generic handler.
187func (w deserializeWrapHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) (
188 out DeserializeOutput, metadata Metadata, err error,
189) {
190 resp, metadata, err := w.Next.Handle(ctx, in.Request)
191 return DeserializeOutput{
192 RawResponse: resp,
193 }, metadata, err
194}
195
196type decoratedDeserializeHandler struct {
197 Next DeserializeHandler
198 With DeserializeMiddleware
199}
200
201var _ DeserializeHandler = (*decoratedDeserializeHandler)(nil)
202
203func (h decoratedDeserializeHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) (
204 out DeserializeOutput, metadata Metadata, err error,
205) {
206 return h.With.HandleDeserialize(ctx, in, h.Next)
207}
208
209// DeserializeHandlerFunc provides a wrapper around a function to be used as a deserialize middleware handler.
210type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error)
211
212// HandleDeserialize invokes the wrapped function with the given arguments.
213func (d DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) {
214 return d(ctx, in)
215}
216
217var _ DeserializeHandler = DeserializeHandlerFunc(nil)