code.dwrz.net

Go monorepo.
Log | Files | Refs

step_deserialize.go (6972B)


      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 		ids: newOrderedIDs(),
     89 	}
     90 }
     91 
     92 var _ Middleware = (*DeserializeStep)(nil)
     93 
     94 // ID returns the unique ID of the step as a middleware.
     95 func (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.
    103 func (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.
    125 func (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.
    135 func (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.
    142 func (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.
    149 func (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.
    160 func (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.
    170 func (s *DeserializeStep) List() []string {
    171 	return s.ids.List()
    172 }
    173 
    174 // Clear removes all middleware in the step.
    175 func (s *DeserializeStep) Clear() {
    176 	s.ids.Clear()
    177 }
    178 
    179 type deserializeWrapHandler struct {
    180 	Next Handler
    181 }
    182 
    183 var _ DeserializeHandler = (*deserializeWrapHandler)(nil)
    184 
    185 // HandleDeserialize implements DeserializeHandler, converts types and delegates to underlying
    186 // generic handler.
    187 func (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 
    196 type decoratedDeserializeHandler struct {
    197 	Next DeserializeHandler
    198 	With DeserializeMiddleware
    199 }
    200 
    201 var _ DeserializeHandler = (*decoratedDeserializeHandler)(nil)
    202 
    203 func (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.
    210 type DeserializeHandlerFunc func(context.Context, DeserializeInput) (DeserializeOutput, Metadata, error)
    211 
    212 // HandleDeserialize invokes the wrapped function with the given arguments.
    213 func (d DeserializeHandlerFunc) HandleDeserialize(ctx context.Context, in DeserializeInput) (DeserializeOutput, Metadata, error) {
    214 	return d(ctx, in)
    215 }
    216 
    217 var _ DeserializeHandler = DeserializeHandlerFunc(nil)