Skip to content

Commit 9d76a1d

Browse files
authored
[Runtime] Integrate the new URI and String coders (#45)
[Runtime] Integrate the new URI and String coders ### Motivation See details in the generator PR on motivation (apple/swift-openapi-generator#226). ### Modifications - Deprecated `_AutoLosslessStringConvertible` and `_StringConvertible` 🎉 - Deprecated all `*Text` helper functions on `Converter`, it was a convoluted mix of `URI` and `String`, so they all need to go away. - Added `*URI` and `*String` helper functions for the appropriate parameters/bodies. Those use the new URI/String coders under the hood. - Note: we now manipulate the `Request.query` property more directly, instead of going through `URLQueryItem`. ### Result Now we fully rely on `Codable` and a combination of system and custom encoder/decoders, which allows us to much more easily support Foundation types (such as Date), generated types (such as string enums), and primitive types - all the same way. While this might not be fully evident in this PR, this refactoring actually makes it possible for us to support much more of the OpenAPI specification. ### Test Plan Deprecated tests of the `*Text` helpers, introduced new tests for the new helpers. Reviewed by: glbrntt Builds: ✔︎ pull request validation (5.8) - Build finished. ✔︎ pull request validation (5.9) - Build finished. ✔︎ pull request validation (api breakage) - Build finished. ✔︎ pull request validation (docc test) - Build finished. ✔︎ pull request validation (integration test) - Build finished. ✔︎ pull request validation (nightly) - Build finished. ✔︎ pull request validation (soundness) - Build finished. #45
1 parent 0769bd0 commit 9d76a1d

16 files changed

+2128
-949
lines changed

Sources/OpenAPIRuntime/Conversion/Converter+Client.swift

+41-120
Original file line numberDiff line numberDiff line change
@@ -31,98 +31,61 @@ extension Converter {
3131
)
3232
}
3333

