@@ -16,8 +16,6 @@ import Foundation
16
16
17
17
package struct DocCServer {
18
18
private let server : DocumentationServer
19
- private let jsonEncoder = JSONEncoder ( )
20
- private let jsonDecoder = JSONDecoder ( )
21
19
22
20
init ( peer peerServer: DocumentationServer ? = nil , qualityOfService: DispatchQoS ) {
23
21
server = DocumentationServer . createDefaultServer ( qualityOfService: qualityOfService, peer: peerServer)
@@ -35,9 +33,8 @@ package struct DocCServer {
35
33
emitSymbolSourceFileURIs: Bool ,
36
34
markupFiles: [ Data ] ,
37
35
tutorialFiles: [ Data ] ,
38
- convertRequestIdentifier: String ,
39
- completion: @escaping ( _: Result < ConvertResponse , DocCServerError > ) -> Void
40
- ) {
36
+ convertRequestIdentifier: String
37
+ ) async throws ( DocCServerError) -> ConvertResponse {
41
38
let request = ConvertRequest (
42
39
bundleInfo: DocumentationBundle . Info (
43
40
displayName: documentationBundleDisplayName,
@@ -61,90 +58,97 @@ package struct DocCServer {
61
58
miscResourceURLs: [ ] ,
62
59
symbolIdentifiersWithExpandedDocumentation: nil
63
60
)
64
-
65
- makeRequest (
61
+ let response = try await makeRequest (
66
62
messageType: ConvertService . convertMessageType,
67
63
messageIdentifier: convertRequestIdentifier,
68
64
request: request
69
- ) { response in
70
- completion (
71
- response. flatMap {
72
- message -> Result < Data , DocCServerError > in
73
- guard let messagePayload = message. payload else {
74
- return . failure( . unexpectedlyNilPayload( message. type. rawValue) )
75
- }
76
-
77
- guard message. type != ConvertService . convertResponseErrorMessageType else {
78
- return Result {
79
- try self . jsonDecoder. decode ( ConvertServiceError . self, from: messagePayload)
80
- }
81
- . flatMapError {
82
- . failure(
83
- DocCServerError . messagePayloadDecodingFailure (
84
- messageType: message. type. rawValue,
85
- decodingError: $0
86
- )
87
- )
88
- }
89
- . flatMap { . failure( . internalError( $0) ) }
90
- }
91
-
92
- guard message. type == ConvertService . convertResponseMessageType else {
93
- return . failure( . unknownMessageType( message. type. rawValue) )
94
- }
95
-
96
- return . success( messagePayload)
97
- }
98
- . flatMap { convertMessagePayload -> Result < ConvertResponse , DocCServerError > in
99
- return Result {
100
- try self . jsonDecoder. decode ( ConvertResponse . self, from: convertMessagePayload)
101
- }
102
- . flatMapError { decodingError -> Result < ConvertResponse , DocCServerError > in
103
- return . failure(
104
- DocCServerError . messagePayloadDecodingFailure (
105
- messageType: ConvertService . convertResponseMessageType. rawValue,
106
- decodingError: decodingError
107
- )
108
- )
109
- }
110
- }
111
- )
65
+ ) ;
66
+ guard let responsePayload = response. payload else {
67
+ throw . unexpectedlyNilPayload( response. type. rawValue)
68
+ }
69
+ // Check for an error response from SwiftDocC
70
+ guard response. type != ConvertService . convertResponseErrorMessageType else {
71
+ let convertServiceError : ConvertServiceError
72
+ do {
73
+ convertServiceError = try JSONDecoder ( ) . decode ( ConvertServiceError . self, from: responsePayload)
74
+ } catch {
75
+ throw . messagePayloadDecodingFailure( messageType: response. type. rawValue, decodingError: error)
76
+ }
77
+ throw . internalError( convertServiceError)
78
+ }
79
+ guard response. type == ConvertService . convertResponseMessageType else {
80
+ throw . unknownMessageType( response. type. rawValue)
81
+ }
82
+ // Decode the SwiftDocC.ConvertResponse and wrap it in our own Sendable type
83
+ let doccConvertResponse : SwiftDocC . ConvertResponse
84
+ do {
85
+ doccConvertResponse = try JSONDecoder ( ) . decode ( SwiftDocC . ConvertResponse. self, from: responsePayload)
86
+ } catch {
87
+ throw . decodingFailure( error)
112
88
}
89
+ return ConvertResponse ( doccConvertResponse: doccConvertResponse)
113
90
}
114
91
115
92
private func makeRequest< Request: Encodable & Sendable > (
116
93
messageType: DocumentationServer . MessageType ,
117
94
messageIdentifier: String ,
118
- request: Request ,
119
- completion: @escaping ( _: Result < DocumentationServer . Message , DocCServerError > ) -> Void
120
- ) {
121
- let encodedMessageResult : Result < Data , DocCServerError > = Result { try jsonEncoder. encode ( request) }
122
- . mapError { . encodingFailure( $0) }
123
- . flatMap { encodedPayload in
124
- Result {
125
- let message = DocumentationServer . Message (
126
- type: messageType,
127
- identifier: messageIdentifier,
128
- payload: encodedPayload
129
- )
130
- return try jsonEncoder. encode ( message)
131
- } . mapError { encodingError -> DocCServerError in
132
- return . encodingFailure( encodingError)
133
- }
95
+ request: Request
96
+ ) async throws ( DocCServerError) -> DocumentationServer . Message {
97
+ let result : Result < DocumentationServer . Message , DocCServerError > = await withCheckedContinuation { continuation in
98
+ // Encode the request in JSON format
99
+ let encodedPayload : Data
100
+ do {
101
+ encodedPayload = try JSONEncoder ( ) . encode ( request)
102
+ } catch {
103
+ return continuation. resume ( returning: . failure( . encodingFailure( error) ) )
134
104
}
135
-
136
- switch encodedMessageResult {
137
- case . success( let encodedMessage) :
105
+ // Encode the full message in JSON format
106
+ let message = DocumentationServer . Message (
107
+ type: messageType,
108
+ identifier: messageIdentifier,
109
+ payload: encodedPayload
110
+ )
111
+ let encodedMessage : Data
112
+ do {
113
+ encodedMessage = try JSONEncoder ( ) . encode ( message)
114
+ } catch {
115
+ return continuation. resume ( returning: . failure( . encodingFailure( error) ) )
116
+ }
117
+ // Send the request to the server and decode the response
138
118
server. process ( encodedMessage) { response in
139
119
let decodeMessageResult : Result < DocumentationServer . Message , DocCServerError > = Result {
140
- try self . jsonDecoder . decode ( DocumentationServer . Message. self, from: response)
120
+ try JSONDecoder ( ) . decode ( DocumentationServer . Message. self, from: response)
141
121
}
142
122
. flatMapError { . failure( . decodingFailure( $0) ) }
143
- completion ( decodeMessageResult)
123
+ continuation . resume ( returning : decodeMessageResult)
144
124
}
145
- case . failure( let encodingError) :
146
- completion ( . failure( encodingError) )
147
125
}
126
+ return try result. get ( )
127
+ }
128
+ }
129
+
130
+ /// A Sendable wrapper around ``SwiftDocC.ConvertResponse``
131
+ struct ConvertResponse : Sendable , Codable {
132
+ /// The render nodes that were created as part of the conversion, encoded as JSON.
133
+ let renderNodes : [ Data ]
134
+
135
+ /// The render reference store that was created as part of the bundle's conversion, encoded as JSON.
136
+ ///
137
+ /// The ``RenderReferenceStore`` contains compiled information for documentation nodes that were registered as part of
138
+ /// the conversion. This information can be used as a lightweight index of the available documentation content in the bundle that's
139
+ /// been converted.
140
+ let renderReferenceStore : Data ?
141
+
142
+ /// Creates a conversion response given the render nodes that were created as part of the conversion.
143
+ init ( renderNodes: [ Data ] , renderReferenceStore: Data ? = nil ) {
144
+ self . renderNodes = renderNodes
145
+ self . renderReferenceStore = renderReferenceStore
146
+ }
147
+
148
+ /// Creates a conversion response given a SwiftDocC conversion response
149
+ init ( doccConvertResponse: SwiftDocC . ConvertResponse ) {
150
+ self . renderNodes = doccConvertResponse. renderNodes
151
+ self . renderReferenceStore = doccConvertResponse. renderReferenceStore
148
152
}
149
153
}
150
154
0 commit comments