Skip to content

Commit 4e8c7da

Browse files
committed
[Swift6][Client] Make Swift 6 generator thread safe
1 parent 22f1a9e commit 4e8c7da

13 files changed

Lines changed: 299 additions & 351 deletions

File tree

modules/openapi-generator/src/main/resources/swift6/CodableHelper.mustache

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,22 @@ import Foundation
1414
private struct State {
1515
var customDateFormatter: DateFormatter?
1616
var defaultDateFormatter: DateFormatter = OpenISO8601DateFormatter()
17+
1718
var customJSONDecoder: JSONDecoder?
18-
var defaultJSONDecoder: JSONDecoder?
19+
var defaultJSONDecoder: JSONDecoder = JSONDecoder()
20+
1921
var customJSONEncoder: JSONEncoder?
20-
var defaultJSONEncoder: JSONEncoder?
22+
var defaultJSONEncoder: JSONEncoder = JSONEncoder()
23+
24+
init() {
25+
didUpdateDateFormatter()
26+
defaultJSONEncoder.outputFormatting = .prettyPrinted
27+
}
28+
29+
mutating func didUpdateDateFormatter() {
30+
defaultJSONDecoder.dateDecodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
31+
defaultJSONEncoder.dateEncodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
32+
}
2133
}
2234

2335
private let _state = OpenAPIMutex(State())
@@ -33,46 +45,30 @@ import Foundation
3345
set {
3446
_state.withValue { state in
3547
state.customDateFormatter = newValue
36-
state.defaultJSONDecoder = nil
37-
state.defaultJSONEncoder = nil
48+
state.didUpdateDateFormatter()
3849
}
3950
}
4051
}
4152

4253
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var jsonDecoder: JSONDecoder {
43-
get {
44-
_state.withValue { state in
45-
if let custom = state.customJSONDecoder { return custom }
46-
if let cached = state.defaultJSONDecoder { return cached }
47-
let decoder = JSONDecoder()
48-
decoder.dateDecodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
49-
state.defaultJSONDecoder = decoder
50-
return decoder
51-
}
52-
}
54+
get { _state.withValue { $0.customJSONDecoder ?? $0.defaultJSONDecoder } }
5355
set { _state.withValue { $0.customJSONDecoder = newValue } }
5456
}
5557

5658
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}public{{/nonPublicApi}} var jsonEncoder: JSONEncoder {
57-
get {
58-
_state.withValue { state in
59-
if let custom = state.customJSONEncoder { return custom }
60-
if let cached = state.defaultJSONEncoder { return cached }
61-
let encoder = JSONEncoder()
62-
encoder.dateEncodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
63-
encoder.outputFormatting = .prettyPrinted
64-
state.defaultJSONEncoder = encoder
65-
return encoder
66-
}
67-
}
59+
get { _state.withValue { $0.customJSONEncoder ?? $0.defaultJSONEncoder } }
6860
set { _state.withValue { $0.customJSONEncoder = newValue } }
6961
}
7062

7163
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} func decode<T>(_ type: T.Type, from data: Data) -> Swift.Result<T, Error> where T: Decodable {
72-
return Swift.Result { try jsonDecoder.decode(type, from: data) }
64+
_state.withValue { state in
65+
Swift.Result { try (state.customJSONDecoder ?? state.defaultJSONDecoder).decode(type, from: data) }
66+
}
7367
}
7468

7569
{{#nonPublicApi}}internal{{/nonPublicApi}}{{^nonPublicApi}}open{{/nonPublicApi}} func encode<T>(_ value: T) -> Swift.Result<Data, Error> where T: Encodable {
76-
return Swift.Result { try jsonEncoder.encode(value) }
70+
_state.withValue { state in
71+
Swift.Result { try (state.customJSONEncoder ?? state.defaultJSONEncoder).encode(value) }
72+
}
7773
}
7874
}

