doc-generate/internal/swagger/properties.go

110 lines
3.0 KiB
Go
Raw Permalink Normal View History

2025-09-30 08:16:44 +00:00
package swagger
import (
"github.com/go-openapi/spec"
apiSpec "github.com/zeromicro/go-zero/tools/goctl/api/spec"
)
func propertiesFromType(ctx Context, tp apiSpec.Type) (spec.SchemaProperties, []string) {
var (
properties = map[string]spec.Schema{}
requiredFields []string
)
switch val := tp.(type) {
case apiSpec.PointerType:
return propertiesFromType(ctx, val.Type)
case apiSpec.ArrayType:
return propertiesFromType(ctx, val.Value)
case apiSpec.DefineStruct, apiSpec.NestedStruct:
rangeMemberAndDo(ctx, val, func(tag *apiSpec.Tags, required bool, member apiSpec.Member) {
var (
jsonTagString = member.Name
minimum, maximum *float64
exclusiveMinimum, exclusiveMaximum bool
example, defaultValue any
enum []any
)
pathTag, _ := tag.Get(tagPath)
if pathTag != nil {
return
}
formTag, _ := tag.Get(tagForm)
if formTag != nil {
return
}
headerTag, _ := tag.Get(tagHeader)
if headerTag != nil {
return
}
jsonTag, _ := tag.Get(tagJson)
if jsonTag != nil {
jsonTagString = jsonTag.Name
minimum, maximum, exclusiveMinimum, exclusiveMaximum = rangeValueFromOptions(jsonTag.Options)
example = exampleValueFromOptions(ctx, jsonTag.Options, member.Type)
defaultValue = defValueFromOptions(ctx, jsonTag.Options, member.Type)
enum = enumsValueFromOptions(jsonTag.Options)
}
if required {
requiredFields = append(requiredFields, jsonTagString)
}
schema := spec.Schema{
SwaggerSchemaProps: spec.SwaggerSchemaProps{
Example: example,
},
SchemaProps: spec.SchemaProps{
Description: formatComment(member.Comment),
Type: typeFromGoType(ctx, member.Type),
Default: defaultValue,
Maximum: maximum,
ExclusiveMaximum: exclusiveMaximum,
Minimum: minimum,
ExclusiveMinimum: exclusiveMinimum,
Enum: enum,
AdditionalProperties: mapFromGoType(ctx, member.Type),
},
}
switch sampleTypeFromGoType(ctx, member.Type) {
case swaggerTypeArray:
schema.Items = itemsFromGoType(ctx, member.Type)
case swaggerTypeObject:
p, r := propertiesFromType(ctx, member.Type)
schema.Properties = p
schema.Required = r
}
if ctx.UseDefinitions {
structName, containsStruct := containsStruct(member.Type)
if containsStruct {
schema.SchemaProps.Ref = spec.MustCreateRef(getRefName(structName))
}
}
properties[jsonTagString] = schema
})
}
return properties, requiredFields
}
func containsStruct(tp apiSpec.Type) (string, bool) {
switch val := tp.(type) {
case apiSpec.PointerType:
return containsStruct(val.Type)
case apiSpec.ArrayType:
return containsStruct(val.Value)
case apiSpec.DefineStruct:
return val.RawName, true
case apiSpec.MapType:
return containsStruct(val.Value)
default:
return "", false
}
}
func getRefName(typeName string) string {
return "#/definitions/" + typeName
}