Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Generic Fields does not handle Arrays in the .swaggo file #1322

Merged
merged 2 commits into from Sep 15, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
5 changes: 3 additions & 2 deletions generics_test.go
Expand Up @@ -31,8 +31,9 @@ func TestParseGenericsBasic(t *testing.T) {

p := New()
p.Overrides = map[string]string{
"types.Field[string]": "string",
"types.DoubleField[string,string]": "string",
"types.Field[string]": "string",
"types.DoubleField[string,string]": "[]string",
"types.TrippleField[string,string]": "[][]string",
}

err = p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth)
Expand Down
20 changes: 12 additions & 8 deletions operation.go
Expand Up @@ -824,6 +824,10 @@ var responsePattern = regexp.MustCompile(`^([\w,]+)\s+([\w{}]+)\s+([\w\-.\\{}=,\
var combinedPattern = regexp.MustCompile(`^([\w\-./\[\]]+){(.*)}$`)

func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
return parseObjectSchema(operation.parser, refType, astFile)
}

func parseObjectSchema(parser *Parser, refType string, astFile *ast.File) (*spec.Schema, error) {
switch {
case refType == NIL:
return nil, nil
Expand All @@ -838,7 +842,7 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
case IsPrimitiveType(refType):
return PrimitiveSchema(refType), nil
case strings.HasPrefix(refType, "[]"):
schema, err := operation.parseObjectSchema(refType[2:], astFile)
schema, err := parseObjectSchema(parser, refType[2:], astFile)
if err != nil {
return nil, err
}
Expand All @@ -856,17 +860,17 @@ func (operation *Operation) parseObjectSchema(refType string, astFile *ast.File)
return spec.MapProperty(nil), nil
}

schema, err := operation.parseObjectSchema(refType, astFile)
schema, err := parseObjectSchema(parser, refType, astFile)
if err != nil {
return nil, err
}

return spec.MapProperty(schema), nil
case strings.Contains(refType, "{"):
return operation.parseCombinedObjectSchema(refType, astFile)
return parseCombinedObjectSchema(parser, refType, astFile)
default:
if operation.parser != nil { // checking refType has existing in 'TypeDefinitions'
schema, err := operation.parser.getTypeSchema(refType, astFile, true)
if parser != nil { // checking refType has existing in 'TypeDefinitions'
schema, err := parser.getTypeSchema(refType, astFile, true)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -896,13 +900,13 @@ func parseFields(s string) []string {
})
}

func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *ast.File) (*spec.Schema, error) {
func parseCombinedObjectSchema(parser *Parser, refType string, astFile *ast.File) (*spec.Schema, error) {
matches := combinedPattern.FindStringSubmatch(refType)
if len(matches) != 3 {
return nil, fmt.Errorf("invalid type: %s", refType)
}

schema, err := operation.parseObjectSchema(matches[1], astFile)
schema, err := parseObjectSchema(parser, matches[1], astFile)
if err != nil {
return nil, err
}
Expand All @@ -912,7 +916,7 @@ func (operation *Operation) parseCombinedObjectSchema(refType string, astFile *a
for _, field := range fields {
keyVal := strings.SplitN(field, "=", 2)
if len(keyVal) == 2 {
schema, err := operation.parseObjectSchema(keyVal[1], astFile)
schema, err := parseObjectSchema(parser, keyVal[1], astFile)
if err != nil {
return nil, err
}
Expand Down
2 changes: 1 addition & 1 deletion parser.go
Expand Up @@ -873,7 +873,7 @@ func convertFromSpecificToPrimitive(typeName string) (string, error) {
func (parser *Parser) getTypeSchema(typeName string, file *ast.File, ref bool) (*spec.Schema, error) {
if override, ok := parser.Overrides[typeName]; ok {
parser.debug.Printf("Override detected for %s: using %s instead", typeName, override)
typeName = override
return parseObjectSchema(parser, override, file)
}

if IsInterfaceLike(typeName) {
Expand Down
3 changes: 2 additions & 1 deletion testdata/generics_basic/.swaggo
@@ -1,2 +1,3 @@
replace types.Field[string] string
replace types.DoubleField[string,string] string
replace types.DoubleField[string,string] []string
replace types.TrippleField[string,string] [][]string
14 changes: 13 additions & 1 deletion testdata/generics_basic/expected.json
Expand Up @@ -181,8 +181,20 @@
"types.Hello": {
"type": "object",
"properties": {
"myNewArrayField": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "string"
}
}
},
"myNewField": {
"type": "string"
"type": "array",
"items": {
"type": "string"
}
},
"myStringField1": {
"type": "string"
Expand Down
12 changes: 9 additions & 3 deletions testdata/generics_basic/types/string.go
Expand Up @@ -9,8 +9,14 @@ type DoubleField[T1 any, T2 any] struct {
Value2 T2
}

type TrippleField[T1 any, T2 any] struct {
Value1 T1
Value2 T2
}

type Hello struct {
MyStringField1 Field[*string] `json:"myStringField1"`
MyStringField2 Field[string] `json:"myStringField2"`
MyArrayField DoubleField[*string, string] `json:"myNewField"`
MyStringField1 Field[*string] `json:"myStringField1"`
MyStringField2 Field[string] `json:"myStringField2"`
MyArrayField DoubleField[*string, string] `json:"myNewField"`
MyArrayDepthField TrippleField[*string, string] `json:"myNewArrayField"`
}