1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package spec
16
17 import (
18 "bytes"
19 "encoding/gob"
20 "encoding/json"
21 "fmt"
22 "strconv"
23
24 "github.com/go-openapi/jsonpointer"
25 "github.com/go-openapi/swag"
26 )
27
28
29
30
31
32
33 type Swagger struct {
34 VendorExtensible
35 SwaggerProps
36 }
37
38
39 func (s Swagger) JSONLookup(token string) (interface{}, error) {
40 if ex, ok := s.Extensions[token]; ok {
41 return &ex, nil
42 }
43 r, _, err := jsonpointer.GetForToken(s.SwaggerProps, token)
44 return r, err
45 }
46
47
48 func (s Swagger) MarshalJSON() ([]byte, error) {
49 b1, err := json.Marshal(s.SwaggerProps)
50 if err != nil {
51 return nil, err
52 }
53 b2, err := json.Marshal(s.VendorExtensible)
54 if err != nil {
55 return nil, err
56 }
57 return swag.ConcatJSON(b1, b2), nil
58 }
59
60
61 func (s *Swagger) UnmarshalJSON(data []byte) error {
62 var sw Swagger
63 if err := json.Unmarshal(data, &sw.SwaggerProps); err != nil {
64 return err
65 }
66 if err := json.Unmarshal(data, &sw.VendorExtensible); err != nil {
67 return err
68 }
69 *s = sw
70 return nil
71 }
72
73
74 func (s Swagger) GobEncode() ([]byte, error) {
75 var b bytes.Buffer
76 raw := struct {
77 Props SwaggerProps
78 Ext VendorExtensible
79 }{
80 Props: s.SwaggerProps,
81 Ext: s.VendorExtensible,
82 }
83 err := gob.NewEncoder(&b).Encode(raw)
84 return b.Bytes(), err
85 }
86
87
88 func (s *Swagger) GobDecode(b []byte) error {
89 var raw struct {
90 Props SwaggerProps
91 Ext VendorExtensible
92 }
93 buf := bytes.NewBuffer(b)
94 err := gob.NewDecoder(buf).Decode(&raw)
95 if err != nil {
96 return err
97 }
98 s.SwaggerProps = raw.Props
99 s.VendorExtensible = raw.Ext
100 return nil
101 }
102
103
104
105
106
107
108
109 type SwaggerProps struct {
110 ID string `json:"id,omitempty"`
111 Consumes []string `json:"consumes,omitempty"`
112 Produces []string `json:"produces,omitempty"`
113 Schemes []string `json:"schemes,omitempty"`
114 Swagger string `json:"swagger,omitempty"`
115 Info *Info `json:"info,omitempty"`
116 Host string `json:"host,omitempty"`
117 BasePath string `json:"basePath,omitempty"`
118 Paths *Paths `json:"paths"`
119 Definitions Definitions `json:"definitions,omitempty"`
120 Parameters map[string]Parameter `json:"parameters,omitempty"`
121 Responses map[string]Response `json:"responses,omitempty"`
122 SecurityDefinitions SecurityDefinitions `json:"securityDefinitions,omitempty"`
123 Security []map[string][]string `json:"security,omitempty"`
124 Tags []Tag `json:"tags,omitempty"`
125 ExternalDocs *ExternalDocumentation `json:"externalDocs,omitempty"`
126 }
127
128 type swaggerPropsAlias SwaggerProps
129
130 type gobSwaggerPropsAlias struct {
131 Security []map[string]struct {
132 List []string
133 Pad bool
134 }
135 Alias *swaggerPropsAlias
136 SecurityIsEmpty bool
137 }
138
139
140 func (o SwaggerProps) GobEncode() ([]byte, error) {
141 raw := gobSwaggerPropsAlias{
142 Alias: (*swaggerPropsAlias)(&o),
143 }
144
145 var b bytes.Buffer
146 if o.Security == nil {
147
148 err := gob.NewEncoder(&b).Encode(raw)
149 return b.Bytes(), err
150 }
151
152 if len(o.Security) == 0 {
153
154 raw.SecurityIsEmpty = true
155 raw.Alias.Security = nil
156 err := gob.NewEncoder(&b).Encode(raw)
157 return b.Bytes(), err
158 }
159
160 raw.Security = make([]map[string]struct {
161 List []string
162 Pad bool
163 }, 0, len(o.Security))
164 for _, req := range o.Security {
165 v := make(map[string]struct {
166 List []string
167 Pad bool
168 }, len(req))
169 for k, val := range req {
170 v[k] = struct {
171 List []string
172 Pad bool
173 }{
174 List: val,
175 }
176 }
177 raw.Security = append(raw.Security, v)
178 }
179
180 err := gob.NewEncoder(&b).Encode(raw)
181 return b.Bytes(), err
182 }
183
184
185 func (o *SwaggerProps) GobDecode(b []byte) error {
186 var raw gobSwaggerPropsAlias
187
188 buf := bytes.NewBuffer(b)
189 err := gob.NewDecoder(buf).Decode(&raw)
190 if err != nil {
191 return err
192 }
193 if raw.Alias == nil {
194 return nil
195 }
196
197 switch {
198 case raw.SecurityIsEmpty:
199
200 raw.Alias.Security = []map[string][]string{}
201 case len(raw.Alias.Security) == 0:
202
203 raw.Alias.Security = nil
204 default:
205 raw.Alias.Security = make([]map[string][]string, 0, len(raw.Security))
206 for _, req := range raw.Security {
207 v := make(map[string][]string, len(req))
208 for k, val := range req {
209 v[k] = make([]string, 0, len(val.List))
210 v[k] = append(v[k], val.List...)
211 }
212 raw.Alias.Security = append(raw.Alias.Security, v)
213 }
214 }
215
216 *o = *(*SwaggerProps)(raw.Alias)
217 return nil
218 }
219
220
221 type Dependencies map[string]SchemaOrStringArray
222
223
224 type SchemaOrBool struct {
225 Allows bool
226 Schema *Schema
227 }
228
229
230 func (s SchemaOrBool) JSONLookup(token string) (interface{}, error) {
231 if token == "allows" {
232 return s.Allows, nil
233 }
234 r, _, err := jsonpointer.GetForToken(s.Schema, token)
235 return r, err
236 }
237
238 var jsTrue = []byte("true")
239 var jsFalse = []byte("false")
240
241
242 func (s SchemaOrBool) MarshalJSON() ([]byte, error) {
243 if s.Schema != nil {
244 return json.Marshal(s.Schema)
245 }
246
247 if s.Schema == nil && !s.Allows {
248 return jsFalse, nil
249 }
250 return jsTrue, nil
251 }
252
253
254 func (s *SchemaOrBool) UnmarshalJSON(data []byte) error {
255 var nw SchemaOrBool
256 if len(data) > 0 {
257 if data[0] == '{' {
258 var sch Schema
259 if err := json.Unmarshal(data, &sch); err != nil {
260 return err
261 }
262 nw.Schema = &sch
263 }
264 nw.Allows = !bytes.Equal(data, []byte("false"))
265 }
266 *s = nw
267 return nil
268 }
269
270
271 type SchemaOrStringArray struct {
272 Schema *Schema
273 Property []string
274 }
275
276
277 func (s SchemaOrStringArray) JSONLookup(token string) (interface{}, error) {
278 r, _, err := jsonpointer.GetForToken(s.Schema, token)
279 return r, err
280 }
281
282
283 func (s SchemaOrStringArray) MarshalJSON() ([]byte, error) {
284 if len(s.Property) > 0 {
285 return json.Marshal(s.Property)
286 }
287 if s.Schema != nil {
288 return json.Marshal(s.Schema)
289 }
290 return []byte("null"), nil
291 }
292
293
294 func (s *SchemaOrStringArray) UnmarshalJSON(data []byte) error {
295 var first byte
296 if len(data) > 1 {
297 first = data[0]
298 }
299 var nw SchemaOrStringArray
300 if first == '{' {
301 var sch Schema
302 if err := json.Unmarshal(data, &sch); err != nil {
303 return err
304 }
305 nw.Schema = &sch
306 }
307 if first == '[' {
308 if err := json.Unmarshal(data, &nw.Property); err != nil {
309 return err
310 }
311 }
312 *s = nw
313 return nil
314 }
315
316
317
318
319
320
321 type Definitions map[string]Schema
322
323
324
325
326
327
328 type SecurityDefinitions map[string]*SecurityScheme
329
330
331
332 type StringOrArray []string
333
334
335 func (s StringOrArray) Contains(value string) bool {
336 for _, str := range s {
337 if str == value {
338 return true
339 }
340 }
341 return false
342 }
343
344
345 func (s SchemaOrArray) JSONLookup(token string) (interface{}, error) {
346 if _, err := strconv.Atoi(token); err == nil {
347 r, _, err := jsonpointer.GetForToken(s.Schemas, token)
348 return r, err
349 }
350 r, _, err := jsonpointer.GetForToken(s.Schema, token)
351 return r, err
352 }
353
354
355 func (s *StringOrArray) UnmarshalJSON(data []byte) error {
356 var first byte
357 if len(data) > 1 {
358 first = data[0]
359 }
360
361 if first == '[' {
362 var parsed []string
363 if err := json.Unmarshal(data, &parsed); err != nil {
364 return err
365 }
366 *s = StringOrArray(parsed)
367 return nil
368 }
369
370 var single interface{}
371 if err := json.Unmarshal(data, &single); err != nil {
372 return err
373 }
374 if single == nil {
375 return nil
376 }
377 switch v := single.(type) {
378 case string:
379 *s = StringOrArray([]string{v})
380 return nil
381 default:
382 return fmt.Errorf("only string or array is allowed, not %T", single)
383 }
384 }
385
386
387 func (s StringOrArray) MarshalJSON() ([]byte, error) {
388 if len(s) == 1 {
389 return json.Marshal([]string(s)[0])
390 }
391 return json.Marshal([]string(s))
392 }
393
394
395
396 type SchemaOrArray struct {
397 Schema *Schema
398 Schemas []Schema
399 }
400
401
402 func (s SchemaOrArray) Len() int {
403 if s.Schema != nil {
404 return 1
405 }
406 return len(s.Schemas)
407 }
408
409
410 func (s *SchemaOrArray) ContainsType(name string) bool {
411 if s.Schema != nil {
412 return s.Schema.Type != nil && s.Schema.Type.Contains(name)
413 }
414 return false
415 }
416
417
418 func (s SchemaOrArray) MarshalJSON() ([]byte, error) {
419 if len(s.Schemas) > 0 {
420 return json.Marshal(s.Schemas)
421 }
422 return json.Marshal(s.Schema)
423 }
424
425
426 func (s *SchemaOrArray) UnmarshalJSON(data []byte) error {
427 var nw SchemaOrArray
428 var first byte
429 if len(data) > 1 {
430 first = data[0]
431 }
432 if first == '{' {
433 var sch Schema
434 if err := json.Unmarshal(data, &sch); err != nil {
435 return err
436 }
437 nw.Schema = &sch
438 }
439 if first == '[' {
440 if err := json.Unmarshal(data, &nw.Schemas); err != nil {
441 return err
442 }
443 }
444 *s = nw
445 return nil
446 }
447
448
449
View as plain text