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)