From af1c5256a1b4149f6958c18977d57895a5594f73 Mon Sep 17 00:00:00 2001 From: Fabian Martin Date: Tue, 9 Aug 2022 15:00:49 +0200 Subject: [PATCH] fix: Go generics cannot find common package object type definition (#1281) * fix: Go generics cannot find common package object type definition - use ast.SelectorExpr instead if ast.Ident to embed types - tests reworked fixes https://github.com/swaggo/swag/issues/1237 * fix: Overrides not working with Generics - Generate full type name, if only one generic field exists - Generate refs to generic properties - Tests extended to test override behavior refs https://github.com/swaggo/swag/issues/1237 fixes https://github.com/swaggo/swag/issues/1253 * test: Extend tests to check error behavior - new tests added --- gen/gen_test.go | 14 + generics.go | 41 +- generics_test.go | 63 ++ testdata/generics_arrays/api/api.go | 25 +- testdata/generics_arrays/expected.json | 360 ++------ testdata/generics_arrays/types/post.go | 17 + testdata/generics_arrays/web/handler.go | 11 - testdata/generics_basic/.swaggo | 2 + testdata/generics_basic/api/api.go | 31 +- testdata/generics_basic/expected.json | 463 ++++------ testdata/generics_basic/types/post.go | 18 + testdata/generics_basic/types/string.go | 16 + testdata/generics_basic/web/handler.go | 11 - testdata/generics_names/api/api.go | 25 +- testdata/generics_names/expected.json | 320 +------ testdata/generics_names/types/post.go | 17 + testdata/generics_names/web/handler.go | 11 - testdata/generics_nested/api/api.go | 33 +- testdata/generics_nested/expected.json | 1022 ++++----------------- testdata/generics_nested/types/post.go | 17 + testdata/generics_nested/web/handler.go | 11 - testdata/generics_property/expected.json | 141 +-- testdata/generics_property/types/post.go | 21 + testdata/generics_property/web/handler.go | 17 +- 24 files changed, 760 insertions(+), 1947 deletions(-) create mode 100644 testdata/generics_arrays/types/post.go create mode 100644 testdata/generics_basic/.swaggo create mode 100644 testdata/generics_basic/types/post.go create mode 100644 testdata/generics_basic/types/string.go create mode 100644 testdata/generics_names/types/post.go create mode 100644 testdata/generics_nested/types/post.go create mode 100644 testdata/generics_property/types/post.go diff --git a/gen/gen_test.go b/gen/gen_test.go index ef0b0f611..27f12421a 100644 --- a/gen/gen_test.go +++ b/gen/gen_test.go @@ -641,6 +641,20 @@ func TestGen_parseOverrides(t *testing.T) { "github.com/foo/bar": "", }, }, + { + Name: "generic-simple", + Data: `replace types.Field[string] string`, + Expected: map[string]string{ + "types.Field[string]": "string", + }, + }, + { + Name: "generic-double", + Data: `replace types.Field[string,string] string`, + Expected: map[string]string{ + "types.Field[string,string]": "string", + }, + }, { Name: "comment", Data: `// this is a comment diff --git a/generics.go b/generics.go index f95141363..d33498fff 100644 --- a/generics.go +++ b/generics.go @@ -4,6 +4,7 @@ package swag import ( + "errors" "fmt" "go/ast" "strings" @@ -19,7 +20,10 @@ type genericTypeSpec struct { func (s *genericTypeSpec) Type() ast.Expr { if s.TypeSpec != nil { - return s.TypeSpec.TypeSpec.Type + return &ast.SelectorExpr{ + X: &ast.Ident{Name: ""}, + Sel: &ast.Ident{Name: s.Name}, + } } return &ast.Ident{Name: s.Name} @@ -78,16 +82,10 @@ func (pkgDefs *PackagesDefinitions) parametrizeStruct(original *TypeSpecDef, ful } tdef := pkgDefs.FindTypeSpec(genericParam, original.File, parseDependency) - if tdef == nil { - genericParamTypeDefs[original.TypeSpec.TypeParams.List[i].Names[0].Name] = &genericTypeSpec{ - ArrayDepth: arrayDepth, - Name: genericParam, - } - } else { - genericParamTypeDefs[original.TypeSpec.TypeParams.List[i].Names[0].Name] = &genericTypeSpec{ - ArrayDepth: arrayDepth, - TypeSpec: tdef, - } + genericParamTypeDefs[original.TypeSpec.TypeParams.List[i].Names[0].Name] = &genericTypeSpec{ + ArrayDepth: arrayDepth, + TypeSpec: tdef, + Name: genericParam, } } @@ -249,10 +247,27 @@ func getGenericFieldType(file *ast.File, field ast.Expr) (string, error) { return "", err } - fullName += fieldName + ", " + fullName += fieldName + "," + } + + return strings.TrimRight(fullName, ",") + "]", nil + case *ast.IndexExpr: + if file.Name == nil { + return "", errors.New("file name is nil") + } + packageName, _ := getFieldType(file, file.Name) + + x, err := getFieldType(file, fieldType.X) + if err != nil { + return "", err + } + + i, err := getFieldType(file, fieldType.Index) + if err != nil { + return "", err } - return strings.TrimRight(fullName, ", ") + "]", nil + return strings.TrimLeft(fmt.Sprintf("%s.%s[%s]", packageName, x, i), "."), nil } return "", fmt.Errorf("unknown field type %#v", field) diff --git a/generics_test.go b/generics_test.go index 81b55c27a..109cb6a12 100644 --- a/generics_test.go +++ b/generics_test.go @@ -5,6 +5,7 @@ package swag import ( "encoding/json" + "go/ast" "io/ioutil" "path/filepath" "testing" @@ -20,6 +21,11 @@ func TestParseGenericsBasic(t *testing.T) { assert.NoError(t, err) p := New() + p.Overrides = map[string]string{ + "types.Field[string]": "string", + "types.DoubleField[string,string]": "string", + } + err = p.ParseAPI(searchDir, mainAPIFile, defaultParseDepth) assert.NoError(t, err) b, err := json.MarshalIndent(p.swagger, "", " ") @@ -86,3 +92,60 @@ func TestParseGenericsNames(t *testing.T) { assert.NoError(t, err) assert.Equal(t, string(expected), string(b)) } + +func TestGetGenericFieldType(t *testing.T) { + field, err := getFieldType( + &ast.File{Name: &ast.Ident{Name: "test"}}, + &ast.IndexListExpr{ + X: &ast.Ident{Name: "types", Obj: &ast.Object{Decl: &ast.TypeSpec{Name: &ast.Ident{Name: "Field"}}}}, + Indices: []ast.Expr{&ast.Ident{Name: "string"}}, + }, + ) + assert.NoError(t, err) + assert.Equal(t, "test.Field[string]", field) + + field, err = getFieldType( + &ast.File{Name: &ast.Ident{}}, + &ast.IndexListExpr{ + X: &ast.Ident{Name: "types", Obj: &ast.Object{Decl: &ast.TypeSpec{Name: &ast.Ident{Name: "Field"}}}}, + Indices: []ast.Expr{&ast.Ident{Name: "string"}}, + }, + ) + assert.NoError(t, err) + assert.Equal(t, "Field[string]", field) + + field, err = getFieldType( + &ast.File{Name: &ast.Ident{Name: "test"}}, + &ast.IndexListExpr{ + X: &ast.Ident{Name: "types", Obj: &ast.Object{Decl: &ast.TypeSpec{Name: &ast.Ident{Name: "Field"}}}}, + Indices: []ast.Expr{&ast.Ident{Name: "string"}, &ast.Ident{Name: "int"}}, + }, + ) + assert.NoError(t, err) + assert.Equal(t, "test.Field[string,int]", field) + + field, err = getFieldType( + &ast.File{Name: &ast.Ident{Name: "test"}}, + &ast.IndexExpr{X: &ast.Ident{Name: "Field"}, Index: &ast.Ident{Name: "string"}}, + ) + assert.NoError(t, err) + assert.Equal(t, "test.Field[string]", field) + + field, err = getFieldType( + &ast.File{Name: nil}, + &ast.IndexExpr{X: &ast.Ident{Name: "Field"}, Index: &ast.Ident{Name: "string"}}, + ) + assert.Error(t, err) + + field, err = getFieldType( + &ast.File{Name: &ast.Ident{Name: "test"}}, + &ast.IndexExpr{X: &ast.BadExpr{}, Index: &ast.Ident{Name: "string"}}, + ) + assert.Error(t, err) + + field, err = getFieldType( + &ast.File{Name: &ast.Ident{Name: "test"}}, + &ast.IndexExpr{X: &ast.Ident{Name: "Field"}, Index: &ast.BadExpr{}}, + ) + assert.Error(t, err) +} diff --git a/testdata/generics_arrays/api/api.go b/testdata/generics_arrays/api/api.go index 42a80b993..66ef1bb02 100644 --- a/testdata/generics_arrays/api/api.go +++ b/testdata/generics_arrays/api/api.go @@ -3,6 +3,7 @@ package api import ( "net/http" + "github.com/swaggo/swag/testdata/generics_arrays/types" "github.com/swaggo/swag/testdata/generics_arrays/web" ) @@ -10,36 +11,36 @@ import ( // @Description Get All of the Posts // @Accept json // @Produce json -// @Param data body web.GenericListBody[web.Post] true "Some ID" -// @Success 200 {object} web.GenericListResponse[web.Post] -// @Success 222 {object} web.GenericListResponseMulti[web.Post, web.Post] +// @Param data body web.GenericListBody[types.Post] true "Some ID" +// @Success 200 {object} web.GenericListResponse[types.Post] +// @Success 222 {object} web.GenericListResponseMulti[types.Post, types.Post] // @Router /posts [get] func GetPosts(w http.ResponseWriter, r *http.Request) { - _ = web.GenericListResponseMulti[web.Post, web.Post]{} + _ = web.GenericListResponseMulti[types.Post, types.Post]{} } // @Summary Add new pets to the store // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericListBodyMulti[web.Post, web.Post] true "Some ID" -// @Success 200 {object} web.GenericListResponse[web.Post] -// @Success 222 {object} web.GenericListResponseMulti[web.Post, web.Post] +// @Param data body web.GenericListBodyMulti[types.Post, types.Post] true "Some ID" +// @Success 200 {object} web.GenericListResponse[types.Post] +// @Success 222 {object} web.GenericListResponseMulti[types.Post, types.Post] // @Router /posts-multi [get] func GetPostMulti(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericListResponseMulti[web.Post, web.Post]{} + _ = web.GenericListResponseMulti[types.Post, types.Post]{} } // @Summary Add new pets to the store // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericListBodyMulti[web.Post, []web.Post] true "Some ID" -// @Success 200 {object} web.GenericListResponse[[]web.Post] -// @Success 222 {object} web.GenericListResponseMulti[web.Post, []web.Post] +// @Param data body web.GenericListBodyMulti[types.Post, []types.Post] true "Some ID" +// @Success 200 {object} web.GenericListResponse[[]types.Post] +// @Success 222 {object} web.GenericListResponseMulti[types.Post, []types.Post] // @Router /posts-multis [get] func GetPostArray(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericListResponseMulti[web.Post, []web.Post]{} + _ = web.GenericListResponseMulti[types.Post, []types.Post]{} } diff --git a/testdata/generics_arrays/expected.json b/testdata/generics_arrays/expected.json index 25dda1fd8..782ffb979 100644 --- a/testdata/generics_arrays/expected.json +++ b/testdata/generics_arrays/expected.json @@ -26,7 +26,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericListBody-web_Post" + "$ref": "#/definitions/web.GenericListBody-types_Post" } } ], @@ -34,13 +34,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericListResponse-web_Post" + "$ref": "#/definitions/web.GenericListResponse-types_Post" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericListResponseMulti-web_Post-web_Post" + "$ref": "#/definitions/web.GenericListResponseMulti-types_Post-types_Post" } } } @@ -63,7 +63,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericListBodyMulti-web_Post-web_Post" + "$ref": "#/definitions/web.GenericListBodyMulti-types_Post-types_Post" } } ], @@ -71,13 +71,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericListResponse-web_Post" + "$ref": "#/definitions/web.GenericListResponse-types_Post" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericListResponseMulti-web_Post-web_Post" + "$ref": "#/definitions/web.GenericListResponseMulti-types_Post-types_Post" } } } @@ -100,7 +100,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericListBodyMulti-web_Post-array_web_Post" + "$ref": "#/definitions/web.GenericListBodyMulti-types_Post-array_types_Post" } } ], @@ -108,13 +108,13 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericListResponse-array_web_Post" + "$ref": "#/definitions/web.GenericListResponse-array_types_Post" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericListResponseMulti-web_Post-array_web_Post" + "$ref": "#/definitions/web.GenericListResponseMulti-types_Post-array_types_Post" } } } @@ -122,74 +122,55 @@ } }, "definitions": { - "web.GenericListBody-web_Post": { + "types.Post": { "type": "object", "properties": { + "@uri": { + "type": "string" + }, "data": { - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" + "description": "Post data", + "type": "object", + "properties": { + "name": { + "description": "Post tag", + "type": "array", + "items": { + "type": "string" } } } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "name": { + "description": "Post name", + "type": "string", + "example": "poti" } } }, - "web.GenericListBodyMulti-web_Post-array_web_Post": { + "web.GenericListBody-types_Post": { "type": "object", "properties": { "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" + } + } + } + }, + "web.GenericListBodyMulti-types_Post-array_types_Post": { + "type": "object", + "properties": { + "data": { + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" } }, "meta": { @@ -197,105 +178,30 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } } } }, - "web.GenericListBodyMulti-web_Post-web_Post": { + "web.GenericListBodyMulti-types_Post-types_Post": { "type": "object", "properties": { "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "meta": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } } }, - "web.GenericListResponse-array_web_Post": { + "web.GenericListResponse-array_types_Post": { "type": "object", "properties": { "items": { @@ -304,32 +210,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, @@ -339,39 +220,14 @@ } } }, - "web.GenericListResponse-web_Post": { + "web.GenericListResponse-types_Post": { "type": "object", "properties": { "items": { "description": "Items from the list response", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "status": { @@ -380,39 +236,14 @@ } } }, - "web.GenericListResponseMulti-web_Post-array_web_Post": { + "web.GenericListResponseMulti-types_Post-array_types_Post": { "type": "object", "properties": { "itemsOne": { "description": "ItemsOne is the first thing", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "itemsTwo": { @@ -421,32 +252,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, @@ -456,71 +262,21 @@ } } }, - "web.GenericListResponseMulti-web_Post-web_Post": { + "web.GenericListResponseMulti-types_Post-types_Post": { "type": "object", "properties": { "itemsOne": { "description": "ItemsOne is the first thing", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "status": { diff --git a/testdata/generics_arrays/types/post.go b/testdata/generics_arrays/types/post.go new file mode 100644 index 000000000..f4455f42f --- /dev/null +++ b/testdata/generics_arrays/types/post.go @@ -0,0 +1,17 @@ +package types + +type APIBase struct { + APIUrl string `json:"@uri,omitempty"` + ID int `json:"id" example:"1" format:"int64"` +} + +type Post struct { + APIBase + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` +} diff --git a/testdata/generics_arrays/web/handler.go b/testdata/generics_arrays/web/handler.go index 9c18316f4..f0ac0f6b4 100644 --- a/testdata/generics_arrays/web/handler.go +++ b/testdata/generics_arrays/web/handler.go @@ -34,17 +34,6 @@ type GenericListResponseMulti[T any, X any] struct { Status string } -type Post struct { - ID int `json:"id" example:"1" format:"int64"` - // Post name - Name string `json:"name" example:"poti"` - // Post data - Data struct { - // Post tag - Tag []string `json:"name"` - } `json:"data"` -} - // APIError // @Description API error // @Description with information about it diff --git a/testdata/generics_basic/.swaggo b/testdata/generics_basic/.swaggo new file mode 100644 index 000000000..8c55f566d --- /dev/null +++ b/testdata/generics_basic/.swaggo @@ -0,0 +1,2 @@ +replace types.Field[string] string +replace types.DoubleField[string,string] string \ No newline at end of file diff --git a/testdata/generics_basic/api/api.go b/testdata/generics_basic/api/api.go index c27fc2729..e42551344 100644 --- a/testdata/generics_basic/api/api.go +++ b/testdata/generics_basic/api/api.go @@ -3,6 +3,7 @@ package api import ( "net/http" + "github.com/swaggo/swag/testdata/generics_basic/types" "github.com/swaggo/swag/testdata/generics_basic/web" ) @@ -10,39 +11,45 @@ import ( // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericBody[web.Post] true "Some ID" -// @Success 200 {object} web.GenericResponse[web.Post] -// @Success 222 {object} web.GenericResponseMulti[web.Post, web.Post] +// @Param data body web.GenericBody[types.Post] true "Some ID" +// @Success 200 {object} web.GenericResponse[types.Post] +// @Success 201 {object} web.GenericResponse[types.Hello] +// @Success 202 {object} web.GenericResponse[types.Field[string]] +// @Success 203 {object} web.GenericResponse[types.Field[int]] +// @Success 222 {object} web.GenericResponseMulti[types.Post, types.Post] // @Failure 400 {object} web.APIError "We need ID!!" // @Failure 404 {object} web.APIError "Can not find ID" // @Router /posts/ [post] func GetPost(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericResponse[web.Post]{} + _ = web.GenericResponse[types.Post]{} } // @Summary Add new pets to the store // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericBodyMulti[web.Post, web.Post] true "Some ID" -// @Success 200 {object} web.GenericResponse[web.Post] -// @Success 222 {object} web.GenericResponseMulti[web.Post, web.Post] +// @Param data body web.GenericBodyMulti[types.Post, types.Post] true "Some ID" +// @Success 200 {object} web.GenericResponse[types.Post] +// @Success 201 {object} web.GenericResponse[types.Hello] +// @Success 202 {object} web.GenericResponse[types.Field[string]] +// @Success 222 {object} web.GenericResponseMulti[types.Post, types.Post] // @Router /posts-multi/ [post] func GetPostMulti(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericResponse[web.Post]{} + _ = web.GenericResponse[types.Post]{} } // @Summary Add new pets to the store // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericBodyMulti[[]web.Post, [][]web.Post] true "Some ID" -// @Success 200 {object} web.GenericResponse[[]web.Post] -// @Success 222 {object} web.GenericResponseMulti[[]web.Post, [][]web.Post] +// @Param data body web.GenericBodyMulti[[]types.Post, [][]types.Post] true "Some ID" +// @Success 200 {object} web.GenericResponse[[]types.Post] +// @Success 201 {object} web.GenericResponse[[]types.Hello] +// @Success 222 {object} web.GenericResponseMulti[[]types.Post, [][]types.Post] // @Router /posts-multis/ [post] func GetPostArray(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericResponse[web.Post]{} + _ = web.GenericResponse[types.Post]{} } diff --git a/testdata/generics_basic/expected.json b/testdata/generics_basic/expected.json index ac61b4f78..8124cc621 100644 --- a/testdata/generics_basic/expected.json +++ b/testdata/generics_basic/expected.json @@ -26,7 +26,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericBodyMulti-web_Post-web_Post" + "$ref": "#/definitions/web.GenericBodyMulti-types_Post-types_Post" } } ], @@ -34,13 +34,25 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericResponse-web_Post" + "$ref": "#/definitions/web.GenericResponse-types_Post" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/web.GenericResponse-types_Hello" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/web.GenericResponse-types_Field_string" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericResponseMulti-web_Post-web_Post" + "$ref": "#/definitions/web.GenericResponseMulti-types_Post-types_Post" } } } @@ -63,7 +75,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericBodyMulti-array_web_Post-array2_web_Post" + "$ref": "#/definitions/web.GenericBodyMulti-array_types_Post-array2_types_Post" } } ], @@ -71,13 +83,19 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericResponse-array_web_Post" + "$ref": "#/definitions/web.GenericResponse-array_types_Post" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/web.GenericResponse-array_types_Hello" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericResponseMulti-array_web_Post-array2_web_Post" + "$ref": "#/definitions/web.GenericResponseMulti-array_types_Post-array2_types_Post" } } } @@ -100,7 +118,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericBody-web_Post" + "$ref": "#/definitions/web.GenericBody-types_Post" } } ], @@ -108,13 +126,31 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericResponse-web_Post" + "$ref": "#/definitions/web.GenericResponse-types_Post" + } + }, + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/web.GenericResponse-types_Hello" + } + }, + "202": { + "description": "Accepted", + "schema": { + "$ref": "#/definitions/web.GenericResponse-types_Field_string" + } + }, + "203": { + "description": "Non-Authoritative Information", + "schema": { + "$ref": "#/definitions/web.GenericResponse-types_Field_int" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericResponseMulti-web_Post-web_Post" + "$ref": "#/definitions/web.GenericResponseMulti-types_Post-types_Post" } }, "400": { @@ -134,6 +170,59 @@ } }, "definitions": { + "types.Field-int": { + "type": "object", + "properties": { + "value": { + "type": "integer" + } + } + }, + "types.Hello": { + "type": "object", + "properties": { + "myNewField": { + "type": "string" + }, + "myStringField1": { + "type": "string" + }, + "myStringField2": { + "type": "string" + } + } + }, + "types.Post": { + "type": "object", + "properties": { + "@uri": { + "type": "string" + }, + "data": { + "description": "Post data", + "type": "object", + "properties": { + "name": { + "description": "Post tag", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "id": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "name": { + "description": "Post name", + "type": "string", + "example": "poti" + } + } + }, "web.APIError": { "description": "API error with information about it", "type": "object", @@ -156,71 +245,21 @@ } } }, - "web.GenericBody-web_Post": { + "web.GenericBody-types_Post": { "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, - "web.GenericBodyMulti-array_web_Post-array2_web_Post": { + "web.GenericBodyMulti-array_types_Post-array2_types_Post": { "type": "object", "properties": { "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "meta": { @@ -228,130 +267,30 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } } } }, - "web.GenericBodyMulti-web_Post-web_Post": { + "web.GenericBodyMulti-types_Post-types_Post": { "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" }, "meta": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, - "web.GenericResponse-array_web_Post": { + "web.GenericResponse-array_types_Hello": { "type": "object", "properties": { "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Hello" } }, "status": { @@ -359,35 +298,13 @@ } } }, - "web.GenericResponse-web_Post": { + "web.GenericResponse-array_types_Post": { "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" } }, "status": { @@ -395,38 +312,57 @@ } } }, - "web.GenericResponseMulti-array_web_Post-array2_web_Post": { + "web.GenericResponse-types_Field_int": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/types.Field-int" + }, + "status": { + "type": "string" + } + } + }, + "web.GenericResponse-types_Field_string": { + "type": "object", + "properties": { + "data": { + "type": "string" + }, + "status": { + "type": "string" + } + } + }, + "web.GenericResponse-types_Hello": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/types.Hello" + }, + "status": { + "type": "string" + } + } + }, + "web.GenericResponse-types_Post": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/types.Post" + }, + "status": { + "type": "string" + } + } + }, + "web.GenericResponseMulti-array_types_Post-array2_types_Post": { "type": "object", "properties": { "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "meta": { @@ -434,32 +370,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, @@ -468,64 +379,14 @@ } } }, - "web.GenericResponseMulti-web_Post-web_Post": { + "web.GenericResponseMulti-types_Post-types_Post": { "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" }, "meta": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" }, "status": { "type": "string" diff --git a/testdata/generics_basic/types/post.go b/testdata/generics_basic/types/post.go new file mode 100644 index 000000000..de12dee31 --- /dev/null +++ b/testdata/generics_basic/types/post.go @@ -0,0 +1,18 @@ +package types + +type APIBase struct { + APIUrl string `json:"@uri,omitempty"` + ID int `json:"id" example:"1" format:"int64"` +} + +type Post struct { + APIBase + ID int `json:"id" example:"1" format:"int64"` + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` +} diff --git a/testdata/generics_basic/types/string.go b/testdata/generics_basic/types/string.go new file mode 100644 index 000000000..c7e251bc9 --- /dev/null +++ b/testdata/generics_basic/types/string.go @@ -0,0 +1,16 @@ +package types + +type Field[T any] struct { + Value T +} + +type DoubleField[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"` +} diff --git a/testdata/generics_basic/web/handler.go b/testdata/generics_basic/web/handler.go index 958ffffec..39b7c7af5 100644 --- a/testdata/generics_basic/web/handler.go +++ b/testdata/generics_basic/web/handler.go @@ -26,17 +26,6 @@ type GenericResponseMulti[T any, X any] struct { Status string } -type Post struct { - ID int `json:"id" example:"1" format:"int64"` - // Post name - Name string `json:"name" example:"poti"` - // Post data - Data struct { - // Post tag - Tag []string `json:"name"` - } `json:"data"` -} - // APIError // @Description API error // @Description with information about it diff --git a/testdata/generics_names/api/api.go b/testdata/generics_names/api/api.go index ef0c9c415..7c30be9de 100644 --- a/testdata/generics_names/api/api.go +++ b/testdata/generics_names/api/api.go @@ -3,6 +3,7 @@ package api import ( "net/http" + "github.com/swaggo/swag/testdata/generics_names/types" "github.com/swaggo/swag/testdata/generics_names/web" ) @@ -10,39 +11,39 @@ import ( // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericBody[web.Post] true "Some ID" -// @Success 200 {object} web.GenericResponse[web.Post] -// @Success 222 {object} web.GenericResponseMulti[web.Post, web.Post] +// @Param data body web.GenericBody[types.Post] true "Some ID" +// @Success 200 {object} web.GenericResponse[types.Post] +// @Success 222 {object} web.GenericResponseMulti[types.Post, types.Post] // @Failure 400 {object} web.APIError "We need ID!!" // @Failure 404 {object} web.APIError "Can not find ID" // @Router /posts/ [post] func GetPost(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericResponse[web.Post]{} + _ = web.GenericResponse[types.Post]{} } // @Summary Add new pets to the store // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericBodyMulti[web.Post, web.Post] true "Some ID" -// @Success 200 {object} web.GenericResponse[web.Post] -// @Success 222 {object} web.GenericResponseMulti[web.Post, web.Post] +// @Param data body web.GenericBodyMulti[types.Post, types.Post] true "Some ID" +// @Success 200 {object} web.GenericResponse[types.Post] +// @Success 222 {object} web.GenericResponseMulti[types.Post, types.Post] // @Router /posts-multi/ [post] func GetPostMulti(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericResponse[web.Post]{} + _ = web.GenericResponse[types.Post]{} } // @Summary Add new pets to the store // @Description get string by ID // @Accept json // @Produce json -// @Param data body web.GenericBodyMulti[[]web.Post, [][]web.Post] true "Some ID" -// @Success 200 {object} web.GenericResponse[[]web.Post] -// @Success 222 {object} web.GenericResponseMulti[[]web.Post, [][]web.Post] +// @Param data body web.GenericBodyMulti[[]types.Post, [][]types.Post] true "Some ID" +// @Success 200 {object} web.GenericResponse[[]types.Post] +// @Success 222 {object} web.GenericResponseMulti[[]types.Post, [][]types.Post] // @Router /posts-multis/ [post] func GetPostArray(w http.ResponseWriter, r *http.Request) { //write your code - _ = web.GenericResponse[web.Post]{} + _ = web.GenericResponse[types.Post]{} } diff --git a/testdata/generics_names/expected.json b/testdata/generics_names/expected.json index 175ab1c12..4891eaf4e 100644 --- a/testdata/generics_names/expected.json +++ b/testdata/generics_names/expected.json @@ -138,32 +138,7 @@ "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } } }, @@ -171,60 +146,10 @@ "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" }, "meta": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } } }, @@ -234,32 +159,7 @@ "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } }, "meta": { @@ -267,32 +167,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } } } @@ -302,60 +177,10 @@ "type": "object", "properties": { "data": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" }, "meta": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" }, "status": { "type": "string" @@ -368,32 +193,7 @@ "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } }, "meta": { @@ -401,32 +201,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } } }, @@ -435,37 +210,43 @@ } } }, - "Response-Post": { + "Post": { "type": "object", "properties": { + "@uri": { + "type": "string" + }, "data": { + "description": "Post data", "type": "object", "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, "name": { - "description": "Post name", - "type": "string", - "example": "poti" + "description": "Post tag", + "type": "array", + "items": { + "type": "string" + } } } }, + "id": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "name": { + "description": "Post name", + "type": "string", + "example": "poti" + } + } + }, + "Response-Post": { + "type": "object", + "properties": { + "data": { + "$ref": "#/definitions/Post" + }, "status": { "type": "string" } @@ -477,32 +258,7 @@ "data": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/Post" } }, "status": { diff --git a/testdata/generics_names/types/post.go b/testdata/generics_names/types/post.go new file mode 100644 index 000000000..4c57b9bfe --- /dev/null +++ b/testdata/generics_names/types/post.go @@ -0,0 +1,17 @@ +package types + +type APIBase struct { + APIUrl string `json:"@uri,omitempty"` + ID int `json:"id" example:"1" format:"int64"` +} + +type Post struct { + APIBase + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` +} // @name Post diff --git a/testdata/generics_names/web/handler.go b/testdata/generics_names/web/handler.go index 09aa7f1de..c0d89d1cf 100644 --- a/testdata/generics_names/web/handler.go +++ b/testdata/generics_names/web/handler.go @@ -26,17 +26,6 @@ type GenericResponseMulti[T any, X any] struct { Status string } // @name MultiResponse -type Post struct { - ID int `json:"id" example:"1" format:"int64"` - // Post name - Name string `json:"name" example:"poti"` - // Post data - Data struct { - // Post tag - Tag []string `json:"name"` - } `json:"data"` -} // @name Post - // APIError // @Description API error // @Description with information about it diff --git a/testdata/generics_nested/api/api.go b/testdata/generics_nested/api/api.go index 8d7f967d0..76bc06b13 100644 --- a/testdata/generics_nested/api/api.go +++ b/testdata/generics_nested/api/api.go @@ -3,6 +3,7 @@ package api import ( "net/http" + "github.com/swaggo/swag/testdata/generics_nested/types" "github.com/swaggo/swag/testdata/generics_nested/web" ) @@ -10,30 +11,30 @@ import ( // @Description Get All of the Posts // @Accept json // @Produce json -// @Param data body web.GenericNestedBody[web.GenericInnerType[web.Post]] true "Some ID" -// @Success 200 {object} web.GenericNestedResponse[web.Post] -// @Success 201 {object} web.GenericNestedResponse[web.GenericInnerType[web.Post]] -// @Success 202 {object} web.GenericNestedResponseMulti[web.Post, web.GenericInnerMultiType[web.Post, web.Post]] -// @Success 203 {object} web.GenericNestedResponseMulti[web.Post, web.GenericInnerMultiType[web.Post, web.GenericInnerType[web.Post]]] -// @Success 222 {object} web.GenericNestedResponseMulti[web.GenericInnerType[web.Post], web.Post] +// @Param data body web.GenericNestedBody[web.GenericInnerType[types.Post]] true "Some ID" +// @Success 200 {object} web.GenericNestedResponse[types.Post] +// @Success 201 {object} web.GenericNestedResponse[web.GenericInnerType[types.Post]] +// @Success 202 {object} web.GenericNestedResponseMulti[types.Post, web.GenericInnerMultiType[types.Post, types.Post]] +// @Success 203 {object} web.GenericNestedResponseMulti[types.Post, web.GenericInnerMultiType[types.Post, web.GenericInnerType[types.Post]]] +// @Success 222 {object} web.GenericNestedResponseMulti[web.GenericInnerType[types.Post], types.Post] // @Router /posts [get] func GetPosts(w http.ResponseWriter, r *http.Request) { - _ = web.GenericNestedResponse[web.Post]{} + _ = web.GenericNestedResponse[types.Post]{} } // @Summary List Posts // @Description Get All of the Posts // @Accept json // @Produce json -// @Param data body web.GenericNestedBody[web.GenericInnerType[[]web.Post]] true "Some ID" -// @Success 200 {object} web.GenericNestedResponse[[]web.Post] -// @Success 201 {object} web.GenericNestedResponse[[]web.GenericInnerType[web.Post]] -// @Success 202 {object} web.GenericNestedResponse[[]web.GenericInnerType[[]web.Post]] -// @Success 203 {object} web.GenericNestedResponseMulti[[]web.Post, web.GenericInnerMultiType[[]web.Post, web.Post]] -// @Success 204 {object} web.GenericNestedResponseMulti[[]web.Post, []web.GenericInnerMultiType[[]web.Post, web.Post]] -// @Success 205 {object} web.GenericNestedResponseMulti[web.Post, web.GenericInnerMultiType[web.Post, []web.GenericInnerType[[][]web.Post]]] -// @Success 222 {object} web.GenericNestedResponseMulti[web.GenericInnerType[[]web.Post], []web.Post] +// @Param data body web.GenericNestedBody[web.GenericInnerType[[]types.Post]] true "Some ID" +// @Success 200 {object} web.GenericNestedResponse[[]types.Post] +// @Success 201 {object} web.GenericNestedResponse[[]web.GenericInnerType[types.Post]] +// @Success 202 {object} web.GenericNestedResponse[[]web.GenericInnerType[[]types.Post]] +// @Success 203 {object} web.GenericNestedResponseMulti[[]types.Post, web.GenericInnerMultiType[[]types.Post, types.Post]] +// @Success 204 {object} web.GenericNestedResponseMulti[[]types.Post, []web.GenericInnerMultiType[[]types.Post, types.Post]] +// @Success 205 {object} web.GenericNestedResponseMulti[types.Post, web.GenericInnerMultiType[types.Post, []web.GenericInnerType[[][]types.Post]]] +// @Success 222 {object} web.GenericNestedResponseMulti[web.GenericInnerType[[]types.Post], []types.Post] // @Router /posts-multis/ [get] func GetPostArray(w http.ResponseWriter, r *http.Request) { - _ = web.GenericNestedResponse[web.Post]{} + _ = web.GenericNestedResponse[types.Post]{} } diff --git a/testdata/generics_nested/expected.json b/testdata/generics_nested/expected.json index b1bbaffc6..78ea43f9c 100644 --- a/testdata/generics_nested/expected.json +++ b/testdata/generics_nested/expected.json @@ -26,7 +26,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericNestedBody-web_GenericInnerType_web_Post" + "$ref": "#/definitions/web.GenericNestedBody-web_GenericInnerType_types_Post" } } ], @@ -34,31 +34,31 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericNestedResponse-web_Post" + "$ref": "#/definitions/web.GenericNestedResponse-types_Post" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/web.GenericNestedResponse-web_GenericInnerType_web_Post" + "$ref": "#/definitions/web.GenericNestedResponse-web_GenericInnerType_types_Post" } }, "202": { "description": "Accepted", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-web_Post-web_GenericInnerMultiType_web_Post_web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-types_Post-web_GenericInnerMultiType_types_Post_types_Post" } }, "203": { "description": "Non-Authoritative Information", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-web_Post-web_GenericInnerMultiType_web_Post_web_GenericInnerType_web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-types_Post-web_GenericInnerMultiType_types_Post_web_GenericInnerType_types_Post" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-web_GenericInnerType_web_Post-web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-web_GenericInnerType_types_Post-types_Post" } } } @@ -81,7 +81,7 @@ "in": "body", "required": true, "schema": { - "$ref": "#/definitions/web.GenericNestedBody-web_GenericInnerType_array_web_Post" + "$ref": "#/definitions/web.GenericNestedBody-web_GenericInnerType_array_types_Post" } } ], @@ -89,43 +89,43 @@ "200": { "description": "OK", "schema": { - "$ref": "#/definitions/web.GenericNestedResponse-array_web_Post" + "$ref": "#/definitions/web.GenericNestedResponse-array_types_Post" } }, "201": { "description": "Created", "schema": { - "$ref": "#/definitions/web.GenericNestedResponse-array_web_GenericInnerType_web_Post" + "$ref": "#/definitions/web.GenericNestedResponse-array_web_GenericInnerType_types_Post" } }, "202": { "description": "Accepted", "schema": { - "$ref": "#/definitions/web.GenericNestedResponse-array_web_GenericInnerType_array_web_Post" + "$ref": "#/definitions/web.GenericNestedResponse-array_web_GenericInnerType_array_types_Post" } }, "203": { "description": "Non-Authoritative Information", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-array_web_Post-web_GenericInnerMultiType_array_web_Post_web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-array_types_Post-web_GenericInnerMultiType_array_types_Post_types_Post" } }, "204": { "description": "No Content", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-array_web_Post-array_web_GenericInnerMultiType_array_web_Post_web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-array_types_Post-array_web_GenericInnerMultiType_array_types_Post_types_Post" } }, "205": { "description": "Reset Content", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-web_Post-web_GenericInnerMultiType_web_Post_array_web_GenericInnerType_array2_web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-types_Post-web_GenericInnerMultiType_types_Post_array_web_GenericInnerType_array2_types_Post" } }, "222": { "description": "", "schema": { - "$ref": "#/definitions/web.GenericNestedResponseMulti-web_GenericInnerType_array_web_Post-array_web_Post" + "$ref": "#/definitions/web.GenericNestedResponseMulti-web_GenericInnerType_array_types_Post-array_types_Post" } } } @@ -133,90 +133,162 @@ } }, "definitions": { - "web.GenericNestedBody-web_GenericInnerType_array_web_Post": { + "types.Post": { "type": "object", "properties": { - "items": { - "description": "Items from the list response", + "@uri": { + "type": "string" + }, + "data": { + "description": "Post data", "type": "object", "properties": { - "items": { - "description": "Items from the list response", + "name": { + "description": "Post tag", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "type": "string" } } } }, - "status": { - "description": "Status of some other stuff", - "type": "string" + "id": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "name": { + "description": "Post name", + "type": "string", + "example": "poti" } } }, - "web.GenericNestedBody-web_GenericInnerType_web_Post": { + "web.GenericInnerMultiType-array_types_Post-types_Post": { + "type": "object", + "properties": { + "itemOne": { + "description": "ItemsOne is the first thing", + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" + } + }, + "itemsTwo": { + "description": "ItemsTwo is the second thing", + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" + } + } + } + }, + "web.GenericInnerMultiType-types_Post-array_web_GenericInnerType_array2_types_Post": { + "type": "object", + "properties": { + "itemOne": { + "description": "ItemsOne is the first thing", + "$ref": "#/definitions/types.Post" + }, + "itemsTwo": { + "description": "ItemsTwo is the second thing", + "type": "array", + "items": { + "type": "array", + "items": { + "$ref": "#/definitions/web.GenericInnerType-array2_types_Post" + } + } + } + } + }, + "web.GenericInnerMultiType-types_Post-types_Post": { + "type": "object", + "properties": { + "itemOne": { + "description": "ItemsOne is the first thing", + "$ref": "#/definitions/types.Post" + }, + "itemsTwo": { + "description": "ItemsTwo is the second thing", + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" + } + } + } + }, + "web.GenericInnerMultiType-types_Post-web_GenericInnerType_types_Post": { + "type": "object", + "properties": { + "itemOne": { + "description": "ItemsOne is the first thing", + "$ref": "#/definitions/types.Post" + }, + "itemsTwo": { + "description": "ItemsTwo is the second thing", + "type": "array", + "items": { + "$ref": "#/definitions/web.GenericInnerType-types_Post" + } + } + } + }, + "web.GenericInnerType-array2_types_Post": { "type": "object", "properties": { "items": { "description": "Items from the list response", - "type": "object", - "properties": { + "type": "array", + "items": { + "type": "array", "items": { - "description": "Items from the list response", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } + } + } + }, + "web.GenericInnerType-array_types_Post": { + "type": "object", + "properties": { + "items": { + "description": "Items from the list response", + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" + } + } + } + }, + "web.GenericInnerType-types_Post": { + "type": "object", + "properties": { + "items": { + "description": "Items from the list response", + "$ref": "#/definitions/types.Post" + } + } + }, + "web.GenericNestedBody-web_GenericInnerType_array_types_Post": { + "type": "object", + "properties": { + "items": { + "description": "Items from the list response", + "$ref": "#/definitions/web.GenericInnerType-array_types_Post" + }, + "status": { + "description": "Status of some other stuff", + "type": "string" + } + } + }, + "web.GenericNestedBody-web_GenericInnerType_types_Post": { + "type": "object", + "properties": { + "items": { + "description": "Items from the list response", + "$ref": "#/definitions/web.GenericInnerType-types_Post" }, "status": { "description": "Status of some other stuff", @@ -224,7 +296,7 @@ } } }, - "web.GenericNestedResponse-array_web_GenericInnerType_array_web_Post": { + "web.GenericNestedResponse-array_types_Post": { "type": "object", "properties": { "items": { @@ -233,41 +305,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } + "$ref": "#/definitions/types.Post" } } }, @@ -277,7 +315,7 @@ } } }, - "web.GenericNestedResponse-array_web_GenericInnerType_web_Post": { + "web.GenericNestedResponse-array_web_GenericInnerType_array_types_Post": { "type": "object", "properties": { "items": { @@ -286,38 +324,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } + "$ref": "#/definitions/web.GenericInnerType-array_types_Post" } } }, @@ -327,7 +334,7 @@ } } }, - "web.GenericNestedResponse-array_web_Post": { + "web.GenericNestedResponse-array_web_GenericInnerType_types_Post": { "type": "object", "properties": { "items": { @@ -336,32 +343,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/web.GenericInnerType-types_Post" } } }, @@ -371,45 +353,14 @@ } } }, - "web.GenericNestedResponse-web_GenericInnerType_web_Post": { + "web.GenericNestedResponse-types_Post": { "type": "object", "properties": { "items": { "description": "Items from the list response", "type": "array", "items": { - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } + "$ref": "#/definitions/types.Post" } }, "status": { @@ -418,39 +369,14 @@ } } }, - "web.GenericNestedResponse-web_Post": { + "web.GenericNestedResponse-web_GenericInnerType_types_Post": { "type": "object", "properties": { "items": { "description": "Items from the list response", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/web.GenericInnerType-types_Post" } }, "status": { @@ -459,39 +385,14 @@ } } }, - "web.GenericNestedResponseMulti-array_web_Post-array_web_GenericInnerMultiType_array_web_Post_web_Post": { + "web.GenericNestedResponseMulti-array_types_Post-array_web_GenericInnerMultiType_array_types_Post_types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "itemsTwo": { @@ -500,73 +401,7 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "itemOne": { - "description": "ItemsOne is the first thing", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - }, - "itemsTwo": { - "description": "ItemsTwo is the second thing", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } + "$ref": "#/definitions/web.GenericInnerMultiType-array_types_Post-types_Post" } } }, @@ -576,112 +411,21 @@ } } }, - "web.GenericNestedResponseMulti-array_web_Post-web_GenericInnerMultiType_array_web_Post_web_Post": { + "web.GenericNestedResponseMulti-array_types_Post-web_GenericInnerMultiType_array_types_Post_types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "object", - "properties": { - "itemOne": { - "description": "ItemsOne is the first thing", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - }, - "itemsTwo": { - "description": "ItemsTwo is the second thing", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } + "$ref": "#/definitions/web.GenericInnerMultiType-array_types_Post-types_Post" } }, "status": { @@ -690,80 +434,18 @@ } } }, - "web.GenericNestedResponseMulti-web_GenericInnerType_array_web_Post-array_web_Post": { + "web.GenericNestedResponseMulti-types_Post-web_GenericInnerMultiType_types_Post_array_web_GenericInnerType_array2_types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } + "$ref": "#/definitions/types.Post" }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } + "$ref": "#/definitions/web.GenericInnerMultiType-types_Post-array_web_GenericInnerType_array2_types_Post" } }, "status": { @@ -772,74 +454,18 @@ } } }, - "web.GenericNestedResponseMulti-web_GenericInnerType_web_Post-web_Post": { + "web.GenericNestedResponseMulti-types_Post-web_GenericInnerMultiType_types_Post_types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } + "$ref": "#/definitions/types.Post" }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/web.GenericInnerMultiType-types_Post-types_Post" } }, "status": { @@ -848,121 +474,18 @@ } } }, - "web.GenericNestedResponseMulti-web_Post-web_GenericInnerMultiType_web_Post_array_web_GenericInnerType_array2_web_Post": { + "web.GenericNestedResponseMulti-types_Post-web_GenericInnerMultiType_types_Post_web_GenericInnerType_types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "object", - "properties": { - "itemOne": { - "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - }, - "itemsTwo": { - "description": "ItemsTwo is the second thing", - "type": "array", - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "array", - "items": { - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } - } - } - } - } - } + "$ref": "#/definitions/web.GenericInnerMultiType-types_Post-web_GenericInnerType_types_Post" } }, "status": { @@ -971,111 +494,20 @@ } } }, - "web.GenericNestedResponseMulti-web_Post-web_GenericInnerMultiType_web_Post_web_GenericInnerType_web_Post": { + "web.GenericNestedResponseMulti-web_GenericInnerType_array_types_Post-array_types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/web.GenericInnerType-array_types_Post" }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "object", - "properties": { - "itemOne": { - "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - }, - "itemsTwo": { - "description": "ItemsTwo is the second thing", - "type": "array", - "items": { - "type": "object", - "properties": { - "items": { - "description": "Items from the list response", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } - } + "type": "array", + "items": { + "$ref": "#/definitions/types.Post" } } }, @@ -1085,106 +517,18 @@ } } }, - "web.GenericNestedResponseMulti-web_Post-web_GenericInnerMultiType_web_Post_web_Post": { + "web.GenericNestedResponseMulti-web_GenericInnerType_types_Post-types_Post": { "type": "object", "properties": { "itemOne": { "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/web.GenericInnerType-types_Post" }, "itemsTwo": { "description": "ItemsTwo is the second thing", "type": "array", "items": { - "type": "object", - "properties": { - "itemOne": { - "description": "ItemsOne is the first thing", - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - }, - "itemsTwo": { - "description": "ItemsTwo is the second thing", - "type": "array", - "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } - } - } - } + "$ref": "#/definitions/types.Post" } }, "status": { diff --git a/testdata/generics_nested/types/post.go b/testdata/generics_nested/types/post.go new file mode 100644 index 000000000..f4455f42f --- /dev/null +++ b/testdata/generics_nested/types/post.go @@ -0,0 +1,17 @@ +package types + +type APIBase struct { + APIUrl string `json:"@uri,omitempty"` + ID int `json:"id" example:"1" format:"int64"` +} + +type Post struct { + APIBase + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` +} diff --git a/testdata/generics_nested/web/handler.go b/testdata/generics_nested/web/handler.go index 5740be057..9d53e91d4 100644 --- a/testdata/generics_nested/web/handler.go +++ b/testdata/generics_nested/web/handler.go @@ -50,17 +50,6 @@ type GenericNestedResponseMulti[T any, X any] struct { Status string } -type Post struct { - ID int `json:"id" example:"1" format:"int64"` - // Post name - Name string `json:"name" example:"poti"` - // Post data - Data struct { - // Post tag - Tag []string `json:"name"` - } `json:"data"` -} - // APIError // @Description API error // @Description with information about it diff --git a/testdata/generics_property/expected.json b/testdata/generics_property/expected.json index 6927fb14e..459ad0a09 100644 --- a/testdata/generics_property/expected.json +++ b/testdata/generics_property/expected.json @@ -70,64 +70,53 @@ } }, "definitions": { - "web.PostResponse": { + "types.Field-string": { "type": "object", "properties": { - "items": { + "value": { + "type": "string" + } + } + }, + "types.Post": { + "type": "object", + "properties": { + "@uri": { + "$ref": "#/definitions/types.Field-string" + }, + "data": { + "description": "Post data", "type": "object", "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, "name": { - "description": "Post name", - "type": "string", - "example": "poti" + "description": "Post tag", + "type": "array", + "items": { + "type": "string" + } } } }, + "id": { + "type": "integer", + "format": "int64", + "example": 1 + }, + "name": { + "description": "Post name", + "type": "string", + "example": "poti" + } + } + }, + "web.PostResponse": { + "type": "object", + "properties": { + "items": { + "$ref": "#/definitions/types.Post" + }, "items2": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, @@ -137,61 +126,11 @@ "items": { "type": "array", "items": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } }, "items2": { - "type": "object", - "properties": { - "data": { - "description": "Post data", - "type": "object", - "properties": { - "name": { - "description": "Post tag", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "id": { - "type": "integer", - "format": "int64", - "example": 1 - }, - "name": { - "description": "Post name", - "type": "string", - "example": "poti" - } - } + "$ref": "#/definitions/types.Post" } } }, diff --git a/testdata/generics_property/types/post.go b/testdata/generics_property/types/post.go new file mode 100644 index 000000000..84850e7ee --- /dev/null +++ b/testdata/generics_property/types/post.go @@ -0,0 +1,21 @@ +package types + +type Field[T any] struct { + Value T +} + +type APIBase struct { + APIUrl Field[string] `json:"@uri,omitempty"` + ID int `json:"id" example:"1" format:"int64"` +} + +type Post struct { + APIBase + // Post name + Name string `json:"name" example:"poti"` + // Post data + Data struct { + // Post tag + Tag []string `json:"name"` + } `json:"data"` +} diff --git a/testdata/generics_property/web/handler.go b/testdata/generics_property/web/handler.go index 2c7c1020e..a46af59eb 100644 --- a/testdata/generics_property/web/handler.go +++ b/testdata/generics_property/web/handler.go @@ -1,5 +1,7 @@ package web +import "github.com/swaggo/swag/testdata/generics_property/types" + type PostSelector func(selector func()) type Filter interface { @@ -30,11 +32,11 @@ type PostPager struct { } type PostResponse struct { - GenericResponse[Post, Post] + GenericResponse[types.Post, types.Post] } type PostResponses struct { - GenericResponse[[]Post, Post] + GenericResponse[[]types.Post, types.Post] } type StringResponse struct { @@ -45,14 +47,3 @@ type GenericResponse[T any, T2 any] struct { Items T Items2 T2 } - -type Post struct { - ID int `json:"id" example:"1" format:"int64"` - // Post name - Name string `json:"name" example:"poti"` - // Post data - Data struct { - // Post tag - Tag []string `json:"name"` - } `json:"data"` -}