@@ -16,8 +16,6 @@ import Foundation
1616
1717package struct DocCServer {
1818 private let server : DocumentationServer
19- private let jsonEncoder = JSONEncoder ( )
20- private let jsonDecoder = JSONDecoder ( )
2119
2220 init ( peer peerServer: DocumentationServer ? = nil , qualityOfService: DispatchQoS ) {
2321 server = DocumentationServer . createDefaultServer ( qualityOfService: qualityOfService, peer: peerServer)
@@ -35,9 +33,8 @@ package struct DocCServer {
3533 emitSymbolSourceFileURIs: Bool ,
3634 markupFiles: [ Data ] ,
3735 tutorialFiles: [ Data ] ,
38- convertRequestIdentifier: String ,
39- completion: @escaping ( _: Result < ConvertResponse , DocCServerError > ) -> Void
40- ) {
36+ convertRequestIdentifier: String
37+ ) async throws ( DocCServerError) -> ConvertResponse {
4138 let request = ConvertRequest (
4239 bundleInfo: DocumentationBundle . Info (
4340 displayName: documentationBundleDisplayName,
@@ -61,90 +58,97 @@ package struct DocCServer {
6158 miscResourceURLs: [ ] ,
6259 symbolIdentifiersWithExpandedDocumentation: nil
6360 )
64-
65- makeRequest (
61+ let response = try await makeRequest (
6662 messageType: ConvertService . convertMessageType,
6763 messageIdentifier: convertRequestIdentifier,
6864 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)
11288 }
89+ return ConvertResponse ( doccConvertResponse: doccConvertResponse)
11390 }
11491
11592 private func makeRequest< Request: Encodable & Sendable > (
11693 messageType: DocumentationServer . MessageType ,
11794 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) ) )
134104 }
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
138118 server. process ( encodedMessage) { response in
139119 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)
141121 }
142122 . flatMapError { . failure( . decodingFailure( $0) ) }
143- completion ( decodeMessageResult)
123+ continuation . resume ( returning : decodeMessageResult)
144124 }
145- case . failure( let encodingError) :
146- completion ( . failure( encodingError) )
147125 }
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
148152 }
149153}
150154
0 commit comments