Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions PlaygroundLogger/PlaygroundLogger/LogEntry+Reflection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -360,15 +360,23 @@ fileprivate struct AnyExistentialContainer {
///
/// In precedence order, the rules are:
/// - If the instance is itself a `String`, return the instance
/// - If the instance is `CustomStringConvertible` or `CustomDebugStringConvertible`, use `String(reflecting:)`
/// - If the instance conforms to `CustomStringConvertible`, use `String(describing:)` to call `.description` directly
/// - If the instance conforms to `CustomDebugStringConvertible` (but NOT `CustomStringConvertible`), use `String(reflecting:)`
/// - If the instance is an enum (as reported using Mirror), use `String(describing:)`
/// - Otherwise, use the normalized type name
fileprivate func generateSummary(for instance: Any, withTypeName typeNameProvider: @autoclosure () -> String, using mirrorProvider: @autoclosure () -> Mirror) -> String {
if let string = instance as? String {
return string
}

if instance is CustomStringConvertible || instance is CustomDebugStringConvertible {
// Use String(describing:) for CustomStringConvertible so that .description is used directly,
// without the debug decoration (e.g. surrounding quotes) added by String(reflecting:).
if instance is CustomStringConvertible {
return String(describing: instance)
}

// Only fall back to String(reflecting:) for types that are solely CustomDebugStringConvertible.
if instance is CustomDebugStringConvertible {
return String(reflecting: instance)
}

Expand Down