Skip to content

Instantly share code, notes, and snippets.

@AliSoftware
Created January 24, 2019 21:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save AliSoftware/7098e9b469317652eb6d23205e0e981c to your computer and use it in GitHub Desktop.
Save AliSoftware/7098e9b469317652eb6d23205e0e981c to your computer and use it in GitHub Desktop.
Some convenience methods using Mirror to build a nice custom debugDescription easily
extension Mirror {
/// Use this to help you implement a custom debugDescription listing all properties of your instances
///
/// - Parameters:
/// - subject: The instance for which to return the description.
///
/// Example usage:
///
/// extension MyType: CustomDebugStringConvertible {
/// var debugDescription: String {
/// return Mirror.debugDescription(self)
/// }
/// }
///
/// - Note: This will use a `Mirror` to extract the subject's type and list of properties
/// to include in the description
///
static func debugDescription(_ subject: Any) -> String {
let mirror = Mirror(reflecting: subject)
return self.debugDescription(type: mirror.subjectType, children: Array(mirror.children))
}
/// Use this to help you implement a custom debugDescription listing custom properties of your instance
///
/// - Parameters:
/// - type: The type for which to print the name of in the description
/// - properties: The list of custom properties to include in the description
///
/// Example usage:
///
/// extension MyType: CustomDebugStringConvertible {
/// var debugDescription: String {
/// return Mirror.debugDescription(type(of: self), [
/// "name": name,
/// "color": color,
/// "ownerName": owner?.name as Any
/// ])
/// }
/// }
///
static func debugDescription(_ type: Any.Type,
_ properties: DictionaryLiteral<String?, Any> = [:]) -> String {
let children = properties.map({ (label: $0.key, value: $0.value) })
return self.debugDescription(type: type, children: children)
}
private static func debugDescription(type: Any.Type, children: [Mirror.Child]) -> String {
let props = children.map { (prop: Mirror.Child) -> String in
let value = String(describing: prop.value)
// for values on multiple lines, also add indentation to all lines except the first
let desc = value.replacingOccurrences(of: "\n", with: "\n ")
return " \(prop.label ?? "-"): \(desc)"
}
return "\(type)(\n\(props.joined(separator: ",\n"))\n)"
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment