File: content.go

package info (click to toggle)
golang-github-getkin-kin-openapi 0.124.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 4,288 kB
  • sloc: sh: 344; makefile: 4
file content (124 lines) | stat: -rw-r--r-- 3,201 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package openapi3

import (
	"context"
	"sort"
	"strings"
)

// Content is specified by OpenAPI/Swagger 3.0 standard.
type Content map[string]*MediaType

func NewContent() Content {
	return make(map[string]*MediaType)
}

func NewContentWithSchema(schema *Schema, consumes []string) Content {
	if len(consumes) == 0 {
		return Content{
			"*/*": NewMediaType().WithSchema(schema),
		}
	}
	content := make(map[string]*MediaType, len(consumes))
	for _, mediaType := range consumes {
		content[mediaType] = NewMediaType().WithSchema(schema)
	}
	return content
}

func NewContentWithSchemaRef(schema *SchemaRef, consumes []string) Content {
	if len(consumes) == 0 {
		return Content{
			"*/*": NewMediaType().WithSchemaRef(schema),
		}
	}
	content := make(map[string]*MediaType, len(consumes))
	for _, mediaType := range consumes {
		content[mediaType] = NewMediaType().WithSchemaRef(schema)
	}
	return content
}

func NewContentWithJSONSchema(schema *Schema) Content {
	return Content{
		"application/json": NewMediaType().WithSchema(schema),
	}
}
func NewContentWithJSONSchemaRef(schema *SchemaRef) Content {
	return Content{
		"application/json": NewMediaType().WithSchemaRef(schema),
	}
}

func NewContentWithFormDataSchema(schema *Schema) Content {
	return Content{
		"multipart/form-data": NewMediaType().WithSchema(schema),
	}
}

func NewContentWithFormDataSchemaRef(schema *SchemaRef) Content {
	return Content{
		"multipart/form-data": NewMediaType().WithSchemaRef(schema),
	}
}

func (content Content) Get(mime string) *MediaType {
	// If the mime is empty then short-circuit to the wildcard.
	// We do this here so that we catch only the specific case of
	// and empty mime rather than a present, but invalid, mime type.
	if mime == "" {
		return content["*/*"]
	}
	// Start by making the most specific match possible
	// by using the mime type in full.
	if v := content[mime]; v != nil {
		return v
	}
	// If an exact match is not found then we strip all
	// metadata from the mime type and only use the x/y
	// portion.
	i := strings.IndexByte(mime, ';')
	if i < 0 {
		// If there is no metadata then preserve the full mime type
		// string for later wildcard searches.
		i = len(mime)
	}
	mime = mime[:i]
	if v := content[mime]; v != nil {
		return v
	}
	// If the x/y pattern has no specific match then we
	// try the x/* pattern.
	i = strings.IndexByte(mime, '/')
	if i < 0 {
		// In the case that the given mime type is not valid because it is
		// missing the subtype we return nil so that this does not accidentally
		// resolve with the wildcard.
		return nil
	}
	mime = mime[:i] + "/*"
	if v := content[mime]; v != nil {
		return v
	}
	// Finally, the most generic match of */* is returned
	// as a catch-all.
	return content["*/*"]
}

// Validate returns an error if Content does not comply with the OpenAPI spec.
func (content Content) Validate(ctx context.Context, opts ...ValidationOption) error {
	ctx = WithValidationOptions(ctx, opts...)

	keys := make([]string, 0, len(content))
	for key := range content {
		keys = append(keys, key)
	}
	sort.Strings(keys)
	for _, k := range keys {
		v := content[k]
		if err := v.Validate(ctx); err != nil {
			return err
		}
	}
	return nil
}