diff --git a/openapi/entities.go b/openapi/entities.go index a553b93..9b658a5 100644 --- a/openapi/entities.go +++ b/openapi/entities.go @@ -10,6 +10,8 @@ type ContentUnit struct { IsDefault bool // IsDefault indicates if this content unit is the default response. Description string // Description provides a description for the content unit. + + Encoding map[string]string // Encoding maps property names to content types } // Contact represents contact information for the API. diff --git a/operation.go b/operation.go index d33067c..b6089c1 100644 --- a/operation.go +++ b/operation.go @@ -8,6 +8,8 @@ import ( specopenapi "github.com/oaswrap/spec/openapi" "github.com/oaswrap/spec/option" "github.com/swaggest/openapi-go" + "github.com/swaggest/openapi-go/openapi3" + "github.com/swaggest/openapi-go/openapi31" ) var _ operationContext = (*operationContextImpl)(nil) @@ -81,6 +83,28 @@ func (oc *operationContextImpl) build() openapi.OperationContext { return oc.op } +func stringMapToEncodingMap3(enc map[string]string) map[string]openapi3.Encoding { + res := map[string]openapi3.Encoding{} + for k, v := range enc { + rv := v + res[k] = openapi3.Encoding{ + ContentType: &rv, + } + } + return res +} + +func stringMapToEncodingMap31(enc map[string]string) map[string]openapi31.Encoding { + res := map[string]openapi31.Encoding{} + for k, v := range enc { + rv := v + res[k] = openapi31.Encoding{ + ContentType: &rv, + } + } + return res +} + func (oc *operationContextImpl) buildRequestOpts(req *specopenapi.ContentUnit) ([]openapi.ContentOption, string) { log := fmt.Sprintf("%T", req.Structure) var opts []openapi.ContentOption @@ -94,6 +118,24 @@ func (oc *operationContextImpl) buildRequestOpts(req *specopenapi.ContentUnit) ( opts = append(opts, openapi.WithContentType(req.ContentType)) log += fmt.Sprintf(" (Content-Type: %s)", req.ContentType) } + opts = append(opts, func(cu *openapi.ContentUnit) { + cu.Customize = func(cor openapi.ContentOrReference) { + switch v := cor.(type) { + case *openapi3.RequestBodyOrRef: + content := map[string]openapi3.MediaType{} + for k, val := range v.RequestBody.Content { + content[k] = *val.WithEncoding(stringMapToEncodingMap3(req.Encoding)) + } + v.RequestBody.WithContent(content) + case *openapi31.RequestBodyOrReference: + content := map[string]openapi31.MediaType{} + for k, val := range v.RequestBody.Content { + content[k] = *val.WithEncoding(stringMapToEncodingMap31(req.Encoding)) + } + v.RequestBody.WithContent(content) + } + } + }) return opts, log } diff --git a/option/content.go b/option/content.go index a4e3fbe..8c93367 100644 --- a/option/content.go +++ b/option/content.go @@ -28,3 +28,12 @@ func ContentDefault(isDefault ...bool) ContentOption { cu.IsDefault = util.Optional(true, isDefault...) } } + +func ContentEncoding(prop, enc string) ContentOption { + return func(cu *openapi.ContentUnit) { + if cu.Encoding == nil { + cu.Encoding = map[string]string{} + } + cu.Encoding[prop] = enc + } +}