@@ -235,175 +235,180 @@ func (g *Generator) generateWithoutSaving(parents []*theTypeInfo, t reflect.Type
235
235
schema := & openapi3.Schema {}
236
236
schema .Nullable = isNullable
237
237
238
- switch t .Kind () {
239
- case reflect .Func , reflect .Chan :
240
- return nil , nil // ignore
241
-
242
- case reflect .Bool :
243
- schema .Type = & openapi3.Types {"boolean" }
244
-
245
- case reflect .Int :
246
- schema .Type = & openapi3.Types {"integer" }
247
- case reflect .Int8 :
248
- schema .Type = & openapi3.Types {"integer" }
249
- schema .Min = & minInt8
250
- schema .Max = & maxInt8
251
- case reflect .Int16 :
252
- schema .Type = & openapi3.Types {"integer" }
253
- schema .Min = & minInt16
254
- schema .Max = & maxInt16
255
- case reflect .Int32 :
256
- schema .Type = & openapi3.Types {"integer" }
257
- schema .Format = "int32"
258
- case reflect .Int64 :
259
- schema .Type = & openapi3.Types {"integer" }
260
- schema .Format = "int64"
261
- case reflect .Uint :
262
- schema .Type = & openapi3.Types {"integer" }
263
- schema .Min = & zeroInt
264
- case reflect .Uint8 :
265
- schema .Type = & openapi3.Types {"integer" }
266
- schema .Min = & zeroInt
267
- schema .Max = & maxUint8
268
- case reflect .Uint16 :
269
- schema .Type = & openapi3.Types {"integer" }
270
- schema .Min = & zeroInt
271
- schema .Max = & maxUint16
272
- case reflect .Uint32 :
273
- schema .Type = & openapi3.Types {"integer" }
274
- schema .Min = & zeroInt
275
- schema .Max = & maxUint32
276
- case reflect .Uint64 :
277
- schema .Type = & openapi3.Types {"integer" }
278
- schema .Min = & zeroInt
279
- schema .Max = & maxUint64
280
-
281
- case reflect .Float32 :
282
- schema .Type = & openapi3.Types {"number" }
283
- schema .Format = "float"
284
- case reflect .Float64 :
285
- schema .Type = & openapi3.Types {"number" }
286
- schema .Format = "double"
287
-
288
- case reflect .String :
289
- schema .Type = & openapi3.Types {"string" }
238
+ // Object has their own schema's implementation, so we'll use those
239
+ var setSchemar SetSchemar
240
+ if v := reflect .New (t ); v .CanInterface () {
241
+ if v , ok := v .Interface ().(SetSchemar ); ok {
242
+ setSchemar = v
243
+ }
244
+ }
290
245
291
- case reflect .Slice :
292
- if t .Elem ().Kind () == reflect .Uint8 {
293
- if t != rawMessageType {
294
- schema .Type = & openapi3.Types {"string" }
295
- schema .Format = "byte"
246
+ if setSchemar != nil {
247
+ setSchemar .SetSchema (schema )
248
+ } else {
249
+
250
+ switch t .Kind () {
251
+ case reflect .Func , reflect .Chan :
252
+ return nil , nil // ignore
253
+
254
+ case reflect .Bool :
255
+ schema .Type = & openapi3.Types {"boolean" }
256
+
257
+ case reflect .Int :
258
+ schema .Type = & openapi3.Types {"integer" }
259
+ case reflect .Int8 :
260
+ schema .Type = & openapi3.Types {"integer" }
261
+ schema .Min = & minInt8
262
+ schema .Max = & maxInt8
263
+ case reflect .Int16 :
264
+ schema .Type = & openapi3.Types {"integer" }
265
+ schema .Min = & minInt16
266
+ schema .Max = & maxInt16
267
+ case reflect .Int32 :
268
+ schema .Type = & openapi3.Types {"integer" }
269
+ schema .Format = "int32"
270
+ case reflect .Int64 :
271
+ schema .Type = & openapi3.Types {"integer" }
272
+ schema .Format = "int64"
273
+ case reflect .Uint :
274
+ schema .Type = & openapi3.Types {"integer" }
275
+ schema .Min = & zeroInt
276
+ case reflect .Uint8 :
277
+ schema .Type = & openapi3.Types {"integer" }
278
+ schema .Min = & zeroInt
279
+ schema .Max = & maxUint8
280
+ case reflect .Uint16 :
281
+ schema .Type = & openapi3.Types {"integer" }
282
+ schema .Min = & zeroInt
283
+ schema .Max = & maxUint16
284
+ case reflect .Uint32 :
285
+ schema .Type = & openapi3.Types {"integer" }
286
+ schema .Min = & zeroInt
287
+ schema .Max = & maxUint32
288
+ case reflect .Uint64 :
289
+ schema .Type = & openapi3.Types {"integer" }
290
+ schema .Min = & zeroInt
291
+ schema .Max = & maxUint64
292
+
293
+ case reflect .Float32 :
294
+ schema .Type = & openapi3.Types {"number" }
295
+ schema .Format = "float"
296
+ case reflect .Float64 :
297
+ schema .Type = & openapi3.Types {"number" }
298
+ schema .Format = "double"
299
+
300
+ case reflect .String :
301
+ schema .Type = & openapi3.Types {"string" }
302
+
303
+ case reflect .Slice :
304
+ if t .Elem ().Kind () == reflect .Uint8 {
305
+ if t != rawMessageType {
306
+ schema .Type = & openapi3.Types {"string" }
307
+ schema .Format = "byte"
308
+ }
309
+ } else {
310
+ schema .Type = & openapi3.Types {"array" }
311
+ items , err := g .generateSchemaRefFor (parents , t .Elem (), name , tag )
312
+ if err != nil {
313
+ if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
314
+ items = g .generateCycleSchemaRef (t .Elem (), schema )
315
+ } else {
316
+ return nil , err
317
+ }
318
+ }
319
+ if items != nil {
320
+ g .SchemaRefs [items ]++
321
+ schema .Items = items
322
+ }
296
323
}
297
- } else {
298
- schema .Type = & openapi3.Types {"array" }
299
- items , err := g .generateSchemaRefFor (parents , t .Elem (), name , tag )
324
+
325
+ case reflect .Map :
326
+ schema .Type = & openapi3.Types {"object" }
327
+ additionalProperties , err := g .generateSchemaRefFor (parents , t .Elem (), name , tag )
300
328
if err != nil {
301
329
if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
302
- items = g .generateCycleSchemaRef (t .Elem (), schema )
330
+ additionalProperties = g .generateCycleSchemaRef (t .Elem (), schema )
303
331
} else {
304
332
return nil , err
305
333
}
306
334
}
307
- if items != nil {
308
- g .SchemaRefs [items ]++
309
- schema .Items = items
335
+ if additionalProperties != nil {
336
+ g .SchemaRefs [additionalProperties ]++
337
+ schema .AdditionalProperties = openapi3. AdditionalProperties { Schema : additionalProperties }
310
338
}
311
- }
312
339
313
- case reflect .Map :
314
- schema .Type = & openapi3.Types {"object" }
315
- additionalProperties , err := g .generateSchemaRefFor (parents , t .Elem (), name , tag )
316
- if err != nil {
317
- if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
318
- additionalProperties = g .generateCycleSchemaRef (t .Elem (), schema )
340
+ case reflect .Struct :
341
+ if t == timeType {
342
+ schema .Type = & openapi3.Types {"string" }
343
+ schema .Format = "date-time"
319
344
} else {
320
- return nil , err
321
- }
322
- }
323
- if additionalProperties != nil {
324
- g .SchemaRefs [additionalProperties ]++
325
- schema .AdditionalProperties = openapi3.AdditionalProperties {Schema : additionalProperties }
326
- }
327
-
328
- case reflect .Struct :
329
- if t == timeType {
330
- schema .Type = & openapi3.Types {"string" }
331
- schema .Format = "date-time"
332
- } else {
333
- typeName := g .generateTypeName (t )
334
-
335
- if _ , ok := g .componentSchemaRefs [typeName ]; ok && g .opts .exportComponentSchemas .ExportComponentSchemas {
336
- // Check if we have already parsed this component schema ref based on the name of the struct
337
- // and use that if so
338
- return openapi3 .NewSchemaRef (fmt .Sprintf ("#/components/schemas/%s" , typeName ), schema ), nil
339
- }
345
+ typeName := g .generateTypeName (t )
340
346
341
- for _ , fieldInfo := range typeInfo . Fields {
342
- // Only fields with JSON tag are considered (by default)
343
- if ! fieldInfo . HasJSONTag && ! g . opts . useAllExportedFields {
344
- continue
347
+ if _ , ok := g . componentSchemaRefs [ typeName ]; ok && g . opts . exportComponentSchemas . ExportComponentSchemas {
348
+ // Check if we have already parsed this component schema ref based on the name of the struct
349
+ // and use that if so
350
+ return openapi3 . NewSchemaRef ( fmt . Sprintf ( "#/components/schemas/%s" , typeName ), schema ), nil
345
351
}
346
- // If asked, try to use yaml tag
347
- fieldName , fType := fieldInfo .JSONName , fieldInfo .Type
348
- if ! fieldInfo .HasJSONTag && g .opts .useAllExportedFields {
349
- // Handle anonymous fields/embedded structs
350
- if t .Field (fieldInfo .Index [0 ]).Anonymous {
351
- ref , err := g .generateSchemaRefFor (parents , fType , fieldName , tag )
352
- if err != nil {
353
- if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
354
- ref = g .generateCycleSchemaRef (fType , schema )
355
- } else {
356
- return nil , err
352
+
353
+ for _ , fieldInfo := range typeInfo .Fields {
354
+ // Only fields with JSON tag are considered (by default)
355
+ if ! fieldInfo .HasJSONTag && ! g .opts .useAllExportedFields {
356
+ continue
357
+ }
358
+ // If asked, try to use yaml tag
359
+ fieldName , fType := fieldInfo .JSONName , fieldInfo .Type
360
+ if ! fieldInfo .HasJSONTag && g .opts .useAllExportedFields {
361
+ // Handle anonymous fields/embedded structs
362
+ if t .Field (fieldInfo .Index [0 ]).Anonymous {
363
+ ref , err := g .generateSchemaRefFor (parents , fType , fieldName , tag )
364
+ if err != nil {
365
+ if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
366
+ ref = g .generateCycleSchemaRef (fType , schema )
367
+ } else {
368
+ return nil , err
369
+ }
370
+ }
371
+ if ref != nil {
372
+ g .SchemaRefs [ref ]++
373
+ schema .WithPropertyRef (fieldName , ref )
374
+ }
375
+ } else {
376
+ ff := getStructField (t , fieldInfo )
377
+ if tag , ok := ff .Tag .Lookup ("yaml" ); ok && tag != "-" {
378
+ fieldName , fType = tag , ff .Type
357
379
}
358
380
}
359
- if ref != nil {
360
- g . SchemaRefs [ ref ] ++
361
- schema . WithPropertyRef ( fieldName , ref )
362
- }
363
- } else {
381
+ }
382
+
383
+ // extract the field tag if we have a customizer
384
+ var fieldTag reflect. StructTag
385
+ if g . opts . schemaCustomizer != nil {
364
386
ff := getStructField (t , fieldInfo )
365
- if tag , ok := ff .Tag .Lookup ("yaml" ); ok && tag != "-" {
366
- fieldName , fType = tag , ff .Type
387
+ fieldTag = ff .Tag
388
+ }
389
+
390
+ ref , err := g .generateSchemaRefFor (parents , fType , fieldName , fieldTag )
391
+ if err != nil {
392
+ if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
393
+ ref = g .generateCycleSchemaRef (fType , schema )
394
+ } else {
395
+ return nil , err
367
396
}
368
397
}
369
- }
398
+ if ref != nil {
399
+ g .SchemaRefs [ref ]++
400
+ schema .WithPropertyRef (fieldName , ref )
401
+ }
370
402
371
- // extract the field tag if we have a customizer
372
- var fieldTag reflect.StructTag
373
- if g .opts .schemaCustomizer != nil {
374
- ff := getStructField (t , fieldInfo )
375
- fieldTag = ff .Tag
376
403
}
377
404
378
- ref , err := g .generateSchemaRefFor (parents , fType , fieldName , fieldTag )
379
- if err != nil {
380
- if _ , ok := err .(* CycleError ); ok && ! g .opts .throwErrorOnCycle {
381
- ref = g .generateCycleSchemaRef (fType , schema )
382
- } else {
383
- return nil , err
384
- }
385
- }
386
- if ref != nil {
387
- g .SchemaRefs [ref ]++
388
- schema .WithPropertyRef (fieldName , ref )
405
+ // Object only if it has properties
406
+ if schema .Properties != nil {
407
+ schema .Type = & openapi3.Types {"object" }
389
408
}
390
-
391
409
}
392
410
393
- // Object only if it has properties
394
- if schema .Properties != nil {
395
- schema .Type = & openapi3.Types {"object" }
396
- }
397
411
}
398
-
399
- default :
400
- // Object has their own schema's implementation, so we'll use those
401
- if v := reflect .New (t ); v .CanInterface () {
402
- if v , ok := v .Interface ().(SetSchemar ); ok {
403
- v .SetSchema (schema )
404
- }
405
- }
406
-
407
412
}
408
413
409
414
if g .opts .schemaCustomizer != nil {
0 commit comments