src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

step_deserialize.go (7050B)


      1 package middleware
      2 
      3 import (
      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.
     10 type 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.
     18 type 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.
     25 type 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.
     34 type 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.
     49 func 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 
     56 type 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.
     67 func (s deserializeMiddlewareFunc) ID() string { return s.id }
     68 
     69 // HandleDeserialize invokes the middleware Fn.
     70 func (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 
     76 var _ DeserializeMiddleware = (deserializeMiddlewareFunc{})
     77 
     78 // DeserializeStep provides the ordered grouping of DeserializeMiddleware to be
     79 // invoked on a handler.
     80 type DeserializeStep struct {
     81 	ids *orderedIDs
     82 }
     83 
     84 // NewDeserializeStep returns a DeserializeStep ready to have middleware for
     85 // initialization added to it.
     86 func NewDeserializeStep() *DeserializeStep {
     87 	return &DeserializeStep{
     88 		// downstream SDK typically has larger Deserialize step
     89 		ids: newOrderedIDs(baseOrderedItems * 2),
     90 	}
     91 }
     92 
     93 var _ Middleware = (*DeserializeStep)(nil)
     94 
     95 // ID returns the unique ID of the step as a middleware.
     96 func (s *DeserializeStep) ID() string {
     97 	return "Deserialize stack step"
     98 }
     99 
    100 // HandleMiddleware invokes the middleware by decorating the next handler
    101 // provided. Returns the result of the middleware and handler being invoked.
    102 //
    103 // Implements Middleware interface.
    104 func (s *DeserializeStep) HandleMiddleware(ctx context.Context, in interface{}, next Handler) (
    105 	out interface{}, metadata Metadata, err error,
    106 ) {
    107 	order := s.ids.GetOrder()
    108 
    109 	var h DeserializeHandler = deserializeWrapHandler{Next: next}
    110 	for i := len(order) - 1; i >= 0; i-- {
    111 		h = decoratedDeserializeHandler{
    112 			Next: h,
    113 			With: order[i].(DeserializeMiddleware),
    114 		}
    115 	}
    116 
    117 	sIn := DeserializeInput{
    118 		Request: in,
    119 	}
    120 
    121 	res, metadata, err := h.HandleDeserialize(ctx, sIn)
    122 	return res.Result, metadata, err
    123 }
    124 
    125 // Get retrieves the middleware identified by id. If the middleware is not present, returns false.
    126 func (s *DeserializeStep) Get(id string) (DeserializeMiddleware, bool) {
    127 	get, ok := s.ids.Get(id)
    128 	if !ok {
    129 		return nil, false
    130 	}
    131 	return get.(DeserializeMiddleware), ok
    132 }
    133 
    134 // Add injects the middleware to the relative position of the middleware group.
    135 // Returns an error if the middleware already exists.
    136 func (s *DeserializeStep) Add(m DeserializeMiddleware, pos RelativePosition) error {
    137 	return s.ids.Add(m, pos)
    138 }
    139 
    140 // Insert injects the middleware relative to an existing middleware ID.
    141 // Returns error if the original middleware does not exist, or the middleware
    142 // being added already exists.
    143 func (s *DeserializeStep) Insert(m DeserializeMiddleware, relativeTo string, pos RelativePosition) error {
    144 	return s.ids.Insert(m, relativeTo, pos)
    145 }
    146 
    147 // Swap removes the middleware by id, replacing it with the new middleware.
    148 // Returns the middleware removed, or error if the middleware to be removed
    149 // doesn't exist.
    150 func (s *DeserializeStep) Swap(id string, m DeserializeMiddleware) (DeserializeMiddleware, error) {
    151 	removed, err := s.ids.Swap(id, m)
    152 	if err != nil {
    153 		return nil, err
    154 	}
    155 
    156 	return removed.(DeserializeMiddleware), nil
    157 }
    158 
    159 // Remove removes the middleware by id. Returns error if the middleware
    160 // doesn't exist.
    161 func (s *DeserializeStep) Remove(id string) (DeserializeMiddleware, error) {
    162 	removed, err := s.ids.Remove(id)
    163 	if err != nil {
    164 		return nil, err
    165 	}
    166 
    167 	return removed.(DeserializeMiddleware), nil
    168 }
    169 
    170 // List returns a list of the middleware in the step.
    171 func (s *DeserializeStep) List() []string {
    172 	return s.ids.List()
    173 }
    174 
    175 // Clear removes all middleware in the step.
    176 func (s *DeserializeStep) Clear() {
    177 	s.ids.Clear()
    178 }
    179 
    180 type deserializeWrapHandler struct {
    181 	Next Handler
    182 }
    183 
    184 var _ DeserializeHandler = (*deserializeWrapHandler)(nil)
    185 
    186 // HandleDeserialize implements DeserializeHandler, converts types and delegates to underlying
    187 // generic handler.
    188 func (w deserializeWrapHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) (
    189 	out DeserializeOutput, metadata Metadata, err error,
    190 ) {
    191 	resp, metadata, err := w.Next.Handle(ctx, in.Request)
    192 	return DeserializeOutput{
    193 		RawResponse: resp,
    194 	}, metadata, err
    195 }
    196 
    197 type decoratedDeserializeHandler struct {
    198 	Next DeserializeHandler
    199 	With DeserializeMiddleware
    200 }
    201 
    202 var _ DeserializeHandler = (*decoratedDeserializeHandler)(nil)
    203 
    204 func (h decoratedDeserializeHandler) HandleDeserialize(ctx context.Context, in DeserializeInput) (
    205 	out DeserializeOutput, metadata Metadata, err error,
    206 ) {
    207 	return h.With.HandleDeserialize(ctx, in, h.Next)
    208 }
    209 
    210 // DeserializeHandlerFunc provides a wrapper around a function to be used as a deserialize middleware handler.
    211 type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error)
    212 
    213 // HandleDeserialize invokes the wrapped function with the given arguments.
    214 func (d DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) {
    215 	return d(ctx, in)
    216 }
    217 
    218 var _ DeserializeHandler = DeserializeHandlerFunc(nil)