@@ -12,10 +12,19 @@ extension OpenAPI {
1212 ///
1313 /// See [OpenAPI Media Type Object](https://spec.openapis.org/oas/v3.1.1.html#media-type-object).
1414 public struct Content : Equatable , CodableVendorExtendable , Sendable {
15+ /// A schema describing the complete content of the request, response,
16+ /// parameter, or header.
1517 public var schema : JSONSchema ?
18+
19+ /// A schema describing each item within a sequential media type.
20+ public var itemSchema : JSONSchema ?
21+
1622 public var example : AnyCodable ?
1723 public var examples : Example . Map ?
18- public var encoding : OrderedDictionary < String , Encoding > ?
24+
25+ /// Provide either a map of encodings or some combination of prefix-
26+ /// and item- positional encodings.
27+ public var encoding : Either < OrderedDictionary < String , Encoding > , PositionalEncoding > ?
1928
2029 /// Dictionary of vendor extensions.
2130 ///
@@ -28,14 +37,51 @@ extension OpenAPI {
2837 /// schema at all and optionally provide a single example.
2938 public init (
3039 schema: JSONSchema ? ,
40+ itemSchema: JSONSchema ? = nil ,
3141 example: AnyCodable ? = nil ,
3242 encoding: OrderedDictionary < String , Encoding > ? = nil ,
3343 vendorExtensions: [ String : AnyCodable ] = [ : ]
3444 ) {
3545 self . schema = schema
46+ self . itemSchema = itemSchema
47+ self . example = example
48+ self . examples = nil
49+ self . encoding = encoding. map ( Either . a)
50+ self . vendorExtensions = vendorExtensions
51+ }
52+
53+ /// Create `Content` with a schema, a reference to a schema, or no
54+ /// schema at all and optionally provide a single example.
55+ public init (
56+ schema: JSONSchema ? ,
57+ itemSchema: JSONSchema ? = nil ,
58+ example: AnyCodable ? = nil ,
59+ prefixEncoding: [ Encoding ] = [ ] ,
60+ itemEncoding: Encoding ? = nil ,
61+ vendorExtensions: [ String : AnyCodable ] = [ : ]
62+ ) {
63+ self . schema = schema
64+ self . itemSchema = itemSchema
3665 self . example = example
3766 self . examples = nil
38- self . encoding = encoding
67+ self . encoding = . b( . init( prefixEncoding: prefixEncoding, itemEncoding: itemEncoding) )
68+ self . vendorExtensions = vendorExtensions
69+ }
70+
71+ /// Create `Content` with a schema, a reference to a schema, or no
72+ /// schema at all and optionally provide a single example.
73+ public init (
74+ itemSchema: JSONSchema ? ,
75+ example: AnyCodable ? = nil ,
76+ prefixEncoding: [ Encoding ] = [ ] ,
77+ itemEncoding: Encoding ? = nil ,
78+ vendorExtensions: [ String : AnyCodable ] = [ : ]
79+ ) {
80+ self . schema = nil
81+ self . itemSchema = itemSchema
82+ self . example = example
83+ self . examples = nil
84+ self . encoding = . b( . init( prefixEncoding: prefixEncoding, itemEncoding: itemEncoding) )
3985 self . vendorExtensions = vendorExtensions
4086 }
4187
@@ -50,22 +96,24 @@ extension OpenAPI {
5096 self . schema = . reference( schemaReference. jsonReference, description: schemaReference. description)
5197 self . example = example
5298 self . examples = nil
53- self . encoding = encoding
99+ self . encoding = encoding. map ( Either . a )
54100 self . vendorExtensions = vendorExtensions
55101 }
56102
57103 /// Create `Content` with a schema and optionally provide a single
58104 /// example.
59105 public init (
60106 schema: JSONSchema ,
107+ itemSchema: JSONSchema ? = nil ,
61108 example: AnyCodable ? = nil ,
62109 encoding: OrderedDictionary < String , Encoding > ? = nil ,
63110 vendorExtensions: [ String : AnyCodable ] = [ : ]
64111 ) {
65112 self . schema = schema
113+ self . itemSchema = itemSchema
66114 self . example = example
67115 self . examples = nil
68- self . encoding = encoding
116+ self . encoding = encoding. map ( Either . a )
69117 self . vendorExtensions = vendorExtensions
70118 }
71119
@@ -89,7 +137,7 @@ extension OpenAPI {
89137 }
90138 self . examples = examples
91139 self . example = examples. flatMap ( Self . firstExample ( from: ) )
92- self . encoding = encoding
140+ self . encoding = encoding. map ( Either . a )
93141 self . vendorExtensions = vendorExtensions
94142 }
95143
@@ -104,22 +152,57 @@ extension OpenAPI {
104152 self . schema = . reference( schemaReference. jsonReference)
105153 self . examples = examples
106154 self . example = examples. flatMap ( Self . firstExample ( from: ) )
107- self . encoding = encoding
155+ self . encoding = encoding. map ( Either . a )
108156 self . vendorExtensions = vendorExtensions
109157 }
110158
111159 /// Create `Content` with a schema and optionally provide a map
112160 /// of examples.
113161 public init (
114162 schema: JSONSchema ,
163+ itemSchema: JSONSchema ? = nil ,
115164 examples: Example . Map ? ,
116165 encoding: OrderedDictionary < String , Encoding > ? = nil ,
117166 vendorExtensions: [ String : AnyCodable ] = [ : ]
118167 ) {
119168 self . schema = schema
169+ self . itemSchema = itemSchema
120170 self . examples = examples
121171 self . example = examples. flatMap ( Self . firstExample ( from: ) )
122- self . encoding = encoding
172+ self . encoding = encoding. map ( Either . a)
173+ self . vendorExtensions = vendorExtensions
174+ }
175+
176+ /// Create `Content` with a schema and optionally provide a map
177+ /// of examples.
178+ public init (
179+ itemSchema: JSONSchema ? ,
180+ examples: Example . Map ? ,
181+ encoding: OrderedDictionary < String , Encoding > ? = nil ,
182+ vendorExtensions: [ String : AnyCodable ] = [ : ]
183+ ) {
184+ self . schema = nil
185+ self . itemSchema = itemSchema
186+ self . examples = examples
187+ self . example = examples. flatMap ( Self . firstExample ( from: ) )
188+ self . encoding = encoding. map ( Either . a)
189+ self . vendorExtensions = vendorExtensions
190+ }
191+
192+ /// Create `Content` with a schema and optionally provide a map
193+ /// of examples.
194+ public init (
195+ itemSchema: JSONSchema ? = nil ,
196+ examples: Example . Map ? ,
197+ prefixEncoding: [ Encoding ] = [ ] ,
198+ itemEncoding: Encoding ? = nil ,
199+ vendorExtensions: [ String : AnyCodable ] = [ : ]
200+ ) {
201+ self . schema = nil
202+ self . itemSchema = itemSchema
203+ self . examples = examples
204+ self . example = examples. flatMap ( Self . firstExample ( from: ) )
205+ self . encoding = . b( . init( prefixEncoding: prefixEncoding, itemEncoding: itemEncoding) )
123206 self . vendorExtensions = vendorExtensions
124207 }
125208 }
@@ -159,6 +242,7 @@ extension OpenAPI.Content: Encodable {
159242 var container = encoder. container ( keyedBy: CodingKeys . self)
160243
161244 try container. encodeIfPresent ( schema, forKey: . schema)
245+ try container. encodeIfPresent ( itemSchema, forKey: . itemSchema)
162246
163247 // only encode `examples` if non-nil,
164248 // otherwise encode `example` if non-nil
@@ -168,7 +252,18 @@ extension OpenAPI.Content: Encodable {
168252 try container. encode ( example, forKey: . example)
169253 }
170254
171- try container. encodeIfPresent ( encoding, forKey: . encoding)
255+ if let encoding {
256+ switch encoding {
257+ case . a( let encoding) :
258+ try container. encode ( encoding, forKey: . encoding)
259+
260+ case . b( let positionalEncoding) :
261+ if !positionalEncoding. prefixEncoding. isEmpty {
262+ try container. encode ( positionalEncoding. prefixEncoding, forKey: . prefixEncoding)
263+ }
264+ try container. encodeIfPresent ( positionalEncoding. itemEncoding, forKey: . itemEncoding)
265+ }
266+ }
172267
173268 if VendorExtensionsConfiguration . isEnabled ( for: encoder) {
174269 try encodeExtensions ( to: & container)
@@ -188,9 +283,25 @@ extension OpenAPI.Content: Decodable {
188283 )
189284 }
190285
286+ guard !( container. contains ( . encoding) && ( container. contains ( . prefixEncoding) || container. contains ( . itemEncoding) ) ) else {
287+ throw GenericError (
288+ subjectName: " Encoding and Positional Encoding " ,
289+ details: " If `prefixEncoding` or `itemEncoding` are specified then `encoding` is not allowed in the Media Type Object (`OpenAPI.Content`). " ,
290+ codingPath: container. codingPath
291+ )
292+ }
293+
191294 schema = try container. decodeIfPresent ( JSONSchema . self, forKey: . schema)
295+ itemSchema = try container. decodeIfPresent ( JSONSchema . self, forKey: . itemSchema)
192296
193- encoding = try container. decodeIfPresent ( OrderedDictionary < String , Encoding > . self, forKey: . encoding)
297+ if container. contains ( . encoding) {
298+ encoding = . a( try container. decode ( OrderedDictionary < String , Encoding > . self, forKey: . encoding) )
299+ } else {
300+ let prefixEncoding = try container. decodeIfPresent ( [ Encoding ] . self, forKey: . prefixEncoding) ?? [ ]
301+ let itemEncoding = try container. decodeIfPresent ( Encoding . self, forKey: . itemEncoding)
302+
303+ encoding = . b( . init( prefixEncoding: prefixEncoding, itemEncoding: itemEncoding) )
304+ }
194305
195306 if container. contains ( . example) {
196307 example = try container. decode ( AnyCodable . self, forKey: . example)
@@ -208,13 +319,24 @@ extension OpenAPI.Content: Decodable {
208319extension OpenAPI . Content {
209320 internal enum CodingKeys : ExtendableCodingKey {
210321 case schema
322+ case itemSchema
211323 case example // `example` and `examples` are mutually exclusive
212324 case examples // `example` and `examples` are mutually exclusive
213325 case encoding
326+ case itemEncoding
327+ case prefixEncoding
214328 case extended( String )
215329
216330 static var allBuiltinKeys : [ CodingKeys ] {
217- return [ . schema, . example, . examples, . encoding]
331+ return [
332+ . schema,
333+ . itemSchema,
334+ . example,
335+ . examples,
336+ . encoding,
337+ . itemEncoding,
338+ . prefixEncoding
339+ ]
218340 }
219341
220342 static func extendedKey( for value: String ) -> CodingKeys {
@@ -225,12 +347,18 @@ extension OpenAPI.Content {
225347 switch stringValue {
226348 case " schema " :
227349 self = . schema
350+ case " itemSchema " :
351+ self = . itemSchema
228352 case " example " :
229353 self = . example
230354 case " examples " :
231355 self = . examples
232356 case " encoding " :
233357 self = . encoding
358+ case " itemEncoding " :
359+ self = . itemEncoding
360+ case " prefixEncoding " :
361+ self = . prefixEncoding
234362 default :
235363 self = . extendedKey( for: stringValue)
236364 }
@@ -240,12 +368,18 @@ extension OpenAPI.Content {
240368 switch self {
241369 case . schema:
242370 return " schema "
371+ case . itemSchema:
372+ return " itemSchema "
243373 case . example:
244374 return " example "
245375 case . examples:
246376 return " examples "
247377 case . encoding:
248378 return " encoding "
379+ case . itemEncoding:
380+ return " itemEncoding "
381+ case . prefixEncoding:
382+ return " prefixEncoding "
249383 case . extended( let key) :
250384 return key
251385 }
0 commit comments