diff --git a/openapi2/openapi2.go b/openapi2/openapi2.go index 167bc572a..032b4204e 100644 --- a/openapi2/openapi2.go +++ b/openapi2/openapi2.go @@ -29,10 +29,12 @@ type T struct { Tags openapi3.Tags `json:"tags,omitempty" yaml:"tags,omitempty"` } +// MarshalJSON returns the JSON encoding of T. func (doc *T) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(doc) } +// UnmarshalJSON sets T to a copy of data. func (doc *T) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, doc) } @@ -64,10 +66,12 @@ type PathItem struct { Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"` } +// MarshalJSON returns the JSON encoding of PathItem. func (pathItem *PathItem) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(pathItem) } +// UnmarshalJSON sets PathItem to a copy of data. func (pathItem *PathItem) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, pathItem) } @@ -155,10 +159,12 @@ type Operation struct { Security *SecurityRequirements `json:"security,omitempty" yaml:"security,omitempty"` } +// MarshalJSON returns the JSON encoding of Operation. func (operation *Operation) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(operation) } +// UnmarshalJSON sets Operation to a copy of data. func (operation *Operation) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, operation) } @@ -207,10 +213,12 @@ type Parameter struct { Default interface{} `json:"default,omitempty" yaml:"default,omitempty"` } +// MarshalJSON returns the JSON encoding of Parameter. func (parameter *Parameter) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(parameter) } +// UnmarshalJSON sets Parameter to a copy of data. func (parameter *Parameter) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, parameter) } @@ -224,10 +232,12 @@ type Response struct { Examples map[string]interface{} `json:"examples,omitempty" yaml:"examples,omitempty"` } +// MarshalJSON returns the JSON encoding of Response. func (response *Response) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(response) } +// UnmarshalJSON sets Response to a copy of data. func (response *Response) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, response) } @@ -236,10 +246,12 @@ type Header struct { Parameter } +// MarshalJSON returns the JSON encoding of Header. func (header *Header) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(header) } +// UnmarshalJSON sets Header to a copy of data. func (header *Header) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, header) } @@ -260,10 +272,12 @@ type SecurityScheme struct { Tags openapi3.Tags `json:"tags,omitempty" yaml:"tags,omitempty"` } +// MarshalJSON returns the JSON encoding of SecurityScheme. func (securityScheme *SecurityScheme) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(securityScheme) } +// UnmarshalJSON sets SecurityScheme to a copy of data. func (securityScheme *SecurityScheme) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, securityScheme) } diff --git a/openapi3/callback.go b/openapi3/callback.go index 5f883c1c9..718f47c1e 100644 --- a/openapi3/callback.go +++ b/openapi3/callback.go @@ -11,6 +11,7 @@ type Callbacks map[string]*CallbackRef var _ jsonpointer.JSONPointable = (*Callbacks)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (c Callbacks) JSONLookup(token string) (interface{}, error) { ref, ok := c[token] if ref == nil || !ok { @@ -27,8 +28,9 @@ func (c Callbacks) JSONLookup(token string) (interface{}, error) { // See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#callbackObject type Callback map[string]*PathItem -func (value Callback) Validate(ctx context.Context) error { - for _, v := range value { +// Validate returns an error if Callback does not comply with the OpenAPI spec. +func (callback Callback) Validate(ctx context.Context) error { + for _, v := range callback { if err := v.Validate(ctx); err != nil { return err } diff --git a/openapi3/components.go b/openapi3/components.go index 6d4fe8086..2f19943db 100644 --- a/openapi3/components.go +++ b/openapi3/components.go @@ -28,14 +28,17 @@ func NewComponents() Components { return Components{} } +// MarshalJSON returns the JSON encoding of Components. func (components *Components) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(components) } +// UnmarshalJSON sets Components to a copy of data. func (components *Components) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, components) } +// Validate returns an error if Components does not comply with the OpenAPI spec. func (components *Components) Validate(ctx context.Context) (err error) { for k, v := range components.Schemas { if err = ValidateIdentifier(k); err != nil { diff --git a/openapi3/content.go b/openapi3/content.go index 5edb7d3fa..10e3e6009 100644 --- a/openapi3/content.go +++ b/openapi3/content.go @@ -104,9 +104,9 @@ func (content Content) Get(mime string) *MediaType { return content["*/*"] } -func (value Content) Validate(ctx context.Context) error { - for _, v := range value { - // Validate MediaType +// Validate returns an error if Content does not comply with the OpenAPI spec. +func (content Content) Validate(ctx context.Context) error { + for _, v := range content { if err := v.Validate(ctx); err != nil { return err } diff --git a/openapi3/discriminator.go b/openapi3/discriminator.go index 5e181a291..4cc4df903 100644 --- a/openapi3/discriminator.go +++ b/openapi3/discriminator.go @@ -15,14 +15,17 @@ type Discriminator struct { Mapping map[string]string `json:"mapping,omitempty" yaml:"mapping,omitempty"` } -func (value *Discriminator) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) +// MarshalJSON returns the JSON encoding of Discriminator. +func (discriminator *Discriminator) MarshalJSON() ([]byte, error) { + return jsoninfo.MarshalStrictStruct(discriminator) } -func (value *Discriminator) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets Discriminator to a copy of data. +func (discriminator *Discriminator) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, discriminator) } -func (value *Discriminator) Validate(ctx context.Context) error { +// Validate returns an error if Discriminator does not comply with the OpenAPI spec. +func (discriminator *Discriminator) Validate(ctx context.Context) error { return nil } diff --git a/openapi3/encoding.go b/openapi3/encoding.go index b0dab7be0..e6453ecc1 100644 --- a/openapi3/encoding.go +++ b/openapi3/encoding.go @@ -39,10 +39,12 @@ func (encoding *Encoding) WithHeaderRef(name string, ref *HeaderRef) *Encoding { return encoding } +// MarshalJSON returns the JSON encoding of Encoding. func (encoding *Encoding) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(encoding) } +// UnmarshalJSON sets Encoding to a copy of data. func (encoding *Encoding) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, encoding) } @@ -62,11 +64,12 @@ func (encoding *Encoding) SerializationMethod() *SerializationMethod { return sm } -func (value *Encoding) Validate(ctx context.Context) error { - if value == nil { +// Validate returns an error if Encoding does not comply with the OpenAPI spec. +func (encoding *Encoding) Validate(ctx context.Context) error { + if encoding == nil { return nil } - for k, v := range value.Headers { + for k, v := range encoding.Headers { if err := ValidateIdentifier(k); err != nil { return nil } @@ -76,7 +79,7 @@ func (value *Encoding) Validate(ctx context.Context) error { } // Validate a media types's serialization method. - sm := value.SerializationMethod() + sm := encoding.SerializationMethod() switch { case sm.Style == SerializationForm && sm.Explode, sm.Style == SerializationForm && !sm.Explode, diff --git a/openapi3/example.go b/openapi3/example.go index 19cceb4d9..080845cad 100644 --- a/openapi3/example.go +++ b/openapi3/example.go @@ -12,6 +12,7 @@ type Examples map[string]*ExampleRef var _ jsonpointer.JSONPointable = (*Examples)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (e Examples) JSONLookup(token string) (interface{}, error) { ref, ok := e[token] if ref == nil || !ok { @@ -41,14 +42,17 @@ func NewExample(value interface{}) *Example { } } +// MarshalJSON returns the JSON encoding of Example. func (example *Example) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(example) } +// UnmarshalJSON sets Example to a copy of data. func (example *Example) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, example) } -func (value *Example) Validate(ctx context.Context) error { +// Validate returns an error if Example does not comply with the OpenAPI spec. +func (example *Example) Validate(ctx context.Context) error { return nil // TODO } diff --git a/openapi3/external_docs.go b/openapi3/external_docs.go index bb9dd5a89..17a38eec0 100644 --- a/openapi3/external_docs.go +++ b/openapi3/external_docs.go @@ -18,14 +18,17 @@ type ExternalDocs struct { URL string `json:"url,omitempty" yaml:"url,omitempty"` } +// MarshalJSON returns the JSON encoding of ExternalDocs. func (e *ExternalDocs) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(e) } +// UnmarshalJSON sets ExternalDocs to a copy of data. func (e *ExternalDocs) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, e) } +// Validate returns an error if ExternalDocs does not comply with the OpenAPI spec. func (e *ExternalDocs) Validate(ctx context.Context) error { if e.URL == "" { return errors.New("url is required") diff --git a/openapi3/header.go b/openapi3/header.go index 9adb5ac35..84ffd8866 100644 --- a/openapi3/header.go +++ b/openapi3/header.go @@ -13,6 +13,7 @@ type Headers map[string]*HeaderRef var _ jsonpointer.JSONPointable = (*Headers)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (h Headers) JSONLookup(token string) (interface{}, error) { ref, ok := h[token] if ref == nil || !ok { @@ -33,33 +34,35 @@ type Header struct { var _ jsonpointer.JSONPointable = (*Header)(nil) -func (value *Header) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets Header to a copy of data. +func (header *Header) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, header) } // SerializationMethod returns a header's serialization method. -func (value *Header) SerializationMethod() (*SerializationMethod, error) { - style := value.Style +func (header *Header) SerializationMethod() (*SerializationMethod, error) { + style := header.Style if style == "" { style = SerializationSimple } explode := false - if value.Explode != nil { - explode = *value.Explode + if header.Explode != nil { + explode = *header.Explode } return &SerializationMethod{Style: style, Explode: explode}, nil } -func (value *Header) Validate(ctx context.Context) error { - if value.Name != "" { +// Validate returns an error if Header does not comply with the OpenAPI spec. +func (header *Header) Validate(ctx context.Context) error { + if header.Name != "" { return errors.New("header 'name' MUST NOT be specified, it is given in the corresponding headers map") } - if value.In != "" { + if header.In != "" { return errors.New("header 'in' MUST NOT be specified, it is implicitly in header") } // Validate a parameter's serialization method. - sm, err := value.SerializationMethod() + sm, err := header.SerializationMethod() if err != nil { return err } @@ -70,17 +73,17 @@ func (value *Header) Validate(ctx context.Context) error { return fmt.Errorf("header schema is invalid: %v", e) } - if (value.Schema == nil) == (value.Content == nil) { - e := fmt.Errorf("parameter must contain exactly one of content and schema: %v", value) + if (header.Schema == nil) == (header.Content == nil) { + e := fmt.Errorf("parameter must contain exactly one of content and schema: %v", header) return fmt.Errorf("header schema is invalid: %v", e) } - if schema := value.Schema; schema != nil { + if schema := header.Schema; schema != nil { if err := schema.Validate(ctx); err != nil { return fmt.Errorf("header schema is invalid: %v", err) } } - if content := value.Content; content != nil { + if content := header.Content; content != nil { if err := content.Validate(ctx); err != nil { return fmt.Errorf("header content is invalid: %v", err) } @@ -88,41 +91,42 @@ func (value *Header) Validate(ctx context.Context) error { return nil } -func (value Header) JSONLookup(token string) (interface{}, error) { +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable +func (header Header) JSONLookup(token string) (interface{}, error) { switch token { case "schema": - if value.Schema != nil { - if value.Schema.Ref != "" { - return &Ref{Ref: value.Schema.Ref}, nil + if header.Schema != nil { + if header.Schema.Ref != "" { + return &Ref{Ref: header.Schema.Ref}, nil } - return value.Schema.Value, nil + return header.Schema.Value, nil } case "name": - return value.Name, nil + return header.Name, nil case "in": - return value.In, nil + return header.In, nil case "description": - return value.Description, nil + return header.Description, nil case "style": - return value.Style, nil + return header.Style, nil case "explode": - return value.Explode, nil + return header.Explode, nil case "allowEmptyValue": - return value.AllowEmptyValue, nil + return header.AllowEmptyValue, nil case "allowReserved": - return value.AllowReserved, nil + return header.AllowReserved, nil case "deprecated": - return value.Deprecated, nil + return header.Deprecated, nil case "required": - return value.Required, nil + return header.Required, nil case "example": - return value.Example, nil + return header.Example, nil case "examples": - return value.Examples, nil + return header.Examples, nil case "content": - return value.Content, nil + return header.Content, nil } - v, _, err := jsonpointer.GetForToken(value.ExtensionProps, token) + v, _, err := jsonpointer.GetForToken(header.ExtensionProps, token) return v, err } diff --git a/openapi3/info.go b/openapi3/info.go index 6b41589b5..e60f8882f 100644 --- a/openapi3/info.go +++ b/openapi3/info.go @@ -20,32 +20,35 @@ type Info struct { Version string `json:"version" yaml:"version"` // Required } -func (value *Info) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) +// MarshalJSON returns the JSON encoding of Info. +func (info *Info) MarshalJSON() ([]byte, error) { + return jsoninfo.MarshalStrictStruct(info) } -func (value *Info) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets Info to a copy of data. +func (info *Info) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, info) } -func (value *Info) Validate(ctx context.Context) error { - if contact := value.Contact; contact != nil { +// Validate returns an error if Info does not comply with the OpenAPI spec. +func (info *Info) Validate(ctx context.Context) error { + if contact := info.Contact; contact != nil { if err := contact.Validate(ctx); err != nil { return err } } - if license := value.License; license != nil { + if license := info.License; license != nil { if err := license.Validate(ctx); err != nil { return err } } - if value.Version == "" { + if info.Version == "" { return errors.New("value of version must be a non-empty string") } - if value.Title == "" { + if info.Title == "" { return errors.New("value of title must be a non-empty string") } @@ -62,15 +65,18 @@ type Contact struct { Email string `json:"email,omitempty" yaml:"email,omitempty"` } -func (value *Contact) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) +// MarshalJSON returns the JSON encoding of Contact. +func (contact *Contact) MarshalJSON() ([]byte, error) { + return jsoninfo.MarshalStrictStruct(contact) } -func (value *Contact) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets Contact to a copy of data. +func (contact *Contact) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, contact) } -func (value *Contact) Validate(ctx context.Context) error { +// Validate returns an error if Contact does not comply with the OpenAPI spec. +func (contact *Contact) Validate(ctx context.Context) error { return nil } @@ -83,16 +89,19 @@ type License struct { URL string `json:"url,omitempty" yaml:"url,omitempty"` } -func (value *License) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) +// MarshalJSON returns the JSON encoding of License. +func (license *License) MarshalJSON() ([]byte, error) { + return jsoninfo.MarshalStrictStruct(license) } -func (value *License) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets License to a copy of data. +func (license *License) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, license) } -func (value *License) Validate(ctx context.Context) error { - if value.Name == "" { +// Validate returns an error if License does not comply with the OpenAPI spec. +func (license *License) Validate(ctx context.Context) error { + if license.Name == "" { return errors.New("value of license name must be a non-empty string") } return nil diff --git a/openapi3/link.go b/openapi3/link.go index 19a725a86..2f0bc57c9 100644 --- a/openapi3/link.go +++ b/openapi3/link.go @@ -11,8 +11,9 @@ import ( type Links map[string]*LinkRef -func (l Links) JSONLookup(token string) (interface{}, error) { - ref, ok := l[token] +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable +func (links Links) JSONLookup(token string) (interface{}, error) { + ref, ok := links[token] if ok == false { return nil, fmt.Errorf("object has no field %q", token) } @@ -38,20 +39,23 @@ type Link struct { RequestBody interface{} `json:"requestBody,omitempty" yaml:"requestBody,omitempty"` } -func (value *Link) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) +// MarshalJSON returns the JSON encoding of Link. +func (link *Link) MarshalJSON() ([]byte, error) { + return jsoninfo.MarshalStrictStruct(link) } -func (value *Link) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets Link to a copy of data. +func (link *Link) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, link) } -func (value *Link) Validate(ctx context.Context) error { - if value.OperationID == "" && value.OperationRef == "" { +// Validate returns an error if Link does not comply with the OpenAPI spec. +func (link *Link) Validate(ctx context.Context) error { + if link.OperationID == "" && link.OperationRef == "" { return errors.New("missing operationId or operationRef on link") } - if value.OperationID != "" && value.OperationRef != "" { - return fmt.Errorf("operationId %q and operationRef %q are mutually exclusive", value.OperationID, value.OperationRef) + if link.OperationID != "" && link.OperationRef != "" { + return fmt.Errorf("operationId %q and operationRef %q are mutually exclusive", link.OperationID, link.OperationRef) } return nil } diff --git a/openapi3/media_type.go b/openapi3/media_type.go index 5c001ca64..dd33b99b2 100644 --- a/openapi3/media_type.go +++ b/openapi3/media_type.go @@ -60,19 +60,22 @@ func (mediaType *MediaType) WithEncoding(name string, enc *Encoding) *MediaType return mediaType } +// MarshalJSON returns the JSON encoding of MediaType. func (mediaType *MediaType) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(mediaType) } +// UnmarshalJSON sets MediaType to a copy of data. func (mediaType *MediaType) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, mediaType) } -func (value *MediaType) Validate(ctx context.Context) error { - if value == nil { +// Validate returns an error if MediaType does not comply with the OpenAPI spec. +func (mediaType *MediaType) Validate(ctx context.Context) error { + if mediaType == nil { return nil } - if schema := value.Schema; schema != nil { + if schema := mediaType.Schema; schema != nil { if err := schema.Validate(ctx); err != nil { return err } @@ -80,6 +83,7 @@ func (value *MediaType) Validate(ctx context.Context) error { return nil } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (mediaType MediaType) JSONLookup(token string) (interface{}, error) { switch token { case "schema": diff --git a/openapi3/openapi3.go b/openapi3/openapi3.go index d376812b5..c0188c25a 100644 --- a/openapi3/openapi3.go +++ b/openapi3/openapi3.go @@ -23,10 +23,12 @@ type T struct { ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"` } +// MarshalJSON returns the JSON encoding of T. func (doc *T) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(doc) } +// UnmarshalJSON sets T to a copy of data. func (doc *T) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, doc) } @@ -49,8 +51,9 @@ func (doc *T) AddServer(server *Server) { doc.Servers = append(doc.Servers, server) } -func (value *T) Validate(ctx context.Context) error { - if value.OpenAPI == "" { +// Validate returns an error if T does not comply with the OpenAPI spec. +func (doc *T) Validate(ctx context.Context) error { + if doc.OpenAPI == "" { return errors.New("value of openapi must be a non-empty string") } @@ -58,14 +61,14 @@ func (value *T) Validate(ctx context.Context) error { { wrap := func(e error) error { return fmt.Errorf("invalid components: %v", e) } - if err := value.Components.Validate(ctx); err != nil { + if err := doc.Components.Validate(ctx); err != nil { return wrap(err) } } { wrap := func(e error) error { return fmt.Errorf("invalid info: %v", e) } - if v := value.Info; v != nil { + if v := doc.Info; v != nil { if err := v.Validate(ctx); err != nil { return wrap(err) } @@ -76,7 +79,7 @@ func (value *T) Validate(ctx context.Context) error { { wrap := func(e error) error { return fmt.Errorf("invalid paths: %v", e) } - if v := value.Paths; v != nil { + if v := doc.Paths; v != nil { if err := v.Validate(ctx); err != nil { return wrap(err) } @@ -87,7 +90,7 @@ func (value *T) Validate(ctx context.Context) error { { wrap := func(e error) error { return fmt.Errorf("invalid security: %v", e) } - if v := value.Security; v != nil { + if v := doc.Security; v != nil { if err := v.Validate(ctx); err != nil { return wrap(err) } @@ -96,7 +99,7 @@ func (value *T) Validate(ctx context.Context) error { { wrap := func(e error) error { return fmt.Errorf("invalid servers: %v", e) } - if v := value.Servers; v != nil { + if v := doc.Servers; v != nil { if err := v.Validate(ctx); err != nil { return wrap(err) } @@ -105,7 +108,7 @@ func (value *T) Validate(ctx context.Context) error { { wrap := func(e error) error { return fmt.Errorf("invalid tags: %w", e) } - if v := value.Tags; v != nil { + if v := doc.Tags; v != nil { if err := v.Validate(ctx); err != nil { return wrap(err) } @@ -114,7 +117,7 @@ func (value *T) Validate(ctx context.Context) error { { wrap := func(e error) error { return fmt.Errorf("invalid external docs: %w", e) } - if v := value.ExternalDocs; v != nil { + if v := doc.ExternalDocs; v != nil { if err := v.Validate(ctx); err != nil { return wrap(err) } diff --git a/openapi3/operation.go b/openapi3/operation.go index 29e70c774..cb9644a77 100644 --- a/openapi3/operation.go +++ b/openapi3/operation.go @@ -56,14 +56,17 @@ func NewOperation() *Operation { return &Operation{} } +// MarshalJSON returns the JSON encoding of Operation. func (operation *Operation) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(operation) } +// UnmarshalJSON sets Operation to a copy of data. func (operation *Operation) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, operation) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (operation Operation) JSONLookup(token string) (interface{}, error) { switch token { case "requestBody": @@ -122,25 +125,26 @@ func (operation *Operation) AddResponse(status int, response *Response) { } } -func (value *Operation) Validate(ctx context.Context) error { - if v := value.Parameters; v != nil { +// Validate returns an error if Operation does not comply with the OpenAPI spec. +func (operation *Operation) Validate(ctx context.Context) error { + if v := operation.Parameters; v != nil { if err := v.Validate(ctx); err != nil { return err } } - if v := value.RequestBody; v != nil { + if v := operation.RequestBody; v != nil { if err := v.Validate(ctx); err != nil { return err } } - if v := value.Responses; v != nil { + if v := operation.Responses; v != nil { if err := v.Validate(ctx); err != nil { return err } } else { return errors.New("value of responses must be an object") } - if v := value.ExternalDocs; v != nil { + if v := operation.ExternalDocs; v != nil { if err := v.Validate(ctx); err != nil { return fmt.Errorf("invalid external docs: %w", err) } diff --git a/openapi3/parameter.go b/openapi3/parameter.go index e283a98fb..b32898c65 100644 --- a/openapi3/parameter.go +++ b/openapi3/parameter.go @@ -14,6 +14,7 @@ type ParametersMap map[string]*ParameterRef var _ jsonpointer.JSONPointable = (*ParametersMap)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (p ParametersMap) JSONLookup(token string) (interface{}, error) { ref, ok := p[token] if ref == nil || ok == false { @@ -31,6 +32,7 @@ type Parameters []*ParameterRef var _ jsonpointer.JSONPointable = (*Parameters)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (p Parameters) JSONLookup(token string) (interface{}, error) { index, err := strconv.Atoi(token) if err != nil { @@ -64,9 +66,10 @@ func (parameters Parameters) GetByInAndName(in string, name string) *Parameter { return nil } -func (value Parameters) Validate(ctx context.Context) error { +// Validate returns an error if Parameters does not comply with the OpenAPI spec. +func (parameters Parameters) Validate(ctx context.Context) error { dupes := make(map[string]struct{}) - for _, item := range value { + for _, item := range parameters { if v := item.Value; v != nil { key := v.In + ":" + v.Name if _, ok := dupes[key]; ok { @@ -161,50 +164,53 @@ func (parameter *Parameter) WithSchema(value *Schema) *Parameter { return parameter } +// MarshalJSON returns the JSON encoding of Parameter. func (parameter *Parameter) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(parameter) } +// UnmarshalJSON sets Parameter to a copy of data. func (parameter *Parameter) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, parameter) } -func (value Parameter) JSONLookup(token string) (interface{}, error) { +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable +func (parameter Parameter) JSONLookup(token string) (interface{}, error) { switch token { case "schema": - if value.Schema != nil { - if value.Schema.Ref != "" { - return &Ref{Ref: value.Schema.Ref}, nil + if parameter.Schema != nil { + if parameter.Schema.Ref != "" { + return &Ref{Ref: parameter.Schema.Ref}, nil } - return value.Schema.Value, nil + return parameter.Schema.Value, nil } case "name": - return value.Name, nil + return parameter.Name, nil case "in": - return value.In, nil + return parameter.In, nil case "description": - return value.Description, nil + return parameter.Description, nil case "style": - return value.Style, nil + return parameter.Style, nil case "explode": - return value.Explode, nil + return parameter.Explode, nil case "allowEmptyValue": - return value.AllowEmptyValue, nil + return parameter.AllowEmptyValue, nil case "allowReserved": - return value.AllowReserved, nil + return parameter.AllowReserved, nil case "deprecated": - return value.Deprecated, nil + return parameter.Deprecated, nil case "required": - return value.Required, nil + return parameter.Required, nil case "example": - return value.Example, nil + return parameter.Example, nil case "examples": - return value.Examples, nil + return parameter.Examples, nil case "content": - return value.Content, nil + return parameter.Content, nil } - v, _, err := jsonpointer.GetForToken(value.ExtensionProps, token) + v, _, err := jsonpointer.GetForToken(parameter.ExtensionProps, token) return v, err } @@ -238,11 +244,12 @@ func (parameter *Parameter) SerializationMethod() (*SerializationMethod, error) } } -func (value *Parameter) Validate(ctx context.Context) error { - if value.Name == "" { +// Validate returns an error if Parameter does not comply with the OpenAPI spec. +func (parameter *Parameter) Validate(ctx context.Context) error { + if parameter.Name == "" { return errors.New("parameter name can't be blank") } - in := value.In + in := parameter.In switch in { case ParameterInPath, @@ -250,60 +257,60 @@ func (value *Parameter) Validate(ctx context.Context) error { ParameterInHeader, ParameterInCookie: default: - return fmt.Errorf("parameter can't have 'in' value %q", value.In) + return fmt.Errorf("parameter can't have 'in' value %q", parameter.In) } - if in == ParameterInPath && !value.Required { - return fmt.Errorf("path parameter %q must be required", value.Name) + if in == ParameterInPath && !parameter.Required { + return fmt.Errorf("path parameter %q must be required", parameter.Name) } // Validate a parameter's serialization method. - sm, err := value.SerializationMethod() + sm, err := parameter.SerializationMethod() if err != nil { return err } var smSupported bool switch { - case value.In == ParameterInPath && sm.Style == SerializationSimple && !sm.Explode, - value.In == ParameterInPath && sm.Style == SerializationSimple && sm.Explode, - value.In == ParameterInPath && sm.Style == SerializationLabel && !sm.Explode, - value.In == ParameterInPath && sm.Style == SerializationLabel && sm.Explode, - value.In == ParameterInPath && sm.Style == SerializationMatrix && !sm.Explode, - value.In == ParameterInPath && sm.Style == SerializationMatrix && sm.Explode, - - value.In == ParameterInQuery && sm.Style == SerializationForm && sm.Explode, - value.In == ParameterInQuery && sm.Style == SerializationForm && !sm.Explode, - value.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && sm.Explode, - value.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && !sm.Explode, - value.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && sm.Explode, - value.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && !sm.Explode, - value.In == ParameterInQuery && sm.Style == SerializationDeepObject && sm.Explode, - - value.In == ParameterInHeader && sm.Style == SerializationSimple && !sm.Explode, - value.In == ParameterInHeader && sm.Style == SerializationSimple && sm.Explode, - - value.In == ParameterInCookie && sm.Style == SerializationForm && !sm.Explode, - value.In == ParameterInCookie && sm.Style == SerializationForm && sm.Explode: + case parameter.In == ParameterInPath && sm.Style == SerializationSimple && !sm.Explode, + parameter.In == ParameterInPath && sm.Style == SerializationSimple && sm.Explode, + parameter.In == ParameterInPath && sm.Style == SerializationLabel && !sm.Explode, + parameter.In == ParameterInPath && sm.Style == SerializationLabel && sm.Explode, + parameter.In == ParameterInPath && sm.Style == SerializationMatrix && !sm.Explode, + parameter.In == ParameterInPath && sm.Style == SerializationMatrix && sm.Explode, + + parameter.In == ParameterInQuery && sm.Style == SerializationForm && sm.Explode, + parameter.In == ParameterInQuery && sm.Style == SerializationForm && !sm.Explode, + parameter.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && sm.Explode, + parameter.In == ParameterInQuery && sm.Style == SerializationSpaceDelimited && !sm.Explode, + parameter.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && sm.Explode, + parameter.In == ParameterInQuery && sm.Style == SerializationPipeDelimited && !sm.Explode, + parameter.In == ParameterInQuery && sm.Style == SerializationDeepObject && sm.Explode, + + parameter.In == ParameterInHeader && sm.Style == SerializationSimple && !sm.Explode, + parameter.In == ParameterInHeader && sm.Style == SerializationSimple && sm.Explode, + + parameter.In == ParameterInCookie && sm.Style == SerializationForm && !sm.Explode, + parameter.In == ParameterInCookie && sm.Style == SerializationForm && sm.Explode: smSupported = true } if !smSupported { e := fmt.Errorf("serialization method with style=%q and explode=%v is not supported by a %s parameter", sm.Style, sm.Explode, in) - return fmt.Errorf("parameter %q schema is invalid: %v", value.Name, e) + return fmt.Errorf("parameter %q schema is invalid: %v", parameter.Name, e) } - if (value.Schema == nil) == (value.Content == nil) { + if (parameter.Schema == nil) == (parameter.Content == nil) { e := errors.New("parameter must contain exactly one of content and schema") - return fmt.Errorf("parameter %q schema is invalid: %v", value.Name, e) + return fmt.Errorf("parameter %q schema is invalid: %v", parameter.Name, e) } - if schema := value.Schema; schema != nil { + if schema := parameter.Schema; schema != nil { if err := schema.Validate(ctx); err != nil { - return fmt.Errorf("parameter %q schema is invalid: %v", value.Name, err) + return fmt.Errorf("parameter %q schema is invalid: %v", parameter.Name, err) } } - if content := value.Content; content != nil { + if content := parameter.Content; content != nil { if err := content.Validate(ctx); err != nil { - return fmt.Errorf("parameter %q content is invalid: %v", value.Name, err) + return fmt.Errorf("parameter %q content is invalid: %v", parameter.Name, err) } } return nil diff --git a/openapi3/path_item.go b/openapi3/path_item.go index 4473d639d..6a8cc7336 100644 --- a/openapi3/path_item.go +++ b/openapi3/path_item.go @@ -29,10 +29,12 @@ type PathItem struct { Parameters Parameters `json:"parameters,omitempty" yaml:"parameters,omitempty"` } +// MarshalJSON returns the JSON encoding of PathItem. func (pathItem *PathItem) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(pathItem) } +// UnmarshalJSON sets PathItem to a copy of data. func (pathItem *PathItem) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, pathItem) } @@ -119,8 +121,9 @@ func (pathItem *PathItem) SetOperation(method string, operation *Operation) { } } -func (value *PathItem) Validate(ctx context.Context) error { - for _, operation := range value.Operations() { +// Validate returns an error if PathItem does not comply with the OpenAPI spec. +func (pathItem *PathItem) Validate(ctx context.Context) error { + for _, operation := range pathItem.Operations() { if err := operation.Validate(ctx); err != nil { return err } diff --git a/openapi3/paths.go b/openapi3/paths.go index 24ab5f300..b4ebe582a 100644 --- a/openapi3/paths.go +++ b/openapi3/paths.go @@ -10,16 +10,17 @@ import ( // See https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#paths-object type Paths map[string]*PathItem -func (value Paths) Validate(ctx context.Context) error { +// Validate returns an error if Paths does not comply with the OpenAPI spec. +func (paths Paths) Validate(ctx context.Context) error { normalizedPaths := make(map[string]string) - for path, pathItem := range value { + for path, pathItem := range paths { if path == "" || path[0] != '/' { return fmt.Errorf("path %q does not start with a forward slash (/)", path) } if pathItem == nil { - value[path] = &PathItem{} - pathItem = value[path] + paths[path] = &PathItem{} + pathItem = paths[path] } normalizedPath, _, varsInPath := normalizeTemplatedPath(path) @@ -84,7 +85,7 @@ func (value Paths) Validate(ctx context.Context) error { } } - if err := value.validateUniqueOperationIDs(); err != nil { + if err := paths.validateUniqueOperationIDs(); err != nil { return err } @@ -120,9 +121,9 @@ func (paths Paths) Find(key string) *PathItem { return nil } -func (value Paths) validateUniqueOperationIDs() error { +func (paths Paths) validateUniqueOperationIDs() error { operationIDs := make(map[string]string) - for urlPath, pathItem := range value { + for urlPath, pathItem := range paths { if pathItem == nil { continue } diff --git a/openapi3/refs.go b/openapi3/refs.go index 333cd1740..a706834ca 100644 --- a/openapi3/refs.go +++ b/openapi3/refs.go @@ -22,14 +22,17 @@ type CallbackRef struct { var _ jsonpointer.JSONPointable = (*CallbackRef)(nil) +// MarshalJSON returns the JSON encoding of CallbackRef. func (value *CallbackRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets CallbackRef to a copy of data. func (value *CallbackRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if CallbackRef does not comply with the OpenAPI spec. func (value *CallbackRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -37,6 +40,7 @@ func (value *CallbackRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value CallbackRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -55,14 +59,17 @@ type ExampleRef struct { var _ jsonpointer.JSONPointable = (*ExampleRef)(nil) +// MarshalJSON returns the JSON encoding of ExampleRef. func (value *ExampleRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets ExampleRef to a copy of data. func (value *ExampleRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if ExampleRef does not comply with the OpenAPI spec. func (value *ExampleRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -70,6 +77,7 @@ func (value *ExampleRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value ExampleRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -88,14 +96,17 @@ type HeaderRef struct { var _ jsonpointer.JSONPointable = (*HeaderRef)(nil) +// MarshalJSON returns the JSON encoding of HeaderRef. func (value *HeaderRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets HeaderRef to a copy of data. func (value *HeaderRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if HeaderRef does not comply with the OpenAPI spec. func (value *HeaderRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -103,6 +114,7 @@ func (value *HeaderRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value HeaderRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -119,14 +131,17 @@ type LinkRef struct { Value *Link } +// MarshalJSON returns the JSON encoding of LinkRef. func (value *LinkRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets LinkRef to a copy of data. func (value *LinkRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if LinkRef does not comply with the OpenAPI spec. func (value *LinkRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -143,14 +158,17 @@ type ParameterRef struct { var _ jsonpointer.JSONPointable = (*ParameterRef)(nil) +// MarshalJSON returns the JSON encoding of ParameterRef. func (value *ParameterRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets ParameterRef to a copy of data. func (value *ParameterRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if ParameterRef does not comply with the OpenAPI spec. func (value *ParameterRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -158,6 +176,7 @@ func (value *ParameterRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value ParameterRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -176,14 +195,17 @@ type ResponseRef struct { var _ jsonpointer.JSONPointable = (*ResponseRef)(nil) +// MarshalJSON returns the JSON encoding of ResponseRef. func (value *ResponseRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets ResponseRef to a copy of data. func (value *ResponseRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if ResponseRef does not comply with the OpenAPI spec. func (value *ResponseRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -191,6 +213,7 @@ func (value *ResponseRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value ResponseRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -209,14 +232,17 @@ type RequestBodyRef struct { var _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil) +// MarshalJSON returns the JSON encoding of RequestBodyRef. func (value *RequestBodyRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets RequestBodyRef to a copy of data. func (value *RequestBodyRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if RequestBodyRef does not comply with the OpenAPI spec. func (value *RequestBodyRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -224,6 +250,7 @@ func (value *RequestBodyRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value RequestBodyRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -249,14 +276,17 @@ func NewSchemaRef(ref string, value *Schema) *SchemaRef { } } +// MarshalJSON returns the JSON encoding of SchemaRef. func (value *SchemaRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets SchemaRef to a copy of data. func (value *SchemaRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if SchemaRef does not comply with the OpenAPI spec. func (value *SchemaRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -264,6 +294,7 @@ func (value *SchemaRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value SchemaRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil @@ -282,14 +313,17 @@ type SecuritySchemeRef struct { var _ jsonpointer.JSONPointable = (*SecuritySchemeRef)(nil) +// MarshalJSON returns the JSON encoding of SecuritySchemeRef. func (value *SecuritySchemeRef) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalRef(value.Ref, value.Value) } +// UnmarshalJSON sets SecuritySchemeRef to a copy of data. func (value *SecuritySchemeRef) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalRef(data, &value.Ref, &value.Value) } +// Validate returns an error if SecuritySchemeRef does not comply with the OpenAPI spec. func (value *SecuritySchemeRef) Validate(ctx context.Context) error { if v := value.Value; v != nil { return v.Validate(ctx) @@ -297,6 +331,7 @@ func (value *SecuritySchemeRef) Validate(ctx context.Context) error { return foundUnresolvedRef(value.Ref) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (value SecuritySchemeRef) JSONLookup(token string) (interface{}, error) { if token == "$ref" { return value.Ref, nil diff --git a/openapi3/request_body.go b/openapi3/request_body.go index 0be098c0b..559eb7122 100644 --- a/openapi3/request_body.go +++ b/openapi3/request_body.go @@ -13,6 +13,7 @@ type RequestBodies map[string]*RequestBodyRef var _ jsonpointer.JSONPointable = (*RequestBodyRef)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (r RequestBodies) JSONLookup(token string) (interface{}, error) { ref, ok := r[token] if ok == false { @@ -92,17 +93,20 @@ func (requestBody *RequestBody) GetMediaType(mediaType string) *MediaType { return m[mediaType] } +// MarshalJSON returns the JSON encoding of RequestBody. func (requestBody *RequestBody) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(requestBody) } +// UnmarshalJSON sets RequestBody to a copy of data. func (requestBody *RequestBody) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, requestBody) } -func (value *RequestBody) Validate(ctx context.Context) error { - if value.Content == nil { +// Validate returns an error if RequestBody does not comply with the OpenAPI spec. +func (requestBody *RequestBody) Validate(ctx context.Context) error { + if requestBody.Content == nil { return errors.New("content of the request body is required") } - return value.Content.Validate(ctx) + return requestBody.Content.Validate(ctx) } diff --git a/openapi3/response.go b/openapi3/response.go index 8e22698f6..23e2f4449 100644 --- a/openapi3/response.go +++ b/openapi3/response.go @@ -30,11 +30,12 @@ func (responses Responses) Get(status int) *ResponseRef { return responses[strconv.FormatInt(int64(status), 10)] } -func (value Responses) Validate(ctx context.Context) error { - if len(value) == 0 { +// Validate returns an error if Responses does not comply with the OpenAPI spec. +func (responses Responses) Validate(ctx context.Context) error { + if len(responses) == 0 { return errors.New("the responses object MUST contain at least one response code") } - for _, v := range value { + for _, v := range responses { if err := v.Validate(ctx); err != nil { return err } @@ -42,6 +43,7 @@ func (value Responses) Validate(ctx context.Context) error { return nil } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (responses Responses) JSONLookup(token string) (interface{}, error) { ref, ok := responses[token] if ok == false { @@ -89,31 +91,34 @@ func (response *Response) WithJSONSchemaRef(schema *SchemaRef) *Response { return response } +// MarshalJSON returns the JSON encoding of Response. func (response *Response) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(response) } +// UnmarshalJSON sets Response to a copy of data. func (response *Response) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, response) } -func (value *Response) Validate(ctx context.Context) error { - if value.Description == nil { +// Validate returns an error if Response does not comply with the OpenAPI spec. +func (response *Response) Validate(ctx context.Context) error { + if response.Description == nil { return errors.New("a short description of the response is required") } - if content := value.Content; content != nil { + if content := response.Content; content != nil { if err := content.Validate(ctx); err != nil { return err } } - for _, header := range value.Headers { + for _, header := range response.Headers { if err := header.Validate(ctx); err != nil { return err } } - for _, link := range value.Links { + for _, link := range response.Links { if err := link.Validate(ctx); err != nil { return err } diff --git a/openapi3/schema.go b/openapi3/schema.go index ee21bc21b..45350eced 100644 --- a/openapi3/schema.go +++ b/openapi3/schema.go @@ -67,6 +67,7 @@ type Schemas map[string]*SchemaRef var _ jsonpointer.JSONPointable = (*Schemas)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (s Schemas) JSONLookup(token string) (interface{}, error) { ref, ok := s[token] if ref == nil || ok == false { @@ -83,6 +84,7 @@ type SchemaRefs []*SchemaRef var _ jsonpointer.JSONPointable = (*SchemaRefs)(nil) +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (s SchemaRefs) JSONLookup(token string) (interface{}, error) { i, err := strconv.ParseUint(token, 10, 64) if err != nil { @@ -164,14 +166,17 @@ func NewSchema() *Schema { return &Schema{} } +// MarshalJSON returns the JSON encoding of Schema. func (schema *Schema) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(schema) } +// UnmarshalJSON sets Schema to a copy of data. func (schema *Schema) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, schema) } +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (schema Schema) JSONLookup(token string) (interface{}, error) { switch token { case "additionalProperties": @@ -588,8 +593,9 @@ func (schema *Schema) IsEmpty() bool { return true } -func (value *Schema) Validate(ctx context.Context) error { - return value.validate(ctx, []*Schema{}) +// Validate returns an error if Schema does not comply with the OpenAPI spec. +func (schema *Schema) Validate(ctx context.Context) error { + return schema.validate(ctx, []*Schema{}) } func (schema *Schema) validate(ctx context.Context, stack []*Schema) (err error) { diff --git a/openapi3/security_requirements.go b/openapi3/security_requirements.go index df6b6b2d1..42d832552 100644 --- a/openapi3/security_requirements.go +++ b/openapi3/security_requirements.go @@ -15,8 +15,9 @@ func (srs *SecurityRequirements) With(securityRequirement SecurityRequirement) * return srs } -func (value SecurityRequirements) Validate(ctx context.Context) error { - for _, item := range value { +// Validate returns an error if SecurityRequirements does not comply with the OpenAPI spec. +func (srs SecurityRequirements) Validate(ctx context.Context) error { + for _, item := range srs { if err := item.Validate(ctx); err != nil { return err } @@ -40,6 +41,7 @@ func (security SecurityRequirement) Authenticate(provider string, scopes ...stri return security } -func (value SecurityRequirement) Validate(ctx context.Context) error { +// Validate returns an error if SecurityRequirement does not comply with the OpenAPI spec. +func (security *SecurityRequirement) Validate(ctx context.Context) error { return nil } diff --git a/openapi3/security_scheme.go b/openapi3/security_scheme.go index 9b89fb950..10057de6b 100644 --- a/openapi3/security_scheme.go +++ b/openapi3/security_scheme.go @@ -11,6 +11,7 @@ import ( type SecuritySchemes map[string]*SecuritySchemeRef +// JSONLookup implements github.com/go-openapi/jsonpointer#JSONPointable func (s SecuritySchemes) JSONLookup(token string) (interface{}, error) { ref, ok := s[token] if ref == nil || ok == false { @@ -67,10 +68,12 @@ func NewJWTSecurityScheme() *SecurityScheme { } } +// MarshalJSON returns the JSON encoding of SecurityScheme. func (ss *SecurityScheme) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(ss) } +// UnmarshalJSON sets SecurityScheme to a copy of data. func (ss *SecurityScheme) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, ss) } @@ -105,15 +108,16 @@ func (ss *SecurityScheme) WithBearerFormat(value string) *SecurityScheme { return ss } -func (value *SecurityScheme) Validate(ctx context.Context) error { +// Validate returns an error if SecurityScheme does not comply with the OpenAPI spec. +func (ss *SecurityScheme) Validate(ctx context.Context) error { hasIn := false hasBearerFormat := false hasFlow := false - switch value.Type { + switch ss.Type { case "apiKey": hasIn = true case "http": - scheme := value.Scheme + scheme := ss.Scheme switch scheme { case "bearer": hasBearerFormat = true @@ -124,46 +128,46 @@ func (value *SecurityScheme) Validate(ctx context.Context) error { case "oauth2": hasFlow = true case "openIdConnect": - if value.OpenIdConnectUrl == "" { - return fmt.Errorf("no OIDC URL found for openIdConnect security scheme %q", value.Name) + if ss.OpenIdConnectUrl == "" { + return fmt.Errorf("no OIDC URL found for openIdConnect security scheme %q", ss.Name) } default: - return fmt.Errorf("security scheme 'type' can't be %q", value.Type) + return fmt.Errorf("security scheme 'type' can't be %q", ss.Type) } // Validate "in" and "name" if hasIn { - switch value.In { + switch ss.In { case "query", "header", "cookie": default: - return fmt.Errorf("security scheme of type 'apiKey' should have 'in'. It can be 'query', 'header' or 'cookie', not %q", value.In) + return fmt.Errorf("security scheme of type 'apiKey' should have 'in'. It can be 'query', 'header' or 'cookie', not %q", ss.In) } - if value.Name == "" { + if ss.Name == "" { return errors.New("security scheme of type 'apiKey' should have 'name'") } - } else if len(value.In) > 0 { - return fmt.Errorf("security scheme of type %q can't have 'in'", value.Type) - } else if len(value.Name) > 0 { + } else if len(ss.In) > 0 { + return fmt.Errorf("security scheme of type %q can't have 'in'", ss.Type) + } else if len(ss.Name) > 0 { return errors.New("security scheme of type 'apiKey' can't have 'name'") } // Validate "format" // "bearerFormat" is an arbitrary string so we only check if the scheme supports it - if !hasBearerFormat && len(value.BearerFormat) > 0 { - return fmt.Errorf("security scheme of type %q can't have 'bearerFormat'", value.Type) + if !hasBearerFormat && len(ss.BearerFormat) > 0 { + return fmt.Errorf("security scheme of type %q can't have 'bearerFormat'", ss.Type) } // Validate "flow" if hasFlow { - flow := value.Flows + flow := ss.Flows if flow == nil { - return fmt.Errorf("security scheme of type %q should have 'flows'", value.Type) + return fmt.Errorf("security scheme of type %q should have 'flows'", ss.Type) } if err := flow.Validate(ctx); err != nil { return fmt.Errorf("security scheme 'flow' is invalid: %v", err) } - } else if value.Flows != nil { - return fmt.Errorf("security scheme of type %q can't have 'flows'", value.Type) + } else if ss.Flows != nil { + return fmt.Errorf("security scheme of type %q can't have 'flows'", ss.Type) } return nil } @@ -188,14 +192,17 @@ const ( oAuthFlowAuthorizationCode ) +// MarshalJSON returns the JSON encoding of OAuthFlows. func (flows *OAuthFlows) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(flows) } +// UnmarshalJSON sets OAuthFlows to a copy of data. func (flows *OAuthFlows) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, flows) } +// Validate returns an error if OAuthFlows does not comply with the OpenAPI spec. func (flows *OAuthFlows) Validate(ctx context.Context) error { if v := flows.Implicit; v != nil { return v.Validate(ctx, oAuthFlowTypeImplicit) @@ -223,14 +230,17 @@ type OAuthFlow struct { Scopes map[string]string `json:"scopes" yaml:"scopes"` } +// MarshalJSON returns the JSON encoding of OAuthFlow. func (flow *OAuthFlow) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(flow) } +// UnmarshalJSON sets OAuthFlow to a copy of data. func (flow *OAuthFlow) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, flow) } +// Validate returns an error if OAuthFlow does not comply with the OpenAPI spec. func (flow *OAuthFlow) Validate(ctx context.Context, typ oAuthFlowType) error { if typ == oAuthFlowAuthorizationCode || typ == oAuthFlowTypeImplicit { if v := flow.AuthorizationURL; v == "" { diff --git a/openapi3/server.go b/openapi3/server.go index 94092a6e6..478f8ffb7 100644 --- a/openapi3/server.go +++ b/openapi3/server.go @@ -14,9 +14,9 @@ import ( // Servers is specified by OpenAPI/Swagger standard version 3. type Servers []*Server -// Validate ensures servers are per the OpenAPIv3 specification. -func (value Servers) Validate(ctx context.Context) error { - for _, v := range value { +// Validate returns an error if Servers does not comply with the OpenAPI spec. +func (servers Servers) Validate(ctx context.Context) error { + for _, v := range servers { if err := v.Validate(ctx); err != nil { return err } @@ -48,10 +48,12 @@ type Server struct { Variables map[string]*ServerVariable `json:"variables,omitempty" yaml:"variables,omitempty"` } +// MarshalJSON returns the JSON encoding of Server. func (server *Server) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(server) } +// UnmarshalJSON sets Server to a copy of data. func (server *Server) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, server) } @@ -127,19 +129,20 @@ func (server Server) MatchRawURL(input string) ([]string, string, bool) { return params, input, true } -func (value *Server) Validate(ctx context.Context) (err error) { - if value.URL == "" { +// Validate returns an error if Server does not comply with the OpenAPI spec. +func (server *Server) Validate(ctx context.Context) (err error) { + if server.URL == "" { return errors.New("value of url must be a non-empty string") } - opening, closing := strings.Count(value.URL, "{"), strings.Count(value.URL, "}") + opening, closing := strings.Count(server.URL, "{"), strings.Count(server.URL, "}") if opening != closing { return errors.New("server URL has mismatched { and }") } - if opening != len(value.Variables) { + if opening != len(server.Variables) { return errors.New("server has undeclared variables") } - for name, v := range value.Variables { - if !strings.Contains(value.URL, fmt.Sprintf("{%s}", name)) { + for name, v := range server.Variables { + if !strings.Contains(server.URL, fmt.Sprintf("{%s}", name)) { return errors.New("server has undeclared variables") } if err = v.Validate(ctx); err != nil { @@ -159,17 +162,20 @@ type ServerVariable struct { Description string `json:"description,omitempty" yaml:"description,omitempty"` } +// MarshalJSON returns the JSON encoding of ServerVariable. func (serverVariable *ServerVariable) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(serverVariable) } +// UnmarshalJSON sets ServerVariable to a copy of data. func (serverVariable *ServerVariable) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, serverVariable) } -func (value *ServerVariable) Validate(ctx context.Context) error { - if value.Default == "" { - data, err := value.MarshalJSON() +// Validate returns an error if ServerVariable does not comply with the OpenAPI spec. +func (serverVariable *ServerVariable) Validate(ctx context.Context) error { + if serverVariable.Default == "" { + data, err := serverVariable.MarshalJSON() if err != nil { return err } diff --git a/openapi3/tag.go b/openapi3/tag.go index 6aa9a1ea2..8fb5ac36c 100644 --- a/openapi3/tag.go +++ b/openapi3/tag.go @@ -19,6 +19,7 @@ func (tags Tags) Get(name string) *Tag { return nil } +// Validate returns an error if Tags does not comply with the OpenAPI spec. func (tags Tags) Validate(ctx context.Context) error { for _, v := range tags { if err := v.Validate(ctx); err != nil { @@ -38,14 +39,17 @@ type Tag struct { ExternalDocs *ExternalDocs `json:"externalDocs,omitempty" yaml:"externalDocs,omitempty"` } +// MarshalJSON returns the JSON encoding of Tag. func (t *Tag) MarshalJSON() ([]byte, error) { return jsoninfo.MarshalStrictStruct(t) } +// UnmarshalJSON sets Tag to a copy of data. func (t *Tag) UnmarshalJSON(data []byte) error { return jsoninfo.UnmarshalStrictStruct(data, t) } +// Validate returns an error if Tag does not comply with the OpenAPI spec. func (t *Tag) Validate(ctx context.Context) error { if v := t.ExternalDocs; v != nil { if err := v.Validate(ctx); err != nil { diff --git a/openapi3/xml.go b/openapi3/xml.go index 8fd2abdee..03686ad9a 100644 --- a/openapi3/xml.go +++ b/openapi3/xml.go @@ -18,14 +18,17 @@ type XML struct { Wrapped bool `json:"wrapped,omitempty" yaml:"wrapped,omitempty"` } -func (value *XML) MarshalJSON() ([]byte, error) { - return jsoninfo.MarshalStrictStruct(value) +// MarshalJSON returns the JSON encoding of XML. +func (xml *XML) MarshalJSON() ([]byte, error) { + return jsoninfo.MarshalStrictStruct(xml) } -func (value *XML) UnmarshalJSON(data []byte) error { - return jsoninfo.UnmarshalStrictStruct(data, value) +// UnmarshalJSON sets XML to a copy of data. +func (xml *XML) UnmarshalJSON(data []byte) error { + return jsoninfo.UnmarshalStrictStruct(data, xml) } -func (value *XML) Validate(ctx context.Context) error { +// Validate returns an error if XML does not comply with the OpenAPI spec. +func (xml *XML) Validate(ctx context.Context) error { return nil // TODO }