1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80
|
/*
This source file is part of the Swift.org open source project
Copyright (c) 2023 Apple Inc. and the Swift project authors
Licensed under Apache License v2.0 with Runtime Library Exception
See https://swift.org/LICENSE.txt for license information
See https://swift.org/CONTRIBUTORS.txt for Swift project authors
*/
import Foundation
/// Translates a symbol's endpoints into a render node's URL section.
struct HTTPEndpointSectionTranslator: RenderSectionTranslator {
let endpointType: RESTEndpointType
func translateSection(
for symbol: Symbol,
renderNode: inout RenderNode,
renderNodeTranslator: inout RenderNodeTranslator
) -> VariantCollection<CodableContentSection?>? {
// Check if there is any endpoint available
guard !symbol.httpEndpointSectionVariants.isEmpty else { return nil }
return translateSectionToVariantCollection(
documentationDataVariants: symbol.httpEndpointSectionVariants
) { _, section in
let endpointURL: URL
if endpointType == .production {
endpointURL = section.endpoint.baseURL
} else if let sandboxURL = section.endpoint.sandboxURL {
endpointURL = sandboxURL
} else {
return nil
}
return RESTEndpointRenderSection(
title: (endpointType == .production ? "URL" : "Sandbox URL"),
tokens: Self.tokensFor(method: section.endpoint.method, baseURL: endpointURL, path: section.endpoint.path)
)
}
}
// Generate DeclarationFragments from endpoint data.
static func tokensFor(method: String, baseURL: URL?, path: String) -> [RESTEndpointRenderSection.Token] {
var fragments : [RESTEndpointRenderSection.Token] = []
// Operation type
fragments.append(RESTEndpointRenderSection.Token(kind: .method, text: method))
fragments.append(RESTEndpointRenderSection.Token(kind: .text, text: " "))
if let base = baseURL {
let cleanBase = base.absoluteString.appendingTrailingSlash
fragments.append(RESTEndpointRenderSection.Token(kind: .baseURL, text: cleanBase))
}
let cleanPath = path.removingLeadingSlash
var searchRange = cleanPath.startIndex..<cleanPath.endIndex
while true {
if let range = cleanPath.range(of: "\\{\\w+\\}", options: .regularExpression, range: searchRange, locale: nil) {
if cleanPath.startIndex < range.lowerBound {
fragments.append(RESTEndpointRenderSection.Token(kind: .path, text: String(cleanPath[searchRange.lowerBound..<range.lowerBound])))
}
fragments.append(RESTEndpointRenderSection.Token(kind: .parameter, text: String(cleanPath[range])))
searchRange = range.upperBound..<cleanPath.endIndex
// Make sure there is more content to search
if searchRange.lowerBound >= cleanPath.endIndex {
break
}
} else {
// Save off the remainder of the path
fragments.append(RESTEndpointRenderSection.Token(kind: .path, text: String(cleanPath[searchRange])))
break
}
}
return fragments
}
}
|