Overriding the description variable of a custom class:
override var description : String {
let mirrored_object = Mirror(reflecting: self)
let
I wouldn't use tabs but use padding(...)
:
var description : String {
let mirrored_object = Mirror(reflecting: self)
let childrenWithLabel = mirrored_object.children.filter { $0.label != nil }
let maxLen = childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0
let lines = childrenWithLabel.map { $0.label!.padding(toLength: maxLen, withPad: " ", startingAt: 0) + " = \($0.value)" }
return lines.joined(separator: "\n")
}
For a struct like
struct Foo: CustomStringConvertible
{
let userID = 42
let username = "Foo"
let verylongpropertyname: String? = "Bar"
}
this produces
userID = 42
username = Foo
verylongpropertyname = Optional("Bar")
As for the "Optional" part, it's not as easy as totiG suggests because the value you get from the mirror is of type Any
. See this question.
Update
I overlooked that you wanted to have a slightly different format.
var description : String {
let mirrored_object = Mirror(reflecting: self)
let childrenWithLabel = mirrored_object.children.filter { $0.label != nil }
let separator = " = "
let firstColumnWidth = (childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0) + separator.characters.count
let lines = childrenWithLabel.map {
($0.label! + separator).padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0) + "\($0.value)"
}
}
produces
userID = 42
username = Foo
verylongpropertyname = Optional("Bar")
Update 2
To get rid of the "Optional" thing, please see my answer here.
If you use (from said answer) unwrap()
or unwrapUsingProtocol()
in description
like this:
var description : String {
let mirrored_object = Mirror(reflecting: self)
let childrenWithLabel = mirrored_object.children.filter { $0.label != nil }
let separator = " = "
let firstColumnWidth = (childrenWithLabel.map { Int($0.label!.characters.count) }.max() ?? 0) + separator.characters.count
let lines = childrenWithLabel.map {
($0.label! + separator).padding(toLength: firstColumnWidth, withPad: " ", startingAt: 0) + "\(unwrap($0.value))"
}
return lines.joined(separator: "\n")
}
this will produce
userID = 42
username = Foo
verylongpropertyname = Bar