-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresponses.go
93 lines (76 loc) · 3.23 KB
/
responses.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
package openapi
import (
"iter"
"github.com/MarkRosemaker/errpath"
"github.com/MarkRosemaker/ordmap"
"github.com/go-json-experiment/json"
"github.com/go-json-experiment/json/jsontext"
)
// OperationsResponses is a container for the expected responses of an operation.
// The container maps a HTTP response code to the expected response.
//
// The documentation is not necessarily expected to cover all possible HTTP response codes because they may not be known in advance.
// However, documentation is expected to cover a successful operation response and any known errors.
//
// The `default` MAY be used as a default response object for all HTTP codes
// that are not covered individually by the `Responses Object`.
//
// The `Responses Object` MUST contain at least one response code, and if only one
// response code is provided it SHOULD be the response for a successful operation
// call.
//
// Note that according to the specification, this object MAY be extended with Specification Extensions, but we do not support that in this implementation.
type OperationResponses = Responses[StatusCode]
// ResponsesByName is a map of response names to response objects.
type ResponsesByName = Responses[string]
// Responses is a map of either response name or status code to a response object.
type Responses[K ~string] map[K]*ResponseRef
// Validate checks that each response is valid.
// It does not check the validity of the keys as they could be either status codes or response names.
func (rs Responses[K]) Validate() error {
for keyOrCode, r := range rs.ByIndex() {
if err := r.Validate(); err != nil {
return &errpath.ErrKey{Key: string(keyOrCode), Err: err}
}
}
return nil
}
// ByIndex returns a sequence of key-value pairs ordered by index.
func (rs Responses[K]) ByIndex() iter.Seq2[K, *ResponseRef] {
return ordmap.ByIndex(rs, getIndexRef[Response, *Response])
}
// Sort sorts the map by key and sets the indices accordingly.
func (rs Responses[_]) Sort() {
ordmap.Sort(rs, setIndexRef[Response, *Response])
}
// Set sets a value in the map, adding it at the end of the order.
func (rs *Responses[K]) Set(key K, v *ResponseRef) {
ordmap.Set(rs, key, v, getIndexRef[Response, *Response], setIndexRef[Response, *Response])
}
// MarshalJSONTo marshals the key-value pairs in order.
func (rs *Responses[_]) MarshalJSONTo(enc *jsontext.Encoder, opts json.Options) error {
return ordmap.MarshalJSONTo(rs, enc, opts)
}
// UnmarshalJSONFrom unmarshals the key-value pairs in order and sets the indices.
func (rs *Responses[_]) UnmarshalJSONFrom(dec *jsontext.Decoder, opts json.Options) error {
return ordmap.UnmarshalJSONFrom(rs, dec, opts, setIndexRef[Response, *Response])
}
func (l *loader) collectResponses(rs ResponsesByName, ref ref) {
for name, r := range rs.ByIndex() {
l.collectResponseRef(r, append(ref, name))
}
}
func (l *loader) resolveResponses(rs ResponsesByName) error {
return resolveResponses(l, rs)
}
func (l *loader) resolveOperationResponses(rs OperationResponses) error {
return resolveResponses(l, rs)
}
func resolveResponses[K ~string](l *loader, rs Responses[K]) error {
for name, r := range rs.ByIndex() {
if err := l.resolveResponseRef(r); err != nil {
return &errpath.ErrKey{Key: string(name), Err: err}
}
}
return nil
}