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 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
/*
This source file is part of the Swift.org open source project
Copyright (c) 2021-2024 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
/// A reference to a resource.
///
/// The reference can refer to a resource within a documentation bundle (e.g., another symbol) or an external resource (e.g., a web URL).
/// Check the conforming types to browse the different kinds of references.
public protocol RenderReference: Codable {
/// The type of the reference.
var type: RenderReferenceType { get }
/// The identifier of the reference.
///
/// The identifier can be used to look up a value in the render node's ``RenderNode/references`` dictionary.
var identifier: RenderReferenceIdentifier { get }
}
/// The type of a reference.
public enum RenderReferenceType: String, Codable, Equatable {
case image, video, file, fileType, xcodeRequirement, topic, section, download, link, externalLocation
case unresolvable
}
/// The identifier of a render reference.
///
/// This structure wraps a string value to make handling of render identifiers more type safe and explicit.
public struct RenderReferenceIdentifier: Codable, Hashable, Equatable {
/// The wrapped string identifier.
public var identifier: String
/// Creates a new render identifier.
/// - Parameter identifier: The string identifier to wrap.
public init(_ identifier: String) {
self.identifier = identifier
}
public init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
identifier = try container.decode(String.self)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.singleValueContainer()
try container.encode(identifier)
}
private enum CodingKeys: CodingKey {
case identifier
}
}
/// A reference that has a file.
public protocol URLReference {
/// The base URL that file URLs of the conforming type are relative to.
static var baseURL: URL { get }
}
extension URLReference {
/// Returns the URL for a given file path relative to the base URL of the conforming type.
///
/// The converter that writes the built documentation to the file system is responsible for copying the referenced file to this destination.
///
/// - Parameters:
/// - path: The path of the file.
/// - prefixComponent: An optional path component to add before the path of the file.
/// - Returns: The destination URL for the given file path.
func destinationURL(for path: String, prefixComponent: String?) -> URL {
var url = Self.baseURL
if let bundleName = prefixComponent {
url.appendPathComponent(bundleName, isDirectory: true)
}
url.appendPathComponent(path, isDirectory: false)
return url
}
}
extension RenderReferenceIdentifier {
/// Creates a new render reference identifier, based on the path of the given external link.
///
/// This is not a unique identifier. If you create two render reference identifiers with the same external link destination, they are equal and interchangeable .
///
/// - Parameter linkDestination: The full path of the external link represented as a `String`.
public init(forExternalLink linkDestination: String) {
self.identifier = "\(linkDestination)"
}
}
// Diffable conformance
extension RenderReferenceIdentifier: RenderJSONDiffable {
/// Returns the difference between this RenderReferenceIdentifier and the given one.
func difference(from other: RenderReferenceIdentifier, at path: CodablePath) -> JSONPatchDifferences {
var diffBuilder = DifferenceBuilder(current: self, other: other, basePath: path)
diffBuilder.addDifferences(atKeyPath: \.identifier, forKey: CodingKeys.identifier)
return diffBuilder.differences
}
}
|