34-
// | client | set | request path | text | string-convertible | required | renderedRequestPath |
35-
public func renderedRequestPath(
34+
// | client | set | request path | URI | required | renderedPath |
35+
public func renderedPath(
3636
template: String,
37-
parameters: [any _StringConvertible]
37+
parameters: [any Encodable]
3838
) throws -> String {
3939
var renderedString = template
40+
let encoder = URIEncoder(
41+
configuration: .init(
42+
style: .simple,
43+
explode: false,
44+
spaceEscapingCharacter: .percentEncoded,
45+
dateTranscoder: configuration.dateTranscoder
46+
)
47+
)
4048
for parameter in parameters {
49+
let value = try encoder.encode(parameter, forKey: "")
4150
if let range = renderedString.range(of: "{}") {
4251
renderedString = renderedString.replacingOccurrences(
4352
of: "{}",
44-
with: parameter.description,
53+
with: value,
4554
range: range
4655
)
4756
}
4857
}
4958
return renderedString
5059
}
5160

52-
// | client | set | request query | text | string-convertible | both | setQueryItemAsText |
53-
public func setQueryItemAsText<T: _StringConvertible>(
61+
// | client | set | request query | URI | both | setQueryItemAsURI |
62+
public func setQueryItemAsURI<T: Encodable>(
5463
in request: inout Request,
5564
style: ParameterStyle?,
5665
explode: Bool?,
5766
name: String,
5867
value: T?
5968
) throws {
60-
try setQueryItem(
69+
try setEscapedQueryItem(
6170
in: &request,
6271
style: style,
6372
explode: explode,
6473
name: name,
6574
value: value,
66-
convert: convertStringConvertibleToText
67-
)
68-
}
69-
70-
// | client | set | request query | text | array of string-convertibles | both | setQueryItemAsText |
71-
public func setQueryItemAsText<T: _StringConvertible>(
72-
in request: inout Request,
73-
style: ParameterStyle?,
74-
explode: Bool?,
75-
name: String,
76-
value: [T]?
77-
) throws {
78-
try setQueryItems(
79-
in: &request,
80-
style: style,
81-
explode: explode,
82-
name: name,
83-
values: value,
84-
convert: convertStringConvertibleToText
85-
)
86-
}
87-
88-
// | client | set | request query | text | date | both | setQueryItemAsText |
89-
public func setQueryItemAsText(
90-
in request: inout Request,
91-
style: ParameterStyle?,
92-
explode: Bool?,
93-
name: String,
94-
value: Date?
95-
) throws {
96-
try setQueryItem(
97-
in: &request,
98-
style: style,
99-
explode: explode,
100-
name: name,
101-
value: value,
102-
convert: convertDateToText
103-
)
104-
}
105-
106-
// | client | set | request query | text | array of dates | both | setQueryItemAsText |
107-
public func setQueryItemAsText(
108-
in request: inout Request,
109-
style: ParameterStyle?,
110-
explode: Bool?,
111-
name: String,
112-
value: [Date]?
113-
) throws {
114-
try setQueryItems(
115-
in: &request,
116-
style: style,
117-
explode: explode,
118-
name: name,
119-
values: value,
120-
convert: convertDateToText
75+
convert: { value, style, explode in
76+
try convertToURI(
77+
style: style,
78+
explode: explode,
79+
inBody: false,
80+
key: name,
81+
value: value
82+
)
83+
}
12184
)
12285
}
12386

124-
// | client | set | request body | text | string-convertible | optional | setOptionalRequestBodyAsText |
125-
public func setOptionalRequestBodyAsText<T: _StringConvertible>(
87+
// | client | set | request body | string | optional | setOptionalRequestBodyAsString |
88+
public func setOptionalRequestBodyAsString<T: Encodable>(
12689
_ value: T?,
12790
headerFields: inout [HeaderField],
12891
contentType: String
@@ -131,12 +94,12 @@ extension Converter {
13194
value,
13295
headerFields: &headerFields,
13396
contentType: contentType,
134-
convert: convertStringConvertibleToTextData
97+
convert: convertToStringData
13598
)
13699
}
137100

138-
// | client | set | request body | text | string-convertible | required | setRequiredRequestBodyAsText |
139-
public func setRequiredRequestBodyAsText<T: _StringConvertible>(
101+
// | client | set | request body | string | required | setRequiredRequestBodyAsString |
102+
public func setRequiredRequestBodyAsString<T: Encodable>(
140103
_ value: T,
141104
headerFields: inout [HeaderField],
142105
contentType: String
@@ -145,39 +108,11 @@ extension Converter {
145108
value,
146109
headerFields: &headerFields,
147110
contentType: contentType,
148-
convert: convertStringConvertibleToTextData
149-
)
150-
}
151-
152-
// | client | set | request body | text | date | optional | setOptionalRequestBodyAsText |
153-
public func setOptionalRequestBodyAsText(
154-
_ value: Date?,
155-
headerFields: inout [HeaderField],
156-
contentType: String
157-
) throws -> Data? {
158-
try setOptionalRequestBody(
159-
value,
160-
headerFields: &headerFields,
161-
contentType: contentType,
162-
convert: convertDateToTextData
111+
convert: convertToStringData
163112
)
164113
}
165114

166-
// | client | set | request body | text | date | required | setRequiredRequestBodyAsText |
167-
public func setRequiredRequestBodyAsText(
168-
_ value: Date,
169-
headerFields: inout [HeaderField],
170-
contentType: String
171-
) throws -> Data {
172-
try setRequiredRequestBody(
173-
value,
174-
headerFields: &headerFields,
175-
contentType: contentType,
176-
convert: convertDateToTextData
177-
)
178-
}
179-
180-
// | client | set | request body | JSON | codable | optional | setOptionalRequestBodyAsJSON |
115+
// | client | set | request body | JSON | optional | setOptionalRequestBodyAsJSON |
181116
public func setOptionalRequestBodyAsJSON<T: Encodable>(
182117
_ value: T?,
183118
headerFields: inout [HeaderField],
@@ -191,7 +126,7 @@ extension Converter {
191126
)
192127
}
193128

194-
// | client | set | request body | JSON | codable | required | setRequiredRequestBodyAsJSON |
129+
// | client | set | request body | JSON | required | setRequiredRequestBodyAsJSON |
195130
public func setRequiredRequestBodyAsJSON<T: Encodable>(
196131
_ value: T,
197132
headerFields: inout [HeaderField],
@@ -205,7 +140,7 @@ extension Converter {
205140
)
206141
}
207142

208-
// | client | set | request body | binary | data | optional | setOptionalRequestBodyAsBinary |
143+
// | client | set | request body | binary | optional | setOptionalRequestBodyAsBinary |
209144
public func setOptionalRequestBodyAsBinary(
210145
_ value: Data?,
211146
headerFields: inout [HeaderField],
@@ -219,7 +154,7 @@ extension Converter {
219154
)
220155
}
221156

222-
// | client | set | request body | binary | data | required | setRequiredRequestBodyAsBinary |
157+
// | client | set | request body | binary | required | setRequiredRequestBodyAsBinary |
223158
public func setRequiredRequestBodyAsBinary(
224159
_ value: Data,
225160
headerFields: inout [HeaderField],
@@ -233,8 +168,8 @@ extension Converter {
233168
)
234169
}
235170

236-
// | client | get | response body | text | string-convertible | required | getResponseBodyAsText |
237-
public func getResponseBodyAsText<T: _StringConvertible, C>(
171+
// | client | get | response body | string | required | getResponseBodyAsString |
172+
public func getResponseBodyAsString<T: Decodable, C>(
238173
_ type: T.Type,
239174
from data: Data,
240175
transforming transform: (T) -> C
@@ -243,25 +178,11 @@ extension Converter {
243178
type,
244179
from: data,
245180
transforming: transform,
246-
convert: convertTextDataToStringConvertible
247-
)
248-
}
249-
250-
// | client | get | response body | text | date | required | getResponseBodyAsText |
251-
public func getResponseBodyAsText<C>(
252-
_ type: Date.Type,
253-
from data: Data,
254-
transforming transform: (Date) -> C
255-
) throws -> C {
256-
try getResponseBody(
257-
type,
258-
from: data,
259-
transforming: transform,
260-
convert: convertTextDataToDate
181+
convert: convertFromStringData
261182
)
262183
}
263184

264-
// | client | get | response body | JSON | codable | required | getResponseBodyAsJSON |
185+
// | client | get | response body | JSON | required | getResponseBodyAsJSON |
265186
public func getResponseBodyAsJSON<T: Decodable, C>(
266187
_ type: T.Type,
267188
from data: Data,
@@ -271,11 +192,11 @@ extension Converter {
271192
type,
272193
from: data,
273194
transforming: transform,
274-
convert: convertJSONToCodable
195+
convert: convertJSONToBodyCodable
275196
)
276197
}
277198

278-
// | client | get | response body | binary | data | required | getResponseBodyAsBinary |
199+
// | client | get | response body | binary | required | getResponseBodyAsBinary |
279200
public func getResponseBodyAsBinary<C>(
280201
_ type: Data.Type,
281202
from data: Data,

0 commit comments

Comments
 (0)