adjusted negotiation logic so that it is possible to add or overwrite render logic for sepcific content-types and added/referenced a default protobuf renderer.

This commit is contained in:
kkoehler 2025-06-24 17:18:33 +02:00
parent cf4775283e
commit ac765410d3

View File

@ -1264,32 +1264,66 @@ type Negotiate struct {
TOMLData any TOMLData any
} }
// Negotiate calls different Render according to acceptable Accept format. func NewNegotiate(offered []string) Negotiate {
func (c *Context) Negotiate(code int, config Negotiate) { return Negotiate{Offered: offered}
switch c.NegotiateFormat(config.Offered...) { }
case binding.MIMEJSON: func (receiver Negotiate) WithData(data any) Negotiate {
receiver.Data = data
return receiver
}
// NegotiationRenderFunc is responsible for rendering data in a specific format.
type NegotiationRenderFunc func(status int, config Negotiate, c *Context)
func AddNegotiationRenderMapping(mimeType string, binding NegotiationRenderFunc) {
negotiationRenderMappings[mimeType] = binding
}
// All predefined negotiationRenderMappings - associate a content type
// with a NegotiationRenderFunc, which is responsible for rendering
// data in a specific format.
var negotiationRenderMappings = map[string]NegotiationRenderFunc{
binding.MIMEJSON: func(code int, config Negotiate, c *Context) {
data := chooseData(config.JSONData, config.Data) data := chooseData(config.JSONData, config.Data)
c.JSON(code, data) c.JSON(code, data)
},
case binding.MIMEHTML: binding.MIMEHTML: func(code int, config Negotiate, c *Context) {
data := chooseData(config.HTMLData, config.Data) data := chooseData(config.HTMLData, config.Data)
c.HTML(code, config.HTMLName, data) c.HTML(code, config.HTMLName, data)
},
case binding.MIMEXML: binding.MIMEXML: func(code int, config Negotiate, c *Context) {
data := chooseData(config.XMLData, config.Data) data := chooseData(config.XMLData, config.Data)
c.XML(code, data) c.XML(code, data)
},
case binding.MIMEYAML, binding.MIMEYAML2: binding.MIMEYAML: func(code int, config Negotiate, c *Context) {
data := chooseData(config.YAMLData, config.Data) data := chooseData(config.YAMLData, config.Data)
c.YAML(code, data) c.YAML(code, data)
},
case binding.MIMETOML: binding.MIMEYAML2: func(code int, config Negotiate, c *Context) {
data := chooseData(config.YAMLData, config.Data)
c.YAML(code, data)
},
binding.MIMETOML: func(code int, config Negotiate, c *Context) {
data := chooseData(config.TOMLData, config.Data) data := chooseData(config.TOMLData, config.Data)
c.TOML(code, data) c.TOML(code, data)
},
default: binding.MIMEPROTOBUF: func(code int, config Negotiate, c *Context) {
c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) //nolint: errcheck c.ProtoBuf(code, config.Data)
},
} }
// Negotiate calls different Render according to acceptable Accept format.
func (c *Context) Negotiate(code int, config Negotiate) {
accepted := c.NegotiateFormat(config.Offered...)
for bind, fn := range negotiationRenderMappings {
if bind == accepted {
fn(code, config, c)
return
}
}
c.AbortWithError(http.StatusNotAcceptable, errors.New("the accepted formats are not offered by the server")) //nolint: errcheck
} }
// NegotiateFormat returns an acceptable Accept format. // NegotiateFormat returns an acceptable Accept format.