...
1 package middleware
2
3 import (
4 "context"
5 "io"
6 "strings"
7 )
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 type Stack struct {
26
27
28
29
30
31
32 Initialize *InitializeStep
33
34
35
36
37
38
39
40 Serialize *SerializeStep
41
42
43
44
45
46
47
48
49 Build *BuildStep
50
51
52
53
54
55
56
57
58
59 Finalize *FinalizeStep
60
61
62
63
64
65
66
67
68
69
70 Deserialize *DeserializeStep
71
72 id string
73 }
74
75
76 func NewStack(id string, newRequestFn func() interface{}) *Stack {
77 return &Stack{
78 id: id,
79 Initialize: NewInitializeStep(),
80 Serialize: NewSerializeStep(newRequestFn),
81 Build: NewBuildStep(),
82 Finalize: NewFinalizeStep(),
83 Deserialize: NewDeserializeStep(),
84 }
85 }
86
87
88 func (s *Stack) ID() string { return s.id }
89
90
91
92
93
94
95
96
97
98 func (s *Stack) HandleMiddleware(ctx context.Context, input interface{}, next Handler) (
99 output interface{}, metadata Metadata, err error,
100 ) {
101 h := DecorateHandler(next,
102 s.Initialize,
103 s.Serialize,
104 s.Build,
105 s.Finalize,
106 s.Deserialize,
107 )
108
109 return h.Handle(ctx, input)
110 }
111
112
113 func (s *Stack) List() []string {
114 var l []string
115 l = append(l, s.id)
116
117 l = append(l, s.Initialize.ID())
118 l = append(l, s.Initialize.List()...)
119
120 l = append(l, s.Serialize.ID())
121 l = append(l, s.Serialize.List()...)
122
123 l = append(l, s.Build.ID())
124 l = append(l, s.Build.List()...)
125
126 l = append(l, s.Finalize.ID())
127 l = append(l, s.Finalize.List()...)
128
129 l = append(l, s.Deserialize.ID())
130 l = append(l, s.Deserialize.List()...)
131
132 return l
133 }
134
135 func (s *Stack) String() string {
136 var b strings.Builder
137
138 w := &indentWriter{w: &b}
139
140 w.WriteLine(s.id)
141 w.Push()
142
143 writeStepItems(w, s.Initialize)
144 writeStepItems(w, s.Serialize)
145 writeStepItems(w, s.Build)
146 writeStepItems(w, s.Finalize)
147 writeStepItems(w, s.Deserialize)
148
149 return b.String()
150 }
151
152 type stackStepper interface {
153 ID() string
154 List() []string
155 }
156
157 func writeStepItems(w *indentWriter, s stackStepper) {
158 type lister interface {
159 List() []string
160 }
161
162 w.WriteLine(s.ID())
163 w.Push()
164
165 defer w.Pop()
166
167
168 if _, ok := s.(*Stack); ok {
169 return
170 }
171
172 for _, id := range s.List() {
173 w.WriteLine(id)
174 }
175 }
176
177 type stringWriter interface {
178 io.Writer
179 WriteString(string) (int, error)
180 WriteRune(rune) (int, error)
181 }
182
183 type indentWriter struct {
184 w stringWriter
185 depth int
186 }
187
188 const indentDepth = "\t\t\t\t\t\t\t\t\t\t"
189
190 func (w *indentWriter) Push() {
191 w.depth++
192 }
193
194 func (w *indentWriter) Pop() {
195 w.depth--
196 if w.depth < 0 {
197 w.depth = 0
198 }
199 }
200
201 func (w *indentWriter) WriteLine(v string) {
202 w.w.WriteString(indentDepth[:w.depth])
203
204 v = strings.ReplaceAll(v, "\n", "\\n")
205 v = strings.ReplaceAll(v, "\r", "\\r")
206
207 w.w.WriteString(v)
208 w.w.WriteRune('\n')
209 }
210
View as plain text