step_deserialize.go

  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)