-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathresult.go
200 lines (159 loc) · 4.63 KB
/
result.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
package core
import (
"context"
"encoding/json"
"io"
"mime/multipart"
"github.com/getkin/kin-openapi/openapi3"
)
type ResultSource struct {
// Will be nil if Result was decoded
Executor Executor `json:"-"`
// Will be nil if Result was decoded
Context context.Context `json:"-"`
Parameters Parameters
Configs Configs
}
type Result interface {
// What was used to produce this result
Source() ResultSource
Encode() ([]byte, error)
Decode([]byte) error
}
type ResultWithValue interface {
Result
Schema() *Schema
// Check value against schema, reports any error
ValidateSchema() error
Value() Value
}
type ResultWithReader interface {
Result
Reader() io.Reader
}
type ResultWithMultipart interface {
Result
Multipart() *multipart.Part
}
type ResultWrapper interface {
Result
Unwrap() Result
}
func ResultAs[T Result](result Result) (T, bool) {
var zeroT T
for {
if t, ok := result.(T); ok {
return t, true
}
if u, ok := result.(ResultWrapper); ok {
result = u.Unwrap()
} else {
break
}
}
return zeroT, false
}
type SimpleResult struct {
SourceData ResultSource
ResultSchema *Schema
ResultValue Value
}
func NewSimpleResult(source ResultSource, schema *Schema, value Value) *SimpleResult {
return &SimpleResult{source, schema, value}
}
func (s SimpleResult) Source() ResultSource {
return s.SourceData
}
func (s SimpleResult) Schema() *Schema {
return s.ResultSchema
}
func (s SimpleResult) ValidateSchema() error {
return s.ResultSchema.VisitJSON(s.ResultValue, openapi3.MultiErrors())
}
func (s SimpleResult) Value() Value {
return s.ResultValue
}
func (s SimpleResult) Encode() ([]byte, error) {
return json.Marshal(s)
}
func (s *SimpleResult) Decode(data []byte) error {
return json.Unmarshal(data, &s)
}
var _ ResultWithValue = (*SimpleResult)(nil)
type resultWithOriginalSource struct {
Result
originalSource ResultSource
}
func (o resultWithOriginalSource) Source() ResultSource {
return o.originalSource
}
func (o resultWithOriginalSource) Unwrap() Result {
return o.Result
}
var _ ResultWrapper = (*resultWithOriginalSource)(nil)
// Wraps (embeds) a result and overrides the original source.
func NewResultWithOriginalSource(originalSource ResultSource, result Result) *resultWithOriginalSource {
return &resultWithOriginalSource{result, originalSource}
}
func NewResultWithOriginalExecutor(originalExecutor Executor, result Result) Result {
originalSource := result.Source()
if originalSource.Executor == originalExecutor {
return result
}
originalSource.Executor = originalExecutor
return NewResultWithOriginalSource(originalSource, result)
}
// Implement this interface in Result that want to provide customized formatting of output.
// It's used by the command line interface (CLI) and possible other tools.
// This is only called if no other explicit formatting is desired
type ResultWithDefaultFormatter interface {
ResultWithValue
DefaultFormatter() string
}
type resultWithDefaultFormatter struct {
ResultWithValue
formatter string
}
func (o resultWithDefaultFormatter) DefaultFormatter() string {
return o.formatter
}
func (o resultWithDefaultFormatter) Unwrap() Result {
return o.ResultWithValue
}
var _ ResultWithDefaultFormatter = (*resultWithDefaultFormatter)(nil)
var _ ResultWrapper = (*resultWithDefaultFormatter)(nil)
// Wraps (embeds) a result and add specific result formatting.
func NewResultWithDefaultFormatter(
result ResultWithValue,
formatter string,
) ResultWithDefaultFormatter {
return &resultWithDefaultFormatter{result, formatter}
}
// Implement this interface in Results that want to provide default output options.
// It's used by the command line interface (CLI) and possible other tools.
// This is only called if no other explicit options are desired
type ResultWithDefaultOutputOptions interface {
ResultWithValue
// The return should be in the same format as CLI -o "VALUE"
// example: "yaml" or "table=COL:$.path.to[*].element,OTHERCOL:$.path.to[*].other"
DefaultOutputOptions() string
}
type resultWithDefaultOutputOptions struct {
ResultWithValue
outputOptions string
}
func (o resultWithDefaultOutputOptions) DefaultOutputOptions() string {
return o.outputOptions
}
func (o resultWithDefaultOutputOptions) Unwrap() Result {
return o.ResultWithValue
}
var _ ResultWithDefaultOutputOptions = (*resultWithDefaultOutputOptions)(nil)
var _ ResultWrapper = (*resultWithDefaultFormatter)(nil)
// Wraps (embeds) a result and add specific result default output options getter.
func NewResultWithDefaultOutputOptions(
result ResultWithValue,
outputOptions string,
) ResultWithDefaultOutputOptions {
return &resultWithDefaultOutputOptions{result, outputOptions}
}