diff --git a/internal/test/issues/issue-removed-external-ref/config.base.yaml b/internal/test/issues/issue-removed-external-ref/config.base.yaml new file mode 100644 index 000000000..17d4d2f08 --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/config.base.yaml @@ -0,0 +1,12 @@ +--- +package: spec_base +generate: + chi-server: true + strict-server: true + models: true +import-mapping: + spec-ext.yaml: "github.com/deepmap/oapi-codegen/internal/test/issues/issue-removed-external-ref/gen/spec_ext" +output: gen/spec_base/issue.gen.go +output-options: + skip-prune: true + # skip-fmt: true diff --git a/internal/test/issues/issue-removed-external-ref/config.ext.yaml b/internal/test/issues/issue-removed-external-ref/config.ext.yaml new file mode 100644 index 000000000..9d0478065 --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/config.ext.yaml @@ -0,0 +1,10 @@ +--- +package: spec_ext +generate: + chi-server: true + strict-server: true + models: true +output: gen/spec_ext/issue.gen.go +output-options: + skip-prune: true + # skip-fmt: true diff --git a/internal/test/issues/issue-removed-external-ref/doc.go b/internal/test/issues/issue-removed-external-ref/doc.go new file mode 100644 index 000000000..7cb5ab0d8 --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/doc.go @@ -0,0 +1,4 @@ +package head_digit_of_httpheader + +//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.ext.yaml spec-ext.yaml +//go:generate go run github.com/deepmap/oapi-codegen/cmd/oapi-codegen --config=config.base.yaml spec-base.yaml diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_base/.gitempty b/internal/test/issues/issue-removed-external-ref/gen/spec_base/.gitempty new file mode 100644 index 000000000..e69de29bb diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go new file mode 100644 index 000000000..61ae3ee99 --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/gen/spec_base/issue.gen.go @@ -0,0 +1,323 @@ +// Package spec_base provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT. +package spec_base + +import ( + "context" + "encoding/json" + "fmt" + "net/http" + + externalRef0 "github.com/deepmap/oapi-codegen/internal/test/issues/issue-removed-external-ref/gen/spec_ext" + "github.com/go-chi/chi/v5" +) + +// DirectBar defines model for DirectBar. +type DirectBar = externalRef0.Foo + +// PackedBar defines model for PackedBar. +type PackedBar struct { + Core *externalRef0.Foo `json:"core,omitempty"` + Directd *DirectBar `json:"directd,omitempty"` + Id *string `json:"id,omitempty"` +} + +// ServerInterface represents all server handlers. +type ServerInterface interface { + + // (POST /invalidExtRefTrouble) + PostInvalidExtRefTrouble(w http.ResponseWriter, r *http.Request) + + // (POST /noTrouble) + PostNoTrouble(w http.ResponseWriter, r *http.Request) +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +type MiddlewareFunc func(http.Handler) http.Handler + +// PostInvalidExtRefTrouble operation middleware +func (siw *ServerInterfaceWrapper) PostInvalidExtRefTrouble(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.PostInvalidExtRefTrouble(w, r) + }) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +// PostNoTrouble operation middleware +func (siw *ServerInterfaceWrapper) PostNoTrouble(w http.ResponseWriter, r *http.Request) { + ctx := r.Context() + + var handler http.Handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + siw.Handler.PostNoTrouble(w, r) + }) + + for _, middleware := range siw.HandlerMiddlewares { + handler = middleware(handler) + } + + handler.ServeHTTP(w, r.WithContext(ctx)) +} + +type UnescapedCookieParamError struct { + ParamName string + Err error +} + +func (e *UnescapedCookieParamError) Error() string { + return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) +} + +func (e *UnescapedCookieParamError) Unwrap() error { + return e.Err +} + +type UnmarshalingParamError struct { + ParamName string + Err error +} + +func (e *UnmarshalingParamError) Error() string { + return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) +} + +func (e *UnmarshalingParamError) Unwrap() error { + return e.Err +} + +type RequiredParamError struct { + ParamName string +} + +func (e *RequiredParamError) Error() string { + return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) +} + +type RequiredHeaderError struct { + ParamName string + Err error +} + +func (e *RequiredHeaderError) Error() string { + return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) +} + +func (e *RequiredHeaderError) Unwrap() error { + return e.Err +} + +type InvalidParamFormatError struct { + ParamName string + Err error +} + +func (e *InvalidParamFormatError) Error() string { + return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) +} + +func (e *InvalidParamFormatError) Unwrap() error { + return e.Err +} + +type TooManyValuesForParamError struct { + ParamName string + Count int +} + +func (e *TooManyValuesForParamError) Error() string { + return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) +} + +// Handler creates http.Handler with routing matching OpenAPI spec. +func Handler(si ServerInterface) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + Middlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. +func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + if options.ErrorHandlerFunc == nil { + options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + wrapper := ServerInterfaceWrapper{ + Handler: si, + HandlerMiddlewares: options.Middlewares, + ErrorHandlerFunc: options.ErrorHandlerFunc, + } + + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/invalidExtRefTrouble", wrapper.PostInvalidExtRefTrouble) + }) + r.Group(func(r chi.Router) { + r.Post(options.BaseURL+"/noTrouble", wrapper.PostNoTrouble) + }) + + return r +} + +type PostInvalidExtRefTroubleRequestObject struct { +} + +type PostInvalidExtRefTroubleResponseObject interface { + VisitPostInvalidExtRefTroubleResponse(w http.ResponseWriter) error +} + +type PostInvalidExtRefTrouble300JSONResponse struct { + externalRef0.PascalJSONResponse +} + +func (response PostInvalidExtRefTrouble300JSONResponse) VisitPostInvalidExtRefTroubleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(300) + + return json.NewEncoder(w).Encode(response) +} + +type PostNoTroubleRequestObject struct { +} + +type PostNoTroubleResponseObject interface { + VisitPostNoTroubleResponse(w http.ResponseWriter) error +} + +type PostNoTrouble200JSONResponse struct { + DirectBar *DirectBar `json:"directBar,omitempty"` + DirectFoo *externalRef0.Foo `json:"directFoo,omitempty"` + IndirectFoo *PackedBar `json:"indirectFoo,omitempty"` + Name *string `json:"name,omitempty"` +} + +func (response PostNoTrouble200JSONResponse) VisitPostNoTroubleResponse(w http.ResponseWriter) error { + w.Header().Set("Content-Type", "application/json") + w.WriteHeader(200) + + return json.NewEncoder(w).Encode(response) +} + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { + + // (POST /invalidExtRefTrouble) + PostInvalidExtRefTrouble(ctx context.Context, request PostInvalidExtRefTroubleRequestObject) (PostInvalidExtRefTroubleResponseObject, error) + + // (POST /noTrouble) + PostNoTrouble(ctx context.Context, request PostNoTroubleRequestObject) (PostNoTroubleResponseObject, error) +} + +type StrictHandlerFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request, args interface{}) (interface{}, error) + +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc + +type StrictHTTPServerOptions struct { + RequestErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) + ResponseErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictHTTPServerOptions{ + RequestErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + }, + ResponseErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} +} + +type strictHandler struct { + ssi StrictServerInterface + middlewares []StrictMiddlewareFunc + options StrictHTTPServerOptions +} + +// PostInvalidExtRefTrouble operation middleware +func (sh *strictHandler) PostInvalidExtRefTrouble(w http.ResponseWriter, r *http.Request) { + var request PostInvalidExtRefTroubleRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.PostInvalidExtRefTrouble(ctx, request.(PostInvalidExtRefTroubleRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "PostInvalidExtRefTrouble") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(PostInvalidExtRefTroubleResponseObject); ok { + if err := validResponse.VisitPostInvalidExtRefTroubleResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("Unexpected response type: %T", response)) + } +} + +// PostNoTrouble operation middleware +func (sh *strictHandler) PostNoTrouble(w http.ResponseWriter, r *http.Request) { + var request PostNoTroubleRequestObject + + handler := func(ctx context.Context, w http.ResponseWriter, r *http.Request, request interface{}) (interface{}, error) { + return sh.ssi.PostNoTrouble(ctx, request.(PostNoTroubleRequestObject)) + } + for _, middleware := range sh.middlewares { + handler = middleware(handler, "PostNoTrouble") + } + + response, err := handler(r.Context(), w, r, request) + + if err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } else if validResponse, ok := response.(PostNoTroubleResponseObject); ok { + if err := validResponse.VisitPostNoTroubleResponse(w); err != nil { + sh.options.ResponseErrorHandlerFunc(w, r, err) + } + } else if response != nil { + sh.options.ResponseErrorHandlerFunc(w, r, fmt.Errorf("Unexpected response type: %T", response)) + } +} diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_ext/.gitempty b/internal/test/issues/issue-removed-external-ref/gen/spec_ext/.gitempty new file mode 100644 index 000000000..e69de29bb diff --git a/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go b/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go new file mode 100644 index 000000000..0240f04ae --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/gen/spec_ext/issue.gen.go @@ -0,0 +1,192 @@ +// Package spec_ext provides primitives to interact with the openapi HTTP API. +// +// Code generated by github.com/deepmap/oapi-codegen version (devel) DO NOT EDIT. +package spec_ext + +import ( + "context" + "fmt" + "net/http" + + "github.com/go-chi/chi/v5" +) + +// CamelSchema defines model for CamelSchema. +type CamelSchema struct { + Id *string `json:"id,omitempty"` +} + +// Foo defines model for Foo. +type Foo struct { + CamelSchema *CamelSchema `json:"CamelSchema,omitempty"` + InternalAttr *string `json:"internalAttr,omitempty"` + PascalSchema *PascalSchema `json:"pascalSchema,omitempty"` +} + +// PascalSchema defines model for pascalSchema. +type PascalSchema struct { + Id *string `json:"id,omitempty"` +} + +// Pascal defines model for pascal. +type Pascal = PascalSchema + +// ServerInterface represents all server handlers. +type ServerInterface interface { +} + +// ServerInterfaceWrapper converts contexts to parameters. +type ServerInterfaceWrapper struct { + Handler ServerInterface + HandlerMiddlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +type MiddlewareFunc func(http.Handler) http.Handler + +type UnescapedCookieParamError struct { + ParamName string + Err error +} + +func (e *UnescapedCookieParamError) Error() string { + return fmt.Sprintf("error unescaping cookie parameter '%s'", e.ParamName) +} + +func (e *UnescapedCookieParamError) Unwrap() error { + return e.Err +} + +type UnmarshalingParamError struct { + ParamName string + Err error +} + +func (e *UnmarshalingParamError) Error() string { + return fmt.Sprintf("Error unmarshaling parameter %s as JSON: %s", e.ParamName, e.Err.Error()) +} + +func (e *UnmarshalingParamError) Unwrap() error { + return e.Err +} + +type RequiredParamError struct { + ParamName string +} + +func (e *RequiredParamError) Error() string { + return fmt.Sprintf("Query argument %s is required, but not found", e.ParamName) +} + +type RequiredHeaderError struct { + ParamName string + Err error +} + +func (e *RequiredHeaderError) Error() string { + return fmt.Sprintf("Header parameter %s is required, but not found", e.ParamName) +} + +func (e *RequiredHeaderError) Unwrap() error { + return e.Err +} + +type InvalidParamFormatError struct { + ParamName string + Err error +} + +func (e *InvalidParamFormatError) Error() string { + return fmt.Sprintf("Invalid format for parameter %s: %s", e.ParamName, e.Err.Error()) +} + +func (e *InvalidParamFormatError) Unwrap() error { + return e.Err +} + +type TooManyValuesForParamError struct { + ParamName string + Count int +} + +func (e *TooManyValuesForParamError) Error() string { + return fmt.Sprintf("Expected one value for %s, got %d", e.ParamName, e.Count) +} + +// Handler creates http.Handler with routing matching OpenAPI spec. +func Handler(si ServerInterface) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{}) +} + +type ChiServerOptions struct { + BaseURL string + BaseRouter chi.Router + Middlewares []MiddlewareFunc + ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +// HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux. +func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseRouter: r, + }) +} + +func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler { + return HandlerWithOptions(si, ChiServerOptions{ + BaseURL: baseURL, + BaseRouter: r, + }) +} + +// HandlerWithOptions creates http.Handler with additional options +func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler { + r := options.BaseRouter + + if r == nil { + r = chi.NewRouter() + } + if options.ErrorHandlerFunc == nil { + options.ErrorHandlerFunc = func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + } + } + + return r +} + +type PascalJSONResponse PascalSchema + +// StrictServerInterface represents all server handlers. +type StrictServerInterface interface { +} + +type StrictHandlerFunc func(ctx context.Context, w http.ResponseWriter, r *http.Request, args interface{}) (interface{}, error) + +type StrictMiddlewareFunc func(f StrictHandlerFunc, operationID string) StrictHandlerFunc + +type StrictHTTPServerOptions struct { + RequestErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) + ResponseErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error) +} + +func NewStrictHandler(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares, options: StrictHTTPServerOptions{ + RequestErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusBadRequest) + }, + ResponseErrorHandlerFunc: func(w http.ResponseWriter, r *http.Request, err error) { + http.Error(w, err.Error(), http.StatusInternalServerError) + }, + }} +} + +func NewStrictHandlerWithOptions(ssi StrictServerInterface, middlewares []StrictMiddlewareFunc, options StrictHTTPServerOptions) ServerInterface { + return &strictHandler{ssi: ssi, middlewares: middlewares, options: options} +} + +type strictHandler struct { + ssi StrictServerInterface + middlewares []StrictMiddlewareFunc + options StrictHTTPServerOptions +} diff --git a/internal/test/issues/issue-removed-external-ref/spec-base.yaml b/internal/test/issues/issue-removed-external-ref/spec-base.yaml new file mode 100644 index 000000000..36f285cc3 --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/spec-base.yaml @@ -0,0 +1,41 @@ +eopenapi: 3.0.2 +info: + version: "0.0.1" +paths: + /noTrouble: + post: + responses: + 200: + description: ... + content: + application/json: + schema: + type: object + properties: + directFoo: + $ref: "spec-ext.yaml#/components/schemas/Foo" + directBar: + $ref: "#/components/schemas/DirectBar" + indirectFoo: + $ref: "#/components/schemas/PackedBar" + name: + type: string + /invalidExtRefTrouble: + post: + responses: + 300: + $ref: "spec-ext.yaml#/components/responses/pascal" + +components: + schemas: + DirectBar: + $ref: "spec-ext.yaml#/components/schemas/Foo" + PackedBar: + type: object + properties: + id: + type: string + core: + $ref: "spec-ext.yaml#/components/schemas/Foo" + directd: + $ref: "#/components/schemas/DirectBar" diff --git a/internal/test/issues/issue-removed-external-ref/spec-ext.yaml b/internal/test/issues/issue-removed-external-ref/spec-ext.yaml new file mode 100644 index 000000000..4fd3b4ed3 --- /dev/null +++ b/internal/test/issues/issue-removed-external-ref/spec-ext.yaml @@ -0,0 +1,30 @@ +openapi: 3.0.2 +info: + version: "0.0.1" +components: + schemas: + CamelSchema: + type: object + properties: + id: + type: string + pascalSchema: + type: object + properties: + id: + type: string + Foo: + type: object + properties: + internalAttr: + type: string + CamelSchema: + $ref: "#/components/schemas/CamelSchema" + pascalSchema: + $ref: "#/components/schemas/pascalSchema" + responses: + "pascal": + content: + application/json: + schema: + $ref: "#/components/schemas/pascalSchema" diff --git a/internal/test/strict-server/chi/server.gen.go b/internal/test/strict-server/chi/server.gen.go index 1004665c4..124c057d2 100644 --- a/internal/test/strict-server/chi/server.gen.go +++ b/internal/test/strict-server/chi/server.gen.go @@ -561,7 +561,7 @@ type ReusableResponsesResponseObject interface { VisitReusableResponsesResponse(w http.ResponseWriter) error } -type ReusableResponses200JSONResponse = ReusableresponseJSONResponse +type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(w http.ResponseWriter) error { w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) diff --git a/internal/test/strict-server/chi/server.go b/internal/test/strict-server/chi/server.go index 7c8ae2b76..5b7026809 100644 --- a/internal/test/strict-server/chi/server.go +++ b/internal/test/strict-server/chi/server.go @@ -98,5 +98,5 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample } func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { - return ReusableResponses200JSONResponse{Body: *request.Body}, nil + return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/echo/server.gen.go b/internal/test/strict-server/echo/server.gen.go index 3002b2ae0..46531bd8a 100644 --- a/internal/test/strict-server/echo/server.gen.go +++ b/internal/test/strict-server/echo/server.gen.go @@ -387,7 +387,7 @@ type ReusableResponsesResponseObject interface { VisitReusableResponsesResponse(w http.ResponseWriter) error } -type ReusableResponses200JSONResponse = ReusableresponseJSONResponse +type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(w http.ResponseWriter) error { w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) diff --git a/internal/test/strict-server/echo/server.go b/internal/test/strict-server/echo/server.go index 748fc7d02..d4007e010 100644 --- a/internal/test/strict-server/echo/server.go +++ b/internal/test/strict-server/echo/server.go @@ -98,5 +98,5 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample } func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { - return ReusableResponses200JSONResponse{Body: *request.Body}, nil + return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/internal/test/strict-server/gin/server.gen.go b/internal/test/strict-server/gin/server.gen.go index 837cb70ab..91ecba08f 100644 --- a/internal/test/strict-server/gin/server.gen.go +++ b/internal/test/strict-server/gin/server.gen.go @@ -421,7 +421,7 @@ type ReusableResponsesResponseObject interface { VisitReusableResponsesResponse(w http.ResponseWriter) error } -type ReusableResponses200JSONResponse = ReusableresponseJSONResponse +type ReusableResponses200JSONResponse struct{ ReusableresponseJSONResponse } func (response ReusableResponses200JSONResponse) VisitReusableResponsesResponse(w http.ResponseWriter) error { w.Header().Set("header1", fmt.Sprint(response.Headers.Header1)) diff --git a/internal/test/strict-server/gin/server.go b/internal/test/strict-server/gin/server.go index 7c8ae2b76..5b7026809 100644 --- a/internal/test/strict-server/gin/server.go +++ b/internal/test/strict-server/gin/server.go @@ -98,5 +98,5 @@ func (s StrictServer) HeadersExample(ctx context.Context, request HeadersExample } func (s StrictServer) ReusableResponses(ctx context.Context, request ReusableResponsesRequestObject) (ReusableResponsesResponseObject, error) { - return ReusableResponses200JSONResponse{Body: *request.Body}, nil + return ReusableResponses200JSONResponse{ReusableresponseJSONResponse: ReusableresponseJSONResponse{Body: *request.Body}}, nil } diff --git a/pkg/codegen/template_helpers.go b/pkg/codegen/template_helpers.go index 54b42dbf2..266a77e49 100644 --- a/pkg/codegen/template_helpers.go +++ b/pkg/codegen/template_helpers.go @@ -278,6 +278,7 @@ var TemplateFunctions = template.FuncMap{ "swaggerUriToGorillaUri": SwaggerUriToGorillaUri, "lcFirst": LowercaseFirstCharacter, "ucFirst": UppercaseFirstCharacter, + "ucFirstWithPkgName": UppercaseFirstCharacterWithPkgName, "camelCase": ToCamelCase, "genResponsePayload": genResponsePayload, "genResponseTypeName": genResponseTypeName, diff --git a/pkg/codegen/templates/strict/strict-interface.tmpl b/pkg/codegen/templates/strict/strict-interface.tmpl index 8a435babe..1911f56e8 100644 --- a/pkg/codegen/templates/strict/strict-interface.tmpl +++ b/pkg/codegen/templates/strict/strict-interface.tmpl @@ -25,7 +25,7 @@ {{$hasHeaders := ne 0 (len .Headers) -}} {{$fixedStatusCode := .HasFixedStatusCode -}} {{$isRef := .IsRef -}} - {{$ref := .Ref | ucFirst -}} + {{$ref := .Ref | ucFirstWithPkgName -}} {{$headers := .Headers -}} {{if (and $hasHeaders (not $isRef)) -}} @@ -37,12 +37,13 @@ {{end}} {{range .Contents}} + {{$receiverTypeName := printf "%s%s%s%s" $opid $statusCode .NameTagOrContentType "Response"}} {{if and $fixedStatusCode $isRef -}} - type {{$opid}}{{$statusCode}}{{.NameTagOrContentType}}Response = {{$ref}}{{.NameTagOrContentType}}Response + type {{$receiverTypeName}} struct{ {{$ref}}{{.NameTagOrContentType}}Response } {{else if and (not $hasHeaders) ($fixedStatusCode) (.IsSupported) -}} - type {{$opid}}{{$statusCode}}{{.NameTagOrContentType}}Response {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{if .Schema.IsRef}}={{end}} {{.Schema.TypeDecl}}{{else}}io.Reader{{end}} + type {{$receiverTypeName}} {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{if .Schema.IsRef}}={{end}} {{.Schema.TypeDecl}}{{else}}io.Reader{{end}} {{else -}} - type {{$opid}}{{$statusCode}}{{.NameTagOrContentType}}Response struct { + type {{$receiverTypeName}} struct { Body {{if eq .NameTag "Multipart"}}func(writer *multipart.Writer)error{{else if .IsSupported}}{{.Schema.TypeDecl}}{{else}}io.Reader{{end}} {{if $hasHeaders -}} Headers {{if $isRef}}{{$ref}}{{else}}{{$opid}}{{$statusCode}}{{end}}ResponseHeaders @@ -62,7 +63,7 @@ } {{end}} - func (response {{$opid}}{{$statusCode}}{{.NameTagOrContentType}}Response) Visit{{$opid}}Response(w http.ResponseWriter) error { + func (response {{$receiverTypeName}}) Visit{{$opid}}Response(w http.ResponseWriter) error { {{range $headers -}} w.Header().Set("{{.Name}}", fmt.Sprint(response.Headers.{{.GoName}})) {{end -}} diff --git a/pkg/codegen/utils.go b/pkg/codegen/utils.go index c538f1b4a..165ae8374 100644 --- a/pkg/codegen/utils.go +++ b/pkg/codegen/utils.go @@ -104,6 +104,24 @@ func UppercaseFirstCharacter(str string) string { return string(runes) } +// Uppercase the first character in a identifier with pkg name. This assumes UTF-8, so we have +// to be careful with unicode, don't treat it as a byte array. +func UppercaseFirstCharacterWithPkgName(str string) string { + if str == "" { + return "" + } + + segs := strings.Split(str, ".") + var prefix string + if len(segs) == 2 { + prefix = segs[0] + "." + str = segs[1] + } + runes := []rune(str) + runes[0] = unicode.ToUpper(runes[0]) + return prefix + string(runes) +} + // LowercaseFirstCharacter Lowercases the first character in a string. This assumes UTF-8, so we have // to be careful with unicode, don't treat it as a byte array. func LowercaseFirstCharacter(str string) string {