code.dwrz.net

Go monorepo.
Log | Files | Refs

step_finalize.go (6478B)


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