samples/client/petstore/swift6/alamofireLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,22 @@ open class CodableHelper: @unchecked Sendable {
1414
private struct State {
1515
var customDateFormatter: DateFormatter?
1616
var defaultDateFormatter: DateFormatter = OpenISO8601DateFormatter()
17+
1718
var customJSONDecoder: JSONDecoder?
18-
var defaultJSONDecoder: JSONDecoder?
19+
var defaultJSONDecoder: JSONDecoder = JSONDecoder()
20+
1921
var customJSONEncoder: JSONEncoder?
20-
var defaultJSONEncoder: JSONEncoder?
22+
var defaultJSONEncoder: JSONEncoder = JSONEncoder()
23+
24+
init() {
25+
didUpdateDateFormatter()
26+
defaultJSONEncoder.outputFormatting = .prettyPrinted
27+
}
28+
29+
mutating func didUpdateDateFormatter() {
30+
defaultJSONDecoder.dateDecodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
31+
defaultJSONEncoder.dateEncodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
32+
}
2133
}
2234

2335
private let _state = OpenAPIMutex(State())
@@ -33,46 +45,30 @@ open class CodableHelper: @unchecked Sendable {
3345
set {
3446
_state.withValue { state in
3547
state.customDateFormatter = newValue
36-
state.defaultJSONDecoder = nil
37-
state.defaultJSONEncoder = nil
48+
state.didUpdateDateFormatter()
3849
}
3950
}
4051
}
4152

4253
public var jsonDecoder: JSONDecoder {
43-
get {
44-
_state.withValue { state in
45-
if let custom = state.customJSONDecoder { return custom }
46-
if let cached = state.defaultJSONDecoder { return cached }
47-
let decoder = JSONDecoder()
48-
decoder.dateDecodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
49-
state.defaultJSONDecoder = decoder
50-
return decoder
51-
}
52-
}
54+
get { _state.withValue { $0.customJSONDecoder ?? $0.defaultJSONDecoder } }
5355
set { _state.withValue { $0.customJSONDecoder = newValue } }
5456
}
5557

5658
public var jsonEncoder: JSONEncoder {
57-
get {
58-
_state.withValue { state in
59-
if let custom = state.customJSONEncoder { return custom }
60-
if let cached = state.defaultJSONEncoder { return cached }
61-
let encoder = JSONEncoder()
62-
encoder.dateEncodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
63-
encoder.outputFormatting = .prettyPrinted
64-
state.defaultJSONEncoder = encoder
65-
return encoder
66-
}
67-
}
59+
get { _state.withValue { $0.customJSONEncoder ?? $0.defaultJSONEncoder } }
6860
set { _state.withValue { $0.customJSONEncoder = newValue } }
6961
}
7062

7163
open func decode<T>(_ type: T.Type, from data: Data) -> Swift.Result<T, Error> where T: Decodable {
72-
return Swift.Result { try jsonDecoder.decode(type, from: data) }
64+
_state.withValue { state in
65+
Swift.Result { try (state.customJSONDecoder ?? state.defaultJSONDecoder).decode(type, from: data) }
66+
}
7367
}
7468

7569
open func encode<T>(_ value: T) -> Swift.Result<Data, Error> where T: Encodable {
76-
return Swift.Result { try jsonEncoder.encode(value) }
70+
_state.withValue { state in
71+
Swift.Result { try (state.customJSONEncoder ?? state.defaultJSONEncoder).encode(value) }
72+
}
7773
}
7874
}

samples/client/petstore/swift6/apiNonStaticMethod/Sources/PetstoreClient/Infrastructure/CodableHelper.swift

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,22 @@ open class CodableHelper: @unchecked Sendable {
1414
private struct State {
1515
var customDateFormatter: DateFormatter?
1616
var defaultDateFormatter: DateFormatter = OpenISO8601DateFormatter()
17+
1718
var customJSONDecoder: JSONDecoder?
18-
var defaultJSONDecoder: JSONDecoder?
19+
var defaultJSONDecoder: JSONDecoder = JSONDecoder()
20+
1921
var customJSONEncoder: JSONEncoder?
20-
var defaultJSONEncoder: JSONEncoder?
22+
var defaultJSONEncoder: JSONEncoder = JSONEncoder()
23+
24+
init() {
25+
didUpdateDateFormatter()
26+
defaultJSONEncoder.outputFormatting = .prettyPrinted
27+
}
28+
29+
mutating func didUpdateDateFormatter() {
30+
defaultJSONDecoder.dateDecodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
31+
defaultJSONEncoder.dateEncodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
32+
}
2133
}
2234

2335
private let _state = OpenAPIMutex(State())
@@ -33,46 +45,30 @@ open class CodableHelper: @unchecked Sendable {
3345
set {
3446
_state.withValue { state in
3547
state.customDateFormatter = newValue
36-
state.defaultJSONDecoder = nil
37-
state.defaultJSONEncoder = nil
48+
state.didUpdateDateFormatter()
3849
}
3950
}
4051
}
4152

4253
public var jsonDecoder: JSONDecoder {
43-
get {
44-
_state.withValue { state in
45-
if let custom = state.customJSONDecoder { return custom }
46-
if let cached = state.defaultJSONDecoder { return cached }
47-
let decoder = JSONDecoder()
48-
decoder.dateDecodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
49-
state.defaultJSONDecoder = decoder
50-
return decoder
51-
}
52-
}
54+
get { _state.withValue { $0.customJSONDecoder ?? $0.defaultJSONDecoder } }
5355
set { _state.withValue { $0.customJSONDecoder = newValue } }
5456
}
5557

5658
public var jsonEncoder: JSONEncoder {
57-
get {
58-
_state.withValue { state in
59-
if let custom = state.customJSONEncoder { return custom }
60-
if let cached = state.defaultJSONEncoder { return cached }
61-
let encoder = JSONEncoder()
62-
encoder.dateEncodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
63-
encoder.outputFormatting = .prettyPrinted
64-
state.defaultJSONEncoder = encoder
65-
return encoder
66-
}
67-
}
59+
get { _state.withValue { $0.customJSONEncoder ?? $0.defaultJSONEncoder } }
6860
set { _state.withValue { $0.customJSONEncoder = newValue } }
6961
}
7062

7163
open func decode<T>(_ type: T.Type, from data: Data) -> Swift.Result<T, Error> where T: Decodable {
72-
return Swift.Result { try jsonDecoder.decode(type, from: data) }
64+
_state.withValue { state in
65+
Swift.Result { try (state.customJSONDecoder ?? state.defaultJSONDecoder).decode(type, from: data) }
66+
}
7367
}
7468

7569
open func encode<T>(_ value: T) -> Swift.Result<Data, Error> where T: Encodable {
76-
return Swift.Result { try jsonEncoder.encode(value) }
70+
_state.withValue { state in
71+
Swift.Result { try (state.customJSONEncoder ?? state.defaultJSONEncoder).encode(value) }
72+
}
7773
}
7874
}

