Merge pull request '增加枚举值描述解析' (#12) from feature/support_enum_desc into master

Reviewed-on: #12
This commit is contained in:
白茶清欢 2025-02-18 23:03:08 +08:00
commit e2d0efe09e
4 changed files with 100 additions and 62 deletions

View File

@ -119,24 +119,25 @@ type PathConfigParameter struct {
//
// Date : 12:32 2024/7/19
type Schema struct {
Nullable bool `json:"nullable,omitempty"` // 对于定义的schema允许发送 null 值。默认值是 false.
Discriminator *SchemaDiscriminator `json:"discriminator,omitempty"` // 说白了, 就是一个字段可能是不同的数据结构。。。
ReadOnly bool `json:"readOnly,omitempty"` // 仅与 Schema "properties" 定义有关。 声明此属性是 "readonly" 的。这意味着它可以作为 response 的一部分但不应该作为 request 的一部分被发送。如果一个 property 的 readOnly 被标记为 true 且在 required 列表中required 将只作用于 response。一个 property 的 readOnly 和 writeOnly 不允许同时被标记为 true。默认值是 false。
WriteOnly bool `json:"writeOnly,omitempty"` // 仅与 Schema "properties" 定义有关。声明此 property 为 "write only"。所以它可以作为 request 的一部分而不应该作为 response 的一部分被发送。如果一个 propertywriteOnly 被标记为 true 且在 required 列表中required 将只作用于 request。一个 property 的 readOnly 和 writeOnly 不能同时被标记为 true。默认值是 false。
Xml *XML `json:"xml,omitempty"` // 这只能用于 properties schemas在root schemas 中没有效果。
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` // 此 schema 附加的外部文档。
Example string `json:"example,omitempty"` // 一个用于示范此 schema实例的示例可以是任意格式。为了表达无法用 JSON 或 YAML 格式呈现的示例,可以使用 string 类型的值,且在必要的地方需要使用字符转义。
Deprecated bool `json:"deprecated,omitempty"` // 表示一个 schema 是废弃的,应该逐渐被放弃使用。默认值是 false.
Properties map[string]*Property `json:"properties,omitempty"` // 数据字段 => 数据规则
Required []string `json:"required,omitempty"` // 必传属性列表
Enum []any `json:"enum,omitempty"` // 枚举值列表
Type string `json:"type,omitempty"` // 类型
Items *PropertyXOf `json:"items,omitempty"` // items 必须存在如果 type 的值是 array。
Ref string `json:"$ref,omitempty"` // 类型引用
Format string `json:"format,omitempty"` // 格式化类型
Maximum *int64 `json:"maximum,omitempty"` // 最大值
Minimum *int64 `json:"minimum,omitempty"` // 最小值
Default any `json:"default,omitempty"` // 默认值
Nullable bool `json:"nullable,omitempty"` // 对于定义的schema允许发送 null 值。默认值是 false.
Discriminator *SchemaDiscriminator `json:"discriminator,omitempty"` // 说白了, 就是一个字段可能是不同的数据结构。。。
ReadOnly bool `json:"readOnly,omitempty"` // 仅与 Schema "properties" 定义有关。 声明此属性是 "readonly" 的。这意味着它可以作为 response 的一部分但不应该作为 request 的一部分被发送。如果一个 property 的 readOnly 被标记为 true 且在 required 列表中required 将只作用于 response。一个 property 的 readOnly 和 writeOnly 不允许同时被标记为 true。默认值是 false。
WriteOnly bool `json:"writeOnly,omitempty"` // 仅与 Schema "properties" 定义有关。声明此 property 为 "write only"。所以它可以作为 request 的一部分而不应该作为 response 的一部分被发送。如果一个 propertywriteOnly 被标记为 true 且在 required 列表中required 将只作用于 request。一个 property 的 readOnly 和 writeOnly 不能同时被标记为 true。默认值是 false。
Xml *XML `json:"xml,omitempty"` // 这只能用于 properties schemas在root schemas 中没有效果。
ExternalDocs *ExternalDocs `json:"externalDocs,omitempty"` // 此 schema 附加的外部文档。
Example string `json:"example,omitempty"` // 一个用于示范此 schema实例的示例可以是任意格式。为了表达无法用 JSON 或 YAML 格式呈现的示例,可以使用 string 类型的值,且在必要的地方需要使用字符转义。
Deprecated bool `json:"deprecated,omitempty"` // 表示一个 schema 是废弃的,应该逐渐被放弃使用。默认值是 false.
Properties map[string]*Property `json:"properties,omitempty"` // 数据字段 => 数据规则
Required []string `json:"required,omitempty"` // 必传属性列表
Enum []any `json:"enum,omitempty"` // 枚举值列表
XEnumDescription map[string]string `json:"x-enumDescriptions,omitempty"` // 枚举值描述的扩展, redoc-free支持
Type string `json:"type,omitempty"` // 类型
Items *PropertyXOf `json:"items,omitempty"` // items 必须存在如果 type 的值是 array。
Ref string `json:"$ref,omitempty"` // 类型引用
Format string `json:"format,omitempty"` // 格式化类型
Maximum *int64 `json:"maximum,omitempty"` // 最大值
Minimum *int64 `json:"minimum,omitempty"` // 最小值
Default any `json:"default,omitempty"` // 默认值
}
// Property 是从 JSON Schema 提取出来的,但是做了一些调整以适应 OpenAPI Specification。
@ -148,6 +149,7 @@ type Property struct {
Type string `json:"type,omitempty"` // 数据类型, swagger本身的定义
Format string `json:"format,omitempty"` // 对应编程语言中的数据类型描述
Enum []any `json:"enum,omitempty"` // 枚举值列表
XEnumDescription map[string]string `json:"x-enumDescriptions,omitempty"` // 枚举值描述的扩展, redoc-free支持
Default any `json:"default,omitempty"` // 默认值 : 不同于 JSON Schema这个值必须符合定义与相同级别的 Schema 对象 中定义的类型,比如 type 是 string那么 default 可以是 "foo" 但不能是 1。
Description string `json:"description,omitempty"` // 数据描述, CommonMark syntax可以被用来呈现富文本格式.
Maximum *int64 `json:"maximum,omitempty"` // 最大值

View File

@ -8,28 +8,29 @@
package define
const (
TagJson = "json"
TagXml = "xml"
TagYaml = "yaml"
TagYml = "yml"
TagForm = "form"
TagBinding = "binding"
TagValidate = "validate"
TagErr = "err"
TagMsg = "msg"
TagDc = "dc"
TagDesc = "desc"
TagDescription = "description"
TagD = "d"
TagDefault = "default"
TagDeprecated = "deprecated"
TagSummary = "summary"
TagPath = "path" // 接口的请求路径
TagMethod = "method" // 接口的请求方法
TagUriTag = "tag" // 接口的tag
TagOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map非严格模式返回任意值
TagErrMsg = "err" // 验证失败错误信息tag
TagContentType = "content_type"
TagOutputContentType = "output_content_type"
TagNameOmitempty = "omitempty"
TagJson = "json"
TagXml = "xml"
TagYaml = "yaml"
TagYml = "yml"
TagForm = "form"
TagBinding = "binding"
TagValidate = "validate"
TagErr = "err"
TagMsg = "msg"
TagDc = "dc"
TagDesc = "desc"
TagDescription = "description"
TagD = "d"
TagDefault = "default"
TagDeprecated = "deprecated"
TagSummary = "summary"
TagPath = "path" // 接口的请求路径
TagMethod = "method" // 接口的请求方法
TagUriTag = "tag" // 接口的tag
TagOutputStrict = "output_strict" // 接口数据是否为严格模式 : 严格模式, 响应数据必须是结构体/map非严格模式返回任意值
TagErrMsg = "err" // 验证失败错误信息tag
TagContentType = "content_type"
TagOutputContentType = "output_content_type"
TagNameOmitempty = "omitempty"
TagNameEnumDescription = "enum-desc" // 枚举值描述: enum1:enum1-desc||enum2:enum2-desc
)

View File

@ -354,11 +354,13 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
Required: ValidateRule.IsRequired(inputType.Field(i)),
Deprecated: ParseStructFieldTag.Deprecated(inputType.Field(i)),
Schema: &define.Schema{
Minimum: ValidateRule.Minimum(inputType.Field(i)),
Maximum: ValidateRule.Maximum(inputType.Field(i)),
Type: convertBaseType,
Format: realInputTypeFormat,
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
Minimum: ValidateRule.Minimum(inputType.Field(i)),
Maximum: ValidateRule.Maximum(inputType.Field(i)),
Type: convertBaseType,
Format: realInputTypeFormat,
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
Enum: ValidateRule.Enum(inputType.Field(i)),
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
},
AllowEmptyValue: false,
Style: "",
@ -402,10 +404,12 @@ func (g *Generate) ParseReadConfigParam(requestCfg *define.UriBaseConfig, baseRe
Required: ValidateRule.IsRequired(inputType.Field(i)),
Deprecated: ParseStructFieldTag.Deprecated(inputType.Field(i)),
Schema: &define.Schema{
Type: convertBaseType,
Items: nil,
Ref: "",
Format: realInputTypeFormat,
Type: convertBaseType,
Items: nil,
Ref: "",
Format: realInputTypeFormat,
Enum: ValidateRule.Enum(inputType.Field(i)),
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
},
AllowEmptyValue: false,
Style: "",
@ -521,12 +525,14 @@ func (g *Generate) AddComponentsSchema(rootSchemaName string, pkgPath string, in
// 当做默认基础类型, 默认不会出现 *map *[]
convertBaseType, _ := g.realBaseType2SwaggerType(inputType.Field(i).Type.String())
g.docData.Components.Schemas[schemaName].Properties[propertyName] = &define.Property{
Type: convertBaseType,
Format: inputType.Field(i).Type.String(),
Maximum: ValidateRule.Maximum(inputType.Field(i)),
Minimum: ValidateRule.Minimum(inputType.Field(i)),
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
Description: ParseStructFieldTag.GetParamDesc(inputType.Field(i)),
Type: convertBaseType,
Format: inputType.Field(i).Type.String(),
Enum: ValidateRule.Enum(inputType.Field(i)),
XEnumDescription: ParseStructFieldTag.EnumDescription(inputType.Field(i)),
Maximum: ValidateRule.Maximum(inputType.Field(i)),
Minimum: ValidateRule.Minimum(inputType.Field(i)),
Default: ParseStructFieldTag.GetDefaultValue(inputType.Field(i)),
Description: ParseStructFieldTag.GetParamDesc(inputType.Field(i)),
}
}
continue
@ -624,11 +630,12 @@ func (g *Generate) handleAnonymousField(schemaName string, field reflect.StructF
} else {
paramName := ParseStructFieldTag.GetParamName(itemField)
g.docData.Components.Schemas[schemaName].Properties[paramName] = &define.Property{
Type: baseConvertType,
Format: itemField.Type.String(),
Enum: ValidateRule.Enum(itemField),
Default: ParseStructFieldTag.GetDefaultValue(handleType.Field(i)),
Description: ParseStructFieldTag.GetParamDesc(handleType.Field(i)),
Type: baseConvertType,
Format: itemField.Type.String(),
Enum: ValidateRule.Enum(itemField),
XEnumDescription: ParseStructFieldTag.EnumDescription(itemField),
Default: ParseStructFieldTag.GetDefaultValue(handleType.Field(i)),
Description: ParseStructFieldTag.GetParamDesc(handleType.Field(i)),
}
if ValidateRule.IsRequired(itemField) {
g.docData.Components.Schemas[schemaName].Required = append(g.docData.Components.Schemas[schemaName].Required, paramName)

View File

@ -150,3 +150,31 @@ func (psf parseStructFieldTag) Summary(structField reflect.StructField) string {
}
return paramName
}
// EnumDescription .枚举值详细描述
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 22:40 2025/2/18
func (psf parseStructFieldTag) EnumDescription(structField reflect.StructField) map[string]string {
defaultTagList := []string{define.TagNameEnumDescription}
res := map[string]string{}
for _, tag := range defaultTagList {
if tagVal, exist := structField.Tag.Lookup(tag); exist && len(tagVal) > 0 {
tagVal = strings.ReplaceAll(tagVal, "###", "`")
enumList := strings.Split(tagVal, "||")
for _, enum := range enumList {
enumArr := strings.Split(enum, ":")
if len(enumArr) < 2 {
continue
}
res[enumArr[0]] = strings.Join(enumArr[1:], ":")
}
return res
}
}
if len(res) == 0 {
return nil
}
return res
}