@@ -11,8 +11,10 @@ extension OpenAPI {
1111 /// OpenAPI Spec "Response Object"
1212 ///
1313 /// See [OpenAPI Response Object](https://spec.openapis.org/oas/v3.1.1.html#response-object).
14- public struct Response : Equatable , CodableVendorExtendable , Sendable {
15- public var description : String
14+ public struct Response : HasConditionalWarnings , CodableVendorExtendable , Sendable {
15+ public var summary : String ?
16+ public var description : String ?
17+
1618 public var headers : Header . Map ?
1719 /// An empty Content map will be omitted from encoding.
1820 public var content : Content . Map
@@ -26,22 +28,62 @@ extension OpenAPI {
2628 /// where the values are anything codable.
2729 public var vendorExtensions : [ String : AnyCodable ]
2830
31+ public let conditionalWarnings : [ ( any Condition , OpenAPI . Warning ) ]
32+
2933 public init (
30- description: String ,
34+ summary: String ? = nil ,
35+ description: String ? = nil ,
3136 headers: Header . Map ? = nil ,
3237 content: Content . Map = [ : ] ,
3338 links: Link . Map = [ : ] ,
3439 vendorExtensions: [ String : AnyCodable ] = [ : ]
3540 ) {
41+ self . summary = summary
3642 self . description = description
3743 self . headers = headers
3844 self . content = content
3945 self . links = links
4046 self . vendorExtensions = vendorExtensions
47+
48+ self . conditionalWarnings = [
49+ // If summary is non-nil, the document must be OAS version 3.2.0 or greater
50+ nonNilVersionWarning ( fieldName: " summary " , value: summary, minimumVersion: . v3_2_0) ,
51+ // If description is nil, the document must be OAS version 3.2.0 or greater
52+ notOptionalVersionWarning ( fieldName: " description " , value: description, minimumVersion: . v3_2_0)
53+ ] . compactMap { $0 }
4154 }
4255 }
4356}
4457
58+ extension OpenAPI . Response : Equatable {
59+ public static func == ( _ lhs: Self , _ rhs: Self ) -> Bool {
60+ lhs. summary == rhs. summary
61+ && lhs. description == rhs. description
62+ && lhs. headers == rhs. headers
63+ && lhs. content == rhs. content
64+ && lhs. links == rhs. links
65+ && lhs. vendorExtensions == rhs. vendorExtensions
66+ }
67+ }
68+
69+ fileprivate func nonNilVersionWarning< Subject> ( fieldName: String , value: Subject ? , minimumVersion: OpenAPI . Document . Version ) -> ( any Condition , OpenAPI . Warning ) ? {
70+ value. map { _ in
71+ OpenAPI . Document. ConditionalWarnings. version (
72+ lessThan: minimumVersion,
73+ doesNotSupport: " The Response \( fieldName) field "
74+ )
75+ }
76+ }
77+
78+ fileprivate func notOptionalVersionWarning< Subject> ( fieldName: String , value: Subject ? , minimumVersion: OpenAPI . Document . Version ) -> ( any Condition , OpenAPI . Warning ) ? {
79+ guard value == nil else { return nil }
80+
81+ return OpenAPI . Document. ConditionalWarnings. version (
82+ lessThan: minimumVersion,
83+ doesNotAllowOptional: " The Response \( fieldName) field "
84+ )
85+ }
86+
4587extension OpenAPI . Response {
4688 public typealias Map = OrderedDictionary < StatusCode , Either < OpenAPI . Reference < OpenAPI . Response > , OpenAPI . Response > >
4789}
@@ -72,7 +114,8 @@ extension OrderedDictionary where Key == OpenAPI.Response.StatusCode {
72114extension Either where A == OpenAPI . Reference < OpenAPI . Response > , B == OpenAPI . Response {
73115
74116 public static func response(
75- description: String ,
117+ summary: String ? = nil ,
118+ description: String ? = nil ,
76119 headers: OpenAPI . Header . Map ? = nil ,
77120 content: OpenAPI . Content . Map = [ : ] ,
78121 links: OpenAPI . Link . Map = [ : ]
@@ -89,19 +132,27 @@ extension Either where A == OpenAPI.Reference<OpenAPI.Response>, B == OpenAPI.Re
89132}
90133
91134// MARK: - Describable
92- extension OpenAPI . Response : OpenAPIDescribable {
135+ extension OpenAPI . Response : OpenAPISummarizable {
93136 public func overriddenNonNil( description: String ? ) -> OpenAPI . Response {
94137 guard let description = description else { return self }
95138 var response = self
96139 response. description = description
97140 return response
98141 }
142+
143+ public func overriddenNonNil( summary: String ? ) -> OpenAPI . Response {
144+ guard let summary = summary else { return self }
145+ var response = self
146+ response. summary = summary
147+ return response
148+ }
99149}
100150
101151// MARK: - Codable
102152
103153extension OpenAPI . Response {
104154 internal enum CodingKeys : ExtendableCodingKey {
155+ case summary
105156 case description
106157 case headers
107158 case content
@@ -110,6 +161,7 @@ extension OpenAPI.Response {
110161
111162 static var allBuiltinKeys : [ CodingKeys ] {
112163 return [
164+ . summary,
113165 . description,
114166 . headers,
115167 . content,
@@ -123,6 +175,8 @@ extension OpenAPI.Response {
123175
124176 init ? ( stringValue: String ) {
125177 switch stringValue {
178+ case " summary " :
179+ self = . summary
126180 case " description " :
127181 self = . description
128182 case " headers " :
@@ -138,6 +192,8 @@ extension OpenAPI.Response {
138192
139193 var stringValue : String {
140194 switch self {
195+ case . summary:
196+ return " summary "
141197 case . description:
142198 return " description "
143199 case . headers:
@@ -157,7 +213,8 @@ extension OpenAPI.Response: Encodable {
157213 public func encode( to encoder: Encoder ) throws {
158214 var container = encoder. container ( keyedBy: CodingKeys . self)
159215
160- try container. encode ( description, forKey: . description)
216+ try container. encodeIfPresent ( summary, forKey: . summary)
217+ try container. encodeIfPresent ( description, forKey: . description)
161218 try container. encodeIfPresent ( headers, forKey: . headers)
162219
163220 if !content. isEmpty {
@@ -179,13 +236,21 @@ extension OpenAPI.Response: Decodable {
179236 let container = try decoder. container ( keyedBy: CodingKeys . self)
180237
181238 do {
182- description = try container. decode ( String . self, forKey: . description)
239+ summary = try container. decodeIfPresent ( String . self, forKey: . summary)
240+ description = try container. decodeIfPresent ( String . self, forKey: . description)
183241 headers = try container. decodeIfPresent ( OpenAPI . Header. Map. self, forKey: . headers)
184242 content = try container. decodeIfPresent ( OpenAPI . Content. Map. self, forKey: . content) ?? [ : ]
185243 links = try container. decodeIfPresent ( OpenAPI . Link. Map. self, forKey: . links) ?? [ : ]
186244
187245 vendorExtensions = try Self . extensions ( from: decoder)
188246
247+ conditionalWarnings = [
248+ // If summary is non-nil, the document must be OAS version 3.2.0 or greater
249+ nonNilVersionWarning ( fieldName: " summary " , value: summary, minimumVersion: . v3_2_0) ,
250+ // If description is nil, the document must be OAS version 3.2.0 or greater
251+ notOptionalVersionWarning ( fieldName: " description " , value: description, minimumVersion: . v3_2_0)
252+ ] . compactMap { $0 }
253+
189254 } catch let error as GenericError {
190255
191256 throw OpenAPI . Error. Decoding. Response ( error)
0 commit comments