samples/client/petstore/swift6/asyncAwaitLibrary/Sources/PetstoreClient/Infrastructure/CodableHelper.swift

Lines changed: 23 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,22 @@ open class CodableHelper: @unchecked Sendable {
1414
private struct State {
1515
var customDateFormatter: DateFormatter?
1616
var defaultDateFormatter: DateFormatter = OpenISO8601DateFormatter()
17+
1718
var customJSONDecoder: JSONDecoder?
18-
var defaultJSONDecoder: JSONDecoder?
19+
var defaultJSONDecoder: JSONDecoder = JSONDecoder()
20+
1921
var customJSONEncoder: JSONEncoder?
20-
var defaultJSONEncoder: JSONEncoder?
22+
var defaultJSONEncoder: JSONEncoder = JSONEncoder()
23+
24+
init() {
25+
didUpdateDateFormatter()
26+
defaultJSONEncoder.outputFormatting = .prettyPrinted
27+
}
28+
29+
mutating func didUpdateDateFormatter() {
30+
defaultJSONDecoder.dateDecodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
31+
defaultJSONEncoder.dateEncodingStrategy = .formatted(customDateFormatter ?? defaultDateFormatter)
32+
}
2133
}
2234

2335
private let _state = OpenAPIMutex(State())
@@ -33,46 +45,30 @@ open class CodableHelper: @unchecked Sendable {
3345
set {
3446
_state.withValue { state in
3547
state.customDateFormatter = newValue
36-
state.defaultJSONDecoder = nil
37-
state.defaultJSONEncoder = nil
48+
state.didUpdateDateFormatter()
3849
}
3950
}
4051
}
4152

4253
public var jsonDecoder: JSONDecoder {
43-
get {
44-
_state.withValue { state in
45-
if let custom = state.customJSONDecoder { return custom }
46-
if let cached = state.defaultJSONDecoder { return cached }
47-
let decoder = JSONDecoder()
48-
decoder.dateDecodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
49-
state.defaultJSONDecoder = decoder
50-
return decoder
51-
}
52-
}
54+
get { _state.withValue { $0.customJSONDecoder ?? $0.defaultJSONDecoder } }
5355
set { _state.withValue { $0.customJSONDecoder = newValue } }
5456
}
5557

5658
public var jsonEncoder: JSONEncoder {
57-
get {
58-
_state.withValue { state in
59-
if let custom = state.customJSONEncoder { return custom }
60-
if let cached = state.defaultJSONEncoder { return cached }
61-
let encoder = JSONEncoder()
62-
encoder.dateEncodingStrategy = .formatted(state.customDateFormatter ?? state.defaultDateFormatter)
63-
encoder.outputFormatting = .prettyPrinted
64-
state.defaultJSONEncoder = encoder
65-
return encoder
66-
}
67-
}
59+
get { _state.withValue { $0.customJSONEncoder ?? $0.defaultJSONEncoder } }
6860
set { _state.withValue { $0.customJSONEncoder = newValue } }
6961
}
7062

7163
open func decode<T>(_ type: T.Type, from data: Data) -> Swift.Result<T, Error> where T: Decodable {
72-
return Swift.Result { try jsonDecoder.decode(type, from: data) }
64+
_state.withValue { state in
65+
Swift.Result { try (state.customJSONDecoder ?? state.defaultJSONDecoder).decode(type, from: data) }
66+
}
7367
}
7468

7569
open func encode<T>(_ value: T) -> Swift.Result<Data, Error> where T: Encodable {
76-
return Swift.Result { try jsonEncoder.encode(value) }
70+
_state.withValue { state in
71+
Swift.Result { try (state.customJSONEncoder ?? state.defaultJSONEncoder).encode(value) }
72+
}
7773
}
7874
}

0 commit comments

Comments
 (0)