From 00d866ee7b6fe0b4e2f322cb41c6edade3eb7b39 Mon Sep 17 00:00:00 2001 From: Kyle Date: Thu, 16 Apr 2026 01:44:43 +0800 Subject: [PATCH] Update NestedCustomStringConvertible implementation --- .../arm64-apple-ios-simulator.swiftinterface | 26 --- .../x86_64-apple-ios-simulator.swiftinterface | 26 --- .../arm64-apple-macos.swiftinterface | 26 --- .../arm64e-apple-macos.swiftinterface | 26 --- .../x86_64-apple-macos.swiftinterface | 26 --- .../template.swiftinterface | 26 --- GF/DeviceSwiftShims/Core/GestureOutput.swift | 17 +- .../Util/NestedCustomStringConvertible.swift | 182 +++++++++++++++++- .../Util/NestedDescription.swift | 136 ------------- 9 files changed, 179 insertions(+), 312 deletions(-) delete mode 100644 GF/DeviceSwiftShims/Util/NestedDescription.swift diff --git a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface index 053d0da..fdd255e 100644 --- a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface +++ b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/arm64-apple-ios-simulator.swiftinterface @@ -38,32 +38,6 @@ public enum GestureOutputEmptyReason : Swift.Hashable, Swift.Sendable { } public struct GestureOutputMetadata : Swift.Sendable { } -public enum GestureOutputStatus : Swift.Hashable, Swift.Sendable { - case empty - case value - case finalValue - public static func == (a: Gestures.GestureOutputStatus, b: Gestures.GestureOutputStatus) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -public struct GestureOutputStatusCombiner : Swift.Sendable { - public var combine: @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus - public init(combine: @escaping @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus) -} -public struct GestureOutputArrayCombiner : Swift.Sendable where A : Swift.Sendable { - public let statusCombiner: Gestures.GestureOutputStatusCombiner - public init(statusCombiner: Gestures.GestureOutputStatusCombiner) -} -public struct GestureOutputCombiner : Swift.Sendable where repeat each A : Swift.Sendable, B : Swift.Sendable { - public let combineValues: (@Sendable (repeat each A) throws -> B)? - public let combineOptionals: (@Sendable (repeat (each A)?) throws -> B)? - public let statusCombiner: Gestures.GestureOutputStatusCombiner - #if compiler(>=5.3) && $NonescapableTypes - public init(combineValues: (@Sendable (repeat each A) throws -> B)?, combineOptionals: (@Sendable (repeat (each A)?) throws -> B)?, statusCombiner: Gestures.GestureOutputStatusCombiner) - #endif -} public struct GestureTrait : Swift.Hashable, Swift.Identifiable, Swift.Sendable { public var id: Gestures.GestureTraitID public var attributes: [Gestures.GestureTrait.AttributeKey : Gestures.GestureTrait.AttributeValue] diff --git a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface index 5739e33..8f8cf1c 100644 --- a/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface +++ b/GF/2025/Gestures.xcframework/ios-arm64-x86_64-simulator/Gestures.framework/Modules/Gestures.swiftmodule/x86_64-apple-ios-simulator.swiftinterface @@ -38,32 +38,6 @@ public enum GestureOutputEmptyReason : Swift.Hashable, Swift.Sendable { } public struct GestureOutputMetadata : Swift.Sendable { } -public enum GestureOutputStatus : Swift.Hashable, Swift.Sendable { - case empty - case value - case finalValue - public static func == (a: Gestures.GestureOutputStatus, b: Gestures.GestureOutputStatus) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -public struct GestureOutputStatusCombiner : Swift.Sendable { - public var combine: @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus - public init(combine: @escaping @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus) -} -public struct GestureOutputArrayCombiner : Swift.Sendable where A : Swift.Sendable { - public let statusCombiner: Gestures.GestureOutputStatusCombiner - public init(statusCombiner: Gestures.GestureOutputStatusCombiner) -} -public struct GestureOutputCombiner : Swift.Sendable where repeat each A : Swift.Sendable, B : Swift.Sendable { - public let combineValues: (@Sendable (repeat each A) throws -> B)? - public let combineOptionals: (@Sendable (repeat (each A)?) throws -> B)? - public let statusCombiner: Gestures.GestureOutputStatusCombiner - #if compiler(>=5.3) && $NonescapableTypes - public init(combineValues: (@Sendable (repeat each A) throws -> B)?, combineOptionals: (@Sendable (repeat (each A)?) throws -> B)?, statusCombiner: Gestures.GestureOutputStatusCombiner) - #endif -} public struct GestureTrait : Swift.Hashable, Swift.Identifiable, Swift.Sendable { public var id: Gestures.GestureTraitID public var attributes: [Gestures.GestureTrait.AttributeKey : Gestures.GestureTrait.AttributeValue] diff --git a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface index d6c35b5..e42e64f 100644 --- a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface +++ b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64-apple-macos.swiftinterface @@ -38,32 +38,6 @@ public enum GestureOutputEmptyReason : Swift.Hashable, Swift.Sendable { } public struct GestureOutputMetadata : Swift.Sendable { } -public enum GestureOutputStatus : Swift.Hashable, Swift.Sendable { - case empty - case value - case finalValue - public static func == (a: Gestures.GestureOutputStatus, b: Gestures.GestureOutputStatus) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -public struct GestureOutputStatusCombiner : Swift.Sendable { - public var combine: @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus - public init(combine: @escaping @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus) -} -public struct GestureOutputArrayCombiner : Swift.Sendable where A : Swift.Sendable { - public let statusCombiner: Gestures.GestureOutputStatusCombiner - public init(statusCombiner: Gestures.GestureOutputStatusCombiner) -} -public struct GestureOutputCombiner : Swift.Sendable where repeat each A : Swift.Sendable, B : Swift.Sendable { - public let combineValues: (@Sendable (repeat each A) throws -> B)? - public let combineOptionals: (@Sendable (repeat (each A)?) throws -> B)? - public let statusCombiner: Gestures.GestureOutputStatusCombiner - #if compiler(>=5.3) && $NonescapableTypes - public init(combineValues: (@Sendable (repeat each A) throws -> B)?, combineOptionals: (@Sendable (repeat (each A)?) throws -> B)?, statusCombiner: Gestures.GestureOutputStatusCombiner) - #endif -} public struct GestureTrait : Swift.Hashable, Swift.Identifiable, Swift.Sendable { public var id: Gestures.GestureTraitID public var attributes: [Gestures.GestureTrait.AttributeKey : Gestures.GestureTrait.AttributeValue] diff --git a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface index 87ac123..f000d2e 100644 --- a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface +++ b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/arm64e-apple-macos.swiftinterface @@ -38,32 +38,6 @@ public enum GestureOutputEmptyReason : Swift.Hashable, Swift.Sendable { } public struct GestureOutputMetadata : Swift.Sendable { } -public enum GestureOutputStatus : Swift.Hashable, Swift.Sendable { - case empty - case value - case finalValue - public static func == (a: Gestures.GestureOutputStatus, b: Gestures.GestureOutputStatus) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -public struct GestureOutputStatusCombiner : Swift.Sendable { - public var combine: @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus - public init(combine: @escaping @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus) -} -public struct GestureOutputArrayCombiner : Swift.Sendable where A : Swift.Sendable { - public let statusCombiner: Gestures.GestureOutputStatusCombiner - public init(statusCombiner: Gestures.GestureOutputStatusCombiner) -} -public struct GestureOutputCombiner : Swift.Sendable where repeat each A : Swift.Sendable, B : Swift.Sendable { - public let combineValues: (@Sendable (repeat each A) throws -> B)? - public let combineOptionals: (@Sendable (repeat (each A)?) throws -> B)? - public let statusCombiner: Gestures.GestureOutputStatusCombiner - #if compiler(>=5.3) && $NonescapableTypes - public init(combineValues: (@Sendable (repeat each A) throws -> B)?, combineOptionals: (@Sendable (repeat (each A)?) throws -> B)?, statusCombiner: Gestures.GestureOutputStatusCombiner) - #endif -} public struct GestureTrait : Swift.Hashable, Swift.Identifiable, Swift.Sendable { public var id: Gestures.GestureTraitID public var attributes: [Gestures.GestureTrait.AttributeKey : Gestures.GestureTrait.AttributeValue] diff --git a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface index 552aa91..5be8ff9 100644 --- a/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface +++ b/GF/2025/Gestures.xcframework/macos-arm64e-arm64-x86_64/Gestures.framework/Versions/A/Modules/Gestures.swiftmodule/x86_64-apple-macos.swiftinterface @@ -38,32 +38,6 @@ public enum GestureOutputEmptyReason : Swift.Hashable, Swift.Sendable { } public struct GestureOutputMetadata : Swift.Sendable { } -public enum GestureOutputStatus : Swift.Hashable, Swift.Sendable { - case empty - case value - case finalValue - public static func == (a: Gestures.GestureOutputStatus, b: Gestures.GestureOutputStatus) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -public struct GestureOutputStatusCombiner : Swift.Sendable { - public var combine: @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus - public init(combine: @escaping @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus) -} -public struct GestureOutputArrayCombiner : Swift.Sendable where A : Swift.Sendable { - public let statusCombiner: Gestures.GestureOutputStatusCombiner - public init(statusCombiner: Gestures.GestureOutputStatusCombiner) -} -public struct GestureOutputCombiner : Swift.Sendable where repeat each A : Swift.Sendable, B : Swift.Sendable { - public let combineValues: (@Sendable (repeat each A) throws -> B)? - public let combineOptionals: (@Sendable (repeat (each A)?) throws -> B)? - public let statusCombiner: Gestures.GestureOutputStatusCombiner - #if compiler(>=5.3) && $NonescapableTypes - public init(combineValues: (@Sendable (repeat each A) throws -> B)?, combineOptionals: (@Sendable (repeat (each A)?) throws -> B)?, statusCombiner: Gestures.GestureOutputStatusCombiner) - #endif -} public struct GestureTrait : Swift.Hashable, Swift.Identifiable, Swift.Sendable { public var id: Gestures.GestureTraitID public var attributes: [Gestures.GestureTrait.AttributeKey : Gestures.GestureTrait.AttributeValue] diff --git a/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface b/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface index 41c4561..de5221f 100644 --- a/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface +++ b/GF/2025/Sources/Modules/Gestures.swiftmodule/template.swiftinterface @@ -34,32 +34,6 @@ public enum GestureOutputEmptyReason : Swift.Hashable, Swift.Sendable { } public struct GestureOutputMetadata : Swift.Sendable { } -public enum GestureOutputStatus : Swift.Hashable, Swift.Sendable { - case empty - case value - case finalValue - public static func == (a: Gestures.GestureOutputStatus, b: Gestures.GestureOutputStatus) -> Swift.Bool - public func hash(into hasher: inout Swift.Hasher) - public var hashValue: Swift.Int { - get - } -} -public struct GestureOutputStatusCombiner : Swift.Sendable { - public var combine: @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus - public init(combine: @escaping @Sendable ([Gestures.GestureOutputStatus]) throws -> Gestures.GestureOutputStatus) -} -public struct GestureOutputArrayCombiner : Swift.Sendable where A : Swift.Sendable { - public let statusCombiner: Gestures.GestureOutputStatusCombiner - public init(statusCombiner: Gestures.GestureOutputStatusCombiner) -} -public struct GestureOutputCombiner : Swift.Sendable where repeat each A : Swift.Sendable, B : Swift.Sendable { - public let combineValues: (@Sendable (repeat each A) throws -> B)? - public let combineOptionals: (@Sendable (repeat (each A)?) throws -> B)? - public let statusCombiner: Gestures.GestureOutputStatusCombiner - #if compiler(>=5.3) && $NonescapableTypes - public init(combineValues: (@Sendable (repeat each A) throws -> B)?, combineOptionals: (@Sendable (repeat (each A)?) throws -> B)?, statusCombiner: Gestures.GestureOutputStatusCombiner) - #endif -} public struct GestureTrait : Swift.Hashable, Swift.Identifiable, Swift.Sendable { public var id: Gestures.GestureTraitID public var attributes: [Gestures.GestureTrait.AttributeKey : Gestures.GestureTrait.AttributeValue] diff --git a/GF/DeviceSwiftShims/Core/GestureOutput.swift b/GF/DeviceSwiftShims/Core/GestureOutput.swift index 2f54857..eb3a329 100644 --- a/GF/DeviceSwiftShims/Core/GestureOutput.swift +++ b/GF/DeviceSwiftShims/Core/GestureOutput.swift @@ -87,22 +87,7 @@ public struct GestureOutputMetadata: Sendable { // MARK: - GestureOutputMetadata + NestedCustomStringConvertible -extension GestureOutputMetadata: NestedCustomStringConvertible { - package func populateNestedDescription(_ nested: inout NestedDescription) { - nested.options.formUnion([.hideTypeName, .compact]) - nested.customPrefix = "" - nested.customSuffix = "" - if !updatesToSchedule.isEmpty { - nested.append("\(updatesToSchedule)", label: "updatesToSchedule") - } - if !updatesToCancel.isEmpty { - nested.append("\(updatesToCancel)", label: "updatesToCancel") - } - if let traceAnnotation { - nested.append(traceAnnotation.value, label: "traceAnnotation") - } - } -} +extension GestureOutputMetadata: NestedCustomStringConvertible {} // MARK: - UpdateTraceAnnotation diff --git a/GF/DeviceSwiftShims/Util/NestedCustomStringConvertible.swift b/GF/DeviceSwiftShims/Util/NestedCustomStringConvertible.swift index 6e018c0..c50ff62 100644 --- a/GF/DeviceSwiftShims/Util/NestedCustomStringConvertible.swift +++ b/GF/DeviceSwiftShims/Util/NestedCustomStringConvertible.swift @@ -12,14 +12,27 @@ package protocol NestedCustomStringConvertible: CustomDebugStringConvertible, Cu } extension NestedCustomStringConvertible { + package func populateNestedDescription(_ nested: inout NestedDescription) { + let mirror = Mirror(reflecting: self) + for child in mirror.children { + guard let label = child.label else { continue } + var value: Any = child.value + if let optional = value as? OptionalProtocol { + guard !optional.isNil else { continue } + value = optional.value! + } + if let collection = value as? any Collection { + guard !collection.isEmpty else { continue } + } + nested.append(value, label: label) + } + } + @_spi(Private) public var description: String { var nested = NestedDescription(depth: 0, target: self) populateNestedDescription(&nested) - var result = nested.buildOpening() - result += nested.buildBody() - result += nested.buildClosing() - return result + return nested.description } @_spi(Private) @@ -28,6 +41,29 @@ extension NestedCustomStringConvertible { } } +// MARK: - OptionalProtocol + +package protocol OptionalProtocol { + var isNil: Bool { get } + var value: Any? { get } +} + +extension Optional: OptionalProtocol { + package var isNil: Bool { + switch self { + case .none: true + case .some: false + } + } + + package var value: Any? { + switch self { + case .none: nil + case let .some(value): value + } + } +} + // MARK: - Standard Library Conformances extension Array: NestedCustomStringConvertible where Element: NestedCustomStringConvertible { @@ -59,3 +95,141 @@ extension Dictionary: NestedCustomStringConvertible where Value: NestedCustomStr } } } + +// MARK: - NestedDescription + +package struct NestedDescription { + package struct Options: OptionSet { + package let rawValue: Int + + package init(rawValue: Int) { + self.rawValue = rawValue + } + + package static let hideTypeName = Self(rawValue: 1 << 0) + package static let hideIdentity = Self(rawValue: 1 << 1) + package static let hideClassAddress = Self(rawValue: 1 << 2) + package static let compact = Self(rawValue: 1 << 3) + } + package var options: Options + package var customPrefix: String? + package var customSuffix: String? + package let depth: Int + package let target: Any + package var buffer: [String] + + package init( + options: Options = [], + customPrefix: String? = nil, + customSuffix: String? = nil, + depth: Int, + target: Any, + buffer: [String] = [] + ) { + self.options = options + self.customPrefix = customPrefix + self.customSuffix = customSuffix + self.depth = depth + self.target = target + self.buffer = buffer + } + + mutating package func append( + _ content: T?, + label: String? = nil + ) { + guard let content else { + return + } + var result: String = "" + if let label { + result += "\(label): " + } + if let nestedConvertible = content as? any NestedCustomStringConvertible { + var childNested = NestedDescription(depth: depth + 1, target: nestedConvertible) + nestedConvertible.populateNestedDescription(&childNested) + result += childNested.description + } else { + result += "\(content)" + } + if !result.isEmpty { + buffer.append(result) + } + } + + // MARK: - Build + + package func buildOpening() -> String { + if let customPrefix { + return customPrefix + } + var result: String + if !options.contains(.hideTypeName) { + result = "\(type(of: target))" + } else { + result = "" + } + var hasClassIdentity = false + if !options.contains(.hideClassAddress) { + let dynamicType = type(of: target) + if dynamicType is AnyObject.Type { + let obj = target as AnyObject + let address = UInt(bitPattern: ObjectIdentifier(obj)) + let addressString = "0x\(String(address, radix: 16, uppercase: false))" + result += " <\(addressString)" + hasClassIdentity = true + } + } + if !options.contains(.hideIdentity), + let identifiable = target as? any Identifiable { + if hasClassIdentity { + result += " \(identifiable.id)>" + } else { + result += " <\(identifiable.id)>" + } + } else if hasClassIdentity { + result += ">" + } + result += result.isEmpty ? "" : " " + result += "{" + result += buffer.isEmpty ? "" : " " + return result + } + + package func buildBody() -> String { + guard !options.contains(.compact) else { + return buffer.joined(separator: ", ") + } + let separator: String + if buffer.isEmpty { + separator = "" + } else { + let depth = depth + 1 + let indent = String(repeating: " ", count: 2) + let indentWithDepth = String(repeating: indent, count: depth) + separator = "\n" + indentWithDepth + } + return separator + buffer.joined(separator: separator) + } + + package func buildClosing() -> String { + var result = customSuffix ?? "}" + guard !buffer.isEmpty else { + return result + } + let leading: String + if options.contains(.compact) { + leading = customSuffix == nil ? " " : "" + } else { + let indent = String(repeating: " ", count: 2) + let indentWithDepth = String(repeating: indent, count: depth) + leading = "\n\(indentWithDepth)" + } + result = leading + result + return result + } + + package var description: String { + buildOpening() + buildBody() + buildClosing() + } +} diff --git a/GF/DeviceSwiftShims/Util/NestedDescription.swift b/GF/DeviceSwiftShims/Util/NestedDescription.swift deleted file mode 100644 index 3ebbd9e..0000000 --- a/GF/DeviceSwiftShims/Util/NestedDescription.swift +++ /dev/null @@ -1,136 +0,0 @@ -// -// NestedDescription.swift -// Gestures -// -// Audited for 9126.1.5 -// Status: Complete - -package struct NestedDescription { - package struct Options: OptionSet { - package let rawValue: Int - - package init(rawValue: Int) { - self.rawValue = rawValue - } - - package static let hideTypeName = Self(rawValue: 1 << 0) - package static let hideIdentity = Self(rawValue: 1 << 1) - package static let hideClassAddress = Self(rawValue: 1 << 2) - package static let compact = Self(rawValue: 1 << 3) - } - package var options: Options - package var customPrefix: String? - package var customSuffix: String? - package let depth: Int - package let target: Any - package var buffer: [String] - - package init( - options: Options = [], - customPrefix: String? = nil, - customSuffix: String? = nil, - depth: Int, - target: Any, - buffer: [String] = [] - ) { - self.options = options - self.customPrefix = customPrefix - self.customSuffix = customSuffix - self.depth = depth - self.target = target - self.buffer = buffer - } - - mutating package func append( - _ content: @autoclosure () -> T?, - label: String? = nil - ) { - guard let content = content() else { - return - } - var result: String = "" - if let label { - result += "\(label): " - } - result += "\(content)" - if !result.isEmpty { - buffer.append(result) - } - } - - // MARK: - Build - - package func buildOpening() -> String { - if let customPrefix { - return customPrefix - } - var result: String - if !options.contains(.hideTypeName) { - result = "\(type(of: target))" - } else { - result = "" - } - var hasClassIdentity = false - if !options.contains(.hideClassAddress) { - let dynamicType = type(of: target) - if dynamicType is AnyObject.Type { - let obj = target as AnyObject - let address = UInt(bitPattern: ObjectIdentifier(obj)) - let addressString = "0x\(String(address, radix: 16, uppercase: false))" - result += " <\(addressString)" - hasClassIdentity = true - } - } - if !options.contains(.hideIdentity), - let identifiable = target as? any Identifiable { - if hasClassIdentity { - result += " \(identifiable.id)>" - } else { - result += " <\(identifiable.id)>" - } - } else if hasClassIdentity { - result += ">" - } - result += result.isEmpty ? "" : " " - result += "{" - result += buffer.isEmpty ? "" : " " - return result - } - - package func buildBody() -> String { - guard !options.contains(.compact) else { - return buffer.joined(separator: ", ") - } - let separator: String - if buffer.isEmpty { - separator = "" - } else { - let depth = depth + 1 - let indent = String(repeating: " ", count: 2) - let indentWithDepth = String(repeating: indent, count: depth) - separator = "\n" + indentWithDepth - } - return separator + buffer.joined(separator: separator) - } - - package func buildClosing() -> String { - var result = customSuffix ?? "}" - guard !buffer.isEmpty else { - return result - } - let leading: String - if options.contains(.compact) { - leading = customSuffix == nil ? " " : "" - } else { - let indent = String(repeating: " ", count: 2) - let indentWithDepth = String(repeating: indent, count: depth) - leading = "\n\(indentWithDepth)" - } - result = leading + result - return result - } - - package var description: String { - buildOpening() + buildBody() + buildClosing() - } -}