1// Copyright 2015 go-swagger maintainers
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//    http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package spec
16
17import (
18	"encoding/json"
19
20	"github.com/go-openapi/jsonpointer"
21	"github.com/go-openapi/swag"
22)
23
24// ResponseProps properties specific to a response
25type ResponseProps struct {
26	Description string                 `json:"description,omitempty"`
27	Schema      *Schema                `json:"schema,omitempty"`
28	Headers     map[string]Header      `json:"headers,omitempty"`
29	Examples    map[string]interface{} `json:"examples,omitempty"`
30}
31
32// Response describes a single response from an API Operation.
33//
34// For more information: http://goo.gl/8us55a#responseObject
35type Response struct {
36	Refable
37	ResponseProps
38	VendorExtensible
39}
40
41// JSONLookup look up a value by the json property name
42func (r Response) JSONLookup(token string) (interface{}, error) {
43	if ex, ok := r.Extensions[token]; ok {
44		return &ex, nil
45	}
46	if token == "$ref" {
47		return &r.Ref, nil
48	}
49	ptr, _, err := jsonpointer.GetForToken(r.ResponseProps, token)
50	return ptr, err
51}
52
53// UnmarshalJSON hydrates this items instance with the data from JSON
54func (r *Response) UnmarshalJSON(data []byte) error {
55	if err := json.Unmarshal(data, &r.ResponseProps); err != nil {
56		return err
57	}
58	if err := json.Unmarshal(data, &r.Refable); err != nil {
59		return err
60	}
61	return json.Unmarshal(data, &r.VendorExtensible)
62}
63
64// MarshalJSON converts this items object to JSON
65func (r Response) MarshalJSON() ([]byte, error) {
66	b1, err := json.Marshal(r.ResponseProps)
67	if err != nil {
68		return nil, err
69	}
70	b2, err := json.Marshal(r.Refable)
71	if err != nil {
72		return nil, err
73	}
74	b3, err := json.Marshal(r.VendorExtensible)
75	if err != nil {
76		return nil, err
77	}
78	return swag.ConcatJSON(b1, b2, b3), nil
79}
80
81// NewResponse creates a new response instance
82func NewResponse() *Response {
83	return new(Response)
84}
85
86// ResponseRef creates a response as a json reference
87func ResponseRef(url string) *Response {
88	resp := NewResponse()
89	resp.Ref = MustCreateRef(url)
90	return resp
91}
92
93// WithDescription sets the description on this response, allows for chaining
94func (r *Response) WithDescription(description string) *Response {
95	r.Description = description
96	return r
97}
98
99// WithSchema sets the schema on this response, allows for chaining.
100// Passing a nil argument removes the schema from this response
101func (r *Response) WithSchema(schema *Schema) *Response {
102	r.Schema = schema
103	return r
104}
105
106// AddHeader adds a header to this response
107func (r *Response) AddHeader(name string, header *Header) *Response {
108	if header == nil {
109		return r.RemoveHeader(name)
110	}
111	if r.Headers == nil {
112		r.Headers = make(map[string]Header)
113	}
114	r.Headers[name] = *header
115	return r
116}
117
118// RemoveHeader removes a header from this response
119func (r *Response) RemoveHeader(name string) *Response {
120	delete(r.Headers, name)
121	return r
122}
123
124// AddExample adds an example to this response
125func (r *Response) AddExample(mediaType string, example interface{}) *Response {
126	if r.Examples == nil {
127		r.Examples = make(map[string]interface{})
128	}
129	r.Examples[mediaType] = example
130	return r
131